From 5a4859c3baa31dd08a68ab07511cdb0029ef8317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 19 Oct 2021 17:37:36 +0200 Subject: [PATCH 01/65] WIP: Successfully replace a waterfall with native async/await --- lib/datastore.js | 118 +++++++++++++++++++----------------------- test/db.test.js | 14 +++++ test/executor.test.js | 10 ++++ 3 files changed, 76 insertions(+), 66 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 16c4d19..491a3f2 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -222,6 +222,38 @@ class Datastore extends EventEmitter { } } + _getCandidates (query) { + const indexNames = Object.keys(this.indexes) + // STEP 1: get candidates list by checking indexes from most to least frequent usecase + // For a basic match + let usableQuery + usableQuery = Object.entries(query) + .filter(([k, v]) => + !!(typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || isDate(v) || v === null) && + indexNames.includes(k) + ) + .pop() + if (usableQuery) return this.indexes[usableQuery[0]].getMatching(usableQuery[1]) + // For a $in match + usableQuery = Object.entries(query) + .filter(([k, v]) => + !!(query[k] && Object.prototype.hasOwnProperty.call(query[k], '$in')) && + indexNames.includes(k) + ) + .pop() + if (usableQuery) return this.indexes[usableQuery[0]].getMatching(usableQuery[1].$in) + // For a comparison match + usableQuery = Object.entries(query) + .filter(([k, v]) => + !!(query[k] && (Object.prototype.hasOwnProperty.call(query[k], '$lt') || Object.prototype.hasOwnProperty.call(query[k], '$lte') || Object.prototype.hasOwnProperty.call(query[k], '$gt') || Object.prototype.hasOwnProperty.call(query[k], '$gte'))) && + indexNames.includes(k) + ) + .pop() + if (usableQuery) return this.indexes[usableQuery[0]].getBetweenBounds(usableQuery[1]) + // By default, return all the DB data + return this.getAllData() + } + /** * Return the list of candidates for a given query * Crude implementation for now, we return the candidates given by the first usable index if any @@ -235,87 +267,41 @@ class Datastore extends EventEmitter { * @param {Boolean} dontExpireStaleDocs Optional, defaults to false, if true don't remove stale docs. Useful for the remove function which shouldn't be impacted by expirations * @param {Function} callback Signature err, candidates */ - getCandidates (query, dontExpireStaleDocs, callback) { - const indexNames = Object.keys(this.indexes) - let usableQueryKeys + async getCandidates (query, dontExpireStaleDocs, callback) { + const validDocs = [] if (typeof dontExpireStaleDocs === 'function') { callback = dontExpireStaleDocs dontExpireStaleDocs = false } - async.waterfall([ + try { // STEP 1: get candidates list by checking indexes from most to least frequent usecase - cb => { - // For a basic match - usableQueryKeys = [] - Object.keys(query).forEach(k => { - if (typeof query[k] === 'string' || typeof query[k] === 'number' || typeof query[k] === 'boolean' || isDate(query[k]) || query[k] === null) { - usableQueryKeys.push(k) - } - }) - usableQueryKeys = usableQueryKeys.filter(k => indexNames.includes(k)) - if (usableQueryKeys.length > 0) { - return cb(null, this.indexes[usableQueryKeys[0]].getMatching(query[usableQueryKeys[0]])) - } - - // For a $in match - usableQueryKeys = [] - Object.keys(query).forEach(k => { - if (query[k] && Object.prototype.hasOwnProperty.call(query[k], '$in')) { - usableQueryKeys.push(k) - } - }) - usableQueryKeys = usableQueryKeys.filter(k => indexNames.includes(k)) - if (usableQueryKeys.length > 0) { - return cb(null, this.indexes[usableQueryKeys[0]].getMatching(query[usableQueryKeys[0]].$in)) - } - - // For a comparison match - usableQueryKeys = [] - Object.keys(query).forEach(k => { - if (query[k] && (Object.prototype.hasOwnProperty.call(query[k], '$lt') || Object.prototype.hasOwnProperty.call(query[k], '$lte') || Object.prototype.hasOwnProperty.call(query[k], '$gt') || Object.prototype.hasOwnProperty.call(query[k], '$gte'))) { - usableQueryKeys.push(k) - } - }) - usableQueryKeys = usableQueryKeys.filter(k => indexNames.includes(k)) - if (usableQueryKeys.length > 0) { - return cb(null, this.indexes[usableQueryKeys[0]].getBetweenBounds(query[usableQueryKeys[0]])) - } - - // By default, return all the DB data - return cb(null, this.getAllData()) - }, + const docs = this._getCandidates(query) // STEP 2: remove all expired documents - docs => { - if (dontExpireStaleDocs) return callback(null, docs) - + if (!dontExpireStaleDocs) { const expiredDocsIds = [] - const validDocs = [] const ttlIndexesFieldNames = Object.keys(this.ttlIndexes) docs.forEach(doc => { - let valid = true - ttlIndexesFieldNames.forEach(i => { - if (doc[i] !== undefined && isDate(doc[i]) && Date.now() > doc[i].getTime() + this.ttlIndexes[i] * 1000) { - valid = false - } - }) - if (valid) validDocs.push(doc) + if (ttlIndexesFieldNames.every(i => !(doc[i] !== undefined && isDate(doc[i]) && Date.now() > doc[i].getTime() + this.ttlIndexes[i] * 1000))) validDocs.push(doc) else expiredDocsIds.push(doc._id) }) - - async.eachSeries(expiredDocsIds, (_id, cb) => { - this._remove({ _id: _id }, {}, err => { - if (err) return callback(err) - return cb() + for (const _id of expiredDocsIds) { + await new Promise((resolve, reject) => { + this._remove({ _id: _id }, {}, err => { + if (err) return reject(err) + return resolve() + }) }) - // eslint-disable-next-line node/handle-callback-err - }, err => { - // TODO: handle error - return callback(null, validDocs) - }) - }]) + } + } else validDocs.push(...docs) + } catch (error) { + if (typeof callback === 'function') callback(error, null) + else throw error + } + if (typeof callback === 'function') callback(null, validDocs) + else return validDocs } /** diff --git a/test/db.test.js b/test/db.test.js index 8620adf..aff8e50 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -431,9 +431,12 @@ describe('Database', function () { it('If the callback throws an uncaught exception, do not catch it inside findOne, this is userspace concern', function (done) { let tryCount = 0 const currentUncaughtExceptionHandlers = process.listeners('uncaughtException') + const currentUnhandledRejectionHandlers = process.listeners('unhandledRejection') + let i process.removeAllListeners('uncaughtException') + process.removeAllListeners('unhandledRejection') process.on('uncaughtException', function MINE (ex) { process.removeAllListeners('uncaughtException') @@ -446,6 +449,17 @@ describe('Database', function () { done() }) + process.on('unhandledRejection', function MINE (ex) { + process.removeAllListeners('unhandledRejection') + + for (i = 0; i < currentUnhandledRejectionHandlers.length; i += 1) { + process.on('unhandledRejection', currentUnhandledRejectionHandlers[i]) + } + + ex.message.should.equal('SOME EXCEPTION') + done() + }) + d.insert({ a: 5 }, function () { // eslint-disable-next-line node/handle-callback-err d.findOne({ a: 5 }, function (err, doc) { diff --git a/test/executor.test.js b/test/executor.test.js index 13c6606..fda65ff 100755 --- a/test/executor.test.js +++ b/test/executor.test.js @@ -14,23 +14,33 @@ chai.should() // We prevent Mocha from catching the exception we throw on purpose by remembering all current handlers, remove them and register them back after test ends function testThrowInCallback (d, done) { const currentUncaughtExceptionHandlers = process.listeners('uncaughtException') + const currentUnhandledRejectionHandlers = process.listeners('unhandledRejection') process.removeAllListeners('uncaughtException') + process.removeAllListeners('unhandledRejection') // eslint-disable-next-line node/handle-callback-err process.on('uncaughtException', function (err) { // Do nothing with the error which is only there to test we stay on track }) + process.on('unhandledRejection', function MINE (ex) { + // Do nothing with the error which is only there to test we stay on track + }) + // eslint-disable-next-line node/handle-callback-err d.find({}, function (err) { process.nextTick(function () { // eslint-disable-next-line node/handle-callback-err d.insert({ bar: 1 }, function (err) { process.removeAllListeners('uncaughtException') + process.removeAllListeners('unhandledRejection') for (let i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) { process.on('uncaughtException', currentUncaughtExceptionHandlers[i]) } + for (let i = 0; i < currentUnhandledRejectionHandlers.length; i += 1) { + process.on('unhandledRejection', currentUnhandledRejectionHandlers[i]) + } done() }) From f9e4c525e41c952b6aeb5eb1ac4b8e85612e8064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 08:55:50 +0200 Subject: [PATCH 02/65] WIP instead of having one function that can handle both async and callback signatures, let's implement a new Async suite of functions, and use callbackify to shim the old interface --- lib/datastore.js | 219 +++++++++++++++++++++++++++-------------------- 1 file changed, 124 insertions(+), 95 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 491a3f2..9dd255c 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -1,4 +1,5 @@ const { EventEmitter } = require('events') +const { callbackify } = require('util') const async = require('async') const Cursor = require('./cursor.js') const customUtils = require('./customUtils.js') @@ -267,26 +268,61 @@ class Datastore extends EventEmitter { * @param {Boolean} dontExpireStaleDocs Optional, defaults to false, if true don't remove stale docs. Useful for the remove function which shouldn't be impacted by expirations * @param {Function} callback Signature err, candidates */ - async getCandidates (query, dontExpireStaleDocs, callback) { - const validDocs = [] - + getCandidates (query, dontExpireStaleDocs, callback) { if (typeof dontExpireStaleDocs === 'function') { callback = dontExpireStaleDocs dontExpireStaleDocs = false } - try { + callbackify(this.getCandidatesAsync.bind(this))(query, dontExpireStaleDocs, callback) + } + + async getCandidatesAsync (query, dontExpireStaleDocs = false) { + const indexNames = Object.keys(this.indexes) + const validDocs = [] + + const _getCandidates = query => { // STEP 1: get candidates list by checking indexes from most to least frequent usecase - const docs = this._getCandidates(query) - // STEP 2: remove all expired documents + // For a basic match + let usableQuery + usableQuery = Object.entries(query) + .filter(([k, v]) => + !!(typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || isDate(v) || v === null) && + indexNames.includes(k) + ) + .pop() + if (usableQuery) return this.indexes[usableQuery[0]].getMatching(usableQuery[1]) + // For a $in match + usableQuery = Object.entries(query) + .filter(([k, v]) => + !!(query[k] && Object.prototype.hasOwnProperty.call(query[k], '$in')) && + indexNames.includes(k) + ) + .pop() + if (usableQuery) return this.indexes[usableQuery[0]].getMatching(usableQuery[1].$in) + // For a comparison match + usableQuery = Object.entries(query) + .filter(([k, v]) => + !!(query[k] && (Object.prototype.hasOwnProperty.call(query[k], '$lt') || Object.prototype.hasOwnProperty.call(query[k], '$lte') || Object.prototype.hasOwnProperty.call(query[k], '$gt') || Object.prototype.hasOwnProperty.call(query[k], '$gte'))) && + indexNames.includes(k) + ) + .pop() + if (usableQuery) return this.indexes[usableQuery[0]].getBetweenBounds(usableQuery[1]) + // By default, return all the DB data + return this.getAllData() + } + + // STEP 1: get candidates list by checking indexes from most to least frequent usecase + const docs = _getCandidates(query) + // STEP 2: remove all expired documents if (!dontExpireStaleDocs) { - const expiredDocsIds = [] - const ttlIndexesFieldNames = Object.keys(this.ttlIndexes) + const expiredDocsIds = [] + const ttlIndexesFieldNames = Object.keys(this.ttlIndexes) - docs.forEach(doc => { + docs.forEach(doc => { if (ttlIndexesFieldNames.every(i => !(doc[i] !== undefined && isDate(doc[i]) && Date.now() > doc[i].getTime() + this.ttlIndexes[i] * 1000))) validDocs.push(doc) - else expiredDocsIds.push(doc._id) - }) + else expiredDocsIds.push(doc._id) + }) for (const _id of expiredDocsIds) { await new Promise((resolve, reject) => { this._remove({ _id: _id }, {}, err => { @@ -294,14 +330,9 @@ class Datastore extends EventEmitter { return resolve() }) }) - } - } else validDocs.push(...docs) - } catch (error) { - if (typeof callback === 'function') callback(error, null) - else throw error - } - if (typeof callback === 'function') callback(null, validDocs) - else return validDocs + } + } else validDocs.push(...docs) + return validDocs } /** @@ -509,92 +540,90 @@ class Datastore extends EventEmitter { options = {} } const callback = cb || (() => {}) + + const _callback = (err, res = {}) => { + callback(err, res.numAffected, res.affectedDocuments, res.upsert) + } + callbackify(this._updateAsync.bind(this))(query, updateQuery, options, _callback) + } + + async _updateAsync (query, updateQuery, options = {}) { const multi = options.multi !== undefined ? options.multi : false const upsert = options.upsert !== undefined ? options.upsert : false - async.waterfall([ - cb => { // If upsert option is set, check whether we need to insert the doc - if (!upsert) return cb() + // If upsert option is set, check whether we need to insert the doc + if (upsert) { + // Need to use an internal function not tied to the executor to avoid deadlock + const cursor = new Cursor(this, query) - // Need to use an internal function not tied to the executor to avoid deadlock - const cursor = new Cursor(this, query) + const docs = await new Promise((resolve, reject) => { cursor.limit(1)._exec((err, docs) => { - if (err) return callback(err) - if (docs.length === 1) return cb() - else { - let toBeInserted - - try { - model.checkObject(updateQuery) - // updateQuery is a simple object with no modifier, use it as the document to insert - toBeInserted = updateQuery - } catch (e) { - // updateQuery contains modifiers, use the find query as the base, - // strip it from all operators and update it according to updateQuery - try { - toBeInserted = model.modify(model.deepCopy(query, true), updateQuery) - } catch (err) { - return callback(err) - } - } - - return this._insert(toBeInserted, (err, newDoc) => { - if (err) return callback(err) - return callback(null, 1, newDoc, true) - }) - } + if (err) reject(err) + else resolve(docs) }) - }, - () => { // Perform the update - let numReplaced = 0 - let modifiedDoc - const modifications = [] - let createdAt - - this.getCandidates(query, (err, candidates) => { - if (err) return callback(err) - - // Preparing update (if an error is thrown here neither the datafile nor - // the in-memory indexes are affected) - try { - for (const candidate of candidates) { - if (model.match(candidate, query) && (multi || numReplaced === 0)) { - numReplaced += 1 - if (this.timestampData) { createdAt = candidate.createdAt } - modifiedDoc = model.modify(candidate, updateQuery) - if (this.timestampData) { - modifiedDoc.createdAt = createdAt - modifiedDoc.updatedAt = new Date() - } - modifications.push({ oldDoc: candidate, newDoc: modifiedDoc }) - } - } - } catch (err) { - return callback(err) - } + }) - // Change the docs in memory - try { - this.updateIndexes(modifications) - } catch (err) { - return callback(err) - } + if (docs.length !== 1) { + let toBeInserted + + try { + model.checkObject(updateQuery) + // updateQuery is a simple object with no modifier, use it as the document to insert + toBeInserted = updateQuery + } catch (e) { + // updateQuery contains modifiers, use the find query as the base, + // strip it from all operators and update it according to updateQuery + toBeInserted = model.modify(model.deepCopy(query, true), updateQuery) + } - // Update the datafile - const updatedDocs = modifications.map(x => x.newDoc) - this.persistence.persistNewState(updatedDocs, err => { - if (err) return callback(err) - if (!options.returnUpdatedDocs) { - return callback(null, numReplaced) - } else { - let updatedDocsDC = [] - updatedDocs.forEach(doc => { updatedDocsDC.push(model.deepCopy(doc)) }) - if (!multi) updatedDocsDC = updatedDocsDC[0] - return callback(null, numReplaced, updatedDocsDC) - } + return new Promise((resolve, reject) => { + this._insert(toBeInserted, (err, newDoc) => { + if (err) return reject(err) + return resolve({ numAffected: 1, affectedDocuments: newDoc, upsert: true }) }) }) - }]) + } + } + // Perform the update + let numReplaced = 0 + let modifiedDoc + const modifications = [] + let createdAt + + const candidates = await this.getCandidatesAsync(query) + // Preparing update (if an error is thrown here neither the datafile nor + // the in-memory indexes are affected) + for (const candidate of candidates) { + if (model.match(candidate, query) && (multi || numReplaced === 0)) { + numReplaced += 1 + if (this.timestampData) { createdAt = candidate.createdAt } + modifiedDoc = model.modify(candidate, updateQuery) + if (this.timestampData) { + modifiedDoc.createdAt = createdAt + modifiedDoc.updatedAt = new Date() + } + modifications.push({ oldDoc: candidate, newDoc: modifiedDoc }) + } + } + + // Change the docs in memory + this.updateIndexes(modifications) + + // Update the datafile + const updatedDocs = modifications.map(x => x.newDoc) + await new Promise((resolve, reject) => { + this.persistence.persistNewState(updatedDocs, err => { + if (err) return reject(err) + else resolve() + }) + }) + if (!options.returnUpdatedDocs) return { numAffected: numReplaced } + else { + let updatedDocsDC = [] + updatedDocs.forEach(doc => { updatedDocsDC.push(model.deepCopy(doc)) }) + if (!multi) updatedDocsDC = updatedDocsDC[0] + return { numAffected: numReplaced, affectedDocuments: updatedDocsDC } + } } update () { From 5f7bc1244d7943c263057b4d73ffb3282d63f685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 08:56:17 +0200 Subject: [PATCH 03/65] WIP: linting --- lib/datastore.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 9dd255c..c1788bd 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -1,6 +1,5 @@ const { EventEmitter } = require('events') const { callbackify } = require('util') -const async = require('async') const Cursor = require('./cursor.js') const customUtils = require('./customUtils.js') const Executor = require('./executor.js') @@ -315,21 +314,21 @@ class Datastore extends EventEmitter { // STEP 1: get candidates list by checking indexes from most to least frequent usecase const docs = _getCandidates(query) // STEP 2: remove all expired documents - if (!dontExpireStaleDocs) { + if (!dontExpireStaleDocs) { const expiredDocsIds = [] const ttlIndexesFieldNames = Object.keys(this.ttlIndexes) docs.forEach(doc => { - if (ttlIndexesFieldNames.every(i => !(doc[i] !== undefined && isDate(doc[i]) && Date.now() > doc[i].getTime() + this.ttlIndexes[i] * 1000))) validDocs.push(doc) + if (ttlIndexesFieldNames.every(i => !(doc[i] !== undefined && isDate(doc[i]) && Date.now() > doc[i].getTime() + this.ttlIndexes[i] * 1000))) validDocs.push(doc) else expiredDocsIds.push(doc._id) }) - for (const _id of expiredDocsIds) { - await new Promise((resolve, reject) => { - this._remove({ _id: _id }, {}, err => { - if (err) return reject(err) - return resolve() - }) + for (const _id of expiredDocsIds) { + await new Promise((resolve, reject) => { + this._remove({ _id: _id }, {}, err => { + if (err) return reject(err) + return resolve() }) + }) } } else validDocs.push(...docs) return validDocs From 64bdd37c4f51b493781e1a543e8a5de08a30c713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 10:29:59 +0200 Subject: [PATCH 04/65] WIP: remove async from storage module --- lib/storage.js | 117 +++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 53 deletions(-) diff --git a/lib/storage.js b/lib/storage.js index fa8f12a..8e8d2eb 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -7,16 +7,21 @@ * It's essentially fs, mkdirp and crash safe write and read functions */ const fs = require('fs') +const fsPromises = require('fs/promises') const path = require('path') -const async = require('async') +const { callbackify, promisify } = require('util') const storage = {} const { Readable } = require('stream') // eslint-disable-next-line node/no-callback-literal storage.exists = (path, cb) => fs.access(path, fs.constants.F_OK, (err) => { cb(!err) }) +storage.existsAsync = path => fsPromises.access(path, fs.constants.F_OK).then(() => true, () => false) storage.rename = fs.rename +storage.renameAsync = fsPromises.rename storage.writeFile = fs.writeFile +storage.writeFileAsync = fsPromises.writeFile storage.unlink = fs.unlink +storage.unlinkAsync = fsPromises.unlink storage.appendFile = fs.appendFile storage.readFile = fs.readFile storage.readFileStream = fs.createReadStream @@ -25,21 +30,21 @@ storage.mkdir = fs.mkdir /** * Explicit name ... */ -storage.ensureFileDoesntExist = (file, callback) => { - storage.exists(file, exists => { - if (!exists) return callback(null) - - storage.unlink(file, err => callback(err)) - }) +storage.ensureFileDoesntExistAsync = async file => { + if (await storage.existsAsync(file)) await storage.unlinkAsync(file) } +storage.ensureFileDoesntExist = (file, callback) => callbackify(storage.ensureFileDoesntExistAsync)(file, err => callback(err)) + /** * Flush data in OS buffer to storage if corresponding option is set * @param {String} options.filename * @param {Boolean} options.isDir Optional, defaults to false * If options is a string, it is assumed that the flush of the file (not dir) called options was requested */ -storage.flushToStorage = (options, callback) => { +storage.flushToStorage = (options, callback) => callbackify(storage.flushToStorageAsync)(options, callback) + +storage.flushToStorageAsync = async (options) => { let filename let flags if (typeof options === 'string') { @@ -62,23 +67,29 @@ storage.flushToStorage = (options, callback) => { * database is loaded and a crash happens. */ - fs.open(filename, flags, (err, fd) => { - if (err) { - return callback((err.code === 'EISDIR' && options.isDir) ? null : err) + let fd, errorOnFsync, errorOnClose + try { + fd = await fsPromises.open(filename, flags) + try { + await fd.sync() + } catch (errFS) { + errorOnFsync = errFS } - fs.fsync(fd, errFS => { - fs.close(fd, errC => { - if ((errFS || errC) && !((errFS.code === 'EPERM' || errFS.code === 'EISDIR') && options.isDir)) { - const e = new Error('Failed to flush to storage') - e.errorOnFsync = errFS - e.errorOnClose = errC - return callback(e) - } else { - return callback(null) - } - }) - }) - }) + } catch (error) { + if (error.code !== 'EISDIR' || !options.isDir) throw error + } finally { + try { + await fd.close() + } catch (errC) { + errorOnClose = errC + } + } + if ((errorOnFsync || errorOnClose) && !((errorOnFsync.code === 'EPERM' || errorOnClose.code === 'EISDIR') && options.isDir)) { + const e = new Error('Failed to flush to storage') + e.errorOnFsync = errorOnFsync + e.errorOnClose = errorOnClose + throw e + } } /** @@ -109,6 +120,8 @@ storage.writeFileLines = (filename, lines, callback = () => {}) => { } } +storage.writeFileLinesAsync = (filename, lines) => promisify(storage.writeFileLines)(filename, lines) + /** * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) * @param {String} filename @@ -116,25 +129,24 @@ storage.writeFileLines = (filename, lines, callback = () => {}) => { * @param {Function} callback Optional callback, signature: err */ storage.crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { + callbackify(storage.crashSafeWriteFileLinesAsync)(filename, lines, callback) +} + +storage.crashSafeWriteFileLinesAsync = async (filename, lines) => { const tempFilename = filename + '~' - async.waterfall([ - async.apply(storage.flushToStorage, { filename: path.dirname(filename), isDir: true }), - cb => { - storage.exists(filename, exists => { - if (exists) storage.flushToStorage(filename, err => cb(err)) - else return cb() - }) - }, - cb => { - storage.writeFileLines(tempFilename, lines, cb) - }, - async.apply(storage.flushToStorage, tempFilename), - cb => { - storage.rename(tempFilename, filename, err => cb(err)) - }, - async.apply(storage.flushToStorage, { filename: path.dirname(filename), isDir: true }) - ], err => callback(err)) + await storage.flushToStorageAsync({ filename: path.dirname(filename), isDir: true }) + + const exists = await storage.existsAsync(filename) + if (exists) await storage.flushToStorageAsync({ filename }) + + await storage.writeFileLinesAsync(tempFilename, lines) + + await storage.flushToStorageAsync(tempFilename) + + await storage.renameAsync(tempFilename, filename) + + await storage.flushToStorageAsync({ filename: path.dirname(filename), isDir: true }) } /** @@ -142,21 +154,20 @@ storage.crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { * @param {String} filename * @param {Function} callback signature: err */ -storage.ensureDatafileIntegrity = (filename, callback) => { - const tempFilename = filename + '~' +storage.ensureDatafileIntegrity = (filename, callback) => callbackify(storage.ensureDatafileIntegrityAsync)(filename, callback) - storage.exists(filename, filenameExists => { - // Write was successful - if (filenameExists) return callback(null) +storage.ensureDatafileIntegrityAsync = async filename => { + const tempFilename = filename + '~' - storage.exists(tempFilename, oldFilenameExists => { - // New database - if (!oldFilenameExists) return storage.writeFile(filename, '', 'utf8', err => { callback(err) }) + const filenameExists = await storage.existsAsync(filename) + // Write was successful + if (filenameExists) return - // Write failed, use old version - storage.rename(tempFilename, filename, err => callback(err)) - }) - }) + const oldFilenameExists = await storage.existsAsync(tempFilename) + // New database + if (!oldFilenameExists) await storage.writeFileAsync(filename, '', 'utf8') + // Write failed, use old version + else await storage.renameAsync(tempFilename, filename) } // Interface From 4d900da6fe851e36b6429fb1c5d3b700f81548d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 11:08:13 +0200 Subject: [PATCH 05/65] WIP: remove async from persistence module --- lib/persistence.js | 120 +++++++++++++++++++++------------------------ lib/storage.js | 6 ++- 2 files changed, 60 insertions(+), 66 deletions(-) diff --git a/lib/persistence.js b/lib/persistence.js index 51b5050..8439a81 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -5,7 +5,7 @@ * * Persistence.persistNewState(newDocs, callback) where newDocs is an array of documents and callback has signature err */ const path = require('path') -const async = require('async') +const { callbackify, promisify } = require('util') const byline = require('./byline') const customUtils = require('./customUtils.js') const Index = require('./indexes.js') @@ -73,9 +73,13 @@ class Persistence { * @param {Function} callback Optional callback, signature: err */ persistCachedDatabase (callback = () => {}) { + return callbackify(this.persistCachedDatabaseAsync.bind(this))(callback) + } + + async persistCachedDatabaseAsync () { const lines = [] - if (this.inMemoryOnly) return callback(null) + if (this.inMemoryOnly) return this.db.getAllData().forEach(doc => { lines.push(this.afterSerialization(model.serialize(doc))) @@ -92,11 +96,8 @@ class Persistence { } }) - storage.crashSafeWriteFileLines(this.filename, lines, err => { - if (err) return callback(err) - this.db.emit('compaction.done') - return callback(null) - }) + await storage.crashSafeWriteFileLinesAsync(this.filename, lines) + this.db.emit('compaction.done') } /** @@ -135,18 +136,22 @@ class Persistence { * @param {Function} callback Optional, signature: err */ persistNewState (newDocs, callback = () => {}) { + callbackify(this.persistNewStateAsync.bind(this))(newDocs, err => callback(err)) + } + + async persistNewStateAsync (newDocs) { let toPersist = '' // In-memory only datastore - if (this.inMemoryOnly) return callback(null) + if (this.inMemoryOnly) return newDocs.forEach(doc => { toPersist += this.afterSerialization(model.serialize(doc)) + '\n' }) - if (toPersist.length === 0) return callback(null) + if (toPersist.length === 0) return - storage.appendFile(this.filename, toPersist, 'utf8', err => callback(err)) + await storage.appendFileAsync(this.filename, toPersist, 'utf8') } /** @@ -232,6 +237,10 @@ class Persistence { }) } + async treatRawStreamAsync (rawStream) { + return promisify(this.treatRawStream.bind(this))(rawStream) + } + /** * Load the database * 1) Create all indexes @@ -243,65 +252,42 @@ class Persistence { * @param {Function} callback Optional callback, signature: err */ loadDatabase (callback = () => {}) { + callbackify(this.loadDatabaseAsync.bind(this))(err => callback(err)) + } + + async loadDatabaseAsync () { this.db.resetIndexes() // In-memory only datastore - if (this.inMemoryOnly) return callback(null) - - async.waterfall([ - cb => { - // eslint-disable-next-line node/handle-callback-err - Persistence.ensureDirectoryExists(path.dirname(this.filename), err => { - // TODO: handle error - // eslint-disable-next-line node/handle-callback-err - storage.ensureDatafileIntegrity(this.filename, err => { - // TODO: handle error - const treatedDataCallback = (err, treatedData) => { - if (err) return cb(err) - - // Recreate all indexes in the datafile - Object.keys(treatedData.indexes).forEach(key => { - this.db.indexes[key] = new Index(treatedData.indexes[key]) - }) - - // Fill cached database (i.e. all indexes) with data - try { - this.db.resetIndexes(treatedData.data) - } catch (e) { - this.db.resetIndexes() // Rollback any index which didn't fail - return cb(e) - } - - this.db.persistence.persistCachedDatabase(cb) - } - - if (storage.readFileStream) { - // Server side - const fileStream = storage.readFileStream(this.filename, { encoding: 'utf8' }) - this.treatRawStream(fileStream, treatedDataCallback) - return - } - - // Browser - storage.readFile(this.filename, 'utf8', (err, rawData) => { - if (err) return cb(err) - - try { - const treatedData = this.treatRawData(rawData) - treatedDataCallback(null, treatedData) - } catch (e) { - return cb(e) - } - }) - }) - }) - } - ], err => { - if (err) return callback(err) - - this.db.executor.processBuffer() - return callback(null) + if (this.inMemoryOnly) return + await Persistence.ensureDirectoryExistsAsync(path.dirname(this.filename)) // TODO: maybe ignore error + await storage.ensureDatafileIntegrityAsync(this.filename) // TODO: maybe ignore error + + let treatedData + if (storage.readFileStream) { + // Server side + const fileStream = storage.readFileStream(this.filename, { encoding: 'utf8' }) + treatedData = await this.treatRawStreamAsync(fileStream) + } else { + // Browser + const rawData = await storage.readFileAsync(this.filename, 'utf8') + treatedData = this.treatRawData(rawData) + } + // Recreate all indexes in the datafile + Object.keys(treatedData.indexes).forEach(key => { + this.db.indexes[key] = new Index(treatedData.indexes[key]) }) + + // Fill cached database (i.e. all indexes) with data + try { + this.db.resetIndexes(treatedData.data) + } catch (e) { + this.db.resetIndexes() // Rollback any index which didn't fail + throw e + } + + await this.db.persistence.persistCachedDatabaseAsync() + this.db.executor.processBuffer() } /** @@ -312,6 +298,10 @@ class Persistence { storage.mkdir(dir, { recursive: true }, err => { callback(err) }) } + static async ensureDirectoryExistsAsync (dir) { + await storage.mkdirAsync(dir, { recursive: true }) + } + /** * Return the path the datafile if the given filename is relative to the directory where Node Webkit stores * data for this application. Probably the best place to store data diff --git a/lib/storage.js b/lib/storage.js index 8e8d2eb..639aba3 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -20,12 +20,16 @@ storage.rename = fs.rename storage.renameAsync = fsPromises.rename storage.writeFile = fs.writeFile storage.writeFileAsync = fsPromises.writeFile +storage.writeFileStream = fs.createWriteStream storage.unlink = fs.unlink storage.unlinkAsync = fsPromises.unlink storage.appendFile = fs.appendFile +storage.appendFileAsync = fsPromises.appendFile storage.readFile = fs.readFile +storage.readFileAsync = fsPromises.readFile storage.readFileStream = fs.createReadStream storage.mkdir = fs.mkdir +storage.mkdirAsync = fsPromises.mkdir /** * Explicit name ... @@ -100,7 +104,7 @@ storage.flushToStorageAsync = async (options) => { */ storage.writeFileLines = (filename, lines, callback = () => {}) => { try { - const stream = fs.createWriteStream(filename) + const stream = storage.writeFileStream(filename) const readable = Readable.from(lines) readable.on('data', (line) => { try { From 7f78b403ae272e0ba8ff6c91b4f2c8e483dd657e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 11:08:48 +0200 Subject: [PATCH 06/65] WIP: use async functions from persistence module in datastore --- lib/datastore.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index c1788bd..57dccc6 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -610,12 +610,7 @@ class Datastore extends EventEmitter { // Update the datafile const updatedDocs = modifications.map(x => x.newDoc) - await new Promise((resolve, reject) => { - this.persistence.persistNewState(updatedDocs, err => { - if (err) return reject(err) - else resolve() - }) - }) + await this.persistence.persistNewStateAsync(updatedDocs) if (!options.returnUpdatedDocs) return { numAffected: numReplaced } else { let updatedDocsDC = [] From fbf2bd8d685f388c81e5faa87cd5a4cddc481c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 15:48:07 +0200 Subject: [PATCH 07/65] WIP: rewrite executor without async --- lib/datastore.js | 31 ++++++++++------ lib/executor.js | 87 +++++++++++++++++++++++++++++++++------------ test/cursor.test.js | 10 +++--- 3 files changed, 89 insertions(+), 39 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 57dccc6..8d45b89 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -89,6 +89,15 @@ class Datastore extends EventEmitter { this.executor.push({ this: this.persistence, fn: this.persistence.loadDatabase, arguments: arguments }, true) } + loadDatabaseAsync () { + return this.executor.push({ + this: this.persistence, + fn: this.persistence.loadDatabaseAsync, + arguments: arguments, + async: true + }, true) + } + /** * Get an array of all the data in the database */ @@ -343,19 +352,15 @@ class Datastore extends EventEmitter { * @private */ _insert (newDoc, callback = () => {}) { - let preparedDoc + return callbackify(this._insertAsync.bind(this))(newDoc, callback) + } - try { - preparedDoc = this._prepareDocumentForInsertion(newDoc) - this._insertInCache(preparedDoc) - } catch (e) { - return callback(e) - } + async _insertAsync (newDoc) { + const preparedDoc = this._prepareDocumentForInsertion(newDoc) + this._insertInCache(preparedDoc) - this.persistence.persistNewState(Array.isArray(preparedDoc) ? preparedDoc : [preparedDoc], err => { - if (err) return callback(err) - return callback(null, model.deepCopy(preparedDoc)) - }) + await this.persistence.persistNewStateAsync(Array.isArray(preparedDoc) ? preparedDoc : [preparedDoc]) + return model.deepCopy(preparedDoc) } /** @@ -433,6 +438,10 @@ class Datastore extends EventEmitter { this.executor.push({ this: this, fn: this._insert, arguments: arguments }) } + insertAsync () { + this.executor.push({ this: this, fn: this._insertAsync, arguments: arguments, async: true }) + } + /** * Count all documents matching the query * @param {Query} query MongoDB-style query diff --git a/lib/executor.js b/lib/executor.js index 98a9c4c..dd866ec 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -1,41 +1,84 @@ /** * Responsible for sequentially executing actions on the database */ -const async = require('async') + +const makeQueue = execute => { + const tasks = new Map() + let running = false + let drainPromise = Promise.resolve() + const executeNextTask = async (self = false) => { + if (!tasks.size) { + running = false + return + } else if (running && !self) { + return + } + running = true + const [task, { resolve, reject }] = tasks[Symbol.iterator]().next().value + + tasks.delete(task) + try { + resolve(await execute(task)) + } catch (err) { + reject(err) + } + drainPromise = executeNextTask(true) + } + + return { + push (task) { + let _resolve, _reject + const promise = new Promise((resolve, reject) => { + _reject = reject + _resolve = resolve + }) + tasks.set(task, { resolve: _resolve, reject: _reject }) + if (!running) drainPromise = executeNextTask() + return promise + }, + async drain () { + return drainPromise + } + } +} class Executor { constructor () { this.buffer = [] this.ready = false - // This queue will execute all commands, one-by-one in order - this.queue = async.queue((task, cb) => { + this.queue = makeQueue(async task => { // task.arguments is an array-like object on which adding a new field doesn't work, so we transform it into a real array const newArguments = Array.from(task.arguments) - const lastArg = newArguments[newArguments.length - 1] - - // Always tell the queue task is complete. Execute callback if any was given. - if (typeof lastArg === 'function') { - // Callback was supplied - newArguments[newArguments.length - 1] = function () { - if (typeof setImmediate === 'function') { - setImmediate(cb) + // If the task isn't async, let's proceed with the old handler + if (!task.async) { + const lastArg = newArguments[newArguments.length - 1] + await new Promise(resolve => { + if (typeof lastArg === 'function') { + // We got a callback + newArguments.pop() // remove original callback + task.fn.apply(task.this, [...newArguments, function () { + resolve() // triggers next task after next tick + lastArg.apply(null, arguments) // call original callback + }]) + } else if (!lastArg && task.arguments.length !== 0) { + // We got a falsy callback + newArguments.pop() // remove original callback + task.fn.apply(task.this, [...newArguments, () => { + resolve() + }]) } else { - process.nextTick(cb) + // We don't have a callback + task.fn.apply(task.this, [...newArguments, () => { + resolve() + }]) } - lastArg.apply(null, arguments) - } - } else if (!lastArg && task.arguments.length !== 0) { - // false/undefined/null supplied as callback - newArguments[newArguments.length - 1] = () => { cb() } + }) } else { - // Nothing supplied as callback - newArguments.push(() => { cb() }) + await task.fn.apply(task.this, newArguments) } - - task.fn.apply(task.this, newArguments) - }, 1) + }) } /** diff --git a/test/cursor.test.js b/test/cursor.test.js index f1fe16d..42d8566 100755 --- a/test/cursor.test.js +++ b/test/cursor.test.js @@ -29,12 +29,10 @@ describe('Cursor', function () { }) }) }, - function (cb) { - d.loadDatabase(function (err) { - assert.isNull(err) - d.getAllData().length.should.equal(0) - return cb() - }) + async function (cb) { + await d.loadDatabaseAsync() + d.getAllData().length.should.equal(0) + cb() } ], done) }) From a694d6ee141b482850443a3f91eca14fe28533b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 18:58:05 +0200 Subject: [PATCH 08/65] WIP: rewrite executor --- lib/datastore.js | 5 +-- lib/executor.js | 97 +++++++++++++++++++++++++++++++----------------- 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 8d45b89..77a19ef 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -90,11 +90,10 @@ class Datastore extends EventEmitter { } loadDatabaseAsync () { - return this.executor.push({ + return this.executor.pushAsync({ this: this.persistence, fn: this.persistence.loadDatabaseAsync, - arguments: arguments, - async: true + arguments: arguments }, true) } diff --git a/lib/executor.js b/lib/executor.js index dd866ec..46b8c3e 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -2,57 +2,80 @@ * Responsible for sequentially executing actions on the database */ -const makeQueue = execute => { - const tasks = new Map() - let running = false - let drainPromise = Promise.resolve() - const executeNextTask = async (self = false) => { - if (!tasks.size) { - running = false - return - } else if (running && !self) { +class Queue { + constructor (execute) { + this.execute = execute + this.tasks = new Map() + this.buffer = new Map() + this.running = false + this.drainPromise = Promise.resolve() + } + + async executeNextTask (force = false) { + if (!this.tasks.size) { + this.running = false return - } - running = true - const [task, { resolve, reject }] = tasks[Symbol.iterator]().next().value + } else if (this.running && !force) return + this.running = true + const [task, { resolve, reject, async }] = this.tasks[Symbol.iterator]().next().value - tasks.delete(task) + this.tasks.delete(task) try { - resolve(await execute(task)) + resolve(await this.execute(task, async)) } catch (err) { reject(err) } - drainPromise = executeNextTask(true) + this.drainPromise = this.executeNextTask(true) } - return { - push (task) { - let _resolve, _reject - const promise = new Promise((resolve, reject) => { - _reject = reject - _resolve = resolve - }) - tasks.set(task, { resolve: _resolve, reject: _reject }) - if (!running) drainPromise = executeNextTask() - return promise - }, - async drain () { - return drainPromise - } + _push (task, async, map, run = false) { + let _resolve, _reject + const promise = new Promise((resolve, reject) => { + _reject = reject + _resolve = resolve + }) + map.set(task, { async: async, resolve: _resolve, reject: _reject }) + if (run && !this.running) this.drainPromise = this.executeNextTask() + return promise + } + + push (task) { + this._push(task, false, this.tasks, true).then(() => {}, () => {}) // to avoid having unhandledRejection + } + + pushAsync (task) { + return this._push(task, true, this.tasks, true) + } + + addToBuffer (task) { + this._push(task, false, this.buffer, false).then(() => {}, () => {}) // to avoid having unhandledRejection + } + + addToBufferAsync (task) { + return this._push(task, true, this.buffer, false) + } + + processBuffer () { + this.tasks = new Map([...this.tasks, ...this.buffer]) + this.buffer = new Map() + this.drainPromise = this.executeNextTask() + } + + async drain () { + return this.drainPromise } } class Executor { constructor () { - this.buffer = [] this.ready = false - this.queue = makeQueue(async task => { + this.queue = new Queue(async (task, async) => { // task.arguments is an array-like object on which adding a new field doesn't work, so we transform it into a real array const newArguments = Array.from(task.arguments) // If the task isn't async, let's proceed with the old handler - if (!task.async) { + if (!async) { const lastArg = newArguments[newArguments.length - 1] await new Promise(resolve => { if (typeof lastArg === 'function') { @@ -93,7 +116,12 @@ class Executor { */ push (task, forceQueuing) { if (this.ready || forceQueuing) this.queue.push(task) - else this.buffer.push(task) + else this.queue.addToBuffer(task) + } + + pushAsync (task, forceQueuing) { + if (this.ready || forceQueuing) return this.queue.pushAsync(task) + else return this.queue.addToBufferAsync(task) } /** @@ -102,8 +130,7 @@ class Executor { */ processBuffer () { this.ready = true - this.buffer.forEach(task => { this.queue.push(task) }) - this.buffer = [] + this.queue.processBuffer() } } From 4c5fc252c212b223916cac467076daf736c09d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 22:42:33 +0200 Subject: [PATCH 09/65] WIP: remove --- lib/datastore.js | 55 +++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 77a19ef..5b157d3 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -154,13 +154,15 @@ class Datastore extends EventEmitter { * @param {String} fieldName * @param {Function} callback Optional callback, signature: err */ + // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state removeIndex (fieldName, callback = () => {}) { + callbackify(this.removeIndexAsync.bind(this))(fieldName, callback) + } + + async removeIndexAsync (fieldName) { delete this.indexes[fieldName] - this.persistence.persistNewState([{ $$indexRemoved: fieldName }], err => { - if (err) return callback(err) - return callback(null) - }) + await this.persistence.persistNewStateAsync([{ $$indexRemoved: fieldName }]) } /** @@ -438,7 +440,7 @@ class Datastore extends EventEmitter { } insertAsync () { - this.executor.push({ this: this, fn: this._insertAsync, arguments: arguments, async: true }) + return this.executor.push({ this: this, fn: this._insertAsync, arguments: arguments, async: true }) } /** @@ -632,6 +634,10 @@ class Datastore extends EventEmitter { this.executor.push({ this: this, fn: this._update, arguments: arguments }) } + updateAsync () { + return this.executor.pushAsync({ this: this, fn: this._updateAsync, arguments: arguments }) + } + /** * Remove all docs matching the query. * Use Datastore.remove which has the same signature @@ -649,35 +655,36 @@ class Datastore extends EventEmitter { options = {} } const callback = cb || (() => {}) + + callbackify(this._removeAsync.bind(this))(query, options, callback) + } + + async _removeAsync (query, options = {}) { const multi = options.multi !== undefined ? options.multi : false - this.getCandidates(query, true, (err, candidates) => { - if (err) return callback(err) - const removedDocs = [] - let numRemoved = 0 + const candidates = await this.getCandidatesAsync(query, true) + const removedDocs = [] + let numRemoved = 0 - try { - candidates.forEach(d => { - if (model.match(d, query) && (multi || numRemoved === 0)) { - numRemoved += 1 - removedDocs.push({ $$deleted: true, _id: d._id }) - this.removeFromIndexes(d) - } - }) - } catch (err) { - return callback(err) + candidates.forEach(d => { + if (model.match(d, query) && (multi || numRemoved === 0)) { + numRemoved += 1 + removedDocs.push({ $$deleted: true, _id: d._id }) + this.removeFromIndexes(d) } - - this.persistence.persistNewState(removedDocs, err => { - if (err) return callback(err) - return callback(null, numRemoved) - }) }) + + await this.persistence.persistNewStateAsync(removedDocs) + return numRemoved } remove () { this.executor.push({ this: this, fn: this._remove, arguments: arguments }) } + + removeAsync () { + return this.executor.pushAsync({ this: this, fn: this._removeAsync, arguments: arguments }) + } } module.exports = Datastore From 70229d3da5fce84f8c29da5fb50ef7bfefc7c343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 21 Oct 2021 22:46:23 +0200 Subject: [PATCH 10/65] WIP: ensureIndex --- lib/datastore.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 5b157d3..362a774 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -125,12 +125,17 @@ class Datastore extends EventEmitter { * @param {Function} callback Optional callback, signature: err */ ensureIndex (options = {}, callback = () => {}) { + callbackify(this.ensureIndexAsync.bind(this))(options, callback) + } + + async ensureIndexAsync (options = {}) { + console.log('exec now') if (!options.fieldName) { const err = new Error('Cannot create an index without a fieldName') err.missingFieldName = true - return callback(err) + throw err } - if (this.indexes[options.fieldName]) return callback(null) + if (this.indexes[options.fieldName]) return this.indexes[options.fieldName] = new Index(options) if (options.expireAfterSeconds !== undefined) this.ttlIndexes[options.fieldName] = options.expireAfterSeconds // With this implementation index creation is not necessary to ensure TTL but we stick with MongoDB's API here @@ -139,14 +144,11 @@ class Datastore extends EventEmitter { this.indexes[options.fieldName].insert(this.getAllData()) } catch (e) { delete this.indexes[options.fieldName] - return callback(e) + throw e } // We may want to force all options to be persisted including defaults, not just the ones passed the index creation function - this.persistence.persistNewState([{ $$indexCreated: options }], err => { - if (err) return callback(err) - return callback(null) - }) + await this.persistence.persistNewStateAsync([{ $$indexCreated: options }]) } /** From 2c4589e108e9387d64c9cef13163a39186ad2a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 08:54:35 +0200 Subject: [PATCH 11/65] WIP: async Cursor and fix async executor --- lib/cursor.js | 81 +++++++++++++++++++++++++++--------------------- lib/datastore.js | 44 ++++++++++++++------------ lib/executor.js | 2 +- 3 files changed, 70 insertions(+), 57 deletions(-) diff --git a/lib/cursor.js b/lib/cursor.js index ed37416..9521458 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -2,6 +2,7 @@ * Manage access to data, be it to find, update or remove it */ const model = require('./model.js') +const { callbackify, promisify } = require('util') class Cursor { /** @@ -10,10 +11,11 @@ class Cursor { * @param {Query} query - The query this cursor will operate on * @param {Function} execFn - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove */ - constructor (db, query, execFn) { + constructor (db, query, execFn, async = false) { this.db = db this.query = query || {} if (execFn) { this.execFn = execFn } + if (async) { this.async = true } } /** @@ -103,50 +105,33 @@ class Cursor { * * @param {Function} callback - Signature: err, results */ - _exec (_callback) { + async _execAsync () { let res = [] let added = 0 let skipped = 0 let error = null - let keys - let key - - const callback = (error, res) => { - if (this.execFn) return this.execFn(error, res, _callback) - else return _callback(error, res) - } - this.db.getCandidates(this.query, (err, candidates) => { - if (err) return callback(err) - - try { - for (const candidate of candidates) { - if (model.match(candidate, this.query)) { - // If a sort is defined, wait for the results to be sorted before applying limit and skip - if (!this._sort) { - if (this._skip && this._skip > skipped) skipped += 1 - else { - res.push(candidate) - added += 1 - if (this._limit && this._limit <= added) break - } - } else res.push(candidate) - } + try { + const candidates = await this.db.getCandidatesAsync(this.query) + + for (const candidate of candidates) { + if (model.match(candidate, this.query)) { + // If a sort is defined, wait for the results to be sorted before applying limit and skip + if (!this._sort) { + if (this._skip && this._skip > skipped) skipped += 1 + else { + res.push(candidate) + added += 1 + if (this._limit && this._limit <= added) break + } + } else res.push(candidate) } - } catch (err) { - return callback(err) } // Apply all sorts if (this._sort) { - keys = Object.keys(this._sort) - // Sorting - const criteria = [] - keys.forEach(item => { - key = item - criteria.push({ key: key, direction: this._sort[key] }) - }) + const criteria = Object.entries(this._sort).map(([key, direction]) => ({ key, direction })) res.sort((a, b) => { for (const criterion of criteria) { const compare = criterion.direction * model.compareThings(model.getDotValue(a, criterion.key), model.getDotValue(b, criterion.key), this.db.compareStrings) @@ -169,14 +154,38 @@ class Cursor { error = e res = undefined } + } catch (e) { + error = e + } + if (this.execFn && !this.async) return promisify(this.execFn)(error, res) + else if (error) throw error + else if (this.execFn) return this.execFn(res) + else return res + } - return callback(error, res) - }) + _exec (_callback) { + callbackify(this._execAsync.bind(this))(_callback) } exec () { this.db.executor.push({ this: this, fn: this._exec, arguments: arguments }) } + + execAsync () { + return this.db.executor.pushAsync({ this: this, fn: this._execAsync, arguments: arguments }) + } + + then (onFulfilled, onRejected) { + return this.execAsync().then(onFulfilled, onRejected) + } + + catch (onRejected) { + return this.execAsync().catch(onRejected) + } + + finally (onFinally) { + return this.execAsync().finally(onFinally) + } } // Interface diff --git a/lib/datastore.js b/lib/datastore.js index 362a774..74411f1 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -129,7 +129,6 @@ class Datastore extends EventEmitter { } async ensureIndexAsync (options = {}) { - console.log('exec now') if (!options.fieldName) { const err = new Error('Cannot create an index without a fieldName') err.missingFieldName = true @@ -451,15 +450,18 @@ class Datastore extends EventEmitter { * @param {Function} callback Optional callback, signature: err, count */ count (query, callback) { - const cursor = new Cursor(this, query, function (err, docs, callback) { - if (err) { return callback(err) } - return callback(null, docs.length) - }) + const cursor = this.countAsync(query) - if (typeof callback === 'function') cursor.exec(callback) + if (typeof callback === 'function') callbackify(cursor.execAsync.bind(cursor))(callback) else return cursor } + countAsync (query) { + const cursor = new Cursor(this, query, async docs => docs.length, true) + + return cursor // this is a trick, Cursor itself is a thenable, which allows to await it + } + /** * Find all documents matching the query * If no callback is passed, we return the cursor so that user can limit, skip and finally exec @@ -478,17 +480,17 @@ class Datastore extends EventEmitter { } // If not assume projection is an object and callback undefined } - const cursor = new Cursor(this, query, function (err, docs, callback) { - if (err) { return callback(err) } + const cursor = this.findAsync(query, projection) - const res = docs.map(doc => model.deepCopy(doc)) + if (typeof callback === 'function') callbackify(cursor.execAsync.bind(cursor))(callback) + else return cursor + } - return callback(null, res) - }) + findAsync (query, projection = {}) { + const cursor = new Cursor(this, query, docs => docs.map(doc => model.deepCopy(doc)), true) cursor.projection(projection) - if (typeof callback === 'function') cursor.exec(callback) - else return cursor + return cursor } /** @@ -508,17 +510,19 @@ class Datastore extends EventEmitter { } // If not assume projection is an object and callback undefined } - const cursor = new Cursor(this, query, (err, docs, callback) => { - if (err) return callback(err) - if (docs.length === 1) return callback(null, model.deepCopy(docs[0])) - else return callback(null, null) - }) + const cursor = this.findOneAsync(query, projection) - cursor.projection(projection).limit(1) - if (typeof callback === 'function') cursor.exec(callback) + if (typeof callback === 'function') callbackify(cursor.execAsync.bind(cursor))(callback) else return cursor } + findOneAsync (query, projection = {}) { + const cursor = new Cursor(this, query, docs => docs.length === 1 ? model.deepCopy(docs[0]) : null, true) + + cursor.projection(projection).limit(1) + return cursor + } + /** * Update all docs matching query. * Use Datastore.update which has the same signature diff --git a/lib/executor.js b/lib/executor.js index 46b8c3e..8a76078 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -99,7 +99,7 @@ class Executor { } }) } else { - await task.fn.apply(task.this, newArguments) + return task.fn.apply(task.this, newArguments) } }) } From 4df151b2035d0624092e92235f2b93d03cc6e265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 08:58:09 +0200 Subject: [PATCH 12/65] WIP: simplify getCandidatesAsync and move async to devDependencies --- lib/datastore.js | 34 +--------------------------------- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 35 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 74411f1..1080956 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -288,42 +288,10 @@ class Datastore extends EventEmitter { } async getCandidatesAsync (query, dontExpireStaleDocs = false) { - const indexNames = Object.keys(this.indexes) const validDocs = [] - const _getCandidates = query => { - // STEP 1: get candidates list by checking indexes from most to least frequent usecase - // For a basic match - let usableQuery - usableQuery = Object.entries(query) - .filter(([k, v]) => - !!(typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || isDate(v) || v === null) && - indexNames.includes(k) - ) - .pop() - if (usableQuery) return this.indexes[usableQuery[0]].getMatching(usableQuery[1]) - // For a $in match - usableQuery = Object.entries(query) - .filter(([k, v]) => - !!(query[k] && Object.prototype.hasOwnProperty.call(query[k], '$in')) && - indexNames.includes(k) - ) - .pop() - if (usableQuery) return this.indexes[usableQuery[0]].getMatching(usableQuery[1].$in) - // For a comparison match - usableQuery = Object.entries(query) - .filter(([k, v]) => - !!(query[k] && (Object.prototype.hasOwnProperty.call(query[k], '$lt') || Object.prototype.hasOwnProperty.call(query[k], '$lte') || Object.prototype.hasOwnProperty.call(query[k], '$gt') || Object.prototype.hasOwnProperty.call(query[k], '$gte'))) && - indexNames.includes(k) - ) - .pop() - if (usableQuery) return this.indexes[usableQuery[0]].getBetweenBounds(usableQuery[1]) - // By default, return all the DB data - return this.getAllData() - } - // STEP 1: get candidates list by checking indexes from most to least frequent usecase - const docs = _getCandidates(query) + const docs = this._getCandidates(query) // STEP 2: remove all expired documents if (!dontExpireStaleDocs) { const expiredDocsIds = [] diff --git a/package-lock.json b/package-lock.json index 62c8812..fe525d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,12 @@ "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", - "async": "0.2.10", "localforage": "^1.9.0" }, "devDependencies": { "@react-native-async-storage/async-storage": "^1.15.9", "@types/jest": "^27.0.2", + "async": "0.2.10", "browser-resolve": "^2.0.0", "chai": "^4.3.4", "commander": "^7.2.0", diff --git a/package.json b/package.json index 34f11a4..7820f23 100755 --- a/package.json +++ b/package.json @@ -42,13 +42,13 @@ }, "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", - "async": "0.2.10", "localforage": "^1.9.0" }, "devDependencies": { "@react-native-async-storage/async-storage": "^1.15.9", "@types/jest": "^27.0.2", "browser-resolve": "^2.0.0", + "async": "0.2.10", "chai": "^4.3.4", "commander": "^7.2.0", "events": "^3.3.0", From 5a9899e9f4241909bbaa9227677a6112cdbdfa11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 11:23:46 +0200 Subject: [PATCH 13/65] use fs.promises instead of fs/promises --- lib/datastore.js | 4 +--- lib/storage.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 1080956..94a707d 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -425,9 +425,7 @@ class Datastore extends EventEmitter { } countAsync (query) { - const cursor = new Cursor(this, query, async docs => docs.length, true) - - return cursor // this is a trick, Cursor itself is a thenable, which allows to await it + return new Cursor(this, query, async docs => docs.length, true) // this is a trick, Cursor itself is a thenable, which allows to await it } /** diff --git a/lib/storage.js b/lib/storage.js index 639aba3..3b2d09d 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -7,7 +7,7 @@ * It's essentially fs, mkdirp and crash safe write and read functions */ const fs = require('fs') -const fsPromises = require('fs/promises') +const fsPromises = fs.promises const path = require('path') const { callbackify, promisify } = require('util') const storage = {} From b57e3a01fb00e661e061f9c27d90650ae0657db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 11:31:18 +0200 Subject: [PATCH 14/65] minor --- lib/cursor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cursor.js b/lib/cursor.js index 9521458..ad6c9bf 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -14,8 +14,8 @@ class Cursor { constructor (db, query, execFn, async = false) { this.db = db this.query = query || {} - if (execFn) { this.execFn = execFn } - if (async) { this.async = true } + if (execFn) this.execFn = execFn + if (async) this.async = true } /** From 42a7d4585679a099f614786f2b6da55dff36a4bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 12:04:02 +0200 Subject: [PATCH 15/65] minor --- lib/cursor.js | 8 ++++---- lib/datastore.js | 32 ++++++++++++++++---------------- lib/executor.js | 19 ++++++++----------- 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/lib/cursor.js b/lib/cursor.js index ad6c9bf..b0eb402 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -167,12 +167,12 @@ class Cursor { callbackify(this._execAsync.bind(this))(_callback) } - exec () { - this.db.executor.push({ this: this, fn: this._exec, arguments: arguments }) + exec (...args) { + this.db.executor.push({ this: this, fn: this._exec, arguments: args }) } - execAsync () { - return this.db.executor.pushAsync({ this: this, fn: this._execAsync, arguments: arguments }) + execAsync (...args) { + return this.db.executor.pushAsync({ this: this, fn: this._execAsync, arguments: args }) } then (onFulfilled, onRejected) { diff --git a/lib/datastore.js b/lib/datastore.js index 94a707d..14e125c 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -85,15 +85,15 @@ class Datastore extends EventEmitter { /** * Load the database from the datafile, and trigger the execution of buffered commands if any */ - loadDatabase () { - this.executor.push({ this: this.persistence, fn: this.persistence.loadDatabase, arguments: arguments }, true) + loadDatabase (...args) { + this.executor.push({ this: this.persistence, fn: this.persistence.loadDatabase, arguments: args }, true) } - loadDatabaseAsync () { + loadDatabaseAsync (...args) { return this.executor.pushAsync({ this: this.persistence, fn: this.persistence.loadDatabaseAsync, - arguments: arguments + arguments: args }, true) } @@ -404,12 +404,12 @@ class Datastore extends EventEmitter { } } - insert () { - this.executor.push({ this: this, fn: this._insert, arguments: arguments }) + insert (...args) { + this.executor.push({ this: this, fn: this._insert, arguments: args }) } - insertAsync () { - return this.executor.push({ this: this, fn: this._insertAsync, arguments: arguments, async: true }) + insertAsync (...args) { + return this.executor.push({ this: this, fn: this._insertAsync, arguments: args, async: true }) } /** @@ -602,12 +602,12 @@ class Datastore extends EventEmitter { } } - update () { - this.executor.push({ this: this, fn: this._update, arguments: arguments }) + update (...args) { + this.executor.push({ this: this, fn: this._update, arguments: args }) } - updateAsync () { - return this.executor.pushAsync({ this: this, fn: this._updateAsync, arguments: arguments }) + updateAsync (...args) { + return this.executor.pushAsync({ this: this, fn: this._updateAsync, arguments: args }) } /** @@ -650,12 +650,12 @@ class Datastore extends EventEmitter { return numRemoved } - remove () { - this.executor.push({ this: this, fn: this._remove, arguments: arguments }) + remove (...args) { + this.executor.push({ this: this, fn: this._remove, arguments: args }) } - removeAsync () { - return this.executor.pushAsync({ this: this, fn: this._removeAsync, arguments: arguments }) + removeAsync (...args) { + return this.executor.pushAsync({ this: this, fn: this._removeAsync, arguments: args }) } } diff --git a/lib/executor.js b/lib/executor.js index 8a76078..1d7f7f6 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -71,35 +71,32 @@ class Executor { this.ready = false this.queue = new Queue(async (task, async) => { - // task.arguments is an array-like object on which adding a new field doesn't work, so we transform it into a real array - const newArguments = Array.from(task.arguments) - // If the task isn't async, let's proceed with the old handler if (!async) { - const lastArg = newArguments[newArguments.length - 1] + const lastArg = task.arguments[task.arguments.length - 1] await new Promise(resolve => { if (typeof lastArg === 'function') { // We got a callback - newArguments.pop() // remove original callback - task.fn.apply(task.this, [...newArguments, function () { - resolve() // triggers next task after next tick + task.arguments.pop() // remove original callback + task.fn.apply(task.this, [...task.arguments, function () { + resolve() // triggers next task after next tick // TODO: check if it's at next tick or not lastArg.apply(null, arguments) // call original callback }]) } else if (!lastArg && task.arguments.length !== 0) { // We got a falsy callback - newArguments.pop() // remove original callback - task.fn.apply(task.this, [...newArguments, () => { + task.arguments.pop() // remove original callback + task.fn.apply(task.this, [...task.arguments, () => { resolve() }]) } else { // We don't have a callback - task.fn.apply(task.this, [...newArguments, () => { + task.fn.apply(task.this, [...task.arguments, () => { resolve() }]) } }) } else { - return task.fn.apply(task.this, newArguments) + return task.fn.apply(task.this, task.arguments) } }) } From 06dc91915cc856d5a75946f17f9cec90e52c2270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 16:00:38 +0200 Subject: [PATCH 16/65] simplify executor --- lib/cursor.js | 2 +- lib/datastore.js | 10 +--- lib/executor.js | 143 +++++++++++++++++------------------------------ 3 files changed, 56 insertions(+), 99 deletions(-) diff --git a/lib/cursor.js b/lib/cursor.js index b0eb402..2c318ca 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -172,7 +172,7 @@ class Cursor { } execAsync (...args) { - return this.db.executor.pushAsync({ this: this, fn: this._execAsync, arguments: args }) + return this.db.executor.pushAsync(() => this._execAsync(...args)) } then (onFulfilled, onRejected) { diff --git a/lib/datastore.js b/lib/datastore.js index 14e125c..e6a7518 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -90,11 +90,7 @@ class Datastore extends EventEmitter { } loadDatabaseAsync (...args) { - return this.executor.pushAsync({ - this: this.persistence, - fn: this.persistence.loadDatabaseAsync, - arguments: args - }, true) + return this.executor.pushAsync(() => this.persistence.loadDatabaseAsync(args), true) } /** @@ -607,7 +603,7 @@ class Datastore extends EventEmitter { } updateAsync (...args) { - return this.executor.pushAsync({ this: this, fn: this._updateAsync, arguments: args }) + return this.executor.pushAsync(() => this._updateAsync(args)) } /** @@ -655,7 +651,7 @@ class Datastore extends EventEmitter { } removeAsync (...args) { - return this.executor.pushAsync({ this: this, fn: this._removeAsync, arguments: args }) + return this.executor.pushAsync(() => this._removeAsync(args)) } } diff --git a/lib/executor.js b/lib/executor.js index 1d7f7f6..6233c13 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -1,104 +1,41 @@ /** * Responsible for sequentially executing actions on the database */ - -class Queue { - constructor (execute) { - this.execute = execute - this.tasks = new Map() - this.buffer = new Map() - this.running = false - this.drainPromise = Promise.resolve() - } - - async executeNextTask (force = false) { - if (!this.tasks.size) { - this.running = false - return - } else if (this.running && !force) return - this.running = true - const [task, { resolve, reject, async }] = this.tasks[Symbol.iterator]().next().value - - this.tasks.delete(task) - try { - resolve(await this.execute(task, async)) - } catch (err) { - reject(err) - } - this.drainPromise = this.executeNextTask(true) - } - - _push (task, async, map, run = false) { - let _resolve, _reject - const promise = new Promise((resolve, reject) => { - _reject = reject - _resolve = resolve - }) - map.set(task, { async: async, resolve: _resolve, reject: _reject }) - if (run && !this.running) this.drainPromise = this.executeNextTask() - return promise - } - - push (task) { - this._push(task, false, this.tasks, true).then(() => {}, () => {}) // to avoid having unhandledRejection - } - - pushAsync (task) { - return this._push(task, true, this.tasks, true) - } - - addToBuffer (task) { - this._push(task, false, this.buffer, false).then(() => {}, () => {}) // to avoid having unhandledRejection +class Waterfall { + constructor () { + this._guardian = Promise.resolve() } - addToBufferAsync (task) { - return this._push(task, true, this.buffer, false) + get guardian () { + return this._guardian } - processBuffer () { - this.tasks = new Map([...this.tasks, ...this.buffer]) - this.buffer = new Map() - this.drainPromise = this.executeNextTask() + waterfall (func) { + return (...args) => { + this._guardian = this.guardian.then(() => { + return func(...args) + .then(result => ({ error: false, result }), result => ({ error: true, result })) + }) + return this.guardian.then(({ error, result }) => { + if (error) return Promise.reject(result) + else return Promise.resolve(result) + }) + } } - async drain () { - return this.drainPromise + chain (promise) { + return this.waterfall(() => promise)() } } class Executor { constructor () { this.ready = false - - this.queue = new Queue(async (task, async) => { - // If the task isn't async, let's proceed with the old handler - if (!async) { - const lastArg = task.arguments[task.arguments.length - 1] - await new Promise(resolve => { - if (typeof lastArg === 'function') { - // We got a callback - task.arguments.pop() // remove original callback - task.fn.apply(task.this, [...task.arguments, function () { - resolve() // triggers next task after next tick // TODO: check if it's at next tick or not - lastArg.apply(null, arguments) // call original callback - }]) - } else if (!lastArg && task.arguments.length !== 0) { - // We got a falsy callback - task.arguments.pop() // remove original callback - task.fn.apply(task.this, [...task.arguments, () => { - resolve() - }]) - } else { - // We don't have a callback - task.fn.apply(task.this, [...task.arguments, () => { - resolve() - }]) - } - }) - } else { - return task.fn.apply(task.this, task.arguments) - } - }) + this._mainWaterfallObject = new Waterfall() + this._bufferWaterfallObject = new Waterfall() + this._bufferWaterfallObject.chain(new Promise(resolve => { + this._resolveBuffer = resolve + })) } /** @@ -112,13 +49,36 @@ class Executor { * @param {Boolean} forceQueuing Optional (defaults to false) force executor to queue task even if it is not ready */ push (task, forceQueuing) { - if (this.ready || forceQueuing) this.queue.push(task) - else this.queue.addToBuffer(task) + const func = async () => { + const lastArg = task.arguments[task.arguments.length - 1] + await new Promise(resolve => { + if (typeof lastArg === 'function') { + // We got a callback + task.arguments.pop() // remove original callback + task.fn.apply(task.this, [...task.arguments, function () { + resolve() // triggers next task after next tick // TODO: check if it's at next tick or not + lastArg.apply(null, arguments) // call original callback + }]) + } else if (!lastArg && task.arguments.length !== 0) { + // We got a falsy callback + task.arguments.pop() // remove original callback + task.fn.apply(task.this, [...task.arguments, () => { + resolve() + }]) + } else { + // We don't have a callback + task.fn.apply(task.this, [...task.arguments, () => { + resolve() + }]) + } + }) + } + this.pushAsync(func, forceQueuing) } pushAsync (task, forceQueuing) { - if (this.ready || forceQueuing) return this.queue.pushAsync(task) - else return this.queue.addToBufferAsync(task) + if (this.ready || forceQueuing) return this._mainWaterfallObject.waterfall(task)() + else return this._bufferWaterfallObject.waterfall(task)() } /** @@ -127,7 +87,8 @@ class Executor { */ processBuffer () { this.ready = true - this.queue.processBuffer() + this._resolveBuffer() + this._mainWaterfallObject.waterfall(() => this._bufferWaterfallObject.guardian) } } From 8cadb9128e5a3645801cc4d69e87a0b52c31711a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 16:02:17 +0200 Subject: [PATCH 17/65] minor --- lib/executor.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/executor.js b/lib/executor.js index 6233c13..19a7038 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -31,10 +31,10 @@ class Waterfall { class Executor { constructor () { this.ready = false - this._mainWaterfallObject = new Waterfall() - this._bufferWaterfallObject = new Waterfall() - this._bufferWaterfallObject.chain(new Promise(resolve => { - this._resolveBuffer = resolve + this.queue = new Waterfall() + this.buffer = new Waterfall() + this.buffer.chain(new Promise(resolve => { + this.triggerBuffer = resolve })) } @@ -77,8 +77,8 @@ class Executor { } pushAsync (task, forceQueuing) { - if (this.ready || forceQueuing) return this._mainWaterfallObject.waterfall(task)() - else return this._bufferWaterfallObject.waterfall(task)() + if (this.ready || forceQueuing) return this.queue.waterfall(task)() + else return this.buffer.waterfall(task)() } /** @@ -87,8 +87,8 @@ class Executor { */ processBuffer () { this.ready = true - this._resolveBuffer() - this._mainWaterfallObject.waterfall(() => this._bufferWaterfallObject.guardian) + this.triggerBuffer() + this.queue.waterfall(() => this.buffer.guardian) } } From b8998ce1d7c289f128feb711b5d854e2956a63db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 16:04:57 +0200 Subject: [PATCH 18/65] remove TODO --- lib/executor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/executor.js b/lib/executor.js index 19a7038..6f0cf34 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -56,7 +56,7 @@ class Executor { // We got a callback task.arguments.pop() // remove original callback task.fn.apply(task.this, [...task.arguments, function () { - resolve() // triggers next task after next tick // TODO: check if it's at next tick or not + resolve() // triggers next task after next tick lastArg.apply(null, arguments) // call original callback }]) } else if (!lastArg && task.arguments.length !== 0) { From 0e60987a207a357c6db1d557e49211113f1b9495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 16:54:14 +0200 Subject: [PATCH 19/65] browserify --- browser-version/lib/storage.browser.js | 120 ++++++++++----- package-lock.json | 205 ++++++++++++++++++++++++- package.json | 1 + webpack.config.js | 3 +- 4 files changed, 289 insertions(+), 40 deletions(-) diff --git a/browser-version/lib/storage.browser.js b/browser-version/lib/storage.browser.js index 885557d..c12abf1 100755 --- a/browser-version/lib/storage.browser.js +++ b/browser-version/lib/storage.browser.js @@ -7,6 +7,7 @@ * This version is the browser version */ const localforage = require('localforage') +const { callbackify } = require('util') // Configure localforage to display NeDB name for now. Would be a good idea to let user use his own app name const store = localforage.createInstance({ @@ -14,73 +15,118 @@ const store = localforage.createInstance({ storeName: 'nedbdata' }) -const exists = (filename, cback) => { - // eslint-disable-next-line node/handle-callback-err - store.getItem(filename, (err, value) => { - if (value !== null) return cback(true) // Even if value is undefined, localforage returns null - else return cback(false) - }) +const existsAsync = async filename => { + try { + const value = await store.getItem(filename) + if (value !== null) return true // Even if value is undefined, localforage returns null + return false + } catch (error) { + return false + } } -const rename = (filename, newFilename, callback) => { - // eslint-disable-next-line node/handle-callback-err - store.getItem(filename, (err, value) => { - if (value === null) store.removeItem(newFilename, () => callback()) +const exists = callbackify(existsAsync) + +const renameAsync = async (filename, newFilename) => { + try { + const value = await store.getItem(filename) + if (value === null) await store.removeItem(newFilename) else { - store.setItem(newFilename, value, () => { - store.removeItem(filename, () => callback()) - }) + await store.setItem(newFilename, value) + await store.removeItem(filename) } - }) + } catch (err) { + console.warn('An error happened while renaming, skip') + } } -const writeFile = (filename, contents, options, callback) => { +const rename = callbackify(renameAsync) + +const writeFileAsync = async (filename, contents, options) => { // Options do not matter in browser setup - if (typeof options === 'function') { callback = options } - store.setItem(filename, contents, () => callback()) + try { + await store.setItem(filename, contents) + } catch (error) { + console.warn('An error happened while writing, skip') + } } -const appendFile = (filename, toAppend, options, callback) => { +const writeFile = callbackify(writeFileAsync) + +const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup - if (typeof options === 'function') { callback = options } - - // eslint-disable-next-line node/handle-callback-err - store.getItem(filename, (err, contents) => { - contents = contents || '' - contents += toAppend - store.setItem(filename, contents, () => callback()) - }) + try { + const contents = (await store.getItem(filename)) || '' + await store.setItem(filename, contents + toAppend) + } catch (error) { + console.warn('An error happened appending to file writing, skip') + } } -const readFile = (filename, options, callback) => { - // Options do not matter in browser setup - if (typeof options === 'function') { callback = options } - // eslint-disable-next-line node/handle-callback-err - store.getItem(filename, (err, contents) => callback(null, contents || '')) +const appendFile = callbackify(appendFileAsync) + +const readFileAsync = async (filename, options) => { + try { + return (await store.getItem(filename)) || '' + } catch (error) { + console.warn('An error happened while reading, skip') + return '' + } } -const unlink = (filename, callback) => { - store.removeItem(filename, () => callback()) +const readFile = callbackify(readFileAsync) + +const unlinkAsync = async filename => { + try { + await store.removeItem(filename) + } catch (error) { + console.warn('An error happened while unlinking, skip') + } } +const unlink = callbackify(unlinkAsync) + // Nothing to do, no directories will be used on the browser -const mkdir = (dir, options, callback) => callback() +const mkdirAsync = (dir, options) => Promise.resolve() + +const mkdir = callbackify(mkdirAsync) // Nothing to do, no data corruption possible in the browser -const ensureDatafileIntegrity = (filename, callback) => callback(null) +const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() + +const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) -const crashSafeWriteFileLines = (filename, lines, callback) => { +const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line - writeFile(filename, lines.join('\n'), callback) + await writeFileAsync(filename, lines.join('\n')) } +const crashSafeWriteFileLines = callbackify(crashSafeWriteFileLinesAsync) + // Interface module.exports.exists = exists +module.exports.existsAsync = existsAsync + module.exports.rename = rename +module.exports.renameAsync = renameAsync + module.exports.writeFile = writeFile +module.exports.writeFileAsync = writeFileAsync + module.exports.crashSafeWriteFileLines = crashSafeWriteFileLines +module.exports.crashSafeWriteFileLinesAsync = crashSafeWriteFileLinesAsync + module.exports.appendFile = appendFile +module.exports.appendFileAsync = appendFileAsync + module.exports.readFile = readFile +module.exports.readFileAsync = readFileAsync + module.exports.unlink = unlink +module.exports.unlinkAsync = unlinkAsync + module.exports.mkdir = mkdir +module.exports.mkdirAsync = mkdirAsync + module.exports.ensureDatafileIntegrity = ensureDatafileIntegrity +module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync diff --git a/package-lock.json b/package-lock.json index fe525d6..b530f55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "ts-jest": "^27.0.7", "ts-node": "^10.3.0", "typescript": "^4.4.4", + "util": "^0.12.4", "webpack": "^5.37.0", "webpack-cli": "^4.7.0", "xvfb-maybe": "^0.2.1" @@ -4421,7 +4422,8 @@ "node_modules/async": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true }, "node_modules/async-limiter": { "version": "1.0.1", @@ -4449,6 +4451,18 @@ "node": ">= 4.5.0" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", @@ -7499,6 +7513,12 @@ "node": ">=0.10.0" } }, + "node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -7776,6 +7796,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -8199,6 +8234,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -8381,6 +8432,21 @@ "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -8505,6 +8571,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", + "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -15795,6 +15880,20 @@ "react": "^16.8.0 || ^17.0.0" } }, + "node_modules/util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -16162,6 +16261,26 @@ "dev": true, "peer": true }, + "node_modules/which-typed-array": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", + "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -19956,7 +20075,8 @@ "async": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true }, "async-limiter": { "version": "1.0.1", @@ -19978,6 +20098,12 @@ "dev": true, "peer": true }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, "babel-core": { "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", @@ -22395,6 +22521,12 @@ "dev": true, "peer": true }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -22590,6 +22722,15 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -22927,6 +23068,16 @@ "kind-of": "^6.0.0" } }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -23060,6 +23211,15 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -23139,6 +23299,19 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", + "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -29009,6 +29182,20 @@ "object-assign": "^4.1.1" } }, + "util": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -29289,6 +29476,20 @@ "dev": true, "peer": true }, + "which-typed-array": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", + "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", + "foreach": "^2.0.5", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" + } + }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", diff --git a/package.json b/package.json index 7820f23..691fd36 100755 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "ts-jest": "^27.0.7", "ts-node": "^10.3.0", "typescript": "^4.4.4", + "util": "^0.12.4", "webpack": "^5.37.0", "webpack-cli": "^4.7.0", "xvfb-maybe": "^0.2.1" diff --git a/webpack.config.js b/webpack.config.js index 8948c34..37a2cb1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -32,7 +32,8 @@ module.exports = (env, argv) => { process: 'process/browser', Buffer: ['buffer', 'Buffer'], setImmediate: ['timers-browserify', 'setImmediate'], - clearImmediate: ['timers-browserify', 'clearImmediate'] + clearImmediate: ['timers-browserify', 'clearImmediate'], + util: 'util' }) ], entry: { From 97908a41954842a8467fa64d5287dd97d4319f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 22 Oct 2021 17:10:01 +0200 Subject: [PATCH 20/65] add TODO --- lib/storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/storage.js b/lib/storage.js index 3b2d09d..d179e68 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -71,7 +71,7 @@ storage.flushToStorageAsync = async (options) => { * database is loaded and a crash happens. */ - let fd, errorOnFsync, errorOnClose + let fd, errorOnFsync, errorOnClose // TODO: sometimes it leaves some file descriptors open try { fd = await fsPromises.open(filename, flags) try { From 2ad5759d7e57563db5fcb0e312c87926b8c1692c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 25 Oct 2021 11:26:55 +0200 Subject: [PATCH 21/65] remove async dependency --- benchmarks/ensureIndex.js | 9 ++--- benchmarks/find.js | 10 +++--- benchmarks/findOne.js | 10 +++--- benchmarks/findWithIn.js | 10 +++--- benchmarks/insert.js | 8 ++--- benchmarks/loadDatabase.js | 10 +++--- benchmarks/profiler.js | 1 + benchmarks/remove.js | 14 ++++---- benchmarks/update.js | 14 ++++---- karma.conf.template.js | 2 +- package-lock.json | 4 +-- package.json | 1 - test/browser/load.spec.js | 68 +++++++++++++++++++------------------- test/cursor.test.js | 36 ++++++++++---------- test/db.test.js | 36 ++++++++++---------- test/executor.test.js | 4 +-- test/persistence.test.js | 10 +++--- test/utils.test.js | 33 ++++++++++++++++++ test_lac/openFds.test.js | 10 +++--- webpack.config.js | 5 +-- 20 files changed, 164 insertions(+), 131 deletions(-) create mode 100644 test/utils.test.js diff --git a/benchmarks/ensureIndex.js b/benchmarks/ensureIndex.js index 43b06b7..cf33c16 100755 --- a/benchmarks/ensureIndex.js +++ b/benchmarks/ensureIndex.js @@ -1,5 +1,5 @@ -const async = require('async') const program = require('commander') +const { apply, waterfall } = require('../test/utils.test.js') const Datastore = require('../lib/datastore') const commonUtilities = require('./commonUtilities') const Profiler = require('./profiler') @@ -19,8 +19,8 @@ console.log('----------------------------') console.log('Test with ' + n + ' documents') console.log('----------------------------') -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(function (err) { if (err) { return cb(err) } @@ -28,7 +28,7 @@ async.waterfall([ }) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.insertDocs, d, n, profiler), function (cb) { let i @@ -41,6 +41,7 @@ async.waterfall([ console.log('Average time for one ensureIndex: ' + (profiler.elapsedSinceLastStep() / n) + 'ms') profiler.step('Finished calling ensureIndex ' + n + ' times') + cb() } ], function (err) { profiler.step('Benchmark finished') diff --git a/benchmarks/find.js b/benchmarks/find.js index b81b03d..d3c9a83 100755 --- a/benchmarks/find.js +++ b/benchmarks/find.js @@ -1,4 +1,4 @@ -const async = require('async') +const { apply, waterfall } = require('../test/utils.test.js') const commonUtilities = require('./commonUtilities') const Profiler = require('./profiler') @@ -8,8 +8,8 @@ const config = commonUtilities.getConfiguration(benchDb) const d = config.d const n = config.n -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(function (err) { if (err) { return cb(err) } @@ -18,8 +18,8 @@ async.waterfall([ }) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler), - async.apply(commonUtilities.findDocs, d, n, profiler) + apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.findDocs, d, n, profiler) ], function (err) { profiler.step('Benchmark finished') diff --git a/benchmarks/findOne.js b/benchmarks/findOne.js index 93911bd..b965709 100755 --- a/benchmarks/findOne.js +++ b/benchmarks/findOne.js @@ -1,4 +1,4 @@ -const async = require('async') +const { apply, waterfall } = require('../test/utils.test.js') const commonUtilities = require('./commonUtilities') const Profiler = require('./profiler') @@ -8,8 +8,8 @@ const config = commonUtilities.getConfiguration(benchDb) const d = config.d const n = config.n -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(function (err) { if (err) { return cb(err) } @@ -18,9 +18,9 @@ async.waterfall([ }) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.insertDocs, d, n, profiler), function (cb) { setTimeout(function () { cb() }, 500) }, - async.apply(commonUtilities.findOneDocs, d, n, profiler) + apply(commonUtilities.findOneDocs, d, n, profiler) ], function (err) { profiler.step('Benchmark finished') diff --git a/benchmarks/findWithIn.js b/benchmarks/findWithIn.js index e167a6f..8df0c41 100755 --- a/benchmarks/findWithIn.js +++ b/benchmarks/findWithIn.js @@ -1,4 +1,4 @@ -const async = require('async') +const { apply, waterfall } = require('../test/utils.test.js') const commonUtilities = require('./commonUtilities') const Profiler = require('./profiler') @@ -8,8 +8,8 @@ const config = commonUtilities.getConfiguration(benchDb) const d = config.d const n = config.n -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(function (err) { if (err) { return cb(err) } @@ -18,8 +18,8 @@ async.waterfall([ }) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler), - async.apply(commonUtilities.findDocsWithIn, d, n, profiler) + apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.findDocsWithIn, d, n, profiler) ], function (err) { profiler.step('Benchmark finished') diff --git a/benchmarks/insert.js b/benchmarks/insert.js index f78d8b5..4938212 100755 --- a/benchmarks/insert.js +++ b/benchmarks/insert.js @@ -1,4 +1,4 @@ -const async = require('async') +const { apply, waterfall } = require('../test/utils.test.js') const commonUtilities = require('./commonUtilities') const Profiler = require('./profiler') @@ -8,8 +8,8 @@ const config = commonUtilities.getConfiguration(benchDb) const d = config.d let n = config.n -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(function (err) { if (err) { return cb(err) } @@ -24,7 +24,7 @@ async.waterfall([ }) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler) + apply(commonUtilities.insertDocs, d, n, profiler) ], function (err) { profiler.step('Benchmark finished') diff --git a/benchmarks/loadDatabase.js b/benchmarks/loadDatabase.js index a9910d3..b007dfb 100755 --- a/benchmarks/loadDatabase.js +++ b/benchmarks/loadDatabase.js @@ -1,4 +1,4 @@ -const async = require('async') +const { apply, waterfall } = require('../test/utils.test.js') const program = require('commander') const Datastore = require('../lib/datastore') const commonUtilities = require('./commonUtilities') @@ -20,14 +20,14 @@ console.log('Test with ' + n + ' documents') console.log(program.withIndex ? 'Use an index' : "Don't use an index") console.log('----------------------------') -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(cb) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler), - async.apply(commonUtilities.loadDatabase, d, n, profiler) + apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.loadDatabase, d, n, profiler) ], function (err) { profiler.step('Benchmark finished') diff --git a/benchmarks/profiler.js b/benchmarks/profiler.js index a5d73af..184aed2 100644 --- a/benchmarks/profiler.js +++ b/benchmarks/profiler.js @@ -1,3 +1,4 @@ +const { apply, waterfall } = require('../test/utils.test.js') const util = require('util') function formatTime (time, precision) { diff --git a/benchmarks/remove.js b/benchmarks/remove.js index a262d52..e3607f2 100755 --- a/benchmarks/remove.js +++ b/benchmarks/remove.js @@ -1,4 +1,4 @@ -const async = require('async') +const { apply, waterfall } = require('../test/utils.test.js') const commonUtilities = require('./commonUtilities') const Profiler = require('./profiler') @@ -8,8 +8,8 @@ const config = commonUtilities.getConfiguration(benchDb) const d = config.d const n = config.n -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(function (err) { if (err) { return cb(err) } @@ -18,16 +18,16 @@ async.waterfall([ }) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.insertDocs, d, n, profiler), // Test with remove only one document function (cb) { profiler.step('MULTI: FALSE'); return cb() }, - async.apply(commonUtilities.removeDocs, { multi: false }, d, n, profiler), + apply(commonUtilities.removeDocs, { multi: false }, d, n, profiler), // Test with multiple documents function (cb) { d.remove({}, { multi: true }, function () { return cb() }) }, - async.apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.insertDocs, d, n, profiler), function (cb) { profiler.step('MULTI: TRUE'); return cb() }, - async.apply(commonUtilities.removeDocs, { multi: true }, d, n, profiler) + apply(commonUtilities.removeDocs, { multi: true }, d, n, profiler) ], function (err) { profiler.step('Benchmark finished') diff --git a/benchmarks/update.js b/benchmarks/update.js index 1304f2f..f36dfd8 100755 --- a/benchmarks/update.js +++ b/benchmarks/update.js @@ -1,4 +1,4 @@ -const async = require('async') +const { apply, waterfall } = require('../test/utils.test.js') const commonUtilities = require('./commonUtilities') const Profiler = require('./profiler') @@ -8,8 +8,8 @@ const config = commonUtilities.getConfiguration(benchDb) const d = config.d const n = config.n -async.waterfall([ - async.apply(commonUtilities.prepareDb, benchDb), +waterfall([ + apply(commonUtilities.prepareDb, benchDb), function (cb) { d.loadDatabase(function (err) { if (err) { return cb(err) } @@ -18,18 +18,18 @@ async.waterfall([ }) }, function (cb) { profiler.beginProfiling(); return cb() }, - async.apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.insertDocs, d, n, profiler), // Test with update only one document function (cb) { profiler.step('MULTI: FALSE'); return cb() }, - async.apply(commonUtilities.updateDocs, { multi: false }, d, n, profiler), + apply(commonUtilities.updateDocs, { multi: false }, d, n, profiler), // Test with multiple documents // eslint-disable-next-line node/handle-callback-err function (cb) { d.remove({}, { multi: true }, function (err) { return cb() }) }, - async.apply(commonUtilities.insertDocs, d, n, profiler), + apply(commonUtilities.insertDocs, d, n, profiler), function (cb) { profiler.step('MULTI: TRUE'); return cb() }, - async.apply(commonUtilities.updateDocs, { multi: true }, d, n, profiler) + apply(commonUtilities.updateDocs, { multi: true }, d, n, profiler) ], function (err) { profiler.step('Benchmark finished') diff --git a/karma.conf.template.js b/karma.conf.template.js index ce493df..0eab6eb 100644 --- a/karma.conf.template.js +++ b/karma.conf.template.js @@ -14,7 +14,7 @@ module.exports = (config) => ({ // list of files / patterns to load in the browser files: [ 'node_modules/localforage/dist/localforage.min.js', - 'node_modules/async/lib/async.js', + 'browser-version/out/testUtils.min.js', 'browser-version/out/nedb.min.js', 'test/browser/nedb-browser.spec.js', 'test/browser/load.spec.js' diff --git a/package-lock.json b/package-lock.json index b530f55..c0d5dd9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "devDependencies": { "@react-native-async-storage/async-storage": "^1.15.9", "@types/jest": "^27.0.2", - "async": "0.2.10", "browser-resolve": "^2.0.0", "chai": "^4.3.4", "commander": "^7.2.0", @@ -20073,8 +20072,7 @@ "dev": true }, "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "version": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", "dev": true }, diff --git a/package.json b/package.json index 691fd36..9028670 100755 --- a/package.json +++ b/package.json @@ -48,7 +48,6 @@ "@react-native-async-storage/async-storage": "^1.15.9", "@types/jest": "^27.0.2", "browser-resolve": "^2.0.0", - "async": "0.2.10", "chai": "^4.3.4", "commander": "^7.2.0", "events": "^3.3.0", diff --git a/test/browser/load.spec.js b/test/browser/load.spec.js index 4390a19..b2a6b39 100755 --- a/test/browser/load.spec.js +++ b/test/browser/load.spec.js @@ -1,5 +1,5 @@ /* eslint-env mocha, browser */ -/* global async, Nedb, localforage */ +/* global Nedb, localforage, testUtils */ const N = 5000 const db = new Nedb({ filename: 'loadTest', autoload: true }) @@ -9,7 +9,7 @@ const sample = JSON.stringify({ data: Math.random(), _id: Math.random() }) const someInserts = (sn, N, callback) => { const beg = Date.now() let i = 0 - async.whilst(() => i < N, _cb => { + testUtils.whilst(() => i < N, _cb => { db.insert({ data: Math.random() }, err => { i += 1; return _cb(err) }) }, err => { console.log('Inserts, series ' + sn + ' ' + (Date.now() - beg)) @@ -41,7 +41,7 @@ const someLSDiff = (sn, N, callback) => { function someLF (sn, N, callback) { const beg = Date.now() let i = 0 - async.whilst(() => i < N, _cb => { + testUtils.whilst(() => i < N, _cb => { localforage.getItem('loadTestLF', (err, value) => { if (err) return _cb(err) localforage.setItem('loadTestLF', value + sample, err => { i += 1; return _cb(err) }) @@ -56,7 +56,7 @@ function someLF (sn, N, callback) { const someLFDiff = (sn, N, callback) => { const beg = Date.now() let i = 0 - async.whilst(() => i < N, _cb => { + testUtils.whilst(() => i < N, _cb => { localforage.setItem('loadTestLF-' + i, sample, err => { i += 1; return _cb(err) }) }, err => { console.log('localForage/IDB, series ' + sn + ' ' + (Date.now() - beg)) @@ -72,54 +72,54 @@ describe.skip('Load tests', function () { db.remove({}, { multi: true }, err => done(err)) }) - it.skip('Inserts', function (done) { - async.waterfall([ + it('Inserts', function (done) { + testUtils.waterfall([ // Slow and gets slower with database size - async.apply(someInserts, '#1', N), // N=5000, 141s - async.apply(someInserts, '#2', N), // N=5000, 208s - async.apply(someInserts, '#3', N), // N=5000, 281s - async.apply(someInserts, '#4', N) // N=5000, 350s + testUtils.apply(someInserts, '#1', N), // N=5000, 141s + testUtils.apply(someInserts, '#2', N), // N=5000, 208s + testUtils.apply(someInserts, '#3', N), // N=5000, 281s + testUtils.apply(someInserts, '#4', N) // N=5000, 350s ], done) }) - it.skip('Localstorage', function (done) { - async.waterfall([ + it('Localstorage', function (done) { + testUtils.waterfall([ // Slow and gets slower really fast with database size, then outright crashes - async.apply(someLS, '#1', N), // N=4000, 2.5s - async.apply(someLS, '#2', N), // N=4000, 8.0s - async.apply(someLS, '#3', N), // N=4000, 26.5s - async.apply(someLS, '#4', N) // N=4000, 47.8s then crash, can't get string (with N=5000 crash happens on second pass) + testUtils.apply(someLS, '#1', N), // N=4000, 2.5s + testUtils.apply(someLS, '#2', N), // N=4000, 8.0s + testUtils.apply(someLS, '#3', N), // N=4000, 26.5s + testUtils.apply(someLS, '#4', N) // N=4000, 47.8s then crash, can't get string (with N=5000 crash happens on second pass) ], done) }) - it.skip('Localstorage Diff', function (done) { - async.waterfall([ + it('Localstorage Diff', function (done) { + testUtils.waterfall([ // Much faster and more consistent - async.apply(someLSDiff, '#1', N), // N=50000, 0.7s - async.apply(someLSDiff, '#2', N), // N=50000, 0.5s - async.apply(someLSDiff, '#3', N), // N=50000, 0.5s - async.apply(someLSDiff, '#4', N) // N=50000, 0.5s + testUtils.apply(someLSDiff, '#1', N), // N=50000, 0.7s + testUtils.apply(someLSDiff, '#2', N), // N=50000, 0.5s + testUtils.apply(someLSDiff, '#3', N), // N=50000, 0.5s + testUtils.apply(someLSDiff, '#4', N) // N=50000, 0.5s ], done) }) - it.skip('LocalForage', function (done) { - async.waterfall([ + it('LocalForage', function (done) { + testUtils.waterfall([ // Slow and gets slower with database size cb => { localforage.setItem('loadTestLF', '', err => cb(err)) }, - async.apply(someLF, '#1', N), // N=5000, 69s - async.apply(someLF, '#2', N), // N=5000, 108s - async.apply(someLF, '#3', N), // N=5000, 137s - async.apply(someLF, '#4', N) // N=5000, 169s + testUtils.apply(someLF, '#1', N), // N=5000, 69s + testUtils.apply(someLF, '#2', N), // N=5000, 108s + testUtils.apply(someLF, '#3', N), // N=5000, 137s + testUtils.apply(someLF, '#4', N) // N=5000, 169s ], done) }) - it.skip('LocalForage diff', function (done) { - async.waterfall([ + it('LocalForage diff', function (done) { + testUtils.waterfall([ // Quite fast and speed doesn't change with database size (tested with N=10000 and N=50000, still no slow-down) - async.apply(someLFDiff, '#1', N), // N=5000, 18s - async.apply(someLFDiff, '#2', N), // N=5000, 18s - async.apply(someLFDiff, '#3', N), // N=5000, 18s - async.apply(someLFDiff, '#4', N) // N=5000, 18s + testUtils.apply(someLFDiff, '#1', N), // N=5000, 18s + testUtils.apply(someLFDiff, '#2', N), // N=5000, 18s + testUtils.apply(someLFDiff, '#3', N), // N=5000, 18s + testUtils.apply(someLFDiff, '#4', N) // N=5000, 18s ], done) }) }) diff --git a/test/cursor.test.js b/test/cursor.test.js index 42d8566..fbce0c4 100755 --- a/test/cursor.test.js +++ b/test/cursor.test.js @@ -3,7 +3,7 @@ const chai = require('chai') const testDb = 'workspace/test.db' const fs = require('fs') const path = require('path') -const async = require('async') +const { each, waterfall } = require('./utils.test.js') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') const Cursor = require('../lib/cursor') @@ -19,7 +19,7 @@ describe('Cursor', function () { d.filename.should.equal(testDb) d.inMemoryOnly.should.equal(false) - async.waterfall([ + waterfall([ function (cb) { Persistence.ensureDirectoryExists(path.dirname(testDb), function () { fs.access(testDb, fs.constants.F_OK, function (err) { @@ -58,7 +58,7 @@ describe('Cursor', function () { }) it('Without query, an empty query or a simple query and no skip or limit', function (done) { - async.waterfall([ + waterfall([ function (cb) { const cursor = new Cursor(d) cursor.exec(function (err, docs) { @@ -100,7 +100,7 @@ describe('Cursor', function () { }) it('With an empty collection', function (done) { - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { return cb(err) }) }, @@ -222,7 +222,7 @@ describe('Cursor', function () { }) it('With an empty collection', function (done) { - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { return cb(err) }) }, @@ -240,7 +240,7 @@ describe('Cursor', function () { it('Ability to chain sorting and exec', function (done) { let i - async.waterfall([ + waterfall([ function (cb) { const cursor = new Cursor(d) cursor.sort({ age: 1 }).exec(function (err, docs) { @@ -267,7 +267,7 @@ describe('Cursor', function () { }) it('Using limit and sort', function (done) { - async.waterfall([ + waterfall([ function (cb) { const cursor = new Cursor(d) cursor.sort({ age: 1 }).limit(3).exec(function (err, docs) { @@ -293,7 +293,7 @@ describe('Cursor', function () { }) it('Using a limit higher than total number of docs shouldnt cause an error', function (done) { - async.waterfall([ + waterfall([ function (cb) { const cursor = new Cursor(d) cursor.sort({ age: 1 }).limit(7).exec(function (err, docs) { @@ -311,7 +311,7 @@ describe('Cursor', function () { }) it('Using limit and skip with sort', function (done) { - async.waterfall([ + waterfall([ function (cb) { const cursor = new Cursor(d) cursor.sort({ age: 1 }).limit(1).skip(2).exec(function (err, docs) { @@ -346,7 +346,7 @@ describe('Cursor', function () { }) it('Using too big a limit and a skip with sort', function (done) { - async.waterfall([ + waterfall([ function (cb) { const cursor = new Cursor(d) cursor.sort({ age: 1 }).limit(8).skip(2).exec(function (err, docs) { @@ -362,7 +362,7 @@ describe('Cursor', function () { }) it('Using too big a skip with sort should return no result', function (done) { - async.waterfall([ + waterfall([ function (cb) { const cursor = new Cursor(d) cursor.sort({ age: 1 }).skip(5).exec(function (err, docs) { @@ -399,7 +399,7 @@ describe('Cursor', function () { }) it('Sorting strings', function (done) { - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { if (err) { return cb(err) } @@ -443,7 +443,7 @@ describe('Cursor', function () { let doc2 let doc3 - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { if (err) { return cb(err) } @@ -489,7 +489,7 @@ describe('Cursor', function () { }) it('Sorting when some fields are undefined', function (done) { - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { if (err) { return cb(err) } @@ -537,7 +537,7 @@ describe('Cursor', function () { }) it('Sorting when all fields are undefined', function (done) { - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { if (err) { return cb(err) } @@ -571,7 +571,7 @@ describe('Cursor', function () { }) it('Multiple consecutive sorts', function (done) { - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { if (err) { return cb(err) } @@ -655,7 +655,7 @@ describe('Cursor', function () { const companies = ['acme', 'milkman', 'zoinks'] const entities = [] - async.waterfall([ + waterfall([ function (cb) { d.remove({}, { multi: true }, function (err) { if (err) { return cb(err) } @@ -672,7 +672,7 @@ describe('Cursor', function () { } } - async.each(entities, function (entity, callback) { + each(entities, function (entity, callback) { d.insert(entity, function () { callback() }) diff --git a/test/db.test.js b/test/db.test.js index aff8e50..a11fef2 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -3,7 +3,7 @@ const chai = require('chai') const testDb = 'workspace/test.db' const fs = require('fs') const path = require('path') -const async = require('async') +const { apply, each, waterfall } = require('./utils.test.js') const model = require('../lib/model') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') @@ -20,7 +20,7 @@ describe('Database', function () { d.filename.should.equal(testDb) d.inMemoryOnly.should.equal(false) - async.waterfall([ + waterfall([ function (cb) { Persistence.ensureDirectoryExists(path.dirname(testDb), function () { fs.access(testDb, fs.constants.FS_OK, function (err) { @@ -697,7 +697,7 @@ describe('Database', function () { describe('Find', function () { it('Can find all documents if an empty query is used', function (done) { - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err) { @@ -722,7 +722,7 @@ describe('Database', function () { }) it('Can find all documents matching a basic query', function (done) { - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err) { @@ -751,7 +751,7 @@ describe('Database', function () { }) it('Can find one document matching a basic query and return null if none is found', function (done) { - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err) { @@ -1025,7 +1025,7 @@ describe('Database', function () { describe('Count', function () { it('Count all documents if an empty query is used', function (done) { - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err) { @@ -1046,7 +1046,7 @@ describe('Database', function () { }) it('Count all documents matching a basic query', function (done) { - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err) { @@ -1115,7 +1115,7 @@ describe('Database', function () { describe('Update', function () { it('If the query doesn\'t match anything, database is not modified', function (done) { - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err) { @@ -1212,7 +1212,7 @@ describe('Database', function () { } // Actually launch the tests - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err, doc1) { @@ -1234,11 +1234,11 @@ describe('Database', function () { return cb() }) }, - async.apply(testPostUpdateState), + apply(testPostUpdateState), function (cb) { d.loadDatabase(function (err) { cb(err) }) }, - async.apply(testPostUpdateState) + apply(testPostUpdateState) ], done) }) @@ -1274,7 +1274,7 @@ describe('Database', function () { } // Actually launch the test - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err, doc1) { @@ -1296,11 +1296,11 @@ describe('Database', function () { return cb() }) }, - async.apply(testPostUpdateState), + apply(testPostUpdateState), function (cb) { d.loadDatabase(function (err) { return cb(err) }) }, - async.apply(testPostUpdateState) // The persisted state has been updated + apply(testPostUpdateState) // The persisted state has been updated ], done) }) @@ -1895,7 +1895,7 @@ describe('Database', function () { } // Actually launch the test - async.waterfall([ + waterfall([ function (cb) { // eslint-disable-next-line node/handle-callback-err d.insert({ somedata: 'ok' }, function (err, doc1) { @@ -1915,11 +1915,11 @@ describe('Database', function () { return cb() }) }, - async.apply(testPostUpdateState), + apply(testPostUpdateState), function (cb) { d.loadDatabase(function (err) { return cb(err) }) }, - async.apply(testPostUpdateState) + apply(testPostUpdateState) ], done) }) @@ -1934,7 +1934,7 @@ describe('Database', function () { // Remove two docs simultaneously const toRemove = ['Mars', 'Saturn'] - async.each(toRemove, function (planet, cb) { + each(toRemove, function (planet, cb) { d.remove({ planet: planet }, function (err) { return cb(err) }) // eslint-disable-next-line node/handle-callback-err }, function (err) { diff --git a/test/executor.test.js b/test/executor.test.js index fda65ff..a9d2de9 100755 --- a/test/executor.test.js +++ b/test/executor.test.js @@ -3,7 +3,7 @@ const chai = require('chai') const testDb = 'workspace/test.db' const fs = require('fs') const path = require('path') -const async = require('async') +const { waterfall } = require('./utils.test.js') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') @@ -151,7 +151,7 @@ describe('Executor', function () { d.filename.should.equal(testDb) d.inMemoryOnly.should.equal(false) - async.waterfall([ + waterfall([ function (cb) { Persistence.ensureDirectoryExists(path.dirname(testDb), function () { fs.access(testDb, fs.constants.F_OK, function (err) { diff --git a/test/persistence.test.js b/test/persistence.test.js index 578707b..a19ae04 100755 --- a/test/persistence.test.js +++ b/test/persistence.test.js @@ -3,7 +3,7 @@ const chai = require('chai') const testDb = 'workspace/test.db' const fs = require('fs') const path = require('path') -const async = require('async') +const { apply, waterfall } = require('./utils.test.js') const model = require('../lib/model') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') @@ -22,7 +22,7 @@ describe('Persistence', function () { d.filename.should.equal(testDb) d.inMemoryOnly.should.equal(false) - async.waterfall([ + waterfall([ function (cb) { Persistence.ensureDirectoryExists(path.dirname(testDb), function () { fs.access(testDb, fs.constants.FS_OK, function (err) { @@ -911,9 +911,9 @@ describe('Persistence', function () { const dbFile = 'workspace/test2.db' let theDb, theDb2, doc1, doc2 - async.waterfall([ - async.apply(storage.ensureFileDoesntExist, dbFile), - async.apply(storage.ensureFileDoesntExist, dbFile + '~'), + waterfall([ + apply(storage.ensureFileDoesntExist, dbFile), + apply(storage.ensureFileDoesntExist, dbFile + '~'), function (cb) { theDb = new Datastore({ filename: dbFile }) theDb.loadDatabase(cb) diff --git a/test/utils.test.js b/test/utils.test.js new file mode 100644 index 0000000..2aa5f62 --- /dev/null +++ b/test/utils.test.js @@ -0,0 +1,33 @@ +const { callbackify, promisify } = require('util') + +const waterfallAsync = async tasks => { + for (const task of tasks) { + await promisify(task)() + } +} + +const waterfall = callbackify(waterfallAsync) + +const eachAsync = async (arr, iterator) => Promise.all(arr.map(el => promisify(iterator)(el))) + +const each = callbackify(eachAsync) + +const apply = function (fn) { + const args = Array.prototype.slice.call(arguments, 1) + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ) + } +} + +const whilstAsync = async (test, fn) => { + while (test()) await promisify(fn)() +} + +const whilst = callbackify(whilstAsync) + +module.exports.whilst = whilst +module.exports.apply = apply +module.exports.waterfall = waterfall +module.exports.each = each diff --git a/test_lac/openFds.test.js b/test_lac/openFds.test.js index b93c06d..4512087 100644 --- a/test_lac/openFds.test.js +++ b/test_lac/openFds.test.js @@ -1,5 +1,5 @@ const fs = require('fs') -const async = require('async') +const { waterfall, whilst } = require('../test/utils.test.js') const Nedb = require('../lib/datastore') const db = new Nedb({ filename: './workspace/openfds.db', autoload: true }) const N = 64 @@ -7,7 +7,7 @@ let i let fds function multipleOpen (filename, N, callback) { - async.whilst(function () { return i < N } + whilst(function () { return i < N } , function (cb) { fs.open(filename, 'r', function (err, fd) { i += 1 @@ -18,7 +18,7 @@ function multipleOpen (filename, N, callback) { , callback) } -async.waterfall([ +waterfall([ // Check that ulimit has been set to the correct value function (cb) { i = 0 @@ -46,7 +46,7 @@ async.waterfall([ if (err) { console.log(err) } i = 0 - async.whilst(function () { return i < 2 * N + 1 } + whilst(function () { return i < 2 * N + 1 } , function (cb) { db.persistence.persistCachedDatabase(function (err) { if (err) { return cb(err) } @@ -61,4 +61,4 @@ async.waterfall([ }) }) } -]) +], () => {}) diff --git a/webpack.config.js b/webpack.config.js index 37a2cb1..6ba8737 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -37,11 +37,12 @@ module.exports = (env, argv) => { }) ], entry: { - Nedb: path.join(__dirname, 'lib', 'datastore.js') + Nedb: path.join(__dirname, 'lib', 'datastore.js'), + testUtils: path.join(__dirname, 'test', 'utils.test.js') }, output: { path: path.join(__dirname, 'browser-version/out'), - filename: minimize ? 'nedb.min.js' : 'nedb.js', + filename: `[name]${minimize ? '.min' : ''}.js`, libraryTarget: 'window', library: '[name]' } From dd7c3c62d436027ab44532f2184a82f76206414b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 25 Oct 2021 11:32:34 +0200 Subject: [PATCH 22/65] linting --- benchmarks/profiler.js | 1 - test/browser/load.spec.js | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/benchmarks/profiler.js b/benchmarks/profiler.js index 184aed2..a5d73af 100644 --- a/benchmarks/profiler.js +++ b/benchmarks/profiler.js @@ -1,4 +1,3 @@ -const { apply, waterfall } = require('../test/utils.test.js') const util = require('util') function formatTime (time, precision) { diff --git a/test/browser/load.spec.js b/test/browser/load.spec.js index b2a6b39..194f2b2 100755 --- a/test/browser/load.spec.js +++ b/test/browser/load.spec.js @@ -72,7 +72,7 @@ describe.skip('Load tests', function () { db.remove({}, { multi: true }, err => done(err)) }) - it('Inserts', function (done) { + it.skip('Inserts', function (done) { testUtils.waterfall([ // Slow and gets slower with database size testUtils.apply(someInserts, '#1', N), // N=5000, 141s @@ -82,7 +82,7 @@ describe.skip('Load tests', function () { ], done) }) - it('Localstorage', function (done) { + it.skip('Localstorage', function (done) { testUtils.waterfall([ // Slow and gets slower really fast with database size, then outright crashes testUtils.apply(someLS, '#1', N), // N=4000, 2.5s @@ -92,7 +92,7 @@ describe.skip('Load tests', function () { ], done) }) - it('Localstorage Diff', function (done) { + it.skip('Localstorage Diff', function (done) { testUtils.waterfall([ // Much faster and more consistent testUtils.apply(someLSDiff, '#1', N), // N=50000, 0.7s @@ -102,7 +102,7 @@ describe.skip('Load tests', function () { ], done) }) - it('LocalForage', function (done) { + it.skip('LocalForage', function (done) { testUtils.waterfall([ // Slow and gets slower with database size cb => { localforage.setItem('loadTestLF', '', err => cb(err)) }, @@ -113,7 +113,7 @@ describe.skip('Load tests', function () { ], done) }) - it('LocalForage diff', function (done) { + it.skip('LocalForage diff', function (done) { testUtils.waterfall([ // Quite fast and speed doesn't change with database size (tested with N=10000 and N=50000, still no slow-down) testUtils.apply(someLFDiff, '#1', N), // N=5000, 18s From c480c1230c5c3abe53b8171cd0d9d2ac5c8a0d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 25 Oct 2021 11:47:11 +0200 Subject: [PATCH 23/65] fix case sensitiveness on filename --- karma.conf.template.js | 2 +- webpack.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/karma.conf.template.js b/karma.conf.template.js index 0eab6eb..c87cae6 100644 --- a/karma.conf.template.js +++ b/karma.conf.template.js @@ -14,7 +14,7 @@ module.exports = (config) => ({ // list of files / patterns to load in the browser files: [ 'node_modules/localforage/dist/localforage.min.js', - 'browser-version/out/testUtils.min.js', + 'browser-version/out/testutils.min.js', 'browser-version/out/nedb.min.js', 'test/browser/nedb-browser.spec.js', 'test/browser/load.spec.js' diff --git a/webpack.config.js b/webpack.config.js index 6ba8737..6846602 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -42,7 +42,7 @@ module.exports = (env, argv) => { }, output: { path: path.join(__dirname, 'browser-version/out'), - filename: `[name]${minimize ? '.min' : ''}.js`, + filename: pathData => `${pathData.chunk.name.toLowerCase()}${minimize ? '.min' : ''}.js`, libraryTarget: 'window', library: '[name]' } From 5f8850df1bbd5779c9b0b6f67360cf1ac074e6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 12 Nov 2021 17:50:33 +0100 Subject: [PATCH 24/65] port react-native storage module to async functions --- browser-version/lib/storage.react-native.js | 132 +++++++++++++------- 1 file changed, 86 insertions(+), 46 deletions(-) diff --git a/browser-version/lib/storage.react-native.js b/browser-version/lib/storage.react-native.js index 11a0af7..f132910 100755 --- a/browser-version/lib/storage.react-native.js +++ b/browser-version/lib/storage.react-native.js @@ -7,80 +7,120 @@ * This version is the react-native version */ const AsyncStorage = require('@react-native-async-storage/async-storage').default +const { callbackify } = require('util') -const exists = (filename, cback) => { - // eslint-disable-next-line node/handle-callback-err - AsyncStorage.getItem(filename, (err, value) => { - if (value !== null) { - return cback(true) - } else { - return cback(false) - } - }) +const existsAsync = async filename => { + try { + const value = await AsyncStorage.getItem(filename) + if (value !== null) return true // Even if value is undefined, localforage returns null + return false + } catch (error) { + return false + } } -const rename = (filename, newFilename, callback) => { - // eslint-disable-next-line node/handle-callback-err - AsyncStorage.getItem(filename, (err, value) => { - if (value === null) { - this.storage.removeItem(newFilename, callback) - } else { - this.storage.setItem(newFilename, value, () => { - this.storage.removeItem(filename, callback) - }) +const exists = callbackify(existsAsync) + +const renameAsync = async (filename, newFilename) => { + try { + const value = await AsyncStorage.getItem(filename) + if (value === null) await AsyncStorage.removeItem(newFilename) + else { + await AsyncStorage.setItem(newFilename, value) + await AsyncStorage.removeItem(filename) } - }) + } catch (err) { + console.warn('An error happened while renaming, skip') + } } -const writeFile = (filename, contents, options, callback) => { - // Options do not matter in a react-native setup - if (typeof options === 'function') { callback = options } - AsyncStorage.setItem(filename, contents, callback) +const rename = callbackify(renameAsync) + +const writeFileAsync = async (filename, contents, options) => { + // Options do not matter in browser setup + try { + await AsyncStorage.setItem(filename, contents) + } catch (error) { + console.warn('An error happened while writing, skip') + } } -const appendFile = (filename, toAppend, options, callback) => { - // Options do not matter in a react-native setup - if (typeof options === 'function') { callback = options } +const writeFile = callbackify(writeFileAsync) - // eslint-disable-next-line node/handle-callback-err - AsyncStorage.getItem(filename, (err, contents) => { - contents = contents || '' - contents += toAppend - AsyncStorage.setItem(filename, contents, callback) - }) +const appendFileAsync = async (filename, toAppend, options) => { + // Options do not matter in browser setup + try { + const contents = (await AsyncStorage.getItem(filename)) || '' + await AsyncStorage.setItem(filename, contents + toAppend) + } catch (error) { + console.warn('An error happened appending to file writing, skip') + } } -const readFile = (filename, options, callback) => { - // Options do not matter in a react-native setup - if (typeof options === 'function') { callback = options } - // eslint-disable-next-line node/handle-callback-err - AsyncStorage.getItem(filename, (err, contents) => { - return callback(null, contents || '') - }) +const appendFile = callbackify(appendFileAsync) + +const readFileAsync = async (filename, options) => { + try { + return (await AsyncStorage.getItem(filename)) || '' + } catch (error) { + console.warn('An error happened while reading, skip') + return '' + } } -const unlink = (filename, callback) => { - AsyncStorage.removeItem(filename, callback) +const readFile = callbackify(readFileAsync) + +const unlinkAsync = async filename => { + try { + await AsyncStorage.removeItem(filename) + } catch (error) { + console.warn('An error happened while unlinking, skip') + } } +const unlink = callbackify(unlinkAsync) + // Nothing to do, no directories will be used on react-native -const mkdir = (dir, options, callback) => callback() +const mkdirAsync = (dir, options) => Promise.resolve() + +const mkdir = callbackify(mkdirAsync) -// Nothing to do, no data corruption possible on react-native -const ensureDatafileIntegrity = (filename, callback) => callback(null) +// Nothing to do, no data corruption possible in the browser +const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() -const crashSafeWriteFileLines = (filename, lines, callback) => { +const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) + +const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line - writeFile(filename, lines.join('\n'), callback) + await writeFileAsync(filename, lines.join('\n')) } +const crashSafeWriteFileLines = callbackify(crashSafeWriteFileLinesAsync) + // Interface module.exports.exists = exists +module.exports.existsAsync = existsAsync + module.exports.rename = rename +module.exports.renameAsync = renameAsync + module.exports.writeFile = writeFile +module.exports.writeFileAsync = writeFileAsync + module.exports.crashSafeWriteFileLines = crashSafeWriteFileLines +module.exports.crashSafeWriteFileLinesAsync = crashSafeWriteFileLinesAsync + module.exports.appendFile = appendFile +module.exports.appendFileAsync = appendFileAsync + module.exports.readFile = readFile +module.exports.readFileAsync = readFileAsync + module.exports.unlink = unlink +module.exports.unlinkAsync = unlinkAsync + module.exports.mkdir = mkdir +module.exports.mkdirAsync = mkdirAsync + module.exports.ensureDatafileIntegrity = ensureDatafileIntegrity +module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync From ba65fbe9b63e8c5b1efed45cb6875973aea4fceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 15 Nov 2021 19:01:24 +0100 Subject: [PATCH 25/65] Added tests for async version of datastore --- lib/datastore.js | 44 +- lib/persistence.js | 4 + test/db.async.test.js | 2046 +++++++++++++++++++++++++++++++++++++++++ test/utils.test.js | 5 + 4 files changed, 2072 insertions(+), 27 deletions(-) create mode 100644 test/db.async.test.js diff --git a/lib/datastore.js b/lib/datastore.js index e6a7518..a0cb98f 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -76,9 +76,14 @@ class Datastore extends EventEmitter { // Queue a load of the database right away and call the onload handler // By default (no onload handler), if there is an error there, no operation will be possible so warn the user by throwing an exception if (this.autoload) { - this.loadDatabase(options.onload || (err => { - if (err) throw err - })) + this.autoloadPromise = this.loadDatabaseAsync() + this.autoloadPromise + .then(() => { + if (options.onload) options.onload() + }, err => { + if (options.onload) options.onload(err) + else throw err + }) } } @@ -298,12 +303,7 @@ class Datastore extends EventEmitter { else expiredDocsIds.push(doc._id) }) for (const _id of expiredDocsIds) { - await new Promise((resolve, reject) => { - this._remove({ _id: _id }, {}, err => { - if (err) return reject(err) - return resolve() - }) - }) + await this._removeAsync({ _id: _id }, {}) } } else validDocs.push(...docs) return validDocs @@ -405,7 +405,7 @@ class Datastore extends EventEmitter { } insertAsync (...args) { - return this.executor.push({ this: this, fn: this._insertAsync, arguments: args, async: true }) + return this.executor.pushAsync(() => this._insertAsync(...args)) } /** @@ -530,15 +530,10 @@ class Datastore extends EventEmitter { // If upsert option is set, check whether we need to insert the doc if (upsert) { - // Need to use an internal function not tied to the executor to avoid deadlock - const cursor = new Cursor(this, query) + const cursor = new Cursor(this, query, x => x, true) - const docs = await new Promise((resolve, reject) => { - cursor.limit(1)._exec((err, docs) => { - if (err) reject(err) - else resolve(docs) - }) - }) + // Need to use an internal function not tied to the executor to avoid deadlock + const docs = await cursor.limit(1)._execAsync() if (docs.length !== 1) { let toBeInserted @@ -552,13 +547,8 @@ class Datastore extends EventEmitter { // strip it from all operators and update it according to updateQuery toBeInserted = model.modify(model.deepCopy(query, true), updateQuery) } - - return new Promise((resolve, reject) => { - this._insert(toBeInserted, (err, newDoc) => { - if (err) return reject(err) - return resolve({ numAffected: 1, affectedDocuments: newDoc, upsert: true }) - }) - }) + const newDoc = await this._insertAsync(toBeInserted) + return { numAffected: 1, affectedDocuments: newDoc, upsert: true } } } // Perform the update @@ -603,7 +593,7 @@ class Datastore extends EventEmitter { } updateAsync (...args) { - return this.executor.pushAsync(() => this._updateAsync(args)) + return this.executor.pushAsync(() => this._updateAsync(...args)) } /** @@ -651,7 +641,7 @@ class Datastore extends EventEmitter { } removeAsync (...args) { - return this.executor.pushAsync(() => this._removeAsync(args)) + return this.executor.pushAsync(() => this._removeAsync(...args)) } } diff --git a/lib/persistence.js b/lib/persistence.js index 8439a81..11a9849 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -107,6 +107,10 @@ class Persistence { this.db.executor.push({ this: this, fn: this.persistCachedDatabase, arguments: [] }) } + compactDatafileAsync () { + return this.db.executor.pushAsync(() => this.persistCachedDatabaseAsync()) + } + /** * Set automatic compaction every interval ms * @param {Number} interval in milliseconds, with an enforced minimum of 5 seconds diff --git a/test/db.async.test.js b/test/db.async.test.js new file mode 100644 index 0000000..ff499e5 --- /dev/null +++ b/test/db.async.test.js @@ -0,0 +1,2046 @@ +/* eslint-env mocha */ +const testDb = 'workspace/test.db' +const fs = require('fs').promises +const fsConstants = require('fs').constants +const path = require('path') +const assert = require('assert').strict +const model = require('../lib/model') +const Datastore = require('../lib/datastore') +const Persistence = require('../lib/persistence') +const { wait } = require('./utils.test') +const reloadTimeUpperBound = 60 // In ms, an upper bound for the reload time used to check createdAt and updatedAt + +describe.only('Database async', function () { + let d + + beforeEach(async () => { + d = new Datastore({ filename: testDb }) + assert.equal(d.filename, testDb) + assert.equal(d.inMemoryOnly, false) + await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb)) + try { + await fs.access(testDb, fsConstants.FS_OK) + await fs.unlink(testDb) + } catch (err) {} + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 0) + }) + + it('Constructor compatibility with v0.6-', () => { + const db1 = new Datastore('somefile') + assert.equal(db1.filename, 'somefile') + assert.equal(db1.inMemoryOnly, false) + + const db2 = new Datastore('') + assert.equal(db2.filename, null) + assert.equal(db2.inMemoryOnly, true) + + const db3 = new Datastore() + assert.equal(db3.filename, null) + assert.equal(db3.inMemoryOnly, true) + }) + + describe('Autoloading', () => { + it('Can autoload a database and query it right away', async () => { + const fileStr = model.serialize({ + _id: '1', + a: 5, + planet: 'Earth' + }) + '\n' + model.serialize({ + _id: '2', + a: 5, + planet: 'Mars' + }) + '\n' + const autoDb = 'workspace/auto.db' + + await fs.writeFile(autoDb, fileStr, 'utf8') + const db = new Datastore({ filename: autoDb, autoload: true }) + + const docs = await db.find({}) + assert.equal(docs.length, 2) + }) + + it('Throws if autoload fails', async () => { + const fileStr = model.serialize({ + _id: '1', + a: 5, + planet: 'Earth' + }) + '\n' + model.serialize({ + _id: '2', + a: 5, + planet: 'Mars' + }) + '\n' + '{"$$indexCreated":{"fieldName":"a","unique":true}}' + const autoDb = 'workspace/auto.db' + + await fs.writeFile(autoDb, fileStr, 'utf8') + + const db = new Datastore({ filename: autoDb, autoload: true }) + await Promise.race([ + // Check the loadDatabase generated an error + assert.rejects(() => db.autoloadPromise, err => { + assert.equal(err.errorType, 'uniqueViolated') + return true + }), + db.findAsync({}).finally(() => { throw new Error('Find should not be executed since autoload failed') }) + ]) + }) + }) + + describe('Insert', () => { + it('Able to insert a document in the database, setting an _id if none provided, and retrieve it even after a reload', async () => { + const docsEmpty = await d.findAsync({}) + assert.equal(docsEmpty.length, 0) + await d.insertAsync({ somedata: 'ok' }) + const docs = await d.findAsync({}) + // The data was correctly updated + assert.equal(docs.length, 1) + assert.equal(Object.keys(docs[0]).length, 2) + assert.equal(docs[0].somedata, 'ok') + assert.notEqual(docs[0]._id, undefined) + // After a reload the data has been correctly persisted + await d.loadDatabaseAsync() + const docsReloaded = await d.findAsync({}) + assert.equal(docsReloaded.length, 1) + assert.equal(Object.keys(docsReloaded[0]).length, 2) + assert.equal(docsReloaded[0].somedata, 'ok') + assert.notEqual(docsReloaded[0]._id, undefined) + }) + + it('Can insert multiple documents in the database', async () => { + const docsEmpty = await d.findAsync({}) + assert.equal(docsEmpty.length, 0) + await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'another' }) + await d.insertAsync({ somedata: 'again' }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 3) + const values = docs.map(x => x.somedata) + assert.ok(values.includes('ok')) + assert.ok(values.includes('another')) + assert.ok(values.includes('again')) + }) + + it('Can insert and get back from DB complex objects with all primitive and secondary types', async () => { + const da = new Date() + const obj = { a: ['ee', 'ff', 42], date: da, subobj: { a: 'b', b: 'c' } } + await d.insertAsync(obj) + const res = await d.findOneAsync({}) + assert.deepEqual(res.a, obj.a) + assert.equal(res.date.getTime(), da.getTime()) + assert.deepEqual(res.subobj, obj.subobj) + }) + + it('If an object returned from the DB is modified and refetched, the original value should be found', async () => { + await d.insertAsync({ a: 'something' }) + const doc = await d.findOneAsync({}) + assert.equal(doc.a, 'something') + doc.a = 'another thing' + assert.equal(doc.a, 'another thing') + // Re-fetching with findOne should yield the persisted value + const doc2 = await d.findOneAsync({}) + assert.equal(doc2.a, 'something') + doc2.a = 'another thing' + assert.equal(doc2.a, 'another thing') + const docs = await d.findAsync({}) + assert.equal(docs[0].a, 'something') + }) + + it('Cannot insert a doc that has a field beginning with a $ sign', async () => { + await assert.rejects(() => d.insertAsync({ $something: 'atest' })) + }) + + it('If an _id is already given when we insert a document, use that instead of generating a random one', async () => { + const newDoc = await d.insertAsync({ _id: 'test', stuff: true }) + assert.equal(newDoc.stuff, true) + assert.equal(newDoc._id, 'test') + + await assert.rejects(() => d.insertAsync({ + _id: 'test', + otherstuff: 42 + }), err => { + assert.equal(err.errorType, 'uniqueViolated') + return true + }) + }) + + it('Modifying the insertedDoc after an insert doesnt change the copy saved in the database', async () => { + const newDoc = await d.insertAsync({ a: 2, hello: 'world' }) + newDoc.hello = 'changed' + const doc = await d.findOneAsync({ a: 2 }) + assert.equal(doc.hello, 'world') + }) + + it('Can insert an array of documents at once', async () => { + const docsToInsert = [{ a: 5, b: 'hello' }, { a: 42, b: 'world' }] + await d.insertAsync(docsToInsert) + const docs = await d.findAsync({}) + assert.equal(docs.find(doc => doc.a === 5).b, 'hello') + assert.equal(docs.find(doc => doc.a === 42).b, 'world') + assert.equal(docs.length, 2) + const data = (await fs.readFile(testDb, 'utf8')) + .split('\n') + .filter(line => line.length > 0) + assert.equal(data.length, 2) + assert.equal(model.deserialize(data[0]).a, 5) + assert.equal(model.deserialize(data[0]).b, 'hello') + assert.equal(model.deserialize(data[1]).a, 42) + assert.equal(model.deserialize(data[1]).b, 'world') + }) + + it('If a bulk insert violates a constraint, all changes are rolled back', async () => { + const docsToInsert = [{ a: 5, b: 'hello' }, { a: 42, b: 'world' }, { a: 5, b: 'bloup' }, { a: 7 }] + // Important to await here to make sure filesystem synced + await d.ensureIndexAsync({ fieldName: 'a', unique: true }) + await assert.rejects(() => d.insertAsync(docsToInsert), err => { + assert.equal(err.errorType, 'uniqueViolated') + return true + }) + const docs = await d.findAsync({}) + // Datafile only contains index definition + const datafileContents = model.deserialize(await fs.readFile(testDb, 'utf8')) + assert.deepEqual(datafileContents, { $$indexCreated: { fieldName: 'a', unique: true } }) + assert.equal(docs.length, 0) + }) + + it('If timestampData option is set, a createdAt field is added and persisted', async () => { + const newDoc = { hello: 'world' } + const beginning = Date.now() + d = new Datastore({ filename: testDb, timestampData: true, autoload: true }) + const docsEmpty = await d.findAsync({}) + assert.equal(docsEmpty.length, 0) + const insertedDoc = await d.insertAsync(newDoc) + // No side effect on given input + assert.deepEqual(newDoc, { hello: 'world' }) + // Insert doc has two new fields, _id and createdAt + assert.equal(insertedDoc.hello, 'world') + assert.notEqual(insertedDoc.createdAt, undefined) + assert.notEqual(insertedDoc.updatedAt, undefined) + assert.equal(insertedDoc.createdAt, insertedDoc.updatedAt) + assert.notEqual(insertedDoc._id, undefined) + assert.equal(Object.keys(insertedDoc).length, 4) + assert.ok(Math.abs(insertedDoc.createdAt.getTime() - beginning) < reloadTimeUpperBound) // No more than 30ms should have elapsed (worst case, if there is a flush) + + // Modifying results of insert doesn't change the cache + insertedDoc.bloup = 'another' + assert.equal(Object.keys(insertedDoc).length, 5) + + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + // No side effect on given input + assert.deepEqual(newDoc, { hello: 'world' }) + assert.deepEqual({ + hello: 'world', + _id: insertedDoc._id, + createdAt: insertedDoc.createdAt, + updatedAt: insertedDoc.updatedAt + }, docs[0]) + + // All data correctly persisted on disk + await d.loadDatabaseAsync() + const docsReloaded = await d.findAsync({}) + assert.equal(docsReloaded.length, 1) + // No side effect on given input + assert.deepEqual(newDoc, { hello: 'world' }) + assert.deepEqual({ + hello: 'world', + _id: insertedDoc._id, + createdAt: insertedDoc.createdAt, + updatedAt: insertedDoc.updatedAt + }, docsReloaded[0]) + }) + + it('If timestampData option not set, don\'t create a createdAt and a updatedAt field', async () => { + const insertedDoc = await d.insertAsync({ hello: 'world' }) + assert.equal(Object.keys(insertedDoc).length, 2) + assert.equal(insertedDoc.createdAt, undefined) + assert.equal(insertedDoc.updatedAt, undefined) + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + assert.deepEqual(docs[0], insertedDoc) + }) + + it('If timestampData is set but createdAt is specified by user, don\'t change it', async () => { + const newDoc = { hello: 'world', createdAt: new Date(234) } + const beginning = Date.now() + d = new Datastore({ filename: testDb, timestampData: true, autoload: true }) + const insertedDoc = await d.insertAsync(newDoc) + assert.equal(Object.keys(insertedDoc).length, 4) + assert.equal(insertedDoc.createdAt.getTime(), 234) // Not modified + assert.ok(insertedDoc.updatedAt.getTime() - beginning < reloadTimeUpperBound) // Created + const docs = await d.findAsync({}) + assert.deepEqual(insertedDoc, docs[0]) + await d.loadDatabaseAsync() + const docsReloaded = await d.findAsync({}) + assert.deepEqual(insertedDoc, docsReloaded[0]) + }) + + it('If timestampData is set but updatedAt is specified by user, don\'t change it', async () => { + const newDoc = { hello: 'world', updatedAt: new Date(234) } + const beginning = Date.now() + d = new Datastore({ filename: testDb, timestampData: true, autoload: true }) + const insertedDoc = await d.insertAsync(newDoc) + assert.equal(Object.keys(insertedDoc).length, 4) + assert.equal(insertedDoc.updatedAt.getTime(), 234) + assert.ok(insertedDoc.createdAt.getTime() - beginning < reloadTimeUpperBound) + const docs = await d.findAsync({}) + assert.deepEqual(insertedDoc, docs[0]) + await d.loadDatabaseAsync() + const docsReloaded = await d.findAsync({}) + assert.deepEqual(insertedDoc, docsReloaded[0]) + }) + + it('Can insert a doc with id 0', async () => { + const doc = await d.insertAsync({ _id: 0, hello: 'world' }) + assert.equal(doc._id, 0) + assert.equal(doc.hello, 'world') + }) + }) // ==== End of 'Insert' ==== // + + describe('#getCandidates', function () { + it('Can use an index to get docs with a basic match', async () => { + await d.ensureIndexAsync({ fieldName: 'tf' }) + const _doc1 = await d.insertAsync({ tf: 4 }) + await d.insertAsync({ tf: 6 }) + const _doc2 = await d.insertAsync({ tf: 4, an: 'other' }) + await d.insertAsync({ tf: 9 }) + const data = await d.getCandidatesAsync({ r: 6, tf: 4 }) + const doc1 = data.find(d => d._id === _doc1._id) + const doc2 = data.find(d => d._id === _doc2._id) + + assert.equal(data.length, 2) + assert.deepEqual(doc1, { _id: doc1._id, tf: 4 }) + assert.deepEqual(doc2, { _id: doc2._id, tf: 4, an: 'other' }) + }) + + it('Can use an index to get docs with a $in match', async () => { + await d.ensureIndex({ fieldName: 'tf' }) + await d.insertAsync({ tf: 4 }) + const _doc1 = await d.insertAsync({ tf: 6 }) + await d.insertAsync({ tf: 4, an: 'other' }) + const _doc2 = await d.insertAsync({ tf: 9 }) + const data = await d.getCandidatesAsync({ r: 6, tf: { $in: [6, 9, 5] } }) + const doc1 = data.find(d => d._id === _doc1._id) + const doc2 = data.find(d => d._id === _doc2._id) + + assert.equal(data.length, 2) + assert.deepEqual(doc1, { _id: doc1._id, tf: 6 }) + assert.deepEqual(doc2, { _id: doc2._id, tf: 9 }) + }) + + it('If no index can be used, return the whole database', async () => { + await d.ensureIndexAsync({ fieldName: 'tf' }) + const _doc1 = await d.insertAsync({ tf: 4 }) + const _doc2 = await d.insertAsync({ tf: 6 }) + const _doc3 = await d.insertAsync({ tf: 4, an: 'other' }) + const _doc4 = await d.insertAsync({ tf: 9 }) + const data = await d.getCandidatesAsync({ r: 6, notf: { $in: [6, 9, 5] } }) + const doc1 = data.find(d => d._id === _doc1._id) + const doc2 = data.find(d => d._id === _doc2._id) + const doc3 = data.find(d => d._id === _doc3._id) + const doc4 = data.find(d => d._id === _doc4._id) + + assert.equal(data.length, 4) + assert.deepEqual(doc1, { _id: doc1._id, tf: 4 }) + assert.deepEqual(doc2, { _id: doc2._id, tf: 6 }) + assert.deepEqual(doc3, { _id: doc3._id, tf: 4, an: 'other' }) + assert.deepEqual(doc4, { _id: doc4._id, tf: 9 }) + }) + + it('Can use indexes for comparison matches', async () => { + await d.ensureIndexAsync({ fieldName: 'tf' }) + await d.insertAsync({ tf: 4 }) + const _doc2 = await d.insertAsync({ tf: 6 }) + await d.insertAsync({ tf: 4, an: 'other' }) + const _doc4 = await d.insertAsync({ tf: 9 }) + const data = await d.getCandidatesAsync({ r: 6, tf: { $lte: 9, $gte: 6 } }) + const doc2 = data.find(d => d._id === _doc2._id) + const doc4 = data.find(d => d._id === _doc4._id) + + assert.equal(data.length, 2) + assert.deepEqual(doc2, { _id: doc2._id, tf: 6 }) + assert.deepEqual(doc4, { _id: doc4._id, tf: 9 }) + }) + + it('Can set a TTL index that expires documents', async () => { + await d.ensureIndexAsync({ fieldName: 'exp', expireAfterSeconds: 0.2 }) + await d.insertAsync({ hello: 'world', exp: new Date() }) + await wait(100) + const doc1 = await d.findOneAsync({}) + assert.equal(doc1.hello, 'world') + + await wait(101) + const doc2 = await d.findOneAsync({}) + assert.equal(doc2, null) + await d.persistence.compactDatafileAsync() + // After compaction, no more mention of the document, correctly removed + const datafileContents = await fs.readFile(testDb, 'utf8') + assert.equal(datafileContents.split('\n').length, 2) + assert.doesNotMatch(datafileContents, /world/) + + // New datastore on same datafile is empty + const d2 = new Datastore({ filename: testDb, autoload: true }) + const doc3 = await d2.findOneAsync({}) + assert.equal(doc3, null) + }) + + it('TTL indexes can expire multiple documents and only what needs to be expired', async () => { + await d.ensureIndexAsync({ fieldName: 'exp', expireAfterSeconds: 0.2 }) + await d.insertAsync({ hello: 'world1', exp: new Date() }) + await d.insertAsync({ hello: 'world2', exp: new Date() }) + await d.insertAsync({ hello: 'world3', exp: new Date((new Date()).getTime() + 100) }) + await wait(100) + const docs1 = await d.findAsync({}) + assert.equal(docs1.length, 3) + + await wait(101) + const docs2 = await d.findAsync({}) + assert.equal(docs2.length, 1) + assert.equal(docs2[0].hello, 'world3') + + await wait(101) + const docs3 = await d.findAsync({}) + assert.equal(docs3.length, 0) + }) + + it('Document where indexed field is absent or not a date are ignored', async () => { + await d.ensureIndexAsync({ fieldName: 'exp', expireAfterSeconds: 0.2 }) + await d.insertAsync({ hello: 'world1', exp: new Date() }) + await d.insertAsync({ hello: 'world2', exp: 'not a date' }) + await d.insertAsync({ hello: 'world3' }) + await wait(101) + const docs1 = await d.findAsync({}) + assert.equal(docs1.length, 3) + + await wait(101) + const docs2 = await d.findAsync({}) + assert.equal(docs2.length, 2) + + docs2[0].hello.should.not.equal('world1') + docs2[1].hello.should.not.equal('world1') + }) + }) // ==== End of '#getCandidates' ==== // + + describe('Find', function () { + it('Can find all documents if an empty query is used', async () => { + await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'another', plus: 'additional data' }) + await d.insertAsync({ somedata: 'again' }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 3) + assert.ok(docs.map(x => x.somedata).includes('ok')) + assert.ok(docs.map(x => x.somedata).includes('another')) + assert.ok(docs.map(x => x.somedata).includes('again')) + assert.equal(docs.find(d => d.somedata === 'another').plus, 'additional data') + }) + + it('Can find all documents matching a basic query', async () => { + await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'again', plus: 'additional data' }) + await d.insertAsync({ somedata: 'again' }) + // Test with query that will return docs + const docs = await d.findAsync({ somedata: 'again' }) + assert.equal(docs.length, 2) + assert.ok(!docs.map(x => x.somedata).includes('ok')) + // Test with query that doesn't match anything + const docs2 = await d.findAsync({ somedata: 'nope' }) + assert.equal(docs2.length, 0) + }) + + it('Can find one document matching a basic query and return null if none is found', async () => { + await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'again', plus: 'additional data' }) + await d.insertAsync({ somedata: 'again' }) + // Test with query that will return docs + const doc = await d.findOne({ somedata: 'ok' }) + assert.equal(Object.keys(doc).length, 2) + assert.equal(doc.somedata, 'ok') + assert.notEqual(doc._id, undefined) + // Test with query that doesn't match anything + const doc2 = await d.findOne({ somedata: 'nope' }) + assert.equal(doc2, null) + }) + + it('Can find dates and objects (non JS-native types)', async () => { + const date1 = new Date(1234543) + const date2 = new Date(9999) + + await d.insertAsync({ now: date1, sth: { name: 'nedb' } }) + const doc1 = await d.findOne({ now: date1 }) + assert.equal(doc1.sth.name, 'nedb') + + const doc2 = await d.findOne({ now: date2 }) + assert.equal(doc2, null) + + const doc3 = await d.findOne({ sth: { name: 'nedb' } }) + assert.equal(doc3.sth.name, 'nedb') + + const doc4 = await d.findOne({ sth: { name: 'other' } }) + assert.equal(doc4, null) + }) + + it('Can use dot-notation to query subfields', async () => { + await d.insertAsync({ greeting: { english: 'hello' } }) + const doc1 = await d.findOne({ 'greeting.english': 'hello' }) + assert.equal(doc1.greeting.english, 'hello') + + const doc2 = await d.findOne({ 'greeting.english': 'hellooo' }) + assert.equal(doc2, null) + + const doc3 = await d.findOne({ 'greeting.englis': 'hello' }) + assert.equal(doc3, null) + }) + + it('Array fields match if any element matches', async () => { + const doc1 = await d.insertAsync({ fruits: ['pear', 'apple', 'banana'] }) + const doc2 = await d.insertAsync({ fruits: ['coconut', 'orange', 'pear'] }) + const doc3 = await d.insertAsync({ fruits: ['banana'] }) + const docs = await d.findAsync({ fruits: 'pear' }) + assert.equal(docs.length, 2) + assert.ok(docs.map(x => x._id).includes(doc1._id)) + assert.ok(docs.map(x => x._id).includes(doc2._id)) + + const docs2 = await d.findAsync({ fruits: 'banana' }) + assert.equal(docs2.length, 2) + assert.ok(docs2.map(x => x._id).includes(doc1._id)) + assert.ok(docs2.map(x => x._id).includes(doc3._id)) + + const docs3 = await d.findAsync({ fruits: 'doesntexist' }) + assert.equal(docs3.length, 0) + }) + + it('Returns an error if the query is not well formed', async () => { + await d.insertAsync({ hello: 'world' }) + await assert.rejects(() => d.findAsync({ $or: { hello: 'world' } })) + await assert.rejects(() => d.findOneAsync({ $or: { hello: 'world' } })) + }) + + it('Changing the documents returned by find or findOne do not change the database state', async () => { + await d.insertAsync({ a: 2, hello: 'world' }) + const doc1 = await d.findOneAsync({ a: 2 }) + doc1.hello = 'changed' + + const doc2 = await d.findOneAsync({ a: 2 }) + assert.equal(doc2.hello, 'world') + + const docs = await d.findAsync({ a: 2 }) + docs[0].hello = 'changed' + + const doc3 = await d.findOneAsync({ a: 2 }) + assert.equal(doc3.hello, 'world') + }) + + it('Can use sort, skip and limit if the callback is not passed to find but to exec', async () => { + await d.insertAsync({ a: 2, hello: 'world' }) + await d.insertAsync({ a: 24, hello: 'earth' }) + await d.insertAsync({ a: 13, hello: 'blueplanet' }) + await d.insertAsync({ a: 15, hello: 'home' }) + const docs = await d.findAsync({}).sort({ a: 1 }).limit(2) + assert.equal(docs.length, 2) + assert.equal(docs[0].hello, 'world') + assert.equal(docs[1].hello, 'blueplanet') + }) + + it('Can use sort and skip if the callback is not passed to findOne but to exec', async () => { + await d.insertAsync({ a: 2, hello: 'world' }) + await d.insertAsync({ a: 24, hello: 'earth' }) + await d.insertAsync({ a: 13, hello: 'blueplanet' }) + await d.insertAsync({ a: 15, hello: 'home' }) + // No skip no query + const doc1 = await d.findOneAsync({}).sort({ a: 1 }) + assert.equal(doc1.hello, 'world') + + // A query + const doc2 = await d.findOneAsync({ a: { $gt: 14 } }).sort({ a: 1 }) + assert.equal(doc2.hello, 'home') + + // And a skip + const doc3 = await d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).skip(1) + assert.equal(doc3.hello, 'earth') + + // No result + const doc4 = await d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).skip(2) + assert.equal(doc4, null) + }) + + it('Can use projections in find, normal or cursor way', async () => { + await d.insertAsync({ a: 2, hello: 'world' }) + await d.insertAsync({ a: 24, hello: 'earth' }) + const docs = await d.findAsync({ a: 2 }, { a: 0, _id: 0 }) + assert.equal(docs.length, 1) + assert.deepEqual(docs[0], { hello: 'world' }) + + const docs1 = await d.findAsync({ a: 2 }, { a: 0, _id: 0 }).execAsync() + assert.equal(docs1.length, 1) + assert.deepEqual(docs1[0], { hello: 'world' }) + + // Can't use both modes at once if not _id + await assert.rejects(() => d.findAsync({ a: 2 }, { a: 0, hello: 1 })) + await assert.rejects(() => d.findAsync({ a: 2 }, { a: 0, hello: 1 }).execAsync()) + }) + + it('Can use projections in findOne, normal or cursor way', async () => { + await d.insertAsync({ a: 2, hello: 'world' }) + await d.insertAsync({ a: 24, hello: 'earth' }) + const doc1 = await d.findOneAsync({ a: 2 }, { a: 0, _id: 0 }) + assert.deepEqual(doc1, { hello: 'world' }) + + const doc2 = await d.findOneAsync({ a: 2 }, { a: 0, _id: 0 }) + assert.deepEqual(doc2, { hello: 'world' }) + + // Can't use both modes at once if not _id + await assert.rejects(() => d.findOneAsync({ a: 2 }, { a: 0, hello: 1 })) + await assert.rejects(() => d.findOneAsync({ a: 2 }, { a: 0, hello: 1 }).execAsync()) + }) // ==== End of 'Find' ==== // + }) + + describe('Count', function () { + it('Count all documents if an empty query is used', async () => { + await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'another', plus: 'additional data' }) + await d.insertAsync({ somedata: 'again' }) + // Test with empty object + const docs = await d.countAsync({}) + assert.equal(docs, 3) + }) + + it('Count all documents matching a basic query', async () => { + await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'again', plus: 'additional data' }) + await d.insertAsync({ somedata: 'again' }) + // Test with query that will return docs + const docs = await d.countAsync({ somedata: 'again' }) + assert.equal(docs, 2) + // Test with query that doesn't match anything + const docs2 = await d.countAsync({ somedata: 'nope' }) + assert.equal(docs2, 0) + }) + + it('Array fields match if any element matches', async () => { + await d.insertAsync({ fruits: ['pear', 'apple', 'banana'] }) + await d.insertAsync({ fruits: ['coconut', 'orange', 'pear'] }) + await d.insertAsync({ fruits: ['banana'] }) + const docs = await d.countAsync({ fruits: 'pear' }) + assert.equal(docs, 2) + + const docs2 = await d.countAsync({ fruits: 'banana' }) + assert.equal(docs2, 2) + + const docs3 = await d.countAsync({ fruits: 'doesntexist' }) + assert.equal(docs3, 0) + }) + + it('Returns an error if the query is not well formed', async () => { + await d.insertAsync({ hello: 'world' }) + await assert.rejects(() => d.countAsync({ $or: { hello: 'world' } })) + }) + }) + + describe('Update', function () { + it('If the query doesn\'t match anything, database is not modified', async () => { + await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'again', plus: 'additional data' }) + await d.insertAsync({ somedata: 'another' }) + // Test with query that doesn't match anything + const { numAffected } = await d.updateAsync({ somedata: 'nope' }, { newDoc: 'yes' }, { multi: true }) + assert.equal(numAffected, 0) + + const docs = await d.findAsync({}) + const doc1 = docs.find(function (d) { return d.somedata === 'ok' }) + const doc2 = docs.find(function (d) { return d.somedata === 'again' }) + const doc3 = docs.find(function (d) { return d.somedata === 'another' }) + + assert.equal(docs.length, 3) + assert.equal(docs.find(d => d.newDoc === 'yes'), undefined) + + assert.deepEqual(doc1, { _id: doc1._id, somedata: 'ok' }) + assert.deepEqual(doc2, { _id: doc2._id, somedata: 'again', plus: 'additional data' }) + assert.deepEqual(doc3, { _id: doc3._id, somedata: 'another' }) + }) + + it('If timestampData option is set, update the updatedAt field', async () => { + const beginning = Date.now() + d = new Datastore({ filename: testDb, autoload: true, timestampData: true }) + const insertedDoc = await d.insertAsync({ hello: 'world' }) + assert.ok(insertedDoc.updatedAt.getTime() - beginning < reloadTimeUpperBound) + assert.ok(insertedDoc.createdAt.getTime() - beginning < reloadTimeUpperBound) + assert.equal(Object.keys(insertedDoc).length, 4) + + // Wait 100ms before performing the update + await wait(100) + const step1 = Date.now() + await d.updateAsync({ _id: insertedDoc._id }, { $set: { hello: 'mars' } }, {}) + const docs = await d.findAsync({ _id: insertedDoc._id }) + assert.equal(docs.length, 1) + assert.equal(Object.keys(docs[0]).length, 4) + assert.equal(docs[0]._id, insertedDoc._id) + assert.equal(docs[0].createdAt, insertedDoc.createdAt) + assert.equal(docs[0].hello, 'mars') + assert.ok(docs[0].updatedAt.getTime() - beginning > 99) // updatedAt modified + assert.ok(docs[0].updatedAt.getTime() - step1 < reloadTimeUpperBound) // updatedAt modified + }) + + it('Can update multiple documents matching the query', async () => { + const doc1 = await d.insertAsync({ somedata: 'ok' }) + const doc2 = await d.insertAsync({ somedata: 'again', plus: 'additional data' }) + const doc3 = await d.insertAsync({ somedata: 'again' }) + const id1 = doc1._id + const id2 = doc2._id + const id3 = doc3._id + // Test DB state after update and reload + const testPostUpdateState = async () => { + const docs = await d.findAsync({}) + const doc1 = docs.find(d => d._id === id1) + const doc2 = docs.find(d => d._id === id2) + const doc3 = docs.find(d => d._id === id3) + + assert.equal(docs.length, 3) + + assert.equal(Object.keys(doc1).length, 2) + assert.equal(doc1.somedata, 'ok') + assert.equal(doc1._id, id1) + + assert.equal(Object.keys(doc2).length, 2) + assert.equal(doc2.newDoc, 'yes') + assert.equal(doc2._id, id2) + + assert.equal(Object.keys(doc3).length, 2) + assert.equal(doc3.newDoc, 'yes') + assert.equal(doc3._id, id3) + } + + const { numAffected } = await d.updateAsync({ somedata: 'again' }, { newDoc: 'yes' }, { multi: true }) + assert.equal(numAffected, 2) + + await testPostUpdateState() + await d.loadDatabaseAsync() + await testPostUpdateState() + }) + + it('Can update only one document matching the query', async () => { + const doc1 = await d.insertAsync({ somedata: 'ok' }) + const doc2 = await d.insertAsync({ somedata: 'again', plus: 'additional data' }) + const doc3 = await d.insertAsync({ somedata: 'again' }) + const id1 = doc1._id + const id2 = doc2._id + const id3 = doc3._id + + // Test DB state after update and reload + const testPostUpdateState = async () => { + const docs = await d.findAsync({}) + const doc1 = docs.find(d => d._id === id1) + const doc2 = docs.find(d => d._id === id2) + const doc3 = docs.find(d => d._id === id3) + + assert.equal(docs.length, 3) + + assert.deepEqual(doc1, { somedata: 'ok', _id: doc1._id }) + + // doc2 or doc3 was modified. Since we sort on _id and it is random + // it can be either of two situations + try { + assert.deepEqual(doc2, { newDoc: 'yes', _id: doc2._id }) + assert.deepEqual(doc3, { somedata: 'again', _id: doc3._id }) + } catch (e) { + assert.deepEqual(doc2, { somedata: 'again', plus: 'additional data', _id: doc2._id }) + assert.deepEqual(doc3, { newDoc: 'yes', _id: doc3._id }) + } + } + + // Test with query that doesn't match anything + const { numAffected } = await d.updateAsync({ somedata: 'again' }, { newDoc: 'yes' }, { multi: false }) + assert.equal(numAffected, 1) + + await testPostUpdateState() + await d.loadDatabaseAsync() + await testPostUpdateState() + }) + }) + + describe('Upserts', function () { + it('Can perform upserts if needed', async () => { + const { + numAffected: numAffectedEmpty, + affectedDocuments: affectedDocumentsEmpty + } = await d.updateAsync({ impossible: 'db is empty anyway' }, { newDoc: true }, {}) + assert.equal(numAffectedEmpty, 0) + assert.equal(affectedDocumentsEmpty, undefined) + + const docsEmpty = await d.findAsync({}) + assert.equal(docsEmpty.length, 0) // Default option for upsert is false + + const { + numAffected, + affectedDocuments + } = await d.updateAsync({ impossible: 'db is empty anyway' }, { something: 'created ok' }, { upsert: true }) + assert.equal(numAffected, 1) + assert.equal(affectedDocuments.something, 'created ok') + assert.notEqual(affectedDocuments._id, undefined) + + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) // Default option for upsert is false + assert.equal(docs[0].something, 'created ok') + + // Modifying the returned upserted document doesn't modify the database + affectedDocuments.newField = true + const docsModified = await d.findAsync({}) + assert.equal(docsModified[0].something, 'created ok') + assert.equal(docsModified[0].newField, undefined) + }) + + it('If the update query is a normal object with no modifiers, it is the doc that will be upserted', async () => { + await d.updateAsync({ $or: [{ a: 4 }, { a: 5 }] }, { hello: 'world', bloup: 'blap' }, { upsert: true }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + const doc = docs[0] + assert.equal(Object.keys(doc).length, 3) + assert.equal(doc.hello, 'world') + assert.equal(doc.bloup, 'blap') + }) + + it('If the update query contains modifiers, it is applied to the object resulting from removing all operators from the find query 1', async () => { + await d.update({ $or: [{ a: 4 }, { a: 5 }] }, { + $set: { hello: 'world' }, + $inc: { bloup: 3 } + // eslint-disable-next-line node/handle-callback-err + }, { upsert: true }) + const docs = await d.findAsync({ hello: 'world' }) + assert.equal(docs.length, 1) + const doc = docs[0] + assert.equal(Object.keys(doc).length, 3) + assert.equal(doc.hello, 'world') + assert.equal(doc.bloup, 3) + }) + + it('If the update query contains modifiers, it is applied to the object resulting from removing all operators from the find query 2', async () => { + await d.update({ $or: [{ a: 4 }, { a: 5 }], cac: 'rrr' }, { + $set: { hello: 'world' }, + $inc: { bloup: 3 } + // eslint-disable-next-line node/handle-callback-err + }, { upsert: true }) + const docs = await d.findAsync({ hello: 'world' }) + assert.equal(docs.length, 1) + const doc = docs[0] + assert.equal(Object.keys(doc).length, 4) + assert.equal(doc.cac, 'rrr') + assert.equal(doc.hello, 'world') + assert.equal(doc.bloup, 3) + }) + + it('Performing upsert with badly formatted fields yields a standard error not an exception', async () => { + await assert.rejects(() => d.updateAsync({ _id: '1234' }, { $set: { $$badfield: 5 } }, { upsert: true })) + }) // ==== End of 'Upserts' ==== // + + it('Cannot perform update if the update query is not either registered-modifiers-only or copy-only, or contain badly formatted fields', async () => { + await d.insertAsync({ something: 'yup' }) + await assert.rejects(() => d.updateAsync({}, { boom: { $badfield: 5 } }, { multi: false })) + await assert.rejects(() => d.updateAsync({}, { boom: { 'bad.field': 5 } }, { multi: false })) + await assert.rejects(() => d.updateAsync({}, { $inc: { test: 5 }, mixed: 'rrr' }, { multi: false })) + await assert.rejects(() => d.updateAsync({}, { $inexistent: { test: 5 } }, { multi: false })) + }) + + it('Can update documents using multiple modifiers', async () => { + const newDoc = await d.insertAsync({ something: 'yup', other: 40 }) + const id = newDoc._id + + const { numAffected } = await d.updateAsync({}, { + $set: { something: 'changed' }, + $inc: { other: 10 } + }, { multi: false }) + assert.equal(numAffected, 1) + + const doc = await d.findOne({ _id: id }) + assert.equal(Object.keys(doc).length, 3) + assert.equal(doc._id, id) + assert.equal(doc.something, 'changed') + assert.equal(doc.other, 50) + }) + + it('Can upsert a document even with modifiers', async () => { + const { + numAffected, + affectedDocuments + } = await d.updateAsync({ bloup: 'blap' }, { $set: { hello: 'world' } }, { upsert: true }) + assert.equal(numAffected, 1) + assert.equal(affectedDocuments.bloup, 'blap') + assert.equal(affectedDocuments.hello, 'world') + assert.notEqual(affectedDocuments._id, undefined) + + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + assert.equal(Object.keys(docs[0]).length, 3) + assert.equal(docs[0].hello, 'world') + assert.equal(docs[0].bloup, 'blap') + assert.notEqual(docs[0]._id, undefined) + }) + + it('When using modifiers, the only way to update subdocs is with the dot-notation', async () => { + await d.insertAsync({ bloup: { blip: 'blap', other: true } }) + // Correct methos + await d.updateAsync({}, { $set: { 'bloup.blip': 'hello' } }, {}) + const doc = await d.findOne({}) + assert.equal(doc.bloup.blip, 'hello') + assert.equal(doc.bloup.other, true) + + // Wrong + await d.updateAsync({}, { $set: { bloup: { blip: 'ola' } } }, {}) + const doc2 = await d.findOne({}) + assert.equal(doc2.bloup.blip, 'ola') + assert.equal(doc2.bloup.other, undefined) // This information was lost + }) + + it('Returns an error if the query is not well formed', async () => { + await d.insertAsync({ hello: 'world' }) + await assert.rejects(() => d.updateAsync({ $or: { hello: 'world' } }, { a: 1 }, {})) + }) + + it('If an error is thrown by a modifier, the database state is not changed', async () => { + const newDoc = await d.insertAsync({ hello: 'world' }) + await assert.rejects(() => d.updateAsync({}, { $inc: { hello: 4 } }, {})) + + const docs = await d.findAsync({}) + assert.deepEqual(docs, [{ _id: newDoc._id, hello: 'world' }]) + }) + + it('Cant change the _id of a document', async () => { + const newDoc = await d.insertAsync({ a: 2 }) + await assert.rejects(() => d.updateAsync({ a: 2 }, { a: 2, _id: 'nope' }, {})) + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + assert.equal(Object.keys(docs[0]).length, 2) + assert.equal(docs[0].a, 2) + assert.equal(docs[0]._id, newDoc._id) + + await assert.rejects(() => d.updateAsync({ a: 2 }, { $set: { _id: 'nope' } }, {})) + const docs2 = await d.findAsync({}) + assert.equal(docs2.length, 1) + assert.equal(Object.keys(docs2[0]).length, 2) + assert.equal(docs2[0].a, 2) + assert.equal(docs2[0]._id, newDoc._id) + }) + + it('Non-multi updates are persistent', async () => { + const doc1 = await d.insertAsync({ a: 1, hello: 'world' }) + const doc2 = await d.insertAsync({ a: 2, hello: 'earth' }) + await d.updateAsync({ a: 2 }, { $set: { hello: 'changed' } }, {}) + + const docs = await d.findAsync({}) + docs.sort((a, b) => a.a - b.a) + assert.equal(docs.length, 2) + assert.deepEqual(docs[0], { _id: doc1._id, a: 1, hello: 'world' }) + assert.deepEqual(docs[1], { _id: doc2._id, a: 2, hello: 'changed' }) + + // Even after a reload the database state hasn't changed + await d.loadDatabaseAsync() + + const docs2 = await d.findAsync({}) + docs2.sort((a, b) => a.a - b.a) + assert.equal(docs2.length, 2) + assert.deepEqual(docs2[0], { _id: doc1._id, a: 1, hello: 'world' }) + assert.deepEqual(docs2[1], { _id: doc2._id, a: 2, hello: 'changed' }) + }) + + it('Multi updates are persistent', async () => { + const doc1 = await d.insertAsync({ a: 1, hello: 'world' }) + const doc2 = await d.insertAsync({ a: 2, hello: 'earth' }) + const doc3 = await d.insertAsync({ a: 5, hello: 'pluton' }) + await d.updateAsync({ a: { $in: [1, 2] } }, { $set: { hello: 'changed' } }, { multi: true }) + + const docs = await d.findAsync({}) + docs.sort((a, b) => a.a - b.a) + assert.equal(docs.length, 3) + assert.deepEqual(docs[0], { _id: doc1._id, a: 1, hello: 'changed' }) + assert.deepEqual(docs[1], { _id: doc2._id, a: 2, hello: 'changed' }) + assert.deepEqual(docs[2], { _id: doc3._id, a: 5, hello: 'pluton' }) + + // Even after a reload the database state hasn't changed + await d.loadDatabaseAsync() + + const docs2 = await d.findAsync({}) + docs2.sort((a, b) => a.a - b.a) + assert.equal(docs2.length, 3) + assert.deepEqual(docs2[0], { _id: doc1._id, a: 1, hello: 'changed' }) + assert.deepEqual(docs2[1], { _id: doc2._id, a: 2, hello: 'changed' }) + assert.deepEqual(docs2[2], { _id: doc3._id, a: 5, hello: 'pluton' }) + }) + + it('Can update without the options arg (will use defaults then)', async () => { + const doc1 = await d.insertAsync({ a: 1, hello: 'world' }) + const doc2 = await d.insertAsync({ a: 2, hello: 'earth' }) + const doc3 = await d.insertAsync({ a: 5, hello: 'pluton' }) + const { numAffected } = await d.updateAsync({ a: 2 }, { $inc: { a: 10 } }) + assert.equal(numAffected, 1) + const docs = await d.findAsync({}) + const d1 = docs.find(doc => doc._id === doc1._id) + const d2 = docs.find(doc => doc._id === doc2._id) + const d3 = docs.find(doc => doc._id === doc3._id) + + assert.equal(d1.a, 1) + assert.equal(d2.a, 12) + assert.equal(d3.a, 5) + }) + + it('If a multi update fails on one document, previous updates should be rolled back', async () => { + d.ensureIndexAsync({ fieldName: 'a' }) // TODO should be awaited, but was not in original tests + const doc1 = await d.insertAsync({ a: 4 }) + const doc2 = await d.insertAsync({ a: 5 }) + const doc3 = await d.insertAsync({ a: 'abc' }) + // With this query, candidates are always returned in the order 4, 5, 'abc' so it's always the last one which fails + await assert.rejects(() => d.updateAsync({ a: { $in: [4, 5, 'abc'] } }, { $inc: { a: 10 } }, { multi: true })) + + // No index modified + for (const key in d.indexes) { + if (Object.prototype.hasOwnProperty.call(d.indexes, key)) { + const index = d.indexes[key] + const docs = index.getAll() + const d1 = docs.find(doc => doc._id === doc1._id) + const d2 = docs.find(doc => doc._id === doc2._id) + const d3 = docs.find(doc => doc._id === doc3._id) + + // All changes rolled back, including those that didn't trigger an error + assert.equal(d1.a, 4) + assert.equal(d2.a, 5) + assert.equal(d3.a, 'abc') + } + } + }) + + it('If an index constraint is violated by an update, all changes should be rolled back', async () => { + d.ensureIndex({ fieldName: 'a', unique: true }) // TODO should be awaited, but was not in original tests + const doc1 = await d.insertAsync({ a: 4 }) + const doc2 = await d.insertAsync({ a: 5 }) + // With this query, candidates are always returned in the order 4, 5, 'abc' so it's always the last one which fails + await assert.rejects(() => d.updateAsync({ a: { $in: [4, 5, 'abc'] } }, { $set: { a: 10 } }, { multi: true })) + + // Check that no index was modified + for (const key in d.indexes) { + if (Object.prototype.hasOwnProperty.call(d.indexes, key)) { + const index = d.indexes[key] + const docs = index.getAll() + const d1 = docs.find(doc => doc._id === doc1._id) + const d2 = docs.find(doc => doc._id === doc2._id) + + assert.equal(d1.a, 4) + assert.equal(d2.a, 5) + } + } + }) + + it('If options.returnUpdatedDocs is true, return all matched docs', async () => { + const docs = await d.insertAsync([{ a: 4 }, { a: 5 }, { a: 6 }]) + assert.equal(docs.length, 3) + + const { + numAffected: numAffectedEmpty, + affectedDocuments: affectedDocumentsEmpty + } = await d.updateAsync({ a: 7 }, { $set: { u: 1 } }, { + multi: true, + returnUpdatedDocs: true + }) + assert.equal(numAffectedEmpty, 0) + assert.equal(affectedDocumentsEmpty.length, 0) + + const { numAffected, affectedDocuments } = await d.updateAsync({ a: 5 }, { $set: { u: 2 } }, { + multi: true, + returnUpdatedDocs: true + }) + assert.equal(numAffected, 1) + assert.equal(affectedDocuments.length, 1) + assert.equal(affectedDocuments[0].a, 5) + assert.equal(affectedDocuments[0].u, 2) + + const { + numAffected: numAffected2, + affectedDocuments: affectedDocuments2 + } = await d.updateAsync({ a: { $in: [4, 6] } }, { $set: { u: 3 } }, { + multi: true, + returnUpdatedDocs: true + }) + assert.equal(numAffected2, 2) + assert.equal(affectedDocuments2.length, 2) + assert.equal(affectedDocuments2[0].u, 3) + assert.equal(affectedDocuments2[1].u, 3) + if (affectedDocuments2[0].a === 4) { + assert.equal(affectedDocuments2[0].a, 4) + assert.equal(affectedDocuments2[1].a, 6) + } else { + assert.equal(affectedDocuments2[0].a, 6) + assert.equal(affectedDocuments2[1].a, 4) + } + }) + + it('createdAt property is unchanged and updatedAt correct after an update, even a complete document replacement', async () => { + const d2 = new Datastore({ inMemoryOnly: true, timestampData: true }) + d2.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests + const doc = await d2.findOneAsync({ a: 1 }) + const createdAt = doc.createdAt.getTime() + + // Modifying update + await wait(20) + d2.updateAsync({ a: 1 }, { $set: { b: 2 } }, {}) // TODO probably should await but was not awaited in original tests + const doc2 = await d2.findOneAsync({ a: 1 }) + assert.equal(doc2.createdAt.getTime(), createdAt) + assert.ok(Date.now() - doc2.updatedAt.getTime() < 5) + + // Complete replacement + await wait(20) + d2.update({ a: 1 }, { c: 3 }, {}) // TODO probably should await but was not awaited in original tests + const doc3 = await d2.findOneAsync({ c: 3 }) + assert.equal(doc3.createdAt.getTime(), createdAt) + assert.ok(Date.now() - doc3.updatedAt.getTime() < 5) + }) + }) + + describe('Callback signature', function () { + it('Regular update, multi false', async () => { + d.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests + d.insertAsync({ a: 2 }) // TODO probably should await but was not awaited in original tests + + // returnUpdatedDocs set to false + const { numAffected, affectedDocuments, upsert } = await d.updateAsync({ a: 1 }, { $set: { b: 20 } }, {}) + assert.equal(numAffected, 1) + assert.equal(affectedDocuments, undefined) + assert.equal(upsert, undefined) + + // returnUpdatedDocs set to true + const { + numAffected: numAffected2, + affectedDocuments: affectedDocuments2, + upsert: upsert2 + } = await d.updateAsync({ a: 1 }, { $set: { b: 21 } }, { returnUpdatedDocs: true }) + assert.equal(numAffected2, 1) + assert.equal(affectedDocuments2.a, 1) + assert.equal(affectedDocuments2.b, 21) + assert.equal(upsert2, undefined) + }) + + it('Regular update, multi true', async () => { + d.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests + d.insertAsync({ a: 2 }) // TODO probably should await but was not awaited in original tests + + // returnUpdatedDocs set to false + const { + numAffected, + affectedDocuments, + upsert + } = await d.updateAsync({}, { $set: { b: 20 } }, { multi: true }) + assert.equal(numAffected, 2) + assert.equal(affectedDocuments, undefined) + assert.equal(upsert, undefined) + + // returnUpdatedDocs set to true + const { + numAffected: numAffected2, + affectedDocuments: affectedDocuments2, + upsert: upsert2 + } = await d.updateAsync({}, { $set: { b: 21 } }, { + multi: true, + returnUpdatedDocs: true + }) + assert.equal(numAffected2, 2) + assert.equal(affectedDocuments2.length, 2) + assert.equal(upsert2, undefined) + }) + + it('Upsert', async () => { + d.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests + d.insertAsync({ a: 2 }) // TODO probably should await but was not awaited in original tests + + // Upsert flag not set + const { numAffected, affectedDocuments, upsert } = await d.updateAsync({ a: 3 }, { $set: { b: 20 } }, {}) + assert.equal(numAffected, 0) + assert.equal(affectedDocuments, undefined) + assert.equal(upsert, undefined) + + // Upsert flag set + const { + numAffected: numAffected2, + affectedDocuments: affectedDocuments2, + upsert: upsert2 + } = await d.updateAsync({ a: 3 }, { $set: { b: 21 } }, { upsert: true }) + assert.equal(numAffected2, 1) + assert.equal(affectedDocuments2.a, 3) + assert.equal(affectedDocuments2.b, 21) + assert.equal(upsert2, true) + + const docs = await d.findAsync({}) + assert.equal(docs.length, 3) + }) // ==== End of 'Update - Callback signature' ==== // + }) // ==== End of 'Update' ==== // + describe('Remove', function () { + it('Can remove multiple documents', async () => { + const doc1 = await d.insertAsync({ somedata: 'ok' }) + await d.insertAsync({ somedata: 'again', plus: 'additional data' }) + await d.insertAsync({ somedata: 'again' }) + const id1 = doc1._id + + // Test DB status + const testPostUpdateState = async () => { + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + + assert.equal(Object.keys(docs[0]).length, 2) + assert.equal(docs[0]._id, id1) + assert.equal(docs[0].somedata, 'ok') + } + // Test with query that doesn't match anything + const n = await d.removeAsync({ somedata: 'again' }, { multi: true }) + assert.equal(n, 2) + await testPostUpdateState() + await d.loadDatabaseAsync() + await testPostUpdateState() + }) + + // This tests concurrency issues + it('Remove can be called multiple times in parallel and everything that needs to be removed will be', async () => { + await d.insertAsync({ planet: 'Earth' }) + await d.insertAsync({ planet: 'Mars' }) + await d.insertAsync({ planet: 'Saturn' }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 3) + + // Remove two docs simultaneously + const toRemove = ['Mars', 'Saturn'] + await Promise.all(toRemove.map(planet => d.removeAsync({ planet }))) + const docs2 = await d.findAsync({}) + assert.equal(docs2.length, 1) + }) + + it('Returns an error if the query is not well formed', async () => { + await d.insertAsync({ hello: 'world' }) + await assert.rejects(() => d.removeAsync({ $or: { hello: 'world' } }, {})) + }) + + it('Non-multi removes are persistent', async () => { + const doc1 = await d.insertAsync({ a: 1, hello: 'world' }) + await d.insertAsync({ a: 2, hello: 'earth' }) + const doc3 = await d.insertAsync({ a: 3, hello: 'moto' }) + await d.removeAsync({ a: 2 }, {}) + + const docs = await d.findAsync({}) + docs.sort((a, b) => a.a - b.a) + assert.equal(docs.length, 2) + assert.deepEqual(docs[0], { _id: doc1._id, a: 1, hello: 'world' }) + assert.deepEqual(docs[1], { _id: doc3._id, a: 3, hello: 'moto' }) + + // Even after a reload the database state hasn't changed + await d.loadDatabaseAsync() + + const docsReloaded = await d.findAsync({}) + docsReloaded.sort((a, b) => a.a - b.a) + assert.equal(docsReloaded.length, 2) + assert.deepEqual(docsReloaded[0], { _id: doc1._id, a: 1, hello: 'world' }) + assert.deepEqual(docsReloaded[1], { _id: doc3._id, a: 3, hello: 'moto' }) + }) + + it('Multi removes are persistent', async () => { + await d.insertAsync({ a: 1, hello: 'world' }) + const doc2 = await d.insertAsync({ a: 2, hello: 'earth' }) + await d.insertAsync({ a: 3, hello: 'moto' }) + await d.removeAsync({ a: { $in: [1, 3] } }, { multi: true }) + + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + assert.deepEqual(docs[0], { _id: doc2._id, a: 2, hello: 'earth' }) + + // Even after a reload the database state hasn't changed + await d.loadDatabaseAsync() + + const docsReloaded = await d.findAsync({}) + assert.equal(docsReloaded.length, 1) + assert.deepEqual(docsReloaded[0], { _id: doc2._id, a: 2, hello: 'earth' }) + }) + + it('Can remove without the options arg (will use defaults then)', async () => { + const doc1 = await d.insertAsync({ a: 1, hello: 'world' }) + const doc2 = await d.insertAsync({ a: 2, hello: 'earth' }) + const doc3 = await d.insertAsync({ a: 5, hello: 'pluton' }) + const numRemoved = await d.removeAsync({ a: 2 }) + assert.equal(numRemoved, 1) + const docs = await d.findAsync({}) + const d1 = docs.find(doc => doc._id === doc1._id) + const d2 = docs.find(doc => doc._id === doc2._id) + const d3 = docs.find(doc => doc._id === doc3._id) + + assert.equal(d1.a, 1) + assert.equal(d2, undefined) + assert.equal(d3.a, 5) + }) + }) // ==== End of 'Remove' ==== // + + describe('Using indexes', function () { + describe('ensureIndex and index initialization in database loading', function () { + it('ensureIndex can be called right after a loadDatabase and be initialized and filled correctly', async () => { + const now = new Date() + const rawData = model.serialize({ _id: 'aaa', z: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: 'bbb', z: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: 'ccc', z: '3', nested: { today: now } }) + + assert.equal(d.getAllData().length, 0) + + await fs.writeFile(testDb, rawData, 'utf8') + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 3) + + assert.deepEqual(Object.keys(d.indexes), ['_id']) + + d.ensureIndexAsync({ fieldName: 'z' }) // TODO: was not async + assert.equal(d.indexes.z.fieldName, 'z') + assert.equal(d.indexes.z.unique, false) + assert.equal(d.indexes.z.sparse, false) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.z.tree.search('1')[0], d.getAllData()[0]) + assert.equal(d.indexes.z.tree.search('2')[0], d.getAllData()[1]) + assert.equal(d.indexes.z.tree.search('3')[0], d.getAllData()[2]) + }) + + it('ensureIndex can be called twice on the same field, the second call will ahve no effect', async () => { + assert.equal(Object.keys(d.indexes).length, 1) + assert.equal(Object.keys(d.indexes)[0], '_id') + + await d.insertAsync({ planet: 'Earth' }) + await d.insertAsync({ planet: 'Mars' }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 2) + + await d.ensureIndexAsync({ fieldName: 'planet' }) + assert.equal(Object.keys(d.indexes).length, 2) + assert.equal(Object.keys(d.indexes)[0], '_id') + assert.equal(Object.keys(d.indexes)[1], 'planet') + + assert.equal(d.indexes.planet.getAll().length, 2) + + // This second call has no effect, documents don't get inserted twice in the index + await d.ensureIndexAsync({ fieldName: 'planet' }) + assert.equal(Object.keys(d.indexes).length, 2) + assert.equal(Object.keys(d.indexes)[0], '_id') + assert.equal(Object.keys(d.indexes)[1], 'planet') + + assert.equal(d.indexes.planet.getAll().length, 2) + }) + + it('ensureIndex can be called after the data set was modified and the index still be correct', async () => { + const rawData = model.serialize({ _id: 'aaa', z: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: 'bbb', z: '2', hello: 'world' }) + + assert.equal(d.getAllData().length, 0) + + await fs.writeFile(testDb, rawData, 'utf8') + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 2) + + assert.deepEqual(Object.keys(d.indexes), ['_id']) + + // eslint-disable-next-line node/handle-callback-err + const newDoc1 = await d.insertAsync({ z: '12', yes: 'yes' }) + // eslint-disable-next-line node/handle-callback-err + const newDoc2 = await d.insertAsync({ z: '14', nope: 'nope' }) + await d.removeAsync({ z: '2' }, {}) + await d.updateAsync({ z: '1' }, { $set: { yes: 'yep' } }, {}) + assert.deepEqual(Object.keys(d.indexes), ['_id']) + + d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + assert.equal(d.indexes.z.fieldName, 'z') + assert.equal(d.indexes.z.unique, false) + assert.equal(d.indexes.z.sparse, false) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 3) + + // The pointers in the _id and z indexes are the same + assert.equal(d.indexes.z.tree.search('1')[0], d.indexes._id.getMatching('aaa')[0]) + assert.equal(d.indexes.z.tree.search('12')[0], d.indexes._id.getMatching(newDoc1._id)[0]) + assert.equal(d.indexes.z.tree.search('14')[0], d.indexes._id.getMatching(newDoc2._id)[0]) + + // The data in the z index is correct + const docs = await d.findAsync({}) + const doc0 = docs.find(doc => doc._id === 'aaa') + const doc1 = docs.find(doc => doc._id === newDoc1._id) + const doc2 = docs.find(doc => doc._id === newDoc2._id) + + assert.equal(docs.length, 3) + + assert.deepEqual(doc0, { _id: 'aaa', z: '1', a: 2, ages: [1, 5, 12], yes: 'yep' }) + assert.deepEqual(doc1, { _id: newDoc1._id, z: '12', yes: 'yes' }) + assert.deepEqual(doc2, { _id: newDoc2._id, z: '14', nope: 'nope' }) + }) + + it('ensureIndex can be called before a loadDatabase and still be initialized and filled correctly', async () => { + const now = new Date() + const rawData = model.serialize({ _id: 'aaa', z: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: 'bbb', z: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: 'ccc', z: '3', nested: { today: now } }) + + assert.equal(d.getAllData().length, 0) + + d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + assert.equal(d.indexes.z.fieldName, 'z') + assert.equal(d.indexes.z.unique, false) + assert.equal(d.indexes.z.sparse, false) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) + + await fs.writeFile(testDb, rawData, 'utf8') + await d.loadDatabaseAsync() + const doc1 = d.getAllData().find(doc => doc.z === '1') + const doc2 = d.getAllData().find(doc => doc.z === '2') + const doc3 = d.getAllData().find(doc => doc.z === '3') + + assert.equal(d.getAllData().length, 3) + + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.z.tree.search('1')[0], doc1) + assert.equal(d.indexes.z.tree.search('2')[0], doc2) + assert.equal(d.indexes.z.tree.search('3')[0], doc3) + }) + + it('Can initialize multiple indexes on a database load', async () => { + const now = new Date() + const rawData = model.serialize({ _id: 'aaa', z: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: 'bbb', z: '2', a: 'world' }) + '\n' + + model.serialize({ _id: 'ccc', z: '3', a: { today: now } }) + + assert.equal(d.getAllData().length, 0) + await d.ensureIndexAsync({ fieldName: 'z' }) + await d.ensureIndexAsync({ fieldName: 'a' }) + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 0) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) + + await fs.writeFile(testDb, rawData, 'utf8') + await d.loadDatabaseAsync() + const doc1 = d.getAllData().find(doc => doc.z === '1') + const doc2 = d.getAllData().find(doc => doc.z === '2') + const doc3 = d.getAllData().find(doc => doc.z === '3') + + assert.equal(d.getAllData().length, 3) + + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.z.tree.search('1')[0], doc1) + assert.equal(d.indexes.z.tree.search('2')[0], doc2) + assert.equal(d.indexes.z.tree.search('3')[0], doc3) + + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.a.tree.search(2)[0], doc1) + assert.equal(d.indexes.a.tree.search('world')[0], doc2) + assert.equal(d.indexes.a.tree.search({ today: now })[0], doc3) + }) + + it('If a unique constraint is not respected, database loading will not work and no data will be inserted', async () => { + const now = new Date() + const rawData = model.serialize({ _id: 'aaa', z: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: 'bbb', z: '2', a: 'world' }) + '\n' + + model.serialize({ _id: 'ccc', z: '1', a: { today: now } }) + + assert.equal(d.getAllData().length, 0) + + d.ensureIndexAsync({ fieldName: 'z', unique: true }) // TODO was not awaited + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) + + await fs.writeFile(testDb, rawData, 'utf8') + await assert.rejects(() => d.loadDatabaseAsync(), err => { + assert.equal(err.errorType, 'uniqueViolated') + assert.equal(err.key, '1') + assert.equal(d.getAllData().length, 0) // TODO wtf ? + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) // TODO wtf ? + return true + }) + }) + + it('If a unique constraint is not respected, ensureIndex will return an error and not create an index', async () => { + await d.insertAsync({ a: 1, b: 4 }) + await d.insertAsync({ a: 2, b: 45 }) + await d.insertAsync({ a: 1, b: 3 }) + await d.ensureIndexAsync({ fieldName: 'b' }) + await assert.rejects(() => d.ensureIndexAsync({ fieldName: 'a', unique: true }), err => { + assert.equal(err.errorType, 'uniqueViolated') + assert.deepEqual(Object.keys(d.indexes), ['_id', 'b']) + return true + }) + }) + + it('Can remove an index', async () => { + await d.ensureIndexAsync({ fieldName: 'e' }) + + assert.equal(Object.keys(d.indexes).length, 2) + assert.notEqual(d.indexes.e, null) + + await d.removeIndexAsync('e') + assert.equal(Object.keys(d.indexes).length, 1) + assert.equal(d.indexes.e, undefined) + }) + }) // ==== End of 'ensureIndex and index initialization in database loading' ==== // + + describe('Indexing newly inserted documents', function () { + it('Newly inserted documents are indexed', async () => { + d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) + + const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 1) + assert.deepEqual(d.indexes.z.getMatching('yes'), [newDoc]) + + const newDoc2 = await d.insertAsync({ a: 5, z: 'nope' }) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 2) + assert.deepEqual(d.indexes.z.getMatching('nope'), [newDoc2]) + }) + + it('If multiple indexes are defined, the document is inserted in all of them', async () => { + d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + d.ensureIndexAsync({ fieldName: 'ya' }) // TODO was not awaited + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) + + const newDoc = await d.insertAsync({ a: 2, z: 'yes', ya: 'indeed' }) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 1) + assert.equal(d.indexes.ya.tree.getNumberOfKeys(), 1) + assert.deepEqual(d.indexes.z.getMatching('yes'), [newDoc]) + assert.deepEqual(d.indexes.ya.getMatching('indeed'), [newDoc]) + + const newDoc2 = await d.insertAsync({ a: 5, z: 'nope', ya: 'sure' }) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.ya.tree.getNumberOfKeys(), 2) + assert.deepEqual(d.indexes.z.getMatching('nope'), [newDoc2]) + assert.deepEqual(d.indexes.ya.getMatching('sure'), [newDoc2]) + }) + + it('Can insert two docs at the same key for a non unique index', async () => { + d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) + + const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 1) + assert.deepEqual(d.indexes.z.getMatching('yes'), [newDoc]) + + const newDoc2 = await d.insertAsync({ a: 5, z: 'yes' }) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 1) + assert.deepEqual(d.indexes.z.getMatching('yes'), [newDoc, newDoc2]) + }) + + it('If the index has a unique constraint, an error is thrown if it is violated and the data is not modified', async () => { + d.ensureIndexAsync({ fieldName: 'z', unique: true }) // TODO was not awaited + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) + + const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 1) + assert.deepEqual(d.indexes.z.getMatching('yes'), [newDoc]) + + await assert.rejects(() => d.insertAsync({ a: 5, z: 'yes' }), err => { + assert.equal(err.errorType, 'uniqueViolated') + assert.equal(err.key, 'yes') + return true + }) + // Index didn't change + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 1) + assert.deepEqual(d.indexes.z.getMatching('yes'), [newDoc]) + + // Data didn't change + assert.deepEqual(d.getAllData(), [newDoc]) + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 1) + assert.deepEqual(d.getAllData()[0], newDoc) + }) + + it('If an index has a unique constraint, other indexes cannot be modified when it raises an error', async () => { + d.ensureIndexAsync({ fieldName: 'nonu1' }) // TODO was not awaited + d.ensureIndexAsync({ fieldName: 'uni', unique: true }) // TODO was not awaited + d.ensureIndexAsync({ fieldName: 'nonu2' }) // TODO was not awaited + + const newDoc = await d.insertAsync({ nonu1: 'yes', nonu2: 'yes2', uni: 'willfail' }) + assert.equal(d.indexes.nonu1.tree.getNumberOfKeys(), 1) + assert.equal(d.indexes.uni.tree.getNumberOfKeys(), 1) + assert.equal(d.indexes.nonu2.tree.getNumberOfKeys(), 1) + + await assert.rejects(() => d.insertAsync({ nonu1: 'no', nonu2: 'no2', uni: 'willfail' }), err => { + assert.equal(err.errorType, 'uniqueViolated') + return true + }) + + // No index was modified + assert.equal(d.indexes.nonu1.tree.getNumberOfKeys(), 1) + assert.equal(d.indexes.uni.tree.getNumberOfKeys(), 1) + assert.equal(d.indexes.nonu2.tree.getNumberOfKeys(), 1) + + assert.deepEqual(d.indexes.nonu1.getMatching('yes'), [newDoc]) + assert.deepEqual(d.indexes.uni.getMatching('willfail'), [newDoc]) + assert.deepEqual(d.indexes.nonu2.getMatching('yes2'), [newDoc]) + }) + + it('Unique indexes prevent you from inserting two docs where the field is undefined except if theyre sparse', async () => { + d.ensureIndexAsync({ fieldName: 'zzz', unique: true }) // TODO was not awaited + assert.equal(d.indexes.zzz.tree.getNumberOfKeys(), 0) + + const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) + assert.equal(d.indexes.zzz.tree.getNumberOfKeys(), 1) + assert.deepEqual(d.indexes.zzz.getMatching(undefined), [newDoc]) + + await assert.rejects(() => d.insertAsync({ a: 5, z: 'other' }), err => { + assert.equal(err.errorType, 'uniqueViolated') + assert.equal(err.key, undefined) + return true + }) + + d.ensureIndexAsync({ fieldName: 'yyy', unique: true, sparse: true }) // TODO was not awaited + + await d.insertAsync({ a: 5, z: 'other', zzz: 'set' }) + assert.equal(d.indexes.yyy.getAll().length, 0) // Nothing indexed + assert.equal(d.indexes.zzz.getAll().length, 2) + }) + + it('Insertion still works as before with indexing', async () => { + d.ensureIndexAsync({ fieldName: 'a' }) // TODO was not awaited + d.ensureIndexAsync({ fieldName: 'b' }) // TODO was not awaited + + const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) + const doc2 = await d.insertAsync({ a: 2, b: 'si' }) + const docs = await d.findAsync({}) + assert.deepEqual(doc1, docs.find(function (d) { return d._id === doc1._id })) + assert.deepEqual(doc2, docs.find(function (d) { return d._id === doc2._id })) + }) + + it('All indexes point to the same data as the main index on _id', async () => { + d.ensureIndexAsync({ fieldName: 'a' }) // TODO was not awaited + + const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) + const doc2 = await d.insertAsync({ a: 2, b: 'si' }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 2) + assert.equal(d.getAllData().length, 2) + + assert.equal(d.indexes._id.getMatching(doc1._id).length, 1) + assert.equal(d.indexes.a.getMatching(1).length, 1) + assert.equal(d.indexes._id.getMatching(doc1._id)[0], d.indexes.a.getMatching(1)[0]) + + assert.equal(d.indexes._id.getMatching(doc2._id).length, 1) + assert.equal(d.indexes.a.getMatching(2).length, 1) + assert.equal(d.indexes._id.getMatching(doc2._id)[0], d.indexes.a.getMatching(2)[0]) + }) + + it('If a unique constraint is violated, no index is changed, including the main one', async () => { + d.ensureIndexAsync({ fieldName: 'a', unique: true }) // TODO was not awaited + + const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) + await assert.rejects(() => d.insertAsync({ a: 1, b: 'si' })) + + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + assert.equal(d.getAllData().length, 1) + + assert.equal(d.indexes._id.getMatching(doc1._id).length, 1) + assert.equal(d.indexes.a.getMatching(1).length, 1) + assert.equal(d.indexes._id.getMatching(doc1._id)[0], d.indexes.a.getMatching(1)[0]) + + assert.equal(d.indexes.a.getMatching(2).length, 0) + }) + }) // ==== End of 'Indexing newly inserted documents' ==== // + + describe('Updating indexes upon document update', function () { + it('Updating docs still works as before with indexing', async () => { + d.ensureIndexAsync({ fieldName: 'a' }) // TODO: not awaited + + const _doc1 = await d.insertAsync({ a: 1, b: 'hello' }) + const _doc2 = await d.insertAsync({ a: 2, b: 'si' }) + const { numAffected } = await d.updateAsync({ a: 1 }, { $set: { a: 456, b: 'no' } }, {}) + const data = d.getAllData() + const doc1 = data.find(doc => doc._id === _doc1._id) + const doc2 = data.find(doc => doc._id === _doc2._id) + + assert.equal(numAffected, 1) + + assert.equal(data.length, 2) + assert.deepEqual(doc1, { a: 456, b: 'no', _id: _doc1._id }) + assert.deepEqual(doc2, { a: 2, b: 'si', _id: _doc2._id }) + + const { numAffected: numAffectedAfterUpdate } = await d.updateAsync({}, { + $inc: { a: 10 }, + $set: { b: 'same' } + }, { multi: true }) + const dataAfterUpdate = d.getAllData() + const doc1AfterUpdate = dataAfterUpdate.find(doc => doc._id === _doc1._id) + const doc2AfterUpdate = dataAfterUpdate.find(doc => doc._id === _doc2._id) + + assert.equal(numAffectedAfterUpdate, 2) + + assert.equal(dataAfterUpdate.length, 2) + assert.deepEqual(doc1AfterUpdate, { a: 466, b: 'same', _id: _doc1._id }) + assert.deepEqual(doc2AfterUpdate, { a: 12, b: 'same', _id: _doc2._id }) + }) + + it('Indexes get updated when a document (or multiple documents) is updated', async () => { + d.ensureIndexAsync({ fieldName: 'a' }) // TODO: not awaited + d.ensureIndexAsync({ fieldName: 'b' }) // TODO: not awaited + + const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) + const doc2 = await d.insertAsync({ a: 2, b: 'si' }) + // Simple update + const { numAffected } = await d.updateAsync({ a: 1 }, { $set: { a: 456, b: 'no' } }, {}) + assert.equal(numAffected, 1) + + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.a.getMatching(456)[0]._id, doc1._id) + assert.equal(d.indexes.a.getMatching(2)[0]._id, doc2._id) + + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.b.getMatching('no')[0]._id, doc1._id) + assert.equal(d.indexes.b.getMatching('si')[0]._id, doc2._id) + + // The same pointers are shared between all indexes + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes._id.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.a.getMatching(456)[0], d.indexes._id.getMatching(doc1._id)[0]) + assert.equal(d.indexes.b.getMatching('no')[0], d.indexes._id.getMatching(doc1._id)[0]) + assert.equal(d.indexes.a.getMatching(2)[0], d.indexes._id.getMatching(doc2._id)[0]) + assert.equal(d.indexes.b.getMatching('si')[0], d.indexes._id.getMatching(doc2._id)[0]) + + // Multi update + const { numAffected: numAffectedMulti } = await d.updateAsync({}, { + $inc: { a: 10 }, + $set: { b: 'same' } + }, { multi: true }) + assert.equal(numAffectedMulti, 2) + + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.a.getMatching(466)[0]._id, doc1._id) + assert.equal(d.indexes.a.getMatching(12)[0]._id, doc2._id) + + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 1) + assert.equal(d.indexes.b.getMatching('same').length, 2) + assert.ok(d.indexes.b.getMatching('same').map(x => x._id).includes(doc1._id)) + assert.ok(d.indexes.b.getMatching('same').map(x => x._id).includes(doc2._id)) + + // The same pointers are shared between all indexes + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 1) + assert.equal(d.indexes.b.getAll().length, 2) + assert.equal(d.indexes._id.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.a.getMatching(466)[0], d.indexes._id.getMatching(doc1._id)[0]) + assert.equal(d.indexes.a.getMatching(12)[0], d.indexes._id.getMatching(doc2._id)[0]) + // Can't test the pointers in b as their order is randomized, but it is the same as with a + }) + + it('If a simple update violates a contraint, all changes are rolled back and an error is thrown', async () => { + d.ensureIndexAsync({ fieldName: 'a', unique: true }) // TODO: not awaited + d.ensureIndexAsync({ fieldName: 'b', unique: true }) // TODO: not awaited + d.ensureIndexAsync({ fieldName: 'c', unique: true }) // TODO: not awaited + + const _doc1 = await d.insertAsync({ a: 1, b: 10, c: 100 }) + const _doc2 = await d.insertAsync({ a: 2, b: 20, c: 200 }) + const _doc3 = await d.insertAsync({ a: 3, b: 30, c: 300 }) + // Will conflict with doc3 + await assert.rejects(() => d.updateAsync({ a: 2 }, { $inc: { a: 10, c: 1000 }, $set: { b: 30 } }, {}), err => { + assert.equal(err.errorType, 'uniqueViolated') + return true + }) + const data = d.getAllData() + const doc1 = data.find(doc => doc._id === _doc1._id) + const doc2 = data.find(doc => doc._id === _doc2._id) + const doc3 = data.find(doc => doc._id === _doc3._id) + + // Data left unchanged + assert.equal(data.length, 3) + assert.deepEqual(doc1, { a: 1, b: 10, c: 100, _id: _doc1._id }) + assert.deepEqual(doc2, { a: 2, b: 20, c: 200, _id: _doc2._id }) + assert.deepEqual(doc3, { a: 3, b: 30, c: 300, _id: _doc3._id }) + + // All indexes left unchanged and pointing to the same docs + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.a.getMatching(1)[0], doc1) + assert.equal(d.indexes.a.getMatching(2)[0], doc2) + assert.equal(d.indexes.a.getMatching(3)[0], doc3) + + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.b.getMatching(10)[0], doc1) + assert.equal(d.indexes.b.getMatching(20)[0], doc2) + assert.equal(d.indexes.b.getMatching(30)[0], doc3) + + assert.equal(d.indexes.c.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.c.getMatching(100)[0], doc1) + assert.equal(d.indexes.c.getMatching(200)[0], doc2) + assert.equal(d.indexes.c.getMatching(300)[0], doc3) + }) + + it('If a multi update violates a contraint, all changes are rolled back and an error is thrown', async () => { + d.ensureIndexAsync({ fieldName: 'a', unique: true }) // TODO: was not awaited + d.ensureIndexAsync({ fieldName: 'b', unique: true }) // TODO: was not awaited + d.ensureIndexAsync({ fieldName: 'c', unique: true }) // TODO: was not awaited + + const _doc1 = await d.insertAsync({ a: 1, b: 10, c: 100 }) + const _doc2 = await d.insertAsync({ a: 2, b: 20, c: 200 }) + const _doc3 = await d.insertAsync({ a: 3, b: 30, c: 300 }) + // Will conflict with doc3 + await assert.rejects(() => d.updateAsync({ a: { $in: [1, 2] } }, { + $inc: { a: 10, c: 1000 }, + $set: { b: 30 } + }, { multi: true }), err => { + assert.equal(err.errorType, 'uniqueViolated') + return true + }) + const data = d.getAllData() + const doc1 = data.find(doc => doc._id === _doc1._id) + const doc2 = data.find(doc => doc._id === _doc2._id) + const doc3 = data.find(doc => doc._id === _doc3._id) + + // Data left unchanged + assert.equal(data.length, 3) + assert.deepEqual(doc1, { a: 1, b: 10, c: 100, _id: _doc1._id }) + assert.deepEqual(doc2, { a: 2, b: 20, c: 200, _id: _doc2._id }) + assert.deepEqual(doc3, { a: 3, b: 30, c: 300, _id: _doc3._id }) + + // All indexes left unchanged and pointing to the same docs + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.a.getMatching(1)[0], doc1) + assert.equal(d.indexes.a.getMatching(2)[0], doc2) + assert.equal(d.indexes.a.getMatching(3)[0], doc3) + + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.b.getMatching(10)[0], doc1) + assert.equal(d.indexes.b.getMatching(20)[0], doc2) + assert.equal(d.indexes.b.getMatching(30)[0], doc3) + + assert.equal(d.indexes.c.tree.getNumberOfKeys(), 3) + assert.equal(d.indexes.c.getMatching(100)[0], doc1) + assert.equal(d.indexes.c.getMatching(200)[0], doc2) + assert.equal(d.indexes.c.getMatching(300)[0], doc3) + }) + }) // ==== End of 'Updating indexes upon document update' ==== // + + describe('Updating indexes upon document remove', function () { + it('Removing docs still works as before with indexing', async () => { + d.ensureIndexAsync({ fieldName: 'a' }) // TODO: was not awaited + + await d.insertAsync({ a: 1, b: 'hello' }) + const _doc2 = await d.insertAsync({ a: 2, b: 'si' }) + const _doc3 = await d.insertAsync({ a: 3, b: 'coin' }) + const numRemoved = await d.removeAsync({ a: 1 }, {}) + const data = d.getAllData() + const doc2 = data.find(function (doc) { return doc._id === _doc2._id }) + const doc3 = data.find(function (doc) { return doc._id === _doc3._id }) + + assert.equal(numRemoved, 1) + + assert.equal(data.length, 2) + assert.deepEqual(doc2, { a: 2, b: 'si', _id: _doc2._id }) + assert.deepEqual(doc3, { a: 3, b: 'coin', _id: _doc3._id }) + + const numRemoved2 = await d.removeAsync({ a: { $in: [2, 3] } }, { multi: true }) + const data2 = d.getAllData() + + assert.equal(numRemoved2, 2) + assert.equal(data2.length, 0) + }) + + it('Indexes get updated when a document (or multiple documents) is removed', async () => { + d.ensureIndexAsync({ fieldName: 'a' }) // TODO: was not awaited + d.ensureIndexAsync({ fieldName: 'b' }) // TODO: was not awaited + + await d.insertAsync({ a: 1, b: 'hello' }) + const doc2 = await d.insertAsync({ a: 2, b: 'si' }) + const doc3 = await d.insertAsync({ a: 3, b: 'coin' }) + // Simple remove + const numRemoved = await d.removeAsync({ a: 1 }, {}) + assert.equal(numRemoved, 1) + + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.a.getMatching(2)[0]._id, doc2._id) + assert.equal(d.indexes.a.getMatching(3)[0]._id, doc3._id) + + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.b.getMatching('si')[0]._id, doc2._id) + assert.equal(d.indexes.b.getMatching('coin')[0]._id, doc3._id) + + // The same pointers are shared between all indexes + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes._id.tree.getNumberOfKeys(), 2) + assert.equal(d.indexes.a.getMatching(2)[0], d.indexes._id.getMatching(doc2._id)[0]) + assert.equal(d.indexes.b.getMatching('si')[0], d.indexes._id.getMatching(doc2._id)[0]) + assert.equal(d.indexes.a.getMatching(3)[0], d.indexes._id.getMatching(doc3._id)[0]) + assert.equal(d.indexes.b.getMatching('coin')[0], d.indexes._id.getMatching(doc3._id)[0]) + + // Multi remove + const numRemovedMulti = await d.removeAsync({}, { multi: true }) + assert.equal(numRemovedMulti, 2) + + assert.equal(d.indexes.a.tree.getNumberOfKeys(), 0) + assert.equal(d.indexes.b.tree.getNumberOfKeys(), 0) + assert.equal(d.indexes._id.tree.getNumberOfKeys(), 0) + }) + }) // ==== End of 'Updating indexes upon document remove' ==== // + + describe('Persisting indexes', function () { + it('Indexes are persisted to a separate file and recreated upon reload', async () => { + const persDb = 'workspace/persistIndexes.db' + let db + try { + await fs.access(persDb, fsConstants.FS_OK) + await fs.writeFile(persDb, '', 'utf8') + } catch (error) {} + db = new Datastore({ filename: persDb, autoload: true }) + + assert.equal(Object.keys(db.indexes).length, 1) + assert.equal(Object.keys(db.indexes)[0], '_id') + + await db.insertAsync({ planet: 'Earth' }) + await db.insertAsync({ planet: 'Mars' }) + + await db.ensureIndexAsync({ fieldName: 'planet' }) + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(db.indexes._id.getAll().length, 2) + assert.equal(db.indexes.planet.getAll().length, 2) + assert.equal(db.indexes.planet.fieldName, 'planet') + + // After a reload the indexes are recreated + db = new Datastore({ filename: persDb }) + await db.loadDatabaseAsync() + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(db.indexes._id.getAll().length, 2) + assert.equal(db.indexes.planet.getAll().length, 2) + assert.equal(db.indexes.planet.fieldName, 'planet') + + // After another reload the indexes are still there (i.e. they are preserved during autocompaction) + db = new Datastore({ filename: persDb }) + await db.loadDatabaseAsync() + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(db.indexes._id.getAll().length, 2) + assert.equal(db.indexes.planet.getAll().length, 2) + assert.equal(db.indexes.planet.fieldName, 'planet') + }) + + it('Indexes are persisted with their options and recreated even if some db operation happen between loads', async () => { + const persDb = 'workspace/persistIndexes.db' + let db + + try { + await fs.access(persDb, fsConstants.FS_OK) + await fs.writeFile(persDb, '', 'utf8') + } catch (error) {} + db = new Datastore({ filename: persDb, autoload: true }) + + assert.equal(Object.keys(db.indexes).length, 1) + assert.equal(Object.keys(db.indexes)[0], '_id') + + await db.insertAsync({ planet: 'Earth' }) + await db.insertAsync({ planet: 'Mars' }) + + await db.ensureIndexAsync({ fieldName: 'planet', unique: true, sparse: false }) + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(db.indexes._id.getAll().length, 2) + assert.equal(db.indexes.planet.getAll().length, 2) + assert.equal(db.indexes.planet.unique, true) + assert.equal(db.indexes.planet.sparse, false) + + await db.insertAsync({ planet: 'Jupiter' }) + + // After a reload the indexes are recreated + db = new Datastore({ filename: persDb }) + await db.loadDatabaseAsync() + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(db.indexes._id.getAll().length, 3) + assert.equal(db.indexes.planet.getAll().length, 3) + assert.equal(db.indexes.planet.unique, true) + assert.equal(db.indexes.planet.sparse, false) + + await db.ensureIndexAsync({ fieldName: 'bloup', unique: false, sparse: true }) + assert.equal(Object.keys(db.indexes).length, 3) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(Object.keys(db.indexes)[2], 'bloup') + assert.equal(db.indexes._id.getAll().length, 3) + assert.equal(db.indexes.planet.getAll().length, 3) + assert.equal(db.indexes.bloup.getAll().length, 0) + assert.equal(db.indexes.planet.unique, true) + assert.equal(db.indexes.planet.sparse, false) + assert.equal(db.indexes.bloup.unique, false) + assert.equal(db.indexes.bloup.sparse, true) + + // After another reload the indexes are still there (i.e. they are preserved during autocompaction) + db = new Datastore({ filename: persDb }) + await db.loadDatabaseAsync() + assert.equal(Object.keys(db.indexes).length, 3) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(Object.keys(db.indexes)[2], 'bloup') + assert.equal(db.indexes._id.getAll().length, 3) + assert.equal(db.indexes.planet.getAll().length, 3) + assert.equal(db.indexes.bloup.getAll().length, 0) + assert.equal(db.indexes.planet.unique, true) + assert.equal(db.indexes.planet.sparse, false) + assert.equal(db.indexes.bloup.unique, false) + assert.equal(db.indexes.bloup.sparse, true) + }) + + it('Indexes can also be removed and the remove persisted', async () => { + const persDb = 'workspace/persistIndexes.db' + let db + + try { + await fs.access(persDb, fsConstants.FS_OK) + await fs.writeFile(persDb, '', 'utf8') + } catch (error) {} + db = new Datastore({ filename: persDb, autoload: true }) + + assert.equal(Object.keys(db.indexes).length, 1) + assert.equal(Object.keys(db.indexes)[0], '_id') + + await db.insertAsync({ planet: 'Earth' }) + await db.insertAsync({ planet: 'Mars' }) + + await db.ensureIndexAsync({ fieldName: 'planet' }) + await db.ensureIndexAsync({ fieldName: 'another' }) + assert.equal(Object.keys(db.indexes).length, 3) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(Object.keys(db.indexes)[2], 'another') + assert.equal(db.indexes._id.getAll().length, 2) + assert.equal(db.indexes.planet.getAll().length, 2) + assert.equal(db.indexes.planet.fieldName, 'planet') + + // After a reload the indexes are recreated + db = new Datastore({ filename: persDb }) + await db.loadDatabaseAsync() + assert.equal(Object.keys(db.indexes).length, 3) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'planet') + assert.equal(Object.keys(db.indexes)[2], 'another') + assert.equal(db.indexes._id.getAll().length, 2) + assert.equal(db.indexes.planet.getAll().length, 2) + assert.equal(db.indexes.planet.fieldName, 'planet') + + // Index is removed + await db.removeIndexAsync('planet') + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'another') + assert.equal(db.indexes._id.getAll().length, 2) + + // After a reload indexes are preserved + db = new Datastore({ filename: persDb }) + await db.loadDatabaseAsync() + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'another') + assert.equal(db.indexes._id.getAll().length, 2) + + // After another reload the indexes are still there (i.e. they are preserved during autocompaction) + db = new Datastore({ filename: persDb }) + await db.loadDatabaseAsync() + assert.equal(Object.keys(db.indexes).length, 2) + assert.equal(Object.keys(db.indexes)[0], '_id') + assert.equal(Object.keys(db.indexes)[1], 'another') + assert.equal(db.indexes._id.getAll().length, 2) + }) + }) // ==== End of 'Persisting indexes' ==== + + it('Results of getMatching should never contain duplicates', async () => { + d.ensureIndexAsync({ fieldName: 'bad' }) // TODO: was not awaited + await d.insertAsync({ bad: ['a', 'b'] }) + const res = await d.getCandidatesAsync({ bad: { $in: ['a', 'b'] } }) + assert.equal(res.length, 1) + }) + }) // ==== End of 'Using indexes' ==== // +}) diff --git a/test/utils.test.js b/test/utils.test.js index 2aa5f62..7d71403 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -27,7 +27,12 @@ const whilstAsync = async (test, fn) => { const whilst = callbackify(whilstAsync) +const wait = delay => new Promise(resolve => { + setTimeout(resolve, delay) +}) + module.exports.whilst = whilst module.exports.apply = apply module.exports.waterfall = waterfall module.exports.each = each +module.exports.wait = wait From 32d2fa14a557e22158eeb60efd895bc0e781afb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 16 Nov 2021 13:12:52 +0100 Subject: [PATCH 26/65] async tests for cursor --- test/cursor.async.test.js | 521 ++++++++++++++++++++++++++++++++++++++ test/db.async.test.js | 5 +- 2 files changed, 523 insertions(+), 3 deletions(-) create mode 100755 test/cursor.async.test.js diff --git a/test/cursor.async.test.js b/test/cursor.async.test.js new file mode 100755 index 0000000..94cdd67 --- /dev/null +++ b/test/cursor.async.test.js @@ -0,0 +1,521 @@ +/* eslint-env mocha */ +const testDb = 'workspace/test.db' +const { promises: fs, constants: fsConstants } = require('fs') +const assert = require('assert').strict +const path = require('path') +const Datastore = require('../lib/datastore') +const Persistence = require('../lib/persistence') +const Cursor = require('../lib/cursor') + +describe('Cursor Async', function () { + let d + + beforeEach(async () => { + d = new Datastore({ filename: testDb }) + assert.equal(d.filename, testDb) + assert.equal(d.inMemoryOnly, false) + await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb)) + try { + await fs.access(testDb, fsConstants.FS_OK) + await fs.unlink(testDb) + } catch (err) {} + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 0) + }) + + describe('Without sorting', function () { + beforeEach(async () => { + await d.insertAsync({ age: 5 }) + await d.insertAsync({ age: 57 }) + await d.insertAsync({ age: 52 }) + await d.insertAsync({ age: 23 }) + await d.insertAsync({ age: 89 }) + }) + + it('Without query, an empty query or a simple query and no skip or limit', async () => { + const cursor = new Cursor(d) + const docs = await cursor + assert.equal(docs.length, 5) + assert.equal(docs.filter(function (doc) { return doc.age === 5 })[0].age, 5) + assert.equal(docs.filter(function (doc) { return doc.age === 57 })[0].age, 57) + assert.equal(docs.filter(function (doc) { return doc.age === 52 })[0].age, 52) + assert.equal(docs.filter(function (doc) { return doc.age === 23 })[0].age, 23) + assert.equal(docs.filter(function (doc) { return doc.age === 89 })[0].age, 89) + const cursor2 = new Cursor(d, {}) + const docs2 = await cursor2 + assert.equal(docs2.length, 5) + assert.equal(docs2.filter(function (doc) { return doc.age === 5 })[0].age, 5) + assert.equal(docs2.filter(function (doc) { return doc.age === 57 })[0].age, 57) + assert.equal(docs2.filter(function (doc) { return doc.age === 52 })[0].age, 52) + assert.equal(docs2.filter(function (doc) { return doc.age === 23 })[0].age, 23) + assert.equal(docs2.filter(function (doc) { return doc.age === 89 })[0].age, 89) + const cursor3 = new Cursor(d, { age: { $gt: 23 } }) + const docs3 = await cursor3 + assert.equal(docs3.length, 3) + assert.equal(docs3.filter(function (doc) { return doc.age === 57 })[0].age, 57) + assert.equal(docs3.filter(function (doc) { return doc.age === 52 })[0].age, 52) + assert.equal(docs3.filter(function (doc) { return doc.age === 89 })[0].age, 89) + }) + + it('With an empty collection', async () => { + await d.removeAsync({}, { multi: true }) + const cursor = new Cursor(d) + const docs = await cursor + assert.equal(docs.length, 0) + }) + + it('With a limit', async () => { + const cursor = new Cursor(d) + cursor.limit(3) + const docs = await cursor + assert.equal(docs.length, 3) + // No way to predict which results are returned of course ... + }) + + it('With a skip', async () => { + const cursor = new Cursor(d) + const docs = await cursor.skip(2) + assert.equal(docs.length, 3) + // No way to predict which results are returned of course ... + }) + + it('With a limit and a skip and method chaining', async () => { + const cursor = new Cursor(d) + cursor.limit(4).skip(3) // Only way to know that the right number of results was skipped is if limit + skip > number of results + const docs = await cursor + assert.equal(docs.length, 2) + // No way to predict which results are returned of course ... + }) + }) // ===== End of 'Without sorting' ===== + + describe('Sorting of the results', function () { + beforeEach(async () => { + // We don't know the order in which docs will be inserted but we ensure correctness by testing both sort orders + await d.insertAsync({ age: 5 }) + await d.insertAsync({ age: 57 }) + await d.insertAsync({ age: 52 }) + await d.insertAsync({ age: 23 }) + await d.insertAsync({ age: 89 }) + }) + + it('Using one sort', async () => { + const cursor = new Cursor(d, {}) + cursor.sort({ age: 1 }) + const docs = await cursor + // Results are in ascending order + for (let i = 0; i < docs.length - 1; i += 1) { + assert(docs[i].age < docs[i + 1].age) + } + + cursor.sort({ age: -1 }) + const docs2 = await cursor + // Results are in descending order + for (let i = 0; i < docs2.length - 1; i += 1) { + assert(docs2[i].age > docs2[i + 1].age) + } + }) + + it('Sorting strings with custom string comparison function', async () => { + const db = new Datastore({ + inMemoryOnly: true, + autoload: true, + compareStrings: function (a, b) { return a.length - b.length } + }) + + db.insertAsync({ name: 'alpha' }) // TODO was not awaited + db.insertAsync({ name: 'charlie' }) // TODO was not awaited + db.insertAsync({ name: 'zulu' }) // TODO was not awaited + + const docs = await db.findAsync({}).sort({ name: 1 }) + assert.equal(docs.map(x => x.name)[0], 'zulu') + assert.equal(docs.map(x => x.name)[1], 'alpha') + assert.equal(docs.map(x => x.name)[2], 'charlie') + + delete db.compareStrings + const docs2 = await db.find({}).sort({ name: 1 }) + assert.equal(docs2.map(x => x.name)[0], 'alpha') + assert.equal(docs2.map(x => x.name)[1], 'charlie') + assert.equal(docs2.map(x => x.name)[2], 'zulu') + }) + + it('With an empty collection', async () => { + await d.removeAsync({}, { multi: true }) + const cursor = new Cursor(d) + cursor.sort({ age: 1 }) + const docs = await cursor + assert.equal(docs.length, 0) + }) + + it('Ability to chain sorting and exec', async () => { + const cursor = new Cursor(d) + const docs = await cursor.sort({ age: 1 }) + // Results are in ascending order + for (let i = 0; i < docs.length - 1; i += 1) { + assert.ok(docs[i].age < docs[i + 1].age) + } + + const cursor2 = new Cursor(d) + const docs2 = await cursor2.sort({ age: -1 }) + // Results are in descending order + for (let i = 0; i < docs2.length - 1; i += 1) { + assert(docs2[i].age > docs2[i + 1].age) + } + }) + + it('Using limit and sort', async () => { + const cursor = new Cursor(d) + const docs = await cursor.sort({ age: 1 }).limit(3) + assert.equal(docs.length, 3) + assert.equal(docs[0].age, 5) + assert.equal(docs[1].age, 23) + assert.equal(docs[2].age, 52) + const cursor2 = new Cursor(d) + const docs2 = await cursor2.sort({ age: -1 }).limit(2) + assert.equal(docs2.length, 2) + assert.equal(docs2[0].age, 89) + assert.equal(docs2[1].age, 57) + }) + + it('Using a limit higher than total number of docs shouldn\'t cause an error', async () => { + const cursor = new Cursor(d) + const docs = await cursor.sort({ age: 1 }).limit(7) + assert.equal(docs.length, 5) + assert.equal(docs[0].age, 5) + assert.equal(docs[1].age, 23) + assert.equal(docs[2].age, 52) + assert.equal(docs[3].age, 57) + assert.equal(docs[4].age, 89) + }) + + it('Using limit and skip with sort', async () => { + const cursor = new Cursor(d) + const docs = await cursor.sort({ age: 1 }).limit(1).skip(2) + assert.equal(docs.length, 1) + assert.equal(docs[0].age, 52) + const cursor2 = new Cursor(d) + const docs2 = await cursor2.sort({ age: 1 }).limit(3).skip(1) + assert.equal(docs2.length, 3) + assert.equal(docs2[0].age, 23) + assert.equal(docs2[1].age, 52) + assert.equal(docs2[2].age, 57) + const cursor3 = new Cursor(d) + const docs3 = await cursor3.sort({ age: -1 }).limit(2).skip(2) + assert.equal(docs3.length, 2) + assert.equal(docs3[0].age, 52) + assert.equal(docs3[1].age, 23) + }) + + it('Using too big a limit and a skip with sort', async () => { + const cursor = new Cursor(d) + const docs = await cursor.sort({ age: 1 }).limit(8).skip(2) + assert.equal(docs.length, 3) + assert.equal(docs[0].age, 52) + assert.equal(docs[1].age, 57) + assert.equal(docs[2].age, 89) + }) + + it('Using too big a skip with sort should return no result', async () => { + const cursor = new Cursor(d) + const docs = await cursor.sort({ age: 1 }).skip(5) + assert.equal(docs.length, 0) + const cursor2 = new Cursor(d) + const docs2 = await cursor2.sort({ age: 1 }).skip(7) + assert.equal(docs2.length, 0) + + const cursor3 = new Cursor(d) + const docs3 = await cursor3.sort({ age: 1 }).limit(3).skip(7) + assert.equal(docs3.length, 0) + const cursor4 = new Cursor(d) + const docs4 = await cursor4.sort({ age: 1 }).limit(6).skip(7) + assert.equal(docs4.length, 0) + }) + + it('Sorting strings', async () => { + await d.removeAsync({}, { multi: true }) + await d.insertAsync({ name: 'jako' }) + await d.insertAsync({ name: 'jakeb' }) + await d.insertAsync({ name: 'sue' }) + + const cursor = new Cursor(d, {}) + const docs = await cursor.sort({ name: 1 }) + assert.equal(docs.length, 3) + assert.equal(docs[0].name, 'jakeb') + assert.equal(docs[1].name, 'jako') + assert.equal(docs[2].name, 'sue') + const cursor2 = new Cursor(d, {}) + const docs2 = await cursor2.sort({ name: -1 }) + assert.equal(docs2.length, 3) + assert.equal(docs2[0].name, 'sue') + assert.equal(docs2[1].name, 'jako') + assert.equal(docs2[2].name, 'jakeb') + }) + + it('Sorting nested fields with dates', async () => { + await d.removeAsync({}, { multi: true }) + const doc1 = await d.insertAsync({ event: { recorded: new Date(400) } }) + const doc2 = await d.insertAsync({ event: { recorded: new Date(60000) } }) + const doc3 = await d.insertAsync({ event: { recorded: new Date(32) } }) + const cursor = new Cursor(d, {}) + const docs = await cursor.sort({ 'event.recorded': 1 }) + assert.equal(docs.length, 3) + assert.equal(docs[0]._id, doc3._id) + assert.equal(docs[1]._id, doc1._id) + assert.equal(docs[2]._id, doc2._id) + + const cursor2 = new Cursor(d, {}) + const docs2 = await cursor2.sort({ 'event.recorded': -1 }) + assert.equal(docs2.length, 3) + assert.equal(docs2[0]._id, doc2._id) + assert.equal(docs2[1]._id, doc1._id) + assert.equal(docs2[2]._id, doc3._id) + }) + + it('Sorting when some fields are undefined', async () => { + await d.removeAsync({}, { multi: true }) + + await d.insertAsync({ name: 'jako', other: 2 }) + await d.insertAsync({ name: 'jakeb', other: 3 }) + await d.insertAsync({ name: 'sue' }) + await d.insertAsync({ name: 'henry', other: 4 }) + + const cursor = new Cursor(d, {}) + // eslint-disable-next-line node/handle-callback-err + const docs = await cursor.sort({ other: 1 }) + assert.equal(docs.length, 4) + assert.equal(docs[0].name, 'sue') + assert.equal(docs[0].other, undefined) + assert.equal(docs[1].name, 'jako') + assert.equal(docs[1].other, 2) + assert.equal(docs[2].name, 'jakeb') + assert.equal(docs[2].other, 3) + assert.equal(docs[3].name, 'henry') + assert.equal(docs[3].other, 4) + const cursor2 = new Cursor(d, { name: { $in: ['suzy', 'jakeb', 'jako'] } }) + const docs2 = await cursor2.sort({ other: -1 }) + assert.equal(docs2.length, 2) + assert.equal(docs2[0].name, 'jakeb') + assert.equal(docs2[0].other, 3) + assert.equal(docs2[1].name, 'jako') + assert.equal(docs2[1].other, 2) + }) + + it('Sorting when all fields are undefined', async () => { + await d.removeAsync({}, { multi: true }) + await d.insertAsync({ name: 'jako' }) + await d.insertAsync({ name: 'jakeb' }) + await d.insertAsync({ name: 'sue' }) + const cursor = new Cursor(d, {}) + const docs = await cursor.sort({ other: 1 }) + assert.equal(docs.length, 3) + + const cursor2 = new Cursor(d, { name: { $in: ['sue', 'jakeb', 'jakob'] } }) + const docs2 = await cursor2.sort({ other: -1 }) + assert.equal(docs2.length, 2) + }) + + it('Multiple consecutive sorts', async () => { + await d.removeAsync({}, { multi: true }) + + await d.insertAsync({ name: 'jako', age: 43, nid: 1 }) + await d.insertAsync({ name: 'jakeb', age: 43, nid: 2 }) + await d.insertAsync({ name: 'sue', age: 12, nid: 3 }) + await d.insertAsync({ name: 'zoe', age: 23, nid: 4 }) + await d.insertAsync({ name: 'jako', age: 35, nid: 5 }) + const cursor = new Cursor(d, {}) + // eslint-disable-next-line node/handle-callback-err + const docs = await cursor.sort({ name: 1, age: -1 }) + assert.equal(docs.length, 5) + + assert.equal(docs[0].nid, 2) + assert.equal(docs[1].nid, 1) + assert.equal(docs[2].nid, 5) + assert.equal(docs[3].nid, 3) + assert.equal(docs[4].nid, 4) + const cursor2 = new Cursor(d, {}) + const docs2 = await cursor2.sort({ name: 1, age: 1 }) + assert.equal(docs2.length, 5) + + assert.equal(docs2[0].nid, 2) + assert.equal(docs2[1].nid, 5) + assert.equal(docs2[2].nid, 1) + assert.equal(docs2[3].nid, 3) + assert.equal(docs2[4].nid, 4) + const cursor3 = new Cursor(d, {}) + const docs3 = await cursor3.sort({ age: 1, name: 1 }) + assert.equal(docs3.length, 5) + + assert.equal(docs3[0].nid, 3) + assert.equal(docs3[1].nid, 4) + assert.equal(docs3[2].nid, 5) + assert.equal(docs3[3].nid, 2) + assert.equal(docs3[4].nid, 1) + + const cursor4 = new Cursor(d, {}) + const docs4 = await cursor4.sort({ age: 1, name: -1 }) + assert.equal(docs4.length, 5) + + assert.equal(docs4[0].nid, 3) + assert.equal(docs4[1].nid, 4) + assert.equal(docs4[2].nid, 5) + assert.equal(docs4[3].nid, 1) + assert.equal(docs4[4].nid, 2) + }) + + it('Similar data, multiple consecutive sorts', async () => { + let id + const companies = ['acme', 'milkman', 'zoinks'] + const entities = [] + await d.removeAsync({}, { multi: true }) + id = 1 + for (let i = 0; i < companies.length; i++) { + for (let j = 5; j <= 100; j += 5) { + entities.push({ + company: companies[i], + cost: j, + nid: id + }) + id++ + } + } + await Promise.all(entities.map(entity => d.insertAsync(entity))) + const cursor = new Cursor(d, {}) + const docs = await cursor.sort({ company: 1, cost: 1 }) + assert.equal(docs.length, 60) + + for (let i = 0; i < docs.length; i++) { + assert.equal(docs[i].nid, i + 1) + } + }) + }) // ===== End of 'Sorting' ===== + + describe('Projections', function () { + let doc1 + let doc2 + let doc3 + let doc4 + let doc0 + + beforeEach(async () => { + // We don't know the order in which docs will be inserted but we ensure correctness by testing both sort orders + doc0 = await d.insertAsync({ age: 5, name: 'Jo', planet: 'B', toys: { bebe: true, ballon: 'much' } }) + doc1 = await d.insertAsync({ age: 57, name: 'Louis', planet: 'R', toys: { ballon: 'yeah', bebe: false } }) + doc2 = await d.insertAsync({ age: 52, name: 'Grafitti', planet: 'C', toys: { bebe: 'kind of' } }) + doc3 = await d.insertAsync({ age: 23, name: 'LM', planet: 'S' }) + doc4 = await d.insertAsync({ age: 89, planet: 'Earth' }) + }) + + it('Takes all results if no projection or empty object given', async () => { + const cursor = new Cursor(d, {}) + cursor.sort({ age: 1 }) // For easier finding + const docs = await cursor + assert.equal(docs.length, 5) + assert.deepStrictEqual(docs[0], doc0) + assert.deepStrictEqual(docs[1], doc3) + assert.deepStrictEqual(docs[2], doc2) + assert.deepStrictEqual(docs[3], doc1) + assert.deepStrictEqual(docs[4], doc4) + + cursor.projection({}) + const docs2 = await cursor + assert.equal(docs2.length, 5) + assert.deepStrictEqual(docs2[0], doc0) + assert.deepStrictEqual(docs2[1], doc3) + assert.deepStrictEqual(docs2[2], doc2) + assert.deepStrictEqual(docs2[3], doc1) + assert.deepStrictEqual(docs2[4], doc4) + }) + + it('Can take only the expected fields', async () => { + const cursor = new Cursor(d, {}) + cursor.sort({ age: 1 }) // For easier finding + cursor.projection({ age: 1, name: 1 }) + const docs = await cursor + assert.equal(docs.length, 5) + // Takes the _id by default + assert.deepStrictEqual(docs[0], { age: 5, name: 'Jo', _id: doc0._id }) + assert.deepStrictEqual(docs[1], { age: 23, name: 'LM', _id: doc3._id }) + assert.deepStrictEqual(docs[2], { age: 52, name: 'Grafitti', _id: doc2._id }) + assert.deepStrictEqual(docs[3], { age: 57, name: 'Louis', _id: doc1._id }) + assert.deepStrictEqual(docs[4], { age: 89, _id: doc4._id }) // No problems if one field to take doesn't exist + + cursor.projection({ age: 1, name: 1, _id: 0 }) + const docs2 = await cursor + assert.equal(docs2.length, 5) + assert.deepStrictEqual(docs2[0], { age: 5, name: 'Jo' }) + assert.deepStrictEqual(docs2[1], { age: 23, name: 'LM' }) + assert.deepStrictEqual(docs2[2], { age: 52, name: 'Grafitti' }) + assert.deepStrictEqual(docs2[3], { age: 57, name: 'Louis' }) + assert.deepStrictEqual(docs2[4], { age: 89 }) // No problems if one field to take doesn't exist + }) + + it('Can omit only the expected fields', async () => { + const cursor = new Cursor(d, {}) + cursor.sort({ age: 1 }) // For easier finding + cursor.projection({ age: 0, name: 0 }) + const docs = await cursor + assert.equal(docs.length, 5) + // Takes the _id by default + assert.deepStrictEqual(docs[0], { planet: 'B', _id: doc0._id, toys: { bebe: true, ballon: 'much' } }) + assert.deepStrictEqual(docs[1], { planet: 'S', _id: doc3._id }) + assert.deepStrictEqual(docs[2], { planet: 'C', _id: doc2._id, toys: { bebe: 'kind of' } }) + assert.deepStrictEqual(docs[3], { planet: 'R', _id: doc1._id, toys: { bebe: false, ballon: 'yeah' } }) + assert.deepStrictEqual(docs[4], { planet: 'Earth', _id: doc4._id }) + + cursor.projection({ age: 0, name: 0, _id: 0 }) + const docs2 = await cursor + assert.equal(docs2.length, 5) + assert.deepStrictEqual(docs2[0], { planet: 'B', toys: { bebe: true, ballon: 'much' } }) + assert.deepStrictEqual(docs2[1], { planet: 'S' }) + assert.deepStrictEqual(docs2[2], { planet: 'C', toys: { bebe: 'kind of' } }) + assert.deepStrictEqual(docs2[3], { planet: 'R', toys: { bebe: false, ballon: 'yeah' } }) + assert.deepStrictEqual(docs2[4], { planet: 'Earth' }) + }) + + it('Cannot use both modes except for _id', async () => { + const cursor = new Cursor(d, {}) + cursor.sort({ age: 1 }) // For easier finding + cursor.projection({ age: 1, name: 0 }) + await assert.rejects(() => cursor) + + cursor.projection({ age: 1, _id: 0 }) + const docs = await cursor + assert.deepStrictEqual(docs[0], { age: 5 }) + assert.deepStrictEqual(docs[1], { age: 23 }) + assert.deepStrictEqual(docs[2], { age: 52 }) + assert.deepStrictEqual(docs[3], { age: 57 }) + assert.deepStrictEqual(docs[4], { age: 89 }) + + cursor.projection({ age: 0, toys: 0, planet: 0, _id: 1 }) + const docs2 = await cursor + assert.deepStrictEqual(docs2[0], { name: 'Jo', _id: doc0._id }) + assert.deepStrictEqual(docs2[1], { name: 'LM', _id: doc3._id }) + assert.deepStrictEqual(docs2[2], { name: 'Grafitti', _id: doc2._id }) + assert.deepStrictEqual(docs2[3], { name: 'Louis', _id: doc1._id }) + assert.deepStrictEqual(docs2[4], { _id: doc4._id }) + }) + + it('Projections on embedded documents - omit type', async () => { + const cursor = new Cursor(d, {}) + cursor.sort({ age: 1 }) // For easier finding + cursor.projection({ name: 0, planet: 0, 'toys.bebe': 0, _id: 0 }) + const docs = await cursor + assert.deepStrictEqual(docs[0], { age: 5, toys: { ballon: 'much' } }) + assert.deepStrictEqual(docs[1], { age: 23 }) + assert.deepStrictEqual(docs[2], { age: 52, toys: {} }) + assert.deepStrictEqual(docs[3], { age: 57, toys: { ballon: 'yeah' } }) + assert.deepStrictEqual(docs[4], { age: 89 }) + }) + + it('Projections on embedded documents - pick type', async () => { + const cursor = new Cursor(d, {}) + cursor.sort({ age: 1 }) // For easier finding + cursor.projection({ name: 1, 'toys.ballon': 1, _id: 0 }) + const docs = await cursor + assert.deepStrictEqual(docs[0], { name: 'Jo', toys: { ballon: 'much' } }) + assert.deepStrictEqual(docs[1], { name: 'LM' }) + assert.deepStrictEqual(docs[2], { name: 'Grafitti' }) + assert.deepStrictEqual(docs[3], { name: 'Louis', toys: { ballon: 'yeah' } }) + assert.deepStrictEqual(docs[4], {}) + }) + }) // ==== End of 'Projections' ==== +}) diff --git a/test/db.async.test.js b/test/db.async.test.js index ff499e5..76fc70f 100644 --- a/test/db.async.test.js +++ b/test/db.async.test.js @@ -1,7 +1,6 @@ /* eslint-env mocha */ const testDb = 'workspace/test.db' -const fs = require('fs').promises -const fsConstants = require('fs').constants +const { promises: fs, constants: fsConstants } = require('fs') const path = require('path') const assert = require('assert').strict const model = require('../lib/model') @@ -10,7 +9,7 @@ const Persistence = require('../lib/persistence') const { wait } = require('./utils.test') const reloadTimeUpperBound = 60 // In ms, an upper bound for the reload time used to check createdAt and updatedAt -describe.only('Database async', function () { +describe('Database async', function () { let d beforeEach(async () => { From 787904d3eff73f515d0c732037da24d9d5507b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 16 Nov 2021 14:18:08 +0100 Subject: [PATCH 27/65] executor async tests --- test/db.test.js | 13 ------ test/executor.async.test.js | 85 +++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 13 deletions(-) create mode 100755 test/executor.async.test.js diff --git a/test/db.test.js b/test/db.test.js index a11fef2..82332d2 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -431,12 +431,10 @@ describe('Database', function () { it('If the callback throws an uncaught exception, do not catch it inside findOne, this is userspace concern', function (done) { let tryCount = 0 const currentUncaughtExceptionHandlers = process.listeners('uncaughtException') - const currentUnhandledRejectionHandlers = process.listeners('unhandledRejection') let i process.removeAllListeners('uncaughtException') - process.removeAllListeners('unhandledRejection') process.on('uncaughtException', function MINE (ex) { process.removeAllListeners('uncaughtException') @@ -449,17 +447,6 @@ describe('Database', function () { done() }) - process.on('unhandledRejection', function MINE (ex) { - process.removeAllListeners('unhandledRejection') - - for (i = 0; i < currentUnhandledRejectionHandlers.length; i += 1) { - process.on('unhandledRejection', currentUnhandledRejectionHandlers[i]) - } - - ex.message.should.equal('SOME EXCEPTION') - done() - }) - d.insert({ a: 5 }, function () { // eslint-disable-next-line node/handle-callback-err d.findOne({ a: 5 }, function (err, doc) { diff --git a/test/executor.async.test.js b/test/executor.async.test.js new file mode 100755 index 0000000..d57127e --- /dev/null +++ b/test/executor.async.test.js @@ -0,0 +1,85 @@ +/* eslint-env mocha */ +const testDb = 'workspace/test.db' +const { promises: fs, constants: fsConstants } = require('fs') +const assert = require('assert').strict +const path = require('path') +const Datastore = require('../lib/datastore') +const Persistence = require('../lib/persistence') + +// Test that operations are executed in the right order +// We prevent Mocha from catching the exception we throw on purpose by remembering all current handlers, remove them and register them back after test ends +const testRightOrder = async d => { + const docs = await d.findAsync({}) + assert.equal(docs.length, 0) + + await d.insertAsync({ a: 1 }) + await d.updateAsync({ a: 1 }, { a: 2 }, {}) + const docs2 = await d.findAsync({}) + assert.equal(docs2[0].a, 2) + d.updateAsync({ a: 2 }, { a: 3 }, {}) // not awaiting + d.executor.pushAsync(async () => { throw new Error('Some error') }) // not awaiting + const docs3 = await d.findAsync({}) + assert.equal(docs3[0].a, 3) +} + +// Note: The following test does not have any assertion because it +// is meant to address the deprecation warning: +// (node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral. +// see +const testEventLoopStarvation = async d => { + const times = 1001 + let i = 0 + while (i < times) { + i++ + d.findAsync({ bogus: 'search' }) + } + await d.findAsync({ bogus: 'search' }) +} + +// Test that operations are executed in the right order even with no callback +const testExecutorWorksWithoutCallback = async d => { + d.insertAsync({ a: 1 }) + d.insertAsync({ a: 2 }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 2) +} + +describe('Executor async', function () { + describe('With persistent database', async () => { + let d + + beforeEach(async () => { + d = new Datastore({ filename: testDb }) + assert.equal(d.filename, testDb) + assert.equal(d.inMemoryOnly, false) + await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb)) + try { + await fs.access(testDb, fsConstants.FS_OK) + await fs.unlink(testDb) + } catch (err) {} + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 0) + }) + + it('Operations are executed in the right order', () => testRightOrder(d)) + + it('Does not starve event loop and raise warning when more than 1000 callbacks are in queue', () => testEventLoopStarvation(d)) + + it('Works in the right order even with no supplied callback', () => testExecutorWorksWithoutCallback(d)) + }) +}) // ==== End of 'With persistent database' ==== + +describe('With non persistent database', function () { + let d + + beforeEach(async () => { + d = new Datastore({ inMemoryOnly: true }) + assert.equal(d.inMemoryOnly, true) + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 0) + }) + + it('Operations are executed in the right order', () => testRightOrder(d)) + + it('Works in the right order even with no supplied callback', () => testExecutorWorksWithoutCallback(d)) +}) // ==== End of 'With non persistent database' ==== From fa9b1b1305f5f9faeaac5b3c85c44dcc84cb9657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 16 Nov 2021 15:12:45 +0100 Subject: [PATCH 28/65] persistence async tests --- test/cursor.async.test.js | 6 +- test/db.async.test.js | 25 +- test/executor.async.test.js | 6 +- test/persistence.async.test.js | 854 +++++++++++++++++++++++++++++++++ test/utils.test.js | 3 + 5 files changed, 869 insertions(+), 25 deletions(-) create mode 100755 test/persistence.async.test.js diff --git a/test/cursor.async.test.js b/test/cursor.async.test.js index 94cdd67..22b00bc 100755 --- a/test/cursor.async.test.js +++ b/test/cursor.async.test.js @@ -6,6 +6,7 @@ const path = require('path') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') const Cursor = require('../lib/cursor') +const { exists } = require('./utils.test.js') describe('Cursor Async', function () { let d @@ -15,10 +16,7 @@ describe('Cursor Async', function () { assert.equal(d.filename, testDb) assert.equal(d.inMemoryOnly, false) await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb)) - try { - await fs.access(testDb, fsConstants.FS_OK) - await fs.unlink(testDb) - } catch (err) {} + if (await exists(testDb)) await fs.unlink(testDb) await d.loadDatabaseAsync() assert.equal(d.getAllData().length, 0) }) diff --git a/test/db.async.test.js b/test/db.async.test.js index 76fc70f..7e10b5a 100644 --- a/test/db.async.test.js +++ b/test/db.async.test.js @@ -1,12 +1,13 @@ /* eslint-env mocha */ const testDb = 'workspace/test.db' -const { promises: fs, constants: fsConstants } = require('fs') +const { promises: fs } = require('fs') const path = require('path') const assert = require('assert').strict const model = require('../lib/model') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') const { wait } = require('./utils.test') +const { exists } = require('./utils.test.js') const reloadTimeUpperBound = 60 // In ms, an upper bound for the reload time used to check createdAt and updatedAt describe('Database async', function () { @@ -17,10 +18,7 @@ describe('Database async', function () { assert.equal(d.filename, testDb) assert.equal(d.inMemoryOnly, false) await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb)) - try { - await fs.access(testDb, fsConstants.FS_OK) - await fs.unlink(testDb) - } catch (err) {} + if (await exists(testDb)) await fs.unlink(testDb) await d.loadDatabaseAsync() assert.equal(d.getAllData().length, 0) }) @@ -1865,10 +1863,7 @@ describe('Database async', function () { it('Indexes are persisted to a separate file and recreated upon reload', async () => { const persDb = 'workspace/persistIndexes.db' let db - try { - await fs.access(persDb, fsConstants.FS_OK) - await fs.writeFile(persDb, '', 'utf8') - } catch (error) {} + if (await exists(persDb)) await fs.unlink(persDb) db = new Datastore({ filename: persDb, autoload: true }) assert.equal(Object.keys(db.indexes).length, 1) @@ -1910,10 +1905,8 @@ describe('Database async', function () { const persDb = 'workspace/persistIndexes.db' let db - try { - await fs.access(persDb, fsConstants.FS_OK) - await fs.writeFile(persDb, '', 'utf8') - } catch (error) {} + if (await exists(persDb)) await fs.unlink(persDb) + db = new Datastore({ filename: persDb, autoload: true }) assert.equal(Object.keys(db.indexes).length, 1) @@ -1977,10 +1970,8 @@ describe('Database async', function () { const persDb = 'workspace/persistIndexes.db' let db - try { - await fs.access(persDb, fsConstants.FS_OK) - await fs.writeFile(persDb, '', 'utf8') - } catch (error) {} + if (await exists(persDb)) await fs.unlink(persDb) + db = new Datastore({ filename: persDb, autoload: true }) assert.equal(Object.keys(db.indexes).length, 1) diff --git a/test/executor.async.test.js b/test/executor.async.test.js index d57127e..9bae34f 100755 --- a/test/executor.async.test.js +++ b/test/executor.async.test.js @@ -5,6 +5,7 @@ const assert = require('assert').strict const path = require('path') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') +const { exists } = require('./utils.test.js') // Test that operations are executed in the right order // We prevent Mocha from catching the exception we throw on purpose by remembering all current handlers, remove them and register them back after test ends @@ -53,10 +54,7 @@ describe('Executor async', function () { assert.equal(d.filename, testDb) assert.equal(d.inMemoryOnly, false) await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb)) - try { - await fs.access(testDb, fsConstants.FS_OK) - await fs.unlink(testDb) - } catch (err) {} + if (await exists(testDb)) await fs.unlink(testDb) await d.loadDatabaseAsync() assert.equal(d.getAllData().length, 0) }) diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js new file mode 100755 index 0000000..472e2ff --- /dev/null +++ b/test/persistence.async.test.js @@ -0,0 +1,854 @@ +/* eslint-env mocha */ +const testDb = 'workspace/test.db' +const { promises: fs, constants: fsConstants } = require('fs') +const path = require('path') +const assert = require('assert').strict +const { exists } = require('./utils.test.js') +const model = require('../lib/model') +const Datastore = require('../lib/datastore') +const Persistence = require('../lib/persistence') +const storage = require('../lib/storage') +const { execFile, fork } = require('child_process') +const { promisify } = require('util') +const Readable = require('stream').Readable + +describe('Persistence async', function () { + let d + + beforeEach(async () => { + d = new Datastore({ filename: testDb }) + assert.equal(d.filename, testDb) + assert.equal(d.inMemoryOnly, false) + await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb)) + if (await exists(testDb)) await fs.unlink(testDb) + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 0) + }) + + it('Every line represents a document', function () { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: '3', nested: { today: now } }) + const treatedData = d.persistence.treatRawData(rawData).data + + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 3) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '2', hello: 'world' }) + assert.deepEqual(treatedData[2], { _id: '3', nested: { today: now } }) + }) + + it('Every line represents a document (with stream)', async () => { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: '3', nested: { today: now } }) + const stream = new Readable() + + stream.push(rawData) + stream.push(null) + + const result = await d.persistence.treatRawStreamAsync(stream) + const treatedData = result.data + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 3) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '2', hello: 'world' }) + assert.deepEqual(treatedData[2], { _id: '3', nested: { today: now } }) + }) + + it('Badly formatted lines have no impact on the treated data', function () { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + 'garbage\n' + + model.serialize({ _id: '3', nested: { today: now } }) + const treatedData = d.persistence.treatRawData(rawData).data + + treatedData.sort(function (a, b) { return a._id - b._id }) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '3', nested: { today: now } }) + }) + + it('Badly formatted lines have no impact on the treated data (with stream)', async () => { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + 'garbage\n' + + model.serialize({ _id: '3', nested: { today: now } }) + const stream = new Readable() + + stream.push(rawData) + stream.push(null) + + const result = await d.persistence.treatRawStreamAsync(stream) + const treatedData = result.data + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '3', nested: { today: now } }) + }) + + it('Well formatted lines that have no _id are not included in the data', function () { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ nested: { today: now } }) + const treatedData = d.persistence.treatRawData(rawData).data + + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '2', hello: 'world' }) + }) + + it('Well formatted lines that have no _id are not included in the data (with stream)', async () => { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ nested: { today: now } }) + const stream = new Readable() + + stream.push(rawData) + stream.push(null) + + const result = await d.persistence.treatRawStreamAsync(stream) + const treatedData = result.data + treatedData.sort(function (a, b) { return a._id - b._id }) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '2', hello: 'world' }) + }) + + it('If two lines concern the same doc (= same _id), the last one is the good version', function () { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: '1', nested: { today: now } }) + const treatedData = d.persistence.treatRawData(rawData).data + + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', nested: { today: now } }) + assert.deepEqual(treatedData[1], { _id: '2', hello: 'world' }) + }) + + it('If two lines concern the same doc (= same _id), the last one is the good version (with stream)', async () => { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: '1', nested: { today: now } }) + const stream = new Readable() + + stream.push(rawData) + stream.push(null) + + const result = await d.persistence.treatRawStreamAsync(stream) + const treatedData = result.data + treatedData.sort(function (a, b) { return a._id - b._id }) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', nested: { today: now } }) + assert.deepEqual(treatedData[1], { _id: '2', hello: 'world' }) + }) + + it('If a doc contains $$deleted: true, that means we need to remove it from the data', function () { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: '1', $$deleted: true }) + '\n' + + model.serialize({ _id: '3', today: now }) + const treatedData = d.persistence.treatRawData(rawData).data + + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '2', hello: 'world' }) + assert.deepEqual(treatedData[1], { _id: '3', today: now }) + }) + + it('If a doc contains $$deleted: true, that means we need to remove it from the data (with stream)', async () => { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', hello: 'world' }) + '\n' + + model.serialize({ _id: '1', $$deleted: true }) + '\n' + + model.serialize({ _id: '3', today: now }) + const stream = new Readable() + + stream.push(rawData) + stream.push(null) + + const result = await d.persistence.treatRawStreamAsync(stream) + const treatedData = result.data + treatedData.sort(function (a, b) { return a._id - b._id }) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '2', hello: 'world' }) + assert.deepEqual(treatedData[1], { _id: '3', today: now }) + }) + + it('If a doc contains $$deleted: true, no error is thrown if the doc wasnt in the list before', function () { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', $$deleted: true }) + '\n' + + model.serialize({ _id: '3', today: now }) + const treatedData = d.persistence.treatRawData(rawData).data + + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '3', today: now }) + }) + + it('If a doc contains $$deleted: true, no error is thrown if the doc wasnt in the list before (with stream)', async () => { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ _id: '2', $$deleted: true }) + '\n' + + model.serialize({ _id: '3', today: now }) + const stream = new Readable() + + stream.push(rawData) + stream.push(null) + + const result = await d.persistence.treatRawStreamAsync(stream) + const treatedData = result.data + treatedData.sort(function (a, b) { return a._id - b._id }) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '3', today: now }) + }) + + it('If a doc contains $$indexCreated, no error is thrown during treatRawData and we can get the index options', function () { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ $$indexCreated: { fieldName: 'test', unique: true } }) + '\n' + + model.serialize({ _id: '3', today: now }) + const treatedData = d.persistence.treatRawData(rawData).data + const indexes = d.persistence.treatRawData(rawData).indexes + + assert.equal(Object.keys(indexes).length, 1) + assert.deepEqual(indexes.test, { fieldName: 'test', unique: true }) + + treatedData.sort((a, b) => a._id - b._id) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '3', today: now }) + }) + + it('If a doc contains $$indexCreated, no error is thrown during treatRawData and we can get the index options (with stream)', async () => { + const now = new Date() + const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + + model.serialize({ $$indexCreated: { fieldName: 'test', unique: true } }) + '\n' + + model.serialize({ _id: '3', today: now }) + const stream = new Readable() + + stream.push(rawData) + stream.push(null) + + const result = await d.persistence.treatRawStreamAsync(stream) + const treatedData = result.data + const indexes = result.indexes + assert.equal(Object.keys(indexes).length, 1) + assert.deepEqual(indexes.test, { fieldName: 'test', unique: true }) + + treatedData.sort(function (a, b) { return a._id - b._id }) + assert.equal(treatedData.length, 2) + assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) + assert.deepEqual(treatedData[1], { _id: '3', today: now }) + }) + + it('Compact database on load', async () => { + await d.insertAsync({ a: 2 }) + await d.insertAsync({ a: 4 }) + await d.removeAsync({ a: 2 }, {}) + // Here, the underlying file is 3 lines long for only one document + const data = (await fs.readFile(d.filename, 'utf8')).split('\n') + let filledCount = 0 + + data.forEach(item => { if (item.length > 0) { filledCount += 1 } }) + assert.equal(filledCount, 3) + + await d.loadDatabaseAsync() + + // Now, the file has been compacted and is only 1 line long + const data2 = (await fs.readFile(d.filename, 'utf8')).split('\n') + filledCount = 0 + + data2.forEach(function (item) { if (item.length > 0) { filledCount += 1 } }) + assert.equal(filledCount, 1) + }) + + it('Calling loadDatabase after the data was modified doesnt change its contents', async () => { + await d.loadDatabaseAsync() + await d.insertAsync({ a: 1 }) + await d.insertAsync({ a: 2 }) + const data = d.getAllData() + const doc1 = data.find(doc => doc.a === 1) + const doc2 = data.find(doc => doc.a === 2) + assert.equal(data.length, 2) + assert.equal(doc1.a, 1) + assert.equal(doc2.a, 2) + + await d.loadDatabaseAsync() + const dataReloaded = d.getAllData() + const doc1Reloaded = dataReloaded.find(doc => doc.a === 1) + const doc2Reloaded = dataReloaded.find(doc => doc.a === 2) + assert.equal(data.length, 2) + assert.equal(doc1Reloaded.a, 1) + assert.equal(doc2Reloaded.a, 2) + }) + + it('Calling loadDatabase after the datafile was removed will reset the database', async () => { + await d.loadDatabaseAsync() + await d.insertAsync({ a: 1 }) + await d.insertAsync({ a: 2 }) + const data = d.getAllData() + const doc1 = data.find(doc => doc.a === 1) + const doc2 = data.find(doc => doc.a === 2) + assert.equal(data.length, 2) + assert.equal(doc1.a, 1) + assert.equal(doc2.a, 2) + + await fs.unlink(testDb) + await d.loadDatabaseAsync() + assert.equal(d.getAllData().length, 0) + }) + + it('Calling loadDatabase after the datafile was modified loads the new data', async () => { + await d.loadDatabaseAsync() + await d.insertAsync({ a: 1 }) + await d.insertAsync({ a: 2 }) + const data = d.getAllData() + const doc1 = data.find(doc => doc.a === 1) + const doc2 = data.find(doc => doc.a === 2) + assert.equal(data.length, 2) + assert.equal(doc1.a, 1) + assert.equal(doc2.a, 2) + + await fs.writeFile(testDb, '{"a":3,"_id":"aaa"}', 'utf8') + await d.loadDatabaseAsync() + const dataReloaded = d.getAllData() + const doc1Reloaded = dataReloaded.find(function (doc) { return doc.a === 1 }) + const doc2Reloaded = dataReloaded.find(function (doc) { return doc.a === 2 }) + const doc3Reloaded = dataReloaded.find(function (doc) { return doc.a === 3 }) + assert.equal(dataReloaded.length, 1) + assert.equal(doc3Reloaded.a, 3) + assert.equal(doc1Reloaded, undefined) + assert.equal(doc2Reloaded, undefined) + }) + + it('When treating raw data, refuse to proceed if too much data is corrupt, to avoid data loss', async () => { + const corruptTestFilename = 'workspace/corruptTest.db' + const fakeData = '{"_id":"one","hello":"world"}\n' + 'Some corrupt data\n' + '{"_id":"two","hello":"earth"}\n' + '{"_id":"three","hello":"you"}\n' + let d + await fs.writeFile(corruptTestFilename, fakeData, 'utf8') + + // Default corruptAlertThreshold + d = new Datastore({ filename: corruptTestFilename }) + await assert.rejects(() => d.loadDatabaseAsync()) + + await fs.writeFile(corruptTestFilename, fakeData, 'utf8') + d = new Datastore({ filename: corruptTestFilename, corruptAlertThreshold: 1 }) + await d.loadDatabaseAsync() + await fs.writeFile(corruptTestFilename, fakeData, 'utf8') + d = new Datastore({ filename: corruptTestFilename, corruptAlertThreshold: 0 }) + await assert.rejects(() => d.loadDatabaseAsync()) + }) + + it('Can listen to compaction events', async () => { + const compacted = new Promise(resolve => { + d.once('compaction.done', function () { + resolve() + }) + }) + await d.persistence.compactDatafileAsync() + await compacted // should already be resolved when the function returns, but still awaiting for it + }) + + describe('Serialization hooks', async () => { + const as = s => `before_${s}_after` + const bd = s => s.substring(7, s.length - 6) + + it('Declaring only one hook will throw an exception to prevent data loss', async () => { + const hookTestFilename = 'workspace/hookTest.db' + await storage.ensureFileDoesntExistAsync(hookTestFilename) + await fs.writeFile(hookTestFilename, 'Some content', 'utf8') + assert.throws(() => { + // eslint-disable-next-line no-new + new Datastore({ + filename: hookTestFilename, + autoload: true, + afterSerialization: as + }) + }) + // Data file left untouched + assert.equal(await fs.readFile(hookTestFilename, 'utf8'), 'Some content') + assert.throws(() => { + // eslint-disable-next-line no-new + new Datastore({ + filename: hookTestFilename, + autoload: true, + beforeDeserialization: bd + }) + }) + + // Data file left untouched + assert.equal(await fs.readFile(hookTestFilename, 'utf8'), 'Some content') + }) + + it('Declaring two hooks that are not reverse of one another will cause an exception to prevent data loss', async () => { + const hookTestFilename = 'workspace/hookTest.db' + await storage.ensureFileDoesntExistAsync(hookTestFilename) + await fs.writeFile(hookTestFilename, 'Some content', 'utf8') + assert.throws(() => { + // eslint-disable-next-line no-new + new Datastore({ + filename: hookTestFilename, + autoload: true, + afterSerialization: as, + beforeDeserialization: function (s) { return s } + }) + }) + + // Data file left untouched + assert.equal(await fs.readFile(hookTestFilename, 'utf8'), 'Some content') + }) + + it('A serialization hook can be used to transform data before writing new state to disk', async () => { + const hookTestFilename = 'workspace/hookTest.db' + await storage.ensureFileDoesntExistAsync(hookTestFilename) + const d = new Datastore({ + filename: hookTestFilename, + autoload: true, + afterSerialization: as, + beforeDeserialization: bd + }) + + await d.insertAsync({ hello: 'world' }) + const data = (await fs.readFile(hookTestFilename, 'utf8')).split('\n') + let doc0 = bd(data[0]) + + assert.equal(data.length, 2) + + assert.equal(data[0].substring(0, 7), 'before_') + assert.equal(data[0].substring(data[0].length - 6), '_after') + + doc0 = model.deserialize(doc0) + assert.equal(Object.keys(doc0).length, 2) + assert.equal(doc0.hello, 'world') + + await d.insertAsync({ p: 'Mars' }) + const data2 = (await fs.readFile(hookTestFilename, 'utf8')).split('\n') + doc0 = bd(data2[0]) + let doc1 = bd(data2[1]) + + assert.equal(data2.length, 3) + + assert.equal(data2[0].substring(0, 7), 'before_') + assert.equal(data2[0].substring(data2[0].length - 6), '_after') + assert.equal(data2[1].substring(0, 7), 'before_') + assert.equal(data2[1].substring(data2[1].length - 6), '_after') + + doc0 = model.deserialize(doc0) + assert.equal(Object.keys(doc0).length, 2) + assert.equal(doc0.hello, 'world') + + doc1 = model.deserialize(doc1) + assert.equal(Object.keys(doc1).length, 2) + assert.equal(doc1.p, 'Mars') + + await d.ensureIndexAsync({ fieldName: 'idefix' }) + const data3 = (await fs.readFile(hookTestFilename, 'utf8')).split('\n') + doc0 = bd(data3[0]) + doc1 = bd(data3[1]) + let idx = bd(data3[2]) + + assert.equal(data3.length, 4) + + assert.equal(data3[0].substring(0, 7), 'before_') + assert.equal(data3[0].substring(data3[0].length - 6), '_after') + assert.equal(data3[1].substring(0, 7), 'before_') + assert.equal(data3[1].substring(data3[1].length - 6), '_after') + + doc0 = model.deserialize(doc0) + assert.equal(Object.keys(doc0).length, 2) + assert.equal(doc0.hello, 'world') + + doc1 = model.deserialize(doc1) + assert.equal(Object.keys(doc1).length, 2) + assert.equal(doc1.p, 'Mars') + + idx = model.deserialize(idx) + assert.deepEqual(idx, { $$indexCreated: { fieldName: 'idefix' } }) + }) + + it('Use serialization hook when persisting cached database or compacting', async () => { + const hookTestFilename = 'workspace/hookTest.db' + await storage.ensureFileDoesntExistAsync(hookTestFilename) + const d = new Datastore({ + filename: hookTestFilename, + autoload: true, + afterSerialization: as, + beforeDeserialization: bd + }) + + await d.insertAsync({ hello: 'world' }) + await d.updateAsync({ hello: 'world' }, { $set: { hello: 'earth' } }, {}) + await d.ensureIndexAsync({ fieldName: 'idefix' }) + const data = (await fs.readFile(hookTestFilename, 'utf8')).split('\n') + let doc0 = bd(data[0]) + let doc1 = bd(data[1]) + let idx = bd(data[2]) + + assert.equal(data.length, 4) + + doc0 = model.deserialize(doc0) + assert.equal(Object.keys(doc0).length, 2) + assert.equal(doc0.hello, 'world') + + doc1 = model.deserialize(doc1) + assert.equal(Object.keys(doc1).length, 2) + assert.equal(doc1.hello, 'earth') + + assert.equal(doc0._id, doc1._id) + const _id = doc0._id + + idx = model.deserialize(idx) + assert.deepEqual(idx, { $$indexCreated: { fieldName: 'idefix' } }) + + await d.persistence.persistCachedDatabaseAsync() + const data2 = (await fs.readFile(hookTestFilename, 'utf8')).split('\n') + doc0 = bd(data2[0]) + idx = bd(data2[1]) + + assert.equal(data2.length, 3) + + doc0 = model.deserialize(doc0) + assert.equal(Object.keys(doc0).length, 2) + assert.equal(doc0.hello, 'earth') + + assert.equal(doc0._id, _id) + + idx = model.deserialize(idx) + assert.deepEqual(idx, { $$indexCreated: { fieldName: 'idefix', unique: false, sparse: false } }) + }) + + it('Deserialization hook is correctly used when loading data', async () => { + const hookTestFilename = 'workspace/hookTest.db' + await storage.ensureFileDoesntExistAsync(hookTestFilename) + const d = new Datastore({ + filename: hookTestFilename, + autoload: true, + afterSerialization: as, + beforeDeserialization: bd + }) + + const doc = await d.insertAsync({ hello: 'world' }) + const _id = doc._id + await d.insertAsync({ yo: 'ya' }) + await d.updateAsync({ hello: 'world' }, { $set: { hello: 'earth' } }, {}) + await d.removeAsync({ yo: 'ya' }, {}) + await d.ensureIndexAsync({ fieldName: 'idefix' }) + const data = (await fs.readFile(hookTestFilename, 'utf8')).split('\n') + + assert.equal(data.length, 6) + + // Everything is deserialized correctly, including deletes and indexes + const d2 = new Datastore({ + filename: hookTestFilename, + afterSerialization: as, + beforeDeserialization: bd + }) + await d2.loadDatabaseAsync() + const docs = await d2.findAsync({}) + assert.equal(docs.length, 1) + assert.equal(docs[0].hello, 'earth') + assert.equal(docs[0]._id, _id) + + assert.equal(Object.keys(d2.indexes).length, 2) + assert.notEqual(Object.keys(d2.indexes).indexOf('idefix'), -1) + }) + }) // ==== End of 'Serialization hooks' ==== // + + describe('Prevent dataloss when persisting data', function () { + it('Creating a datastore with in memory as true and a bad filename wont cause an error', () => { + // eslint-disable-next-line no-new + new Datastore({ filename: 'workspace/bad.db~', inMemoryOnly: true }) + }) + + it('Creating a persistent datastore with a bad filename will cause an error', function () { + assert.throws(() => { + // eslint-disable-next-line no-new + new Datastore({ filename: 'workspace/bad.db~' }) + }) + }) + + it('If no file stat, ensureDatafileIntegrity creates an empty datafile', async () => { + const p = new Persistence({ db: { inMemoryOnly: false, filename: 'workspace/it.db' } }) + if (await exists('workspace/it.db')) await fs.unlink('workspace/it.db') + if (await exists('workspace/it.db~')) await fs.unlink('workspace/it.db~') + + assert.equal(await exists('workspace/it.db'), false) + assert.equal(await exists('workspace/it.db~'), false) + + await storage.ensureDatafileIntegrityAsync(p.filename) + + assert.equal(await exists('workspace/it.db'), true) + assert.equal(await exists('workspace/it.db~'), false) + + assert.equal(await fs.readFile('workspace/it.db', 'utf8'), '') + }) + + it('If only datafile stat, ensureDatafileIntegrity will use it', async () => { + const p = new Persistence({ db: { inMemoryOnly: false, filename: 'workspace/it.db' } }) + + if (await exists('workspace/it.db')) { await fs.unlink('workspace/it.db') } + if (await exists('workspace/it.db~')) { await fs.unlink('workspace/it.db~') } + + await fs.writeFile('workspace/it.db', 'something', 'utf8') + + assert.equal(await exists('workspace/it.db'), true) + assert.equal(await exists('workspace/it.db~'), false) + + await storage.ensureDatafileIntegrityAsync(p.filename) + + assert.equal(await exists('workspace/it.db'), true) + assert.equal(await exists('workspace/it.db~'), false) + + assert.equal(await fs.readFile('workspace/it.db', 'utf8'), 'something') + }) + + it('If temp datafile stat and datafile doesnt, ensureDatafileIntegrity will use it (cannot happen except upon first use)', async () => { + const p = new Persistence({ db: { inMemoryOnly: false, filename: 'workspace/it.db' } }) + + if (await exists('workspace/it.db')) { await fs.unlink('workspace/it.db') } + if (await exists('workspace/it.db~')) { await fs.unlink('workspace/it.db~~') } + + await fs.writeFile('workspace/it.db~', 'something', 'utf8') + + assert.equal(await exists('workspace/it.db'), false) + assert.equal(await exists('workspace/it.db~'), true) + + await storage.ensureDatafileIntegrityAsync(p.filename) + + assert.equal(await exists('workspace/it.db'), true) + assert.equal(await exists('workspace/it.db~'), false) + + assert.equal(await fs.readFile('workspace/it.db', 'utf8'), 'something') + }) + + // Technically it could also mean the write was successful but the rename wasn't, but there is in any case no guarantee that the data in the temp file is whole so we have to discard the whole file + it('If both temp and current datafiles exist, ensureDatafileIntegrity will use the datafile, as it means that the write of the temp file failed', async () => { + const theDb = new Datastore({ filename: 'workspace/it.db' }) + + if (await exists('workspace/it.db')) { await fs.unlink('workspace/it.db') } + if (await exists('workspace/it.db~')) { await fs.unlink('workspace/it.db~') } + + await fs.writeFile('workspace/it.db', '{"_id":"0","hello":"world"}', 'utf8') + await fs.writeFile('workspace/it.db~', '{"_id":"0","hello":"other"}', 'utf8') + + assert.equal(await exists('workspace/it.db'), true) + assert.equal(await exists('workspace/it.db~'), true) + + await storage.ensureDatafileIntegrityAsync(theDb.persistence.filename) + + assert.equal(await exists('workspace/it.db'), true) + assert.equal(await exists('workspace/it.db~'), true) + + assert.equal(await fs.readFile('workspace/it.db', 'utf8'), '{"_id":"0","hello":"world"}') + + await theDb.loadDatabaseAsync() + const docs = await theDb.findAsync({}) + assert.equal(docs.length, 1) + assert.equal(docs[0].hello, 'world') + assert.equal(await exists('workspace/it.db'), true) + assert.equal(await exists('workspace/it.db~'), false) + }) + + it('persistCachedDatabase should update the contents of the datafile and leave a clean state', async () => { + await d.insertAsync({ hello: 'world' }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + + if (await exists(testDb)) { await fs.unlink(testDb) } + if (await exists(testDb + '~')) { await fs.unlink(testDb + '~') } + assert.equal(await exists(testDb), false) + + await fs.writeFile(testDb + '~', 'something', 'utf8') + assert.equal(await exists(testDb + '~'), true) + + await d.persistence.persistCachedDatabaseAsync() + const contents = await fs.readFile(testDb, 'utf8') + assert.equal(await exists(testDb), true) + assert.equal(await exists(testDb + '~'), false) + if (!contents.match(/^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/)) { + throw new Error('Datafile contents not as expected') + } + }) + + it('After a persistCachedDatabase, there should be no temp or old filename', async () => { + await d.insertAsync({ hello: 'world' }) + const docs = await d.findAsync({}) + assert.equal(docs.length, 1) + + if (await exists(testDb)) { await fs.unlink(testDb) } + if (await exists(testDb + '~')) { await fs.unlink(testDb + '~') } + assert.equal(await exists(testDb), false) + assert.equal(await exists(testDb + '~'), false) + + await fs.writeFile(testDb + '~', 'bloup', 'utf8') + assert.equal(await exists(testDb + '~'), true) + + await d.persistence.persistCachedDatabaseAsync() + const contents = await fs.readFile(testDb, 'utf8') + assert.equal(await exists(testDb), true) + assert.equal(await exists(testDb + '~'), false) + if (!contents.match(/^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/)) { + throw new Error('Datafile contents not as expected') + } + }) + + it('persistCachedDatabase should update the contents of the datafile and leave a clean state even if there is a temp datafile', async () => { + await d.insertAsync({ hello: 'world' }) + const docs = await d.find({}) + assert.equal(docs.length, 1) + + if (await exists(testDb)) { await fs.unlink(testDb) } + await fs.writeFile(testDb + '~', 'blabla', 'utf8') + assert.equal(await exists(testDb), false) + assert.equal(await exists(testDb + '~'), true) + + await d.persistence.persistCachedDatabaseAsync() + const contents = await fs.readFile(testDb, 'utf8') + assert.equal(await exists(testDb), true) + assert.equal(await exists(testDb + '~'), false) + if (!contents.match(/^{"hello":"world","_id":"[0-9a-zA-Z]{16}"}\n$/)) { + throw new Error('Datafile contents not as expected') + } + }) + + it('persistCachedDatabase should update the contents of the datafile and leave a clean state even if there is a temp datafile', async () => { + const dbFile = 'workspace/test2.db' + + if (await exists(dbFile)) { await fs.unlink(dbFile) } + if (await exists(dbFile + '~')) { await fs.unlink(dbFile + '~') } + + const theDb = new Datastore({ filename: dbFile }) + + await theDb.loadDatabaseAsync() + const contents = await fs.readFile(dbFile, 'utf8') + assert.equal(await exists(dbFile), true) + assert.equal(await exists(dbFile + '~'), false) + if (contents !== '') { + throw new Error('Datafile contents not as expected') + } + }) + + it('Persistence works as expected when everything goes fine', async () => { + const dbFile = 'workspace/test2.db' + + await storage.ensureFileDoesntExistAsync(dbFile) + await storage.ensureFileDoesntExistAsync(dbFile + '~') + + const theDb = new Datastore({ filename: dbFile }) + await theDb.loadDatabaseAsync() + const docs = await theDb.find({}) + assert.equal(docs.length, 0) + + const doc1 = await theDb.insertAsync({ a: 'hello' }) + const doc2 = await theDb.insertAsync({ a: 'world' }) + + const docs2 = await theDb.findAsync({}) + assert.equal(docs2.length, 2) + assert.equal(docs2.find(item => item._id === doc1._id).a, 'hello') + assert.equal(docs2.find(item => item._id === doc2._id).a, 'world') + + await theDb.loadDatabaseAsync() + + const docs3 = await theDb.findAsync({}) + assert.equal(docs3.length, 2) + assert.equal(docs3.find(item => item._id === doc1._id).a, 'hello') + assert.equal(docs3.find(item => item._id === doc2._id).a, 'world') + assert.equal(await exists(dbFile), true) + assert.equal(await exists(dbFile + '~'), false) + + const theDb2 = new Datastore({ filename: dbFile }) + await theDb2.loadDatabaseAsync() + // No change in second db + const docs4 = await theDb2.findAsync({}) + assert.equal(docs4.length, 2) + assert.equal(docs4.find(item => item._id === doc1._id).a, 'hello') + assert.equal(docs4.find(item => item._id === doc2._id).a, 'world') + + assert.equal(await exists(dbFile), true) + assert.equal(await exists(dbFile + '~'), false) + }) + + // The child process will load the database with the given datafile, but the fs.writeFile function + // is rewritten to crash the process before it finished (after 5000 bytes), to ensure data was not lost + it('If system crashes during a loadDatabase, the former version is not lost', async () => { + const N = 500 + let toWrite = '' + let i + let docI + + // Ensuring the state is clean + if (await exists('workspace/lac.db')) { await fs.unlink('workspace/lac.db') } + if (await exists('workspace/lac.db~')) { await fs.unlink('workspace/lac.db~') } + + // Creating a db file with 150k records (a bit long to load) + for (i = 0; i < N; i += 1) { + toWrite += model.serialize({ _id: 'anid_' + i, hello: 'world' }) + '\n' + } + await fs.writeFile('workspace/lac.db', toWrite, 'utf8') + + const datafileLength = (await fs.readFile('workspace/lac.db', 'utf8')).length + + // Loading it in a separate process that we will crash before finishing the loadDatabase + fork('test_lac/loadAndCrash.test').on('exit', async function (code) { + assert.equal(code, 1) // See test_lac/loadAndCrash.test.js + + assert.equal(await exists('workspace/lac.db'), true) + assert.equal(await exists('workspace/lac.db~'), true) + assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) + assert.equal((await fs.readFile('workspace/lac.db~', 'utf8')).length, 5000) + + // Reload database without a crash, check that no data was lost and fs state is clean (no temp file) + const db = new Datastore({ filename: 'workspace/lac.db' }) + await db.loadDatabaseAsync() + assert.equal(await exists('workspace/lac.db'), true) + assert.equal(await exists('workspace/lac.db~'), false) + assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) + + const docs = await db.findAsync({}) + assert.equal(docs.length, N) + for (i = 0; i < N; i += 1) { + docI = docs.find(d => d._id === 'anid_' + i) + assert.notEqual(docI, undefined) + assert.deepEqual({ hello: 'world', _id: 'anid_' + i }, docI) + } + }) + + // Not run on Windows as there is no clean way to set maximum file descriptors. Not an issue as the code itself is tested. + it('Cannot cause EMFILE errors by opening too many file descriptors', async function () { + this.timeout(5000) + if (process.platform === 'win32' || process.platform === 'win64') { return } + const { stdout } = await promisify(execFile)('test_lac/openFdsLaunch.sh') + // The subprocess will not output anything to stdout unless part of the test fails + if (stdout.length !== 0) throw new Error(stdout) + }) + }) + }) // ==== End of 'Prevent dataloss when persisting data' ==== + + describe('ensureFileDoesntExist', function () { + it('Doesnt do anything if file already doesnt exist', async () => { + await storage.ensureFileDoesntExistAsync('workspace/nonexisting') + assert.equal(await exists('workspace/nonexisting'), false) + }) + + it('Deletes file if it stat', async () => { + await fs.writeFile('workspace/existing', 'hello world', 'utf8') + assert.equal(await exists('workspace/existing'), true) + + await storage.ensureFileDoesntExistAsync('workspace/existing') + assert.equal(await exists('workspace/existing'), false) + }) + }) // ==== End of 'ensureFileDoesntExist' ==== +}) diff --git a/test/utils.test.js b/test/utils.test.js index 7d71403..8b0497d 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -1,4 +1,5 @@ const { callbackify, promisify } = require('util') +const { promises: fs, constants: fsConstants } = require('fs') const waterfallAsync = async tasks => { for (const task of tasks) { @@ -30,9 +31,11 @@ const whilst = callbackify(whilstAsync) const wait = delay => new Promise(resolve => { setTimeout(resolve, delay) }) +const exists = path => fs.access(path, fsConstants.FS_OK).then(() => true, () => false) module.exports.whilst = whilst module.exports.apply = apply module.exports.waterfall = waterfall module.exports.each = each module.exports.wait = wait +module.exports.exists = exists From db2da8a1e064ffa5513f4f924b6b79edcfd20679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 16 Nov 2021 17:41:39 +0100 Subject: [PATCH 29/65] lint --- test/cursor.async.test.js | 2 +- test/executor.async.test.js | 2 +- test/persistence.async.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/cursor.async.test.js b/test/cursor.async.test.js index 22b00bc..f4c3b4c 100755 --- a/test/cursor.async.test.js +++ b/test/cursor.async.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const testDb = 'workspace/test.db' -const { promises: fs, constants: fsConstants } = require('fs') +const { promises: fs } = require('fs') const assert = require('assert').strict const path = require('path') const Datastore = require('../lib/datastore') diff --git a/test/executor.async.test.js b/test/executor.async.test.js index 9bae34f..d835400 100755 --- a/test/executor.async.test.js +++ b/test/executor.async.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const testDb = 'workspace/test.db' -const { promises: fs, constants: fsConstants } = require('fs') +const { promises: fs } = require('fs') const assert = require('assert').strict const path = require('path') const Datastore = require('../lib/datastore') diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index 472e2ff..de70922 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const testDb = 'workspace/test.db' -const { promises: fs, constants: fsConstants } = require('fs') +const { promises: fs } = require('fs') const path = require('path') const assert = require('assert').strict const { exists } = require('./utils.test.js') From a2528ee45e49385642057022231310000828c783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Wed, 22 Dec 2021 19:02:37 +0100 Subject: [PATCH 30/65] jsdoc --- .gitignore | 1 + CHANGELOG.md | 16 + README.md | 4 +- jsdoc.conf.js | 11 + lib/cursor.js | 21 +- lib/datastore.js | 615 +- lib/indexes.js | 70 +- lib/persistence.js | 49 +- lib/storage.js | 3 +- package-lock.json | 11572 ++++++++++++++----------------- package.json | 6 +- test/db.async.test.js | 18 +- test/db.test.js | 20 +- test/persistence.async.test.js | 2 +- 14 files changed, 6060 insertions(+), 6348 deletions(-) create mode 100644 jsdoc.conf.js diff --git a/.gitignore b/.gitignore index e7cc9b2..add07a4 100755 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ browser-version/node_modules browser-version/out test-results +docs diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e6adc6..013c8b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.0.0] - Unreleased +### Added +- Added an async interface for all functions +- The JSDoc is now much more exhaustive + +### Changed +- All the functions are now async at the core, and a fully retro-compatible callback-ified version is exposed. +- The executor is now much simpler and Promise-based. A retro-compatible shim is still exposed, with the exception that it no longer handles [`arguments`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/arguments) as the arguments Array. If you use the executor directly, you'll need to convert it to a proper Array beforehand. +- As a result, the `async` dependency has been removed completely. To avoid rewriting the tests, shims of some functions of `async` are defined in an utilities file used exclusively in the tests. +- The `Datastore#update`'s callback has its signature slightly changed. The `upsert` flag is always defined either at `true` or `false` but not `null` nor `undefined`, and `affectedDocuments` is `null` when none is given rather than `undefined` (except when there is an error of course). + +### Deprecated +- Formally deprecate giving a string as argument to the `Datastore` constructor +- Formally deprecate using `Persistence.getNWAppFilename()` and `options.nodeWebkitAppName` + + ## [2.2.1] - 2022-01-18 ### Changed - [#20](https://github.com/seald/nedb/pull/20) storage.js: check fsync capability from return code rather than using process.platform heuristics (Thanks [@bitmeal](https://github.com/bitmeal)). diff --git a/README.md b/README.md index 762ac1d..02d614a 100755 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ and maintain it for the needs of [Seald](https://www.seald.io). browsers, 100% JavaScript, no binary dependency**. API is a subset of MongoDB's and it's [plenty fast](#speed). -## Installation, tests +## Installation -Module name on npm is `@seald-io/nedb`. +Module name on npm is [`@seald-io/nedb`](https://www.npmjs.com/package/@seald-io/nedb). ``` npm install @seald-io/nedb diff --git a/jsdoc.conf.js b/jsdoc.conf.js new file mode 100644 index 0000000..db450cd --- /dev/null +++ b/jsdoc.conf.js @@ -0,0 +1,11 @@ +'use strict' + +module.exports = { + plugins: ['plugins/markdown'], + source: { + include: ['./lib'] + }, + opts: { + destination: './docs' + } +} diff --git a/lib/cursor.js b/lib/cursor.js index 2c318ca..603b844 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -4,12 +4,29 @@ const model = require('./model.js') const { callbackify, promisify } = require('util') +/** + * @callback Cursor~execFn + * @param {?Error} err + * @param {?document[]|?document} res + */ + +/** + * @callback Cursor~execFnAsync + * @param {?document[]|?document} res + * @return {Promise} + */ + +/** + * @extends Promise + */ class Cursor { /** * Create a new cursor for this collection * @param {Datastore} db - The datastore this cursor is bound to - * @param {Query} query - The query this cursor will operate on - * @param {Function} execFn - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove + * @param {query} query - The query this cursor will operate on + * @param {Cursor~execFn|Cursor~execFnAsync} [execFn] - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove + * @param {boolean} [async = false] If true, specifies that the `execFn` is of type {@link Cursor~execFnAsync} rather than {@link Cursor~execFn}. + * */ constructor (db, query, execFn, async = false) { this.db = db diff --git a/lib/datastore.js b/lib/datastore.js index a0cb98f..a7f7319 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -1,5 +1,5 @@ const { EventEmitter } = require('events') -const { callbackify } = require('util') +const { callbackify, deprecate } = require('util') const Cursor = require('./cursor.js') const customUtils = require('./customUtils.js') const Executor = require('./executor.js') @@ -8,22 +8,147 @@ const model = require('./model.js') const Persistence = require('./persistence.js') const { isDate } = require('./utils.js') +/** + * Compaction event. Happens when the Datastore's Persistence has been compacted. + * It happens when calling `datastore.persistence.compactDatafile`, which is called periodically if you have called + * `datastore.persistence.setAutocompactionInterval`. + * + * @event Datastore#event:"compaction.done" + * @type {undefined} + */ + +/** + * String comparison function. + * ``` + * if (a < b) return -1 + * if (a > b) return 1 + * return 0 + * ``` + * @callback compareStrings + * @param {string} a + * @param {string} b + * @return {number} + */ + +/** + * Generic document in NeDB. + * It consists of an Object with anything you want inside. + * @typedef document + * @property {?string} _id Internal `_id` of the document, which can be `null` at some points (when not inserted yet + * for example). + * @type {object.} + */ + +/** + * Nedb query. + * + * Each key of a query references a field name, which can use the dot-notation to reference subfields inside nested + * documents, arrays, arrays of subdocuments and to match a specific element of an array. + * + * Each value of a query can be one of the following: + * - `string`: matches all documents which have this string as value for the referenced field name + * - `number`: matches all documents which have this number as value for the referenced field name + * - `Regexp`: matches all documents which have a value that matches the given `Regexp` for the referenced field name + * - `object`: matches all documents which have this object as deep-value for the referenced field name + * - Comparison operators: the syntax is `{ field: { $op: value } }` where `$op` is any comparison operator: + * - `$lt`, `$lte`: less than, less than or equal + * - `$gt`, `$gte`: greater than, greater than or equal + * - `$in`: member of. `value` must be an array of values + * - `$ne`, `$nin`: not equal, not a member of + * - `$stat`: checks whether the document posses the property `field`. `value` should be true or false + * - `$regex`: checks whether a string is matched by the regular expression. Contrary to MongoDB, the use of + * `$options` with `$regex` is not supported, because it doesn't give you more power than regex flags. Basic + * queries are more readable so only use the `$regex` operator when you need to use another operator with it + * - `$size`: if the referenced filed is an Array, matches on the size of the array + * - `$elemMatch`: matches if at least one array element matches the sub-query entirely + * - Logical operators: You can combine queries using logical operators: + * - For `$or` and `$and`, the syntax is `{ $op: [query1, query2, ...] }`. + * - For `$not`, the syntax is `{ $not: query }` + * - For `$where`, the syntax is: + * ``` + * { $where: function () { + * // object is 'this' + * // return a boolean + * } } + * ``` + * @typedef query + * @type {object.} + */ + +/** + * Nedb projection. + * + * You can give `find` and `findOne` an optional second argument, `projections`. + * The syntax is the same as MongoDB: `{ a: 1, b: 1 }` to return only the `a` + * and `b` fields, `{ a: 0, b: 0 }` to omit these two fields. You cannot use both + * modes at the time, except for `_id` which is by default always returned and + * which you can choose to omit. You can project on nested documents. + * + * To reference subfields, you can use the dot-notation. + * + * @typedef projection + * @type {object.} + */ + +/** + * The `beforeDeserialization`and `afterDeserialization` callbacks should + * @callback serializationHook + * @param {string} x + * @return {string} + */ + +/** + * The `Datastore` class is the main class of NeDB. + * @extends EventEmitter + */ class Datastore extends EventEmitter { /** - * Create a new collection - * @param {String} [options.filename] Optional, datastore will be in-memory only if not provided - * @param {Boolean} [options.timestampData] Optional, defaults to false. If set to true, createdAt and updatedAt will be created and populated automatically (if not specified by user) - * @param {Boolean} [options.inMemoryOnly] Optional, defaults to false - * @param {String} [options.nodeWebkitAppName] Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion) - * @param {Boolean} [options.autoload] Optional, defaults to false - * @param {Function} [options.onload] Optional, if autoload is used this will be called after the load database with the error object as parameter. If you don't pass it the error will be thrown - * @param {Function} [options.beforeDeserialization] Optional, serialization hooks - * @param {Function} [options.afterSerialization] Optional, serialization hooks - * @param {Number} [options.corruptAlertThreshold] Optional, threshold after which an alert is thrown if too much data is corrupt - * @param {Function} [options.compareStrings] Optional, string comparison function that overrides default for sorting + * Create a new collection, either persistent or in-memory. * - * Event Emitter - Events - * * compaction.done - Fired whenever a compaction operation was finished + * If you use a persistent datastore without the `autoload` option, you need to call `loadDatabase` manually. This + * function fetches the data from datafile and prepares the database. **Don't forget it!** If you use a persistent + * datastore, no command (insert, find, update, remove) will be executed before `loadDatabase` is called, so make sure + * to call it yourself or use the `autoload` option. + * + * @param {object|string} options Can be an object or a string. If options is a string, the behavior is the same as in + * v0.6: it will be interpreted as `options.filename`. **Giving a string is deprecated, and will be removed in the + * next major version.** + * @param {string} [options.filename = null] Path to the file where the data is persisted. If left blank, the datastore is + * automatically considered in-memory only. It cannot end with a `~` which is used in the temporary files NeDB uses to + * perform crash-safe writes. + * @param {boolean} [options.inMemoryOnly = false] If set to true, no data will be written in storage. + * @param {boolean} [options.timestampData = false] If set to true, createdAt and updatedAt will be created and + * populated automatically (if not specified by user) + * @param {boolean} [options.autoload = false] If used, the database will automatically be loaded from the datafile + * upon creation (you don't need to call `loadDatabase`). Any command issued before load is finished is buffered and + * will be executed when load is done. When autoloading is done, you can either use the `onload` callback, or you can + * use `this.autoloadPromise` which resolves (or rejects) when autloading is done. + * @param {function} [options.onload] If you use autoloading, this is the handler called after the `loadDatabase`. It + * takes one `error` argument. If you use autoloading without specifying this handler, and an error happens during + * load, an error will be thrown. + * @param {function} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and + * before it is written to disk. Can be used for example to encrypt data before writing database to disk. This + * function takes a string as parameter (one line of an NeDB data file) and outputs the transformed string, **which + * must absolutely not contain a `\n` character** (or data will be lost). + * @param {function} [options.afterSerialization] Inverse of `afterSerialization`. Make sure to include both and not + * just one, or you risk data loss. For the same reason, make sure both functions are inverses of one another. Some + * failsafe mechanisms are in place to prevent data loss if you misuse the serialization hooks: NeDB checks that never + * one is declared without the other, and checks that they are reverse of one another by testing on random strings of + * various lengths. In addition, if too much data is detected as corrupt, NeDB will refuse to start as it could mean + * you're not using the deserialization hook corresponding to the serialization hook used before. + * @param {number} [options.corruptAlertThreshold = 0.1] Between 0 and 1, defaults to 10%. NeDB will refuse to start + * if more than this percentage of the datafile is corrupt. 0 means you don't tolerate any corruption, 1 means you + * don't care. + * @param {compareStrings} [options.compareStrings] If specified, it overrides default string comparison which is not + * well adapted to non-US characters in particular accented letters. Native `localCompare` will most of the time be + * the right choice. + * @param {string} [options.nodeWebkitAppName] **Deprecated:** if you are using NeDB from whithin a Node Webkit app, + * specify its name (the same one you use in the `package.json`) in this field and the `filename` will be relative to + * the directory Node Webkit uses to store the rest of the application's data (local storage etc.). It works on Linux, + * OS X and Windows. Now that you can use `require('nw.gui').App.dataPath` in Node Webkit to get the path to the data + * directory for your application, you should not use this option anymore and it will be removed. + * + * @fires Datastore#event:"compaction.done" */ constructor (options) { super() @@ -31,18 +156,42 @@ class Datastore extends EventEmitter { // Retrocompatibility with v0.6 and before if (typeof options === 'string') { - filename = options - this.inMemoryOnly = false // Default + deprecate(() => { + filename = options + this.inMemoryOnly = false // Default + }, 'Giving a string to the Datastore constructor is deprecated and will be removed in the next version. Please use an options object with an argument \'filename\'.')() } else { options = options || {} filename = options.filename + /** + * Determines if the `Datastore` keeps data in-memory, or if it saves it in storage. Is not read after + * instanciation. + * @type {boolean} + * @private + */ this.inMemoryOnly = options.inMemoryOnly || false + /** + * Determines if the `Datastore` should autoload the database upon instantiation. Is not read after instanciation. + * @type {boolean} + * @private + */ this.autoload = options.autoload || false + /** + * Determines if the `Datastore` should add `createdAt` and `updatedAt` fields automatically if not set by the user. + * @type {boolean} + * @private + */ this.timestampData = options.timestampData || false } // Determine whether in memory or persistent if (!filename || typeof filename !== 'string' || filename.length === 0) { + /** + * If null, it means `inMemoryOnly` is `true`. The `filename` is the name given to the storage module. Is not read + * after instanciation. + * @type {?string} + * @private + */ this.filename = null this.inMemoryOnly = true } else { @@ -50,9 +199,19 @@ class Datastore extends EventEmitter { } // String comparison function + /** + * Overrides default string comparison which is not well adapted to non-US characters in particular accented + * letters. Native `localCompare` will most of the time be the right choice + * @type {compareStrings} + * @private + */ this.compareStrings = options.compareStrings // Persistence handling + /** + * The `Persistence` instance for this `Datastore`. + * @type {Persistence} + */ this.persistence = new Persistence({ db: this, nodeWebkitAppName: options.nodeWebkitAppName, @@ -63,19 +222,40 @@ class Datastore extends EventEmitter { // This new executor is ready if we don't use persistence // If we do, it will only be ready once loadDatabase is called + /** + * The `Executor` instance for this `Datastore`. It is used in all methods exposed by the `Datastore`, any `Cursor` + * produced by the `Datastore` and by `this.persistence.compactDataFile` & `this.persistence.compactDataFileAsync` + * to ensure operations are performed sequentially in the database. + * @type {Executor} + */ this.executor = new Executor() if (this.inMemoryOnly) this.executor.ready = true - // Indexed by field name, dot notation can be used - // _id is always indexed and since _ids are generated randomly the underlying - // binary is always well-balanced + /** + * Indexed by field name, dot notation can be used. + * _id is always indexed and since _ids are generated randomly the underlying binary search tree is always well-balanced + * @type {Object.} + * @private + */ this.indexes = {} this.indexes._id = new Index({ fieldName: '_id', unique: true }) + /** + * Stores the time to live (TTL) of the indexes created. The key represents the field name, the value the number of + * seconds after which data with this index field should be removed. + * @type {Object.} + * @private + */ this.ttlIndexes = {} // Queue a load of the database right away and call the onload handler // By default (no onload handler), if there is an error there, no operation will be possible so warn the user by throwing an exception if (this.autoload) { + /** + * A Promise that resolves when the autoload has finished. + * + * The onload callback is not awaited by this Promise, it is started immediately after that. + * @type {Promise} + */ this.autoloadPromise = this.loadDatabaseAsync() this.autoloadPromise .then(() => { @@ -88,18 +268,25 @@ class Datastore extends EventEmitter { } /** - * Load the database from the datafile, and trigger the execution of buffered commands if any + * Load the database from the datafile, and trigger the execution of buffered commands if any. + * @param {function} callback */ - loadDatabase (...args) { - this.executor.push({ this: this.persistence, fn: this.persistence.loadDatabase, arguments: args }, true) + loadDatabase (callback) { + this.executor.push({ this: this.persistence, fn: this.persistence.loadDatabase, arguments: [callback] }, true) } - loadDatabaseAsync (...args) { - return this.executor.pushAsync(() => this.persistence.loadDatabaseAsync(args), true) + /** + * Load the database from the datafile, and trigger the execution of buffered commands if any. + * @async + * @return {Promise} + */ + loadDatabaseAsync () { + return this.executor.pushAsync(() => this.persistence.loadDatabaseAsync(), true) } /** * Get an array of all the data in the database + * @return {document[]} */ getAllData () { return this.indexes._id.getAll() @@ -114,21 +301,41 @@ class Datastore extends EventEmitter { } } + /** + * @callback Datastore~ensureIndexCallback + * @param {?Error} err + */ + /** * Ensure an index is kept for this field. Same parameters as lib/indexes - * For now this function is synchronous, we need to test how much time it takes - * We use an async API for consistency with the rest of the code - * @param {Object} options - * @param {String} options.fieldName - * @param {Boolean} [options.unique] - * @param {Boolean} [options.sparse] - * @param {Number} [options.expireAfterSeconds] - Optional, if set this index becomes a TTL index (only works on Date fields, not arrays of Date) - * @param {Function} callback Optional callback, signature: err + * This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the + * executor. + * Previous versions said explicitly the callback was optional, it is now recommended setting one. + * @param {object} options + * @param {string} options.fieldName Name of the field to index. Use the dot notation to index a field in a nested document. + * @param {boolean} [options.unique = false] Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined. + * @param {boolean} [options.sparse = false] don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined. + * @param {number} [options.expireAfterSeconds] - if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored + * @param {Datastore~ensureIndexCallback} callback Callback, signature: err */ + // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state ensureIndex (options = {}, callback = () => {}) { callbackify(this.ensureIndexAsync.bind(this))(options, callback) } + /** + * Ensure an index is kept for this field. Same parameters as lib/indexes + * This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the + * executor. + * Previous versions said explicitly the callback was optional, it is now recommended setting one. + * @param {object} options + * @param {string} options.fieldName Name of the field to index. Use the dot notation to index a field in a nested document. + * @param {boolean} [options.unique = false] Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined. + * @param {boolean} [options.sparse = false] Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined. + * @param {number} [options.expireAfterSeconds] - If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored + * @return {Promise} + */ + // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state async ensureIndexAsync (options = {}) { if (!options.fieldName) { const err = new Error('Cannot create an index without a fieldName') @@ -151,16 +358,31 @@ class Datastore extends EventEmitter { await this.persistence.persistNewStateAsync([{ $$indexCreated: options }]) } + /** + * @callback Datastore~removeIndexCallback + * @param {?Error} err + */ + /** * Remove an index - * @param {String} fieldName - * @param {Function} callback Optional callback, signature: err + * Previous versions said explicitly the callback was optional, it is now recommended setting one. + * @param {string} fieldName Field name of the index to remove. Use the dot notation to remove an index referring to a + * field in a nested document. + * @param {Datastore~removeIndexCallback} callback Optional callback, signature: err */ // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state removeIndex (fieldName, callback = () => {}) { callbackify(this.removeIndexAsync.bind(this))(fieldName, callback) } + /** + * Remove an index + * Previous versions said explicitly the callback was optional, it is now recommended setting one. + * @param {string} fieldName Field name of the index to remove. Use the dot notation to remove an index referring to a + * field in a nested document. + * @return {Promise} + */ + // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state async removeIndexAsync (fieldName) { delete this.indexes[fieldName] @@ -169,6 +391,8 @@ class Datastore extends EventEmitter { /** * Add one or several document(s) to all indexes + * @param {document} doc + * @private */ addToIndexes (doc) { let failingIndex @@ -197,6 +421,7 @@ class Datastore extends EventEmitter { /** * Remove one or several document(s) from all indexes + * @param {document} doc */ removeFromIndexes (doc) { for (const index of Object.values(this.indexes)) { @@ -208,6 +433,10 @@ class Datastore extends EventEmitter { * Update one or several documents in all indexes * To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs * If one update violates a constraint, all changes are rolled back + * @param {document|Array.<{oldDoc: document, newDoc: document}>} oldDoc Document to update, or an `Array` of + * `{oldDoc, newDoc}` pairs. + * @param {document} [newDoc] Document to replace the oldDoc with. If the first argument is an `Array` of + * `{oldDoc, newDoc}` pairs, this second argument is ignored. */ updateIndexes (oldDoc, newDoc) { let failingIndex @@ -234,6 +463,13 @@ class Datastore extends EventEmitter { } } + /** + * Get all candidate documents matching the query, regardless of their expiry status. + * @param {query} query + * @return {document[]} + * + * @private + */ _getCandidates (query) { const indexNames = Object.keys(this.indexes) // STEP 1: get candidates list by checking indexes from most to least frequent usecase @@ -266,6 +502,12 @@ class Datastore extends EventEmitter { return this.getAllData() } + /** + * @callback Datastore~getCandidatesCallback + * @param {?Error} err + * @param {?document[]} candidates + */ + /** * Return the list of candidates for a given query * Crude implementation for now, we return the candidates given by the first usable index if any @@ -275,9 +517,12 @@ class Datastore extends EventEmitter { * * Returned candidates will be scanned to find and remove all expired documents * - * @param {Query} query - * @param {Boolean} dontExpireStaleDocs Optional, defaults to false, if true don't remove stale docs. Useful for the remove function which shouldn't be impacted by expirations - * @param {Function} callback Signature err, candidates + * @param {query} query + * @param {boolean|function} [dontExpireStaleDocs = false] If true don't remove stale docs. Useful for the remove + * function which shouldn't be impacted by expirations. If argument is not given, it is used as the callback. + * @param {Datastore~getCandidatesCallback} callback Signature err, candidates + * + * @private */ getCandidates (query, dontExpireStaleDocs, callback) { if (typeof dontExpireStaleDocs === 'function') { @@ -288,6 +533,22 @@ class Datastore extends EventEmitter { callbackify(this.getCandidatesAsync.bind(this))(query, dontExpireStaleDocs, callback) } + /** + * Return the list of candidates for a given query + * Crude implementation for now, we return the candidates given by the first usable index if any + * We try the following query types, in this order: basic match, $in match, comparison match + * One way to make it better would be to enable the use of multiple indexes if the first usable index + * returns too much data. I may do it in the future. + * + * Returned candidates will be scanned to find and remove all expired documents + * + * @param {query} query + * @param {boolean} [dontExpireStaleDocs = false] If true don't remove stale docs. Useful for the remove function + * which shouldn't be impacted by expirations. + * @return {Promise} candidates + * + * @private + */ async getCandidatesAsync (query, dontExpireStaleDocs = false) { const validDocs = [] @@ -309,11 +570,17 @@ class Datastore extends EventEmitter { return validDocs } + /** + * @callback Datastore~insertCallback + * @param {?Error} err + * @param {?document} insertedDoc + */ + /** * Insert a new document * Private Use Datastore.insert which has the same signature - * @param {Document} newDoc - * @param {Function} callback Optional callback, signature: err, insertedDoc + * @param {?document} newDoc + * @param {Datastore~insertCallback} callback Optional callback, signature: err, insertedDoc * * @private */ @@ -321,6 +588,13 @@ class Datastore extends EventEmitter { return callbackify(this._insertAsync.bind(this))(newDoc, callback) } + /** + * Insert a new document + * Private Use Datastore.insertAsync which has the same signature + * @param {document} newDoc + * @return {Promise} + * @private + */ async _insertAsync (newDoc) { const preparedDoc = this._prepareDocumentForInsertion(newDoc) this._insertInCache(preparedDoc) @@ -331,6 +605,7 @@ class Datastore extends EventEmitter { /** * Create a new _id that's not already in use + * @return {string} id * @private */ _createNewId () { @@ -343,6 +618,8 @@ class Datastore extends EventEmitter { /** * Prepare a document (or array of documents) to be inserted in a database * Meaning adds _id and timestamps if necessary on a copy of newDoc to avoid any side effect on user input + * @param {document|document[]} newDoc document, or Array of documents, to prepare + * @return {document|document[]} prepared document, or Array of prepared documents * @private */ _prepareDocumentForInsertion (newDoc) { @@ -365,6 +642,7 @@ class Datastore extends EventEmitter { /** * If newDoc is an array of documents, this will insert all documents in the cache + * @param {document|document[]} preparedDoc * @private */ _insertInCache (preparedDoc) { @@ -375,6 +653,7 @@ class Datastore extends EventEmitter { /** * If one insertion fails (e.g. because of a unique constraint), roll back all previous * inserts and throws the error + * @param {document[]} preparedDocs * @private */ _insertMultipleDocsInCache (preparedDocs) { @@ -400,18 +679,40 @@ class Datastore extends EventEmitter { } } + /** + * Insert a new document + * Private Use Datastore.insert which has the same signature + * @param {document} newDoc + * @param {Datastore~insertCallback} callback Optional callback, signature: err, insertedDoc + * + * @private + */ insert (...args) { this.executor.push({ this: this, fn: this._insert, arguments: args }) } + /** + * Insert a new document + * Private Use Datastore.insertAsync which has the same signature + * @param {document} newDoc + * @return {Promise} + * @async + */ insertAsync (...args) { return this.executor.pushAsync(() => this._insertAsync(...args)) } + /** + * @callback Datastore~countCallback + * @param {?Error} err + * @param {?number} count + */ + /** * Count all documents matching the query - * @param {Query} query MongoDB-style query - * @param {Function} callback Optional callback, signature: err, count + * @param {query} query MongoDB-style query + * @param {Datastore~countCallback} [callback] If given, the function will return undefined, otherwise it will return the Cursor. + * @return {Cursor|undefined} */ count (query, callback) { const cursor = this.countAsync(query) @@ -420,16 +721,30 @@ class Datastore extends EventEmitter { else return cursor } + /** + * Count all documents matching the query + * @param {query} query MongoDB-style query + * @return {Cursor} count + * @async + */ countAsync (query) { return new Cursor(this, query, async docs => docs.length, true) // this is a trick, Cursor itself is a thenable, which allows to await it } + /** + * @callback Datastore~findCallback + * @param {?Error} err + * @param {document[]} docs + */ + /** * Find all documents matching the query * If no callback is passed, we return the cursor so that user can limit, skip and finally exec - * @param {Object} query MongoDB-style query - * @param {Object} projection MongoDB-style projection - * @param {Function} callback Optional callback, signature: err, docs + * @param {query} query MongoDB-style query + * @param {projection|Datastore~findCallback} [projection = {}] MongoDB-style projection. If not given, will be + * interpreted as the callback. + * @param {Datastore~findCallback} [callback] Optional callback, signature: err, docs + * @return {Cursor|undefined} */ find (query, projection, callback) { if (arguments.length === 1) { @@ -448,6 +763,14 @@ class Datastore extends EventEmitter { else return cursor } + /** + * Find all documents matching the query + * If no callback is passed, we return the cursor so that user can limit, skip and finally exec + * @param {query} query MongoDB-style query + * @param {projection} [projection = {}] MongoDB-style projection + * @return {Cursor} + * @async + */ findAsync (query, projection = {}) { const cursor = new Cursor(this, query, docs => docs.map(doc => model.deepCopy(doc)), true) @@ -455,11 +778,18 @@ class Datastore extends EventEmitter { return cursor } + /** + * @callback Datastore~findOneCallback + * @param {?Error} err + * @param {document} doc + */ + /** * Find one document matching the query - * @param {Object} query MongoDB-style query - * @param {Object} projection MongoDB-style projection - * @param {Function} callback Optional callback, signature: err, doc + * @param {query} query MongoDB-style query + * @param {projection} projection MongoDB-style projection + * @param {Datastore~findOneCallback} callback Optional callback, signature: err, doc + * @return {Cursor|undefined} */ findOne (query, projection, callback) { if (arguments.length === 1) { @@ -478,6 +808,12 @@ class Datastore extends EventEmitter { else return cursor } + /** + * Find one document matching the query + * @param {query} query MongoDB-style query + * @param {projection} projection MongoDB-style projection + * @return {Cursor} + */ findOneAsync (query, projection = {}) { const cursor = new Cursor(this, query, docs => docs.length === 1 ? model.deepCopy(docs[0]) : null, true) @@ -485,33 +821,52 @@ class Datastore extends EventEmitter { return cursor } + /** + * If update was an upsert, `upsert` flag is set to true, `affectedDocuments` can be one of the following: + * - For an upsert, the upserted document + * - For an update with returnUpdatedDocs option false, null + * - For an update with returnUpdatedDocs true and multi false, the updated document + * - For an update with returnUpdatedDocs true and multi true, the array of updated documents + * + * **WARNING:** The API was changed between v1.7.4 and v1.8, for consistency and readability reasons. Prior and + * including to v1.7.4, the callback signature was (err, numAffected, updated) where updated was the updated document + * in case of an upsert or the array of updated documents for an update if the returnUpdatedDocs option was true. That + * meant that the type of affectedDocuments in a non multi update depended on whether there was an upsert or not, + * leaving only two ways for the user to check whether an upsert had occured: checking the type of affectedDocuments + * or running another find query on the whole dataset to check its size. Both options being ugly, the breaking change + * was necessary. + * @callback Datastore~updateCallback + * @param {?Error} err + * @param {?number} numAffected + * @param {?document[]|?document} affectedDocuments + * @param {?boolean} upsert + */ + /** * Update all docs matching query. * Use Datastore.update which has the same signature - * @param {Object} query - * @param {Object} updateQuery - * @param {Object} options Optional options - * options.multi If true, can update multiple documents (defaults to false) - * options.upsert If true, document is inserted if the query doesn't match anything - * options.returnUpdatedDocs Defaults to false, if true return as third argument the array of updated matched documents (even if no change actually took place) - * @param {Function} cb Optional callback, signature: (err, numAffected, affectedDocuments, upsert) - * If update was an upsert, upsert flag is set to true - * affectedDocuments can be one of the following: - * * For an upsert, the upserted document - * * For an update with returnUpdatedDocs option false, null - * * For an update with returnUpdatedDocs true and multi false, the updated document - * * For an update with returnUpdatedDocs true and multi true, the array of updated documents - * - * WARNING: The API was changed between v1.7.4 and v1.8, for consistency and readability reasons. Prior and including to v1.7.4, - * the callback signature was (err, numAffected, updated) where updated was the updated document in case of an upsert - * or the array of updated documents for an update if the returnUpdatedDocs option was true. That meant that the type of - * affectedDocuments in a non multi update depended on whether there was an upsert or not, leaving only two ways for the - * user to check whether an upsert had occured: checking the type of affectedDocuments or running another find query on - * the whole dataset to check its size. Both options being ugly, the breaking change was necessary. + * @param {query} query is the same kind of finding query you use with `find` and `findOne` + * @param {document|update} update specifies how the documents should be modified. It is either a new document or a + * set of modifiers (you cannot use both together, it doesn't make sense!): + * - A new document will replace the matched docs + * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. + * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a + * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current + * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * @param {object|Datastore~updateCallback} [options] Optional options. If not given, is interpreted as the callback. + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if + * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted + * document. In the other case, the `query` is stripped from all operator recursively, and the `update` is applied to + * it. + * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, + * will return the array of documents matched by the find query and updated. Updated documents will be returned even + * if the update did not actually modify them. + * @param {Datastore~updateCallback} [cb] Optional callback * * @private */ - _update (query, updateQuery, options, cb) { + _update (query, update, options, cb) { if (typeof options === 'function') { cb = options options = {} @@ -521,10 +876,35 @@ class Datastore extends EventEmitter { const _callback = (err, res = {}) => { callback(err, res.numAffected, res.affectedDocuments, res.upsert) } - callbackify(this._updateAsync.bind(this))(query, updateQuery, options, _callback) + callbackify(this._updateAsync.bind(this))(query, update, options, _callback) } - async _updateAsync (query, updateQuery, options = {}) { + /** + * Update all docs matching query. + * Use Datastore.updateAsync which has the same signature + * @param {query} query is the same kind of finding query you use with `find` and `findOne` + * @param {document|update} update specifies how the documents should be modified. It is either a new document or a + * set of modifiers (you cannot use both together, it doesn't make sense!): + * - A new document will replace the matched docs + * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. + * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a + * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current + * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * @param {Object} [options] Optional options + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if + * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted + * document. In the other case, the `query` is stripped from all operator recursively, and the `update` is applied to + * it. + * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, + * will return the array of documents matched by the find query and updated. Updated documents will be returned even + * if the update did not actually modify them. + * + * @return {Promise<{numAffected: number, affectedDocuments: document[]|document, upsert: boolean}>} + * + * @private + */ + async _updateAsync (query, update, options = {}) { const multi = options.multi !== undefined ? options.multi : false const upsert = options.upsert !== undefined ? options.upsert : false @@ -539,13 +919,13 @@ class Datastore extends EventEmitter { let toBeInserted try { - model.checkObject(updateQuery) + model.checkObject(update) // updateQuery is a simple object with no modifier, use it as the document to insert - toBeInserted = updateQuery + toBeInserted = update } catch (e) { // updateQuery contains modifiers, use the find query as the base, // strip it from all operators and update it according to updateQuery - toBeInserted = model.modify(model.deepCopy(query, true), updateQuery) + toBeInserted = model.modify(model.deepCopy(query, true), update) } const newDoc = await this._insertAsync(toBeInserted) return { numAffected: 1, affectedDocuments: newDoc, upsert: true } @@ -564,7 +944,7 @@ class Datastore extends EventEmitter { if (model.match(candidate, query) && (multi || numReplaced === 0)) { numReplaced += 1 if (this.timestampData) { createdAt = candidate.createdAt } - modifiedDoc = model.modify(candidate, updateQuery) + modifiedDoc = model.modify(candidate, update) if (this.timestampData) { modifiedDoc.createdAt = createdAt modifiedDoc.updatedAt = new Date() @@ -579,31 +959,81 @@ class Datastore extends EventEmitter { // Update the datafile const updatedDocs = modifications.map(x => x.newDoc) await this.persistence.persistNewStateAsync(updatedDocs) - if (!options.returnUpdatedDocs) return { numAffected: numReplaced } + if (!options.returnUpdatedDocs) return { numAffected: numReplaced, upsert: false, affectedDocuments: null } else { let updatedDocsDC = [] updatedDocs.forEach(doc => { updatedDocsDC.push(model.deepCopy(doc)) }) if (!multi) updatedDocsDC = updatedDocsDC[0] - return { numAffected: numReplaced, affectedDocuments: updatedDocsDC } + return { numAffected: numReplaced, affectedDocuments: updatedDocsDC, upsert: false } } } + /** + * Update all docs matching query. + * @param {query} query is the same kind of finding query you use with `find` and `findOne` + * @param {document|update} update specifies how the documents should be modified. It is either a new document or a + * set of modifiers (you cannot use both together, it doesn't make sense!): + * - A new document will replace the matched docs + * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. + * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a + * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current + * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * @param {Object} [options] Optional options + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if + * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted + * document. In the other case, the `query` is stripped from all operator recursively, and the `update` is applied to + * it. + * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, + * will return the array of documents matched by the find query and updated. Updated documents will be returned even + * if the update did not actually modify them. + * @param {Datastore~updateCallback} [cb] Optional callback + * + */ update (...args) { this.executor.push({ this: this, fn: this._update, arguments: args }) } + /** + * Update all docs matching query. + * @param {query} query is the same kind of finding query you use with `find` and `findOne` + * @param {document|update} update specifies how the documents should be modified. It is either a new document or a + * set of modifiers (you cannot use both together, it doesn't make sense!): + * - A new document will replace the matched docs + * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. + * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a + * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current + * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * @param {Object} [options] Optional options + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if + * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted + * document. In the other case, the `query` is stripped from all operator recursively, and the `update` is applied to + * it. + * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, + * will return the array of documents matched by the find query and updated. Updated documents will be returned even + * if the update did not actually modify them. + * @async + * @return {Promise<{numAffected: number, affectedDocuments: document[]|document, upsert: boolean}>} + */ updateAsync (...args) { return this.executor.pushAsync(() => this._updateAsync(...args)) } + /** + * @callback Datastore~removeCallback + * @param {?Error} err + * @param {?number} numRemoved + */ + /** * Remove all docs matching the query. * Use Datastore.remove which has the same signature * For now very naive implementation (similar to update) - * @param {Object} query - * @param {Object} options Optional options - * options.multi If true, can update multiple documents (defaults to false) - * @param {Function} cb Optional callback, signature: err, numRemoved + * @param {query} query + * @param {object} [options] Optional options + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @param {Datastore~removeCallback} [cb] * * @private */ @@ -617,6 +1047,15 @@ class Datastore extends EventEmitter { callbackify(this._removeAsync.bind(this))(query, options, callback) } + /** + * Remove all docs matching the query. + * Use Datastore.removeAsync which has the same signature + * @param {query} query + * @param {object} [options] Optional options + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @return {Promise} How many documents were removed + * @private + */ async _removeAsync (query, options = {}) { const multi = options.multi !== undefined ? options.multi : false @@ -636,10 +1075,26 @@ class Datastore extends EventEmitter { return numRemoved } + /** + * Remove all docs matching the query. + * @param {query} query + * @param {object} [options] Optional options + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @param {Datastore~removeCallback} [cb] Optional callback, signature: err, numRemoved + */ remove (...args) { this.executor.push({ this: this, fn: this._remove, arguments: args }) } + /** + * Remove all docs matching the query. + * Use Datastore.removeAsync which has the same signature + * @param {query} query + * @param {object} [options] Optional options + * @param {boolean} [options.multi = false] If true, can update multiple documents + * @return {Promise} How many documents were removed + * @async + */ removeAsync (...args) { return this.executor.pushAsync(() => this._removeAsync(...args)) } diff --git a/lib/indexes.js b/lib/indexes.js index 21fabe2..21eb8cf 100755 --- a/lib/indexes.js +++ b/lib/indexes.js @@ -3,12 +3,17 @@ const model = require('./model.js') const { uniq, isDate } = require('./utils.js') /** - * Two indexed pointers are equal iif they point to the same place + * Two indexed pointers are equal if they point to the same place + * @param {*} a + * @param {*} b + * @return {boolean} */ const checkValueEquality = (a, b) => a === b /** * Type-aware projection + * @param {*} elt + * @return {string|*} */ function projectForUnique (elt) { if (elt === null) return '$null' @@ -25,24 +30,45 @@ class Index { * Create a new index * All methods on an index guarantee that either the whole operation was successful and the index changed * or the operation was unsuccessful and an error is thrown while the index is unchanged - * @param {String} options.fieldName On which field should the index apply (can use dot notation to index on sub fields) - * @param {Boolean} options.unique Optional, enforce a unique constraint (default: false) - * @param {Boolean} options.sparse Optional, allow a sparse index (we can have documents for which fieldName is undefined) (default: false) + * @param {object} options + * @param {string} options.fieldName On which field should the index apply (can use dot notation to index on sub fields) + * @param {boolean} [options.unique = false] Enforces a unique constraint + * @param {boolean} [options.sparse = false] Allows a sparse index (we can have documents for which fieldName is `undefined`) */ constructor (options) { + /** + * On which field the index applies to (may use dot notation to index on sub fields). + * @type {string} + */ this.fieldName = options.fieldName + /** + * Defines if the index enforces a unique constraint for this index. + * @type {boolean} + */ this.unique = options.unique || false + /** + * Defines if we can have documents for which fieldName is `undefined` + * @type {boolean} + */ this.sparse = options.sparse || false + /** + * Options object given to the underlying BinarySearchTree. + * @type {{unique: boolean, checkValueEquality: (function(*, *): boolean), compareKeys: ((function(*, *, compareStrings): (number|number))|*)}} + */ this.treeOptions = { unique: this.unique, compareKeys: model.compareThings, checkValueEquality: checkValueEquality } - this.reset() // No data in the beginning + /** + * Underlying BinarySearchTree for this index. Uses an AVLTree for optimization. + * @type {AVLTree} + */ + this.tree = new BinarySearchTree(this.treeOptions) } /** * Reset an index - * @param {Document or Array of documents} newData Optional, data to initialize the index with - * If an error is thrown during insertion, the index is not modified + * @param {?document|?document[]} [newData] Data to initialize the index with. If an error is thrown during + * insertion, the index is not modified. */ reset (newData) { this.tree = new BinarySearchTree(this.treeOptions) @@ -54,6 +80,7 @@ class Index { * Insert a new document in the index * If an array is passed, we insert all its elements (if one insertion fails the index is not modified) * O(log(n)) + * @param {document|document[]} doc The document, or array of documents, to insert. */ insert (doc) { let keys @@ -98,8 +125,8 @@ class Index { /** * Insert an array of documents in the index * If a constraint is violated, the changes should be rolled back and an error thrown - * - * @API private + * @param {document[]} docs Array of documents to insert. + * @private */ insertMultipleDocs (docs) { let error @@ -125,10 +152,11 @@ class Index { } /** - * Remove a document from the index + * Removes a document from the index. * If an array is passed, we remove all its elements * The remove operation is safe with regards to the 'unique' constraint * O(log(n)) + * @param {document[]|document} doc The document, or Array of documents, to remove. */ remove (doc) { if (Array.isArray(doc)) { @@ -153,6 +181,10 @@ class Index { * Update a document in the index * If a constraint is violated, changes are rolled back and an error thrown * Naive implementation, still in O(log(n)) + * @param {document|Array.<{oldDoc: document, newDoc: document}>} oldDoc Document to update, or an `Array` of + * `{oldDoc, newDoc}` pairs. + * @param {document} [newDoc] Document to replace the oldDoc with. If the first argument is an `Array` of + * `{oldDoc, newDoc}` pairs, this second argument is ignored. */ update (oldDoc, newDoc) { if (Array.isArray(oldDoc)) { @@ -174,7 +206,7 @@ class Index { * Update multiple documents in the index * If a constraint is violated, the changes need to be rolled back * and an error thrown - * @param {Array<{ oldDoc: T, newDoc: T }>} pairs + * @param {Array.<{oldDoc: document, newDoc: document}>} pairs * * @private */ @@ -212,6 +244,8 @@ class Index { /** * Revert an update + * @param {document|Array.<{oldDoc: document, newDoc: document}>} oldDoc Document to revert to, or an `Array` of `{oldDoc, newDoc}` pairs. + * @param {document} [newDoc] Document to revert from. If the first argument is an Array of {oldDoc, newDoc}, this second argument is ignored. */ revertUpdate (oldDoc, newDoc) { const revert = [] @@ -227,8 +261,8 @@ class Index { /** * Get all documents in index whose key match value (if it is a Thing) or one of the elements of value (if it is an array of Things) - * @param {Thing} value Value to match the key against - * @return {Array of documents} + * @param {Array.<*>|*} value Value to match the key against + * @return {document[]} */ getMatching (value) { if (!Array.isArray(value)) return this.tree.search(value) @@ -253,8 +287,12 @@ class Index { /** * Get all documents in index whose key is between bounds are they are defined by query * Documents are sorted by key - * @param {Query} query - * @return {Array of documents} + * @param {object} query An object with at least one matcher among $gt, $gte, $lt, $lte. + * @param {*} [query.$gt] Greater than matcher. + * @param {*} [query.$gte] Greater than or equal matcher. + * @param {*} [query.$lt] Lower than matcher. + * @param {*} [query.$lte] Lower than or equal matcher. + * @return {document[]} */ getBetweenBounds (query) { return this.tree.betweenBounds(query) @@ -262,7 +300,7 @@ class Index { /** * Get all elements in the index - * @return {Array of documents} + * @return {document[]} */ getAll () { const res = [] diff --git a/lib/persistence.js b/lib/persistence.js index 11a9849..ac22eb4 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -5,7 +5,7 @@ * * Persistence.persistNewState(newDocs, callback) where newDocs is an array of documents and callback has signature err */ const path = require('path') -const { callbackify, promisify } = require('util') +const { callbackify, promisify, deprecate } = require('util') const byline = require('./byline') const customUtils = require('./customUtils.js') const Index = require('./indexes.js') @@ -55,14 +55,9 @@ class Persistence { // For NW apps, store data in the same directory where NW stores application data if (this.filename && options.nodeWebkitAppName) { - console.log('==================================================================') - console.log('WARNING: The nodeWebkitAppName option is deprecated') - console.log('To get the path to the directory where Node Webkit stores the data') - console.log('for your app, use the internal nw.gui module like this') - console.log('require(\'nw.gui\').App.dataPath') - console.log('See https://github.com/rogerwang/node-webkit/issues/500') - console.log('==================================================================') - this.filename = Persistence.getNWAppFilename(options.nodeWebkitAppName, this.filename) + deprecate(() => { + this.filename = Persistence.getNWAppFilename(options.nodeWebkitAppName, this.filename) + }, 'The nodeWebkitAppName option is deprecated and will be removed in the next version. To get the path to the directory where Node Webkit stores the data for your app, use the internal nw.gui module like this require(\'nw.gui\').App.dataPath See https://github.com/rogerwang/node-webkit/issues/500')() } } @@ -311,23 +306,25 @@ class Persistence { * data for this application. Probably the best place to store data */ static getNWAppFilename (appName, relativeFilename) { - let home - - if (process.platform === 'win32' || process.platform === 'win64') { - home = process.env.LOCALAPPDATA || process.env.APPDATA - if (!home) throw new Error('Couldn\'t find the base application data folder') - home = path.join(home, appName) - } else if (process.platform === 'darwin') { - home = process.env.HOME - if (!home) throw new Error('Couldn\'t find the base application data directory') - home = path.join(home, 'Library', 'Application Support', appName) - } else if (process.platform === 'linux') { - home = process.env.HOME - if (!home) throw new Error('Couldn\'t find the base application data directory') - home = path.join(home, '.config', appName) - } else throw new Error(`Can't use the Node Webkit relative path for platform ${process.platform}`) - - return path.join(home, 'nedb-data', relativeFilename) + return deprecate(() => { + let home + + if (process.platform === 'win32' || process.platform === 'win64') { + home = process.env.LOCALAPPDATA || process.env.APPDATA + if (!home) throw new Error('Couldn\'t find the base application data folder') + home = path.join(home, appName) + } else if (process.platform === 'darwin') { + home = process.env.HOME + if (!home) throw new Error('Couldn\'t find the base application data directory') + home = path.join(home, 'Library', 'Application Support', appName) + } else if (process.platform === 'linux') { + home = process.env.HOME + if (!home) throw new Error('Couldn\'t find the base application data directory') + home = path.join(home, '.config', appName) + } else throw new Error(`Can't use the Node Webkit relative path for platform ${process.platform}`) + + return path.join(home, 'nedb-data', relativeFilename) + }, 'The getNWAppFilename static method is deprecated and will be removed in the next version. To get the path to the directory where Node Webkit stores the data for your app, use the internal nw.gui module like this require(\'nw.gui\').App.dataPath See https://github.com/rogerwang/node-webkit/issues/500')() } } diff --git a/lib/storage.js b/lib/storage.js index d179e68..43bf3de 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -108,8 +108,7 @@ storage.writeFileLines = (filename, lines, callback = () => {}) => { const readable = Readable.from(lines) readable.on('data', (line) => { try { - stream.write(line) - stream.write('\n') + stream.write(line + '\n') } catch (err) { callback(err) } diff --git a/package-lock.json b/package-lock.json index c0d5dd9..c6c6c01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,13 +21,14 @@ "events": "^3.3.0", "jest": "^27.3.1", "jquery": "^3.6.0", + "jsdoc": "^3.6.7", "karma": "^6.3.2", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.0", "karma-junit-reporter": "^2.0.1", "karma-mocha": "^2.0.1", "karma-source-map-support": "^1.4.0", - "mocha": "^8.4.0", + "mocha": "^9.1.3", "mocha-junit-reporter": "^2.0.0", "path-browserify": "^1.0.1", "process": "^0.11.10", @@ -46,41 +47,41 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", + "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helpers": "^7.16.5", + "@babel/parser": "^7.16.5", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -96,21 +97,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -130,12 +116,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", + "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", "dev": true, "dependencies": { - "@babel/types": "^7.15.6", + "@babel/types": "^7.16.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -153,41 +139,41 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", - "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", + "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-explode-assignable-expression": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", + "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.15.0", + "@babel/compat-data": "^7.16.0", "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "browserslist": "^4.17.5", "semver": "^6.3.0" }, "engines": { @@ -207,18 +193,19 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", - "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", + "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4" + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -228,13 +215,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", + "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-annotate-as-pure": "^7.16.0", "regexpu-core": "^4.7.1" }, "engines": { @@ -245,9 +232,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", - "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", + "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", "dev": true, "peer": true, "dependencies": { @@ -274,183 +261,199 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", + "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", - "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", + "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", + "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", + "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", + "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", + "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", "dev": true, + "peer": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", + "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", + "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", "dev": true, + "peer": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", + "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", - "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", + "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-wrap-function": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-wrap-function": "^7.16.5", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", + "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", "dev": true, + "peer": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", + "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", - "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", + "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -475,42 +478,42 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", - "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", + "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-function-name": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-function-name": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", + "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", "dev": true, "dependencies": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -590,9 +593,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "version": "7.16.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", + "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -601,16 +604,32 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", + "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz", - "integrity": "sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", + "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", "dev": true, "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", - "@babel/plugin-proposal-optional-chaining": "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -620,14 +639,14 @@ } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz", - "integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", + "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.15.4", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -638,14 +657,14 @@ } }, "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", - "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", + "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -655,14 +674,14 @@ } }, "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz", - "integrity": "sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", + "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -673,13 +692,13 @@ } }, "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", - "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", + "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -690,14 +709,14 @@ } }, "node_modules/@babel/plugin-proposal-export-default-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.14.5.tgz", - "integrity": "sha512-T8KZ5abXvKMjF6JcoXjgac3ElmXf0AWzJwi2O/42Jk+HmCky3D9+i1B7NPP1FblyceqTevKeV/9szeikFoaMDg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.5.tgz", + "integrity": "sha512-pU4aCS+AzGjDD/6LnwSmeelmtqfMSjzQxs7+/AS673bYsshK1XZm9eth6OkgivVscQM8XdkVYhrb6tPFVTBVHA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-export-default-from": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-export-default-from": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -707,13 +726,13 @@ } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", - "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", + "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -724,13 +743,13 @@ } }, "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", + "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -741,13 +760,13 @@ } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", - "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", + "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -758,13 +777,13 @@ } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", + "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -775,13 +794,13 @@ } }, "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", + "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -792,17 +811,17 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", - "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", + "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", "dev": true, "peer": true, "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" + "@babel/plugin-transform-parameters": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -812,13 +831,13 @@ } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", + "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -829,14 +848,14 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", + "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -847,14 +866,14 @@ } }, "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", - "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", + "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -864,15 +883,15 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", - "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", + "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -883,14 +902,14 @@ } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", - "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", + "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=4" @@ -965,13 +984,13 @@ } }, "node_modules/@babel/plugin-syntax-export-default-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.14.5.tgz", - "integrity": "sha512-snWDxjuaPEobRBnhpqEfZ8RMxDbHt8+87fiEioGuE+Uc0xAKgSD8QiuL3lF93hPVQfZFAcYwrrf+H5qUhike3Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.5.tgz", + "integrity": "sha512-tvY55nhq4mSG9WbM7IZcLIhdc5jzIZu0PQKJHtZ16+dF7oBxKbqV/Z0e9ta2zaLMvUjH+3rJv1hbZ0+lpXzuFQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -994,13 +1013,13 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", - "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.5.tgz", + "integrity": "sha512-Nrx+7EAJx1BieBQseZa2pavVH2Rp7hADK2xn7coYqVbWRu9C2OFizYcsKo6TrrqJkJl+qF/+Qqzrk/+XDu4GnA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1034,13 +1053,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", - "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz", + "integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1153,12 +1172,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", + "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1168,13 +1187,13 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", + "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1184,15 +1203,15 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", + "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5" + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1202,13 +1221,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", + "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1218,13 +1237,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", - "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", + "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1234,18 +1253,19 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", - "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", + "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0", "globals": "^11.1.0" }, "engines": { @@ -1255,24 +1275,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", + "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1282,13 +1292,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", + "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1298,14 +1308,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", - "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", + "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1315,13 +1325,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", - "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", + "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1331,14 +1341,14 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", + "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1348,14 +1358,14 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", - "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.5.tgz", + "integrity": "sha512-skE02E/MptkZdBS4HwoRhjWXqeKQj0BWKEAPfPC+8R4/f6bjQqQ9Nftv/+HkxWwnVxh/E2NV9TNfzLN5H/oiBw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-flow": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-flow": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1365,13 +1375,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", - "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", + "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1381,14 +1391,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", - "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", + "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1398,13 +1408,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", + "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1414,13 +1424,13 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", - "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", + "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1430,14 +1440,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", - "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", + "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1448,15 +1458,15 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", - "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", + "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-simple-access": "^7.16.0", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1467,16 +1477,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", - "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", + "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-identifier": "^7.15.7", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1487,14 +1497,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", - "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", + "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1504,13 +1514,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", - "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", + "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -1520,13 +1530,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", - "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", + "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1536,13 +1546,13 @@ } }, "node_modules/@babel/plugin-transform-object-assign": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz", - "integrity": "sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.5.tgz", + "integrity": "sha512-KVuJ7sWf6bcXawKVH6ZDQFYcOulObt1IOvl/gvNrkNXzmFf1IdgKOy4thmVomReleXqffMbptmXXMl3zPI7zHw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1552,14 +1562,14 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", + "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1569,13 +1579,13 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", - "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", + "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1585,13 +1595,13 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", + "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1601,13 +1611,13 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.15.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.15.1.tgz", - "integrity": "sha512-yQZ/i/pUCJAHI/LbtZr413S3VT26qNrEm0M5RRxQJA947/YNYwbZbBaXGDrq6CG5QsZycI1VIP6d7pQaBfP+8Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.5.tgz", + "integrity": "sha512-dHYCOnzSsXFz8UcdNQIHGvg94qPL/teF7CCiCEMRxmA1G2p5Mq4JnKVowCDxYfiQ9D7RstaAp9kwaSI+sXbnhw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1617,17 +1627,17 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.9.tgz", - "integrity": "sha512-30PeETvS+AeD1f58i1OVyoDlVYQhap/K20ZrMjLmmzmC2AYR/G43D4sdJAaDAqCD3MYpSWbmrz3kES158QSLjw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.5.tgz", + "integrity": "sha512-+arLIz1d7kmwX0fKxTxbnoeG85ONSnLpvdODa4P3pc1sS7CV1hfmtYWufkW/oYsPnkDrEeQFxhUWcFnrXW7jQQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-jsx": "^7.14.5", - "@babel/types": "^7.14.9" + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-jsx": "^7.16.5", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -1637,13 +1647,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.14.9.tgz", - "integrity": "sha512-Fqqu0f8zv9W+RyOnx29BX/RlEsBRANbOf5xs5oxb2aHP4FKbLXxIaVPUiCti56LAR1IixMH4EyaixhUsKqoBHw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.5.tgz", + "integrity": "sha512-fvwq+jir1Vn4f5oBS0H/J/gD5CneTD53MHs+NMjlHcha4Sq35fwxI5RtmJGEBXO+M93f/eeD9cAhRPhmLyJiVw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1653,13 +1663,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.5.tgz", - "integrity": "sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.5.tgz", + "integrity": "sha512-/eP+nZywJntGLjSPjksAnM9/ELIs3RbiEuTu2/zAOzwwBcfiu+m/iptEq1lERUUtSXubYSHVnVHMr13GR+TwPw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1669,9 +1679,9 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", + "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", "dev": true, "peer": true, "dependencies": { @@ -1685,13 +1695,13 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", - "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", + "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1701,17 +1711,17 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.8.tgz", - "integrity": "sha512-+6zsde91jMzzvkzuEA3k63zCw+tm/GvuuabkpisgbDMTPQsIMHllE3XczJFFtEHLjjhKQFZmGQVRdELetlWpVw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz", + "integrity": "sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "babel-plugin-polyfill-corejs2": "^0.2.2", - "babel-plugin-polyfill-corejs3": "^0.2.5", - "babel-plugin-polyfill-regenerator": "^0.2.2", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", "semver": "^6.3.0" }, "engines": { @@ -1732,13 +1742,13 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", + "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1748,14 +1758,14 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz", - "integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", + "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -1765,13 +1775,13 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", + "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1781,13 +1791,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", + "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1797,13 +1807,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", + "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1813,15 +1823,15 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", - "integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", + "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-create-class-features-plugin": "^7.16.0", "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.14.5" + "@babel/plugin-syntax-typescript": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -1831,13 +1841,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", - "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", + "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1847,14 +1857,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", + "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1864,32 +1874,33 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz", - "integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", + "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", "dev": true, "peer": true, "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4", - "@babel/plugin-proposal-async-generator-functions": "^7.15.8", - "@babel/plugin-proposal-class-properties": "^7.14.5", - "@babel/plugin-proposal-class-static-block": "^7.15.4", - "@babel/plugin-proposal-dynamic-import": "^7.14.5", - "@babel/plugin-proposal-export-namespace-from": "^7.14.5", - "@babel/plugin-proposal-json-strings": "^7.14.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", - "@babel/plugin-proposal-numeric-separator": "^7.14.5", - "@babel/plugin-proposal-object-rest-spread": "^7.15.6", - "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", - "@babel/plugin-proposal-optional-chaining": "^7.14.5", - "@babel/plugin-proposal-private-methods": "^7.14.5", - "@babel/plugin-proposal-private-property-in-object": "^7.15.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-async-generator-functions": "^7.16.5", + "@babel/plugin-proposal-class-properties": "^7.16.5", + "@babel/plugin-proposal-class-static-block": "^7.16.5", + "@babel/plugin-proposal-dynamic-import": "^7.16.5", + "@babel/plugin-proposal-export-namespace-from": "^7.16.5", + "@babel/plugin-proposal-json-strings": "^7.16.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", + "@babel/plugin-proposal-numeric-separator": "^7.16.5", + "@babel/plugin-proposal-object-rest-spread": "^7.16.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", + "@babel/plugin-proposal-optional-chaining": "^7.16.5", + "@babel/plugin-proposal-private-methods": "^7.16.5", + "@babel/plugin-proposal-private-property-in-object": "^7.16.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", @@ -1904,44 +1915,44 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.14.5", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/plugin-transform-block-scoped-functions": "^7.14.5", - "@babel/plugin-transform-block-scoping": "^7.15.3", - "@babel/plugin-transform-classes": "^7.15.4", - "@babel/plugin-transform-computed-properties": "^7.14.5", - "@babel/plugin-transform-destructuring": "^7.14.7", - "@babel/plugin-transform-dotall-regex": "^7.14.5", - "@babel/plugin-transform-duplicate-keys": "^7.14.5", - "@babel/plugin-transform-exponentiation-operator": "^7.14.5", - "@babel/plugin-transform-for-of": "^7.15.4", - "@babel/plugin-transform-function-name": "^7.14.5", - "@babel/plugin-transform-literals": "^7.14.5", - "@babel/plugin-transform-member-expression-literals": "^7.14.5", - "@babel/plugin-transform-modules-amd": "^7.14.5", - "@babel/plugin-transform-modules-commonjs": "^7.15.4", - "@babel/plugin-transform-modules-systemjs": "^7.15.4", - "@babel/plugin-transform-modules-umd": "^7.14.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9", - "@babel/plugin-transform-new-target": "^7.14.5", - "@babel/plugin-transform-object-super": "^7.14.5", - "@babel/plugin-transform-parameters": "^7.15.4", - "@babel/plugin-transform-property-literals": "^7.14.5", - "@babel/plugin-transform-regenerator": "^7.14.5", - "@babel/plugin-transform-reserved-words": "^7.14.5", - "@babel/plugin-transform-shorthand-properties": "^7.14.5", - "@babel/plugin-transform-spread": "^7.15.8", - "@babel/plugin-transform-sticky-regex": "^7.14.5", - "@babel/plugin-transform-template-literals": "^7.14.5", - "@babel/plugin-transform-typeof-symbol": "^7.14.5", - "@babel/plugin-transform-unicode-escapes": "^7.14.5", - "@babel/plugin-transform-unicode-regex": "^7.14.5", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.15.6", - "babel-plugin-polyfill-corejs2": "^0.2.2", - "babel-plugin-polyfill-corejs3": "^0.2.5", - "babel-plugin-polyfill-regenerator": "^0.2.2", - "core-js-compat": "^3.16.0", + "@babel/plugin-transform-arrow-functions": "^7.16.5", + "@babel/plugin-transform-async-to-generator": "^7.16.5", + "@babel/plugin-transform-block-scoped-functions": "^7.16.5", + "@babel/plugin-transform-block-scoping": "^7.16.5", + "@babel/plugin-transform-classes": "^7.16.5", + "@babel/plugin-transform-computed-properties": "^7.16.5", + "@babel/plugin-transform-destructuring": "^7.16.5", + "@babel/plugin-transform-dotall-regex": "^7.16.5", + "@babel/plugin-transform-duplicate-keys": "^7.16.5", + "@babel/plugin-transform-exponentiation-operator": "^7.16.5", + "@babel/plugin-transform-for-of": "^7.16.5", + "@babel/plugin-transform-function-name": "^7.16.5", + "@babel/plugin-transform-literals": "^7.16.5", + "@babel/plugin-transform-member-expression-literals": "^7.16.5", + "@babel/plugin-transform-modules-amd": "^7.16.5", + "@babel/plugin-transform-modules-commonjs": "^7.16.5", + "@babel/plugin-transform-modules-systemjs": "^7.16.5", + "@babel/plugin-transform-modules-umd": "^7.16.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", + "@babel/plugin-transform-new-target": "^7.16.5", + "@babel/plugin-transform-object-super": "^7.16.5", + "@babel/plugin-transform-parameters": "^7.16.5", + "@babel/plugin-transform-property-literals": "^7.16.5", + "@babel/plugin-transform-regenerator": "^7.16.5", + "@babel/plugin-transform-reserved-words": "^7.16.5", + "@babel/plugin-transform-shorthand-properties": "^7.16.5", + "@babel/plugin-transform-spread": "^7.16.5", + "@babel/plugin-transform-sticky-regex": "^7.16.5", + "@babel/plugin-transform-template-literals": "^7.16.5", + "@babel/plugin-transform-typeof-symbol": "^7.16.5", + "@babel/plugin-transform-unicode-escapes": "^7.16.5", + "@babel/plugin-transform-unicode-regex": "^7.16.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.0", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.19.1", "semver": "^6.3.0" }, "engines": { @@ -1962,15 +1973,15 @@ } }, "node_modules/@babel/preset-flow": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.14.5.tgz", - "integrity": "sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.16.5.tgz", + "integrity": "sha512-rmC6Nznp4V55N4Zfec87jwd14TdREqwKVJFM/6Z2wTwoeZQr56czjaPRCezqzqc8TsHF7aLP1oczjadIQ058gw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-flow-strip-types": "^7.14.5" + "@babel/plugin-transform-flow-strip-types": "^7.16.5" }, "engines": { "node": ">=6.9.0" @@ -1997,15 +2008,15 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", - "integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", + "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.15.0" + "@babel/plugin-transform-typescript": "^7.16.1" }, "engines": { "node": ">=6.9.0" @@ -2015,9 +2026,9 @@ } }, "node_modules/@babel/register": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.15.3.tgz", - "integrity": "sha512-mj4IY1ZJkorClxKTImccn4T81+UKTo4Ux0+OFSV9hME1ooqS9UV+pJ6BjD0qXPK4T3XW/KNa79XByjeEMZz+fw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.5.tgz", + "integrity": "sha512-NpluD+cToBiZiDsG3y9rtIcqDyivsahpaM9csfyfiq1qQWduSmihUZ+ruIqqSDGjZKZMJfgAElo9x2YWlOQuRw==", "dev": true, "peer": true, "dependencies": { @@ -2069,9 +2080,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", "dev": true, "peer": true, "dependencies": { @@ -2082,32 +2093,33 @@ } }, "node_modules/@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", + "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", + "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.5", + "@babel/types": "^7.16.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2115,22 +2127,13 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2182,18 +2185,18 @@ } }, "node_modules/@discoveryjs/json-ext": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", - "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", + "integrity": "sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==", "dev": true, "engines": { "node": ">=10.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", + "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -2203,7 +2206,7 @@ "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, @@ -2211,26 +2214,53 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/@eslint/eslintrc/node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/@hapi/hoek": { @@ -2266,154 +2296,62 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@jest/console": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", + "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.4.2", + "jest-util": "^27.4.2", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/@jest/core": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", + "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz", - "integrity": "sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.3.1", - "jest-util": "^27.3.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz", - "integrity": "sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg==", - "dev": true, - "dependencies": { - "@jest/console": "^27.3.1", - "@jest/reporters": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/reporters": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-resolve-dependencies": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "jest-watcher": "^27.3.1", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.5", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-resolve-dependencies": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "jest-watcher": "^27.4.2", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", @@ -2431,91 +2369,76 @@ } } }, - "node_modules/@jest/core/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@jest/create-cache-key-function": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.3.1.tgz", - "integrity": "sha512-21lx0HRgkznc5Tc2WGiXVYQQ6Vdfohs6CkLV2FLogLRb52f6v9SiSIjTNflu23lzEmY4EalLgQLxCfhgvREV6w==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.4.2.tgz", + "integrity": "sha512-aSSCAJwUNX4R1hJQoyimsND5l+2EsFgzlepS8NuOJJHjXij/UdxYFngac44tmv9IYdI+kglAyORg0plt4/aFMQ==", "dev": true, "peer": true, "dependencies": { - "@jest/types": "^27.2.5" + "@jest/types": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/environment": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz", - "integrity": "sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", + "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0" + "jest-mock": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz", - "integrity": "sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", + "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/globals": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz", - "integrity": "sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", + "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/types": "^27.2.5", - "expect": "^27.3.1" + "@jest/environment": "^27.4.4", + "@jest/types": "^27.4.2", + "expect": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz", - "integrity": "sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", + "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -2527,10 +2450,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -2549,24 +2472,10 @@ } } }, - "node_modules/@jest/reporters/node_modules/jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", "dev": true, "dependencies": { "callsites": "^3.0.0", @@ -2578,13 +2487,13 @@ } }, "node_modules/@jest/test-result": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz", - "integrity": "sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", + "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", "dev": true, "dependencies": { - "@jest/console": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -2593,36 +2502,36 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz", - "integrity": "sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", + "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", "dev": true, "dependencies": { - "@jest/test-result": "^27.3.1", + "@jest/test-result": "^27.4.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-runtime": "^27.3.1" + "jest-haste-map": "^27.4.5", + "jest-runtime": "^27.4.5" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz", - "integrity": "sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", + "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -2634,9 +2543,9 @@ } }, "node_modules/@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -2650,9 +2559,9 @@ } }, "node_modules/@react-native-async-storage/async-storage": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.9.tgz", - "integrity": "sha512-LrVPfhKqodRiDWCgZp7J2X55JQqOhdQUxbl17RrktIGCZ0ud2XHdNoTIvyI1VccqHoF/CZK6v+G0IoX5NYZ1JA==", + "version": "1.15.14", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.14.tgz", + "integrity": "sha512-eJF2horabXazwszCyyXDe4w7sBSWlB0WPA8akKXuN2n7WXKHYeQJPN41lS9OahrhSZuZwqftNFE9VWgPXA8wyA==", "dev": true, "dependencies": { "merge-options": "^3.0.4" @@ -2662,20 +2571,20 @@ } }, "node_modules/@react-native-community/cli": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-6.1.0.tgz", - "integrity": "sha512-Ck1XjvsnYYVYqooxmSlvRvGMGgxj3t+evUGlg80b+TxnurhlGq8D8pW7++L/sECChI43YWMBtLIdAYG/lGkN8Q==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-6.3.1.tgz", + "integrity": "sha512-UQ77AkGvPzdwJt6qhYXUyDMP1v2rdCcIlrhU48FOcAhGX+N/LCL9Cp/Ic6CkiiSHJdktbgiEEJ2srprXH8nzVg==", "dev": true, "peer": true, "dependencies": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", - "@react-native-community/cli-hermes": "^6.1.0", - "@react-native-community/cli-plugin-metro": "^6.1.0", - "@react-native-community/cli-server-api": "^6.1.0", - "@react-native-community/cli-tools": "^6.1.0", + "@react-native-community/cli-hermes": "^6.3.0", + "@react-native-community/cli-plugin-metro": "^6.2.0", + "@react-native-community/cli-server-api": "^6.2.0", + "@react-native-community/cli-tools": "^6.2.0", "@react-native-community/cli-types": "^6.0.0", "appdirsjs": "^1.2.4", - "chalk": "^3.0.0", + "chalk": "^4.1.2", "command-exists": "^1.2.8", "commander": "^2.19.0", "cosmiconfig": "^5.1.0", @@ -2690,7 +2599,6 @@ "leven": "^3.1.0", "lodash": "^4.17.15", "minimist": "^1.2.0", - "mkdirp": "^0.5.1", "node-stream-zip": "^1.9.1", "ora": "^3.4.0", "pretty-format": "^26.6.2", @@ -2722,55 +2630,28 @@ } }, "node_modules/@react-native-community/cli-hermes": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-6.1.0.tgz", - "integrity": "sha512-BJyzGlUqnggbBL4Vh4cIC08oKOK4PoelxZFEo7TjFjfdBKvbM6955JN77ExJ7IdeLuGVpY4vaMwAJdx5l7LxKg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-6.3.0.tgz", + "integrity": "sha512-Uhbm9bubyZLZ12vFCIfWbE/Qi3SBTbYIN/TC08EudTLhv/KbPomCQnmFsnJ7AXQFuOZJs73mBxoEAYSbRbwyVA==", "dev": true, "peer": true, "dependencies": { - "@react-native-community/cli-platform-android": "^6.1.0", - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", + "@react-native-community/cli-platform-android": "^6.3.0", + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", "hermes-profile-transformer": "^0.0.6", "ip": "^1.1.5" } }, - "node_modules/@react-native-community/cli-hermes/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@react-native-community/cli-hermes/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-platform-android": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-6.1.0.tgz", - "integrity": "sha512-MBYGfgCpieoqskKc5QyQYIPc74DBEW60JaacQLntHjPLCEXG+hPsJi3AuXeNTJYPki5pyiSp3kviqciUvrS96A==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.0.tgz", + "integrity": "sha512-d5ufyYcvrZoHznYm5bjBXaiHIJv552t5gYtQpnUsxBhHSQ8QlaNmlLUyeSPRDfOw4ND9b0tPHqs4ufwx6vp/fQ==", "dev": true, "peer": true, "dependencies": { - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", "execa": "^1.0.0", "fs-extra": "^8.1.0", "glob": "^7.1.3", @@ -2781,20 +2662,6 @@ "xmldoc": "^1.1.2" } }, - "node_modules/@react-native-community/cli-platform-android/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-platform-android/node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2910,19 +2777,6 @@ "node": ">=0.10.0" } }, - "node_modules/@react-native-community/cli-platform-android/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-platform-android/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -2937,128 +2791,50 @@ } }, "node_modules/@react-native-community/cli-platform-ios": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.1.0.tgz", - "integrity": "sha512-whIm55fUeJUHrqZ2ecZ6FycZ5c/R3ZK8ViHwZQ+wM4uhXY8YSkrjnrJPUg68Q8inLkrAliLisypfm1z+VqJljw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.2.0.tgz", + "integrity": "sha512-k15MhExxLiLDDZOeuPgvTxbp0CsoLQQpk2Du0HjZDePqqWcKJylQqMZru1o8HuQHPcEr+b71HIs5V+lKyFYpfg==", "dev": true, "peer": true, "dependencies": { - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", "glob": "^7.1.3", "js-yaml": "^3.13.1", "lodash": "^4.17.15", + "ora": "^3.4.0", "plist": "^3.0.2", "xcode": "^2.0.0" } }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-plugin-metro": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-6.1.0.tgz", - "integrity": "sha512-ltHJquEgA6H4OTIUqWIkNm/xxAB9D4DK2K9M0jie9FfkOoqBXA7QS2WnC8GEa6a+3VIDwevB0RJsch218FdZCw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-6.2.0.tgz", + "integrity": "sha512-JfmzuFNzOr+dFTUQJo1rV0t87XAqgHRTMYXNleQVt8otOVCk1FSCgKlgqMdvQc/FCx2ZjoMWEEV/g0LrPI8Etw==", "dev": true, "peer": true, "dependencies": { - "@react-native-community/cli-server-api": "^6.1.0", - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", + "@react-native-community/cli-server-api": "^6.2.0", + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", "metro": "^0.66.1", "metro-config": "^0.66.1", "metro-core": "^0.66.1", "metro-react-native-babel-transformer": "^0.66.1", "metro-resolver": "^0.66.1", "metro-runtime": "^0.66.1", - "mkdirp": "^0.5.1", "readline": "^1.3.0" } }, - "node_modules/@react-native-community/cli-plugin-metro/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@react-native-community/cli-plugin-metro/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-server-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-6.1.0.tgz", - "integrity": "sha512-WEJzdoF4JNUogZAd+Gdgbr+D/S/PHGjxH+PDjk3ST9pAUxEHb6naNwEl5dSJUY/ecBV63latNZkKunRyvFAx9A==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-6.2.0.tgz", + "integrity": "sha512-OnbnYclhoDpjge33QO5Slhfn0DsmLzzAgyrSCnb24HhSqwq7ObjMHaLpoEhpajzLG71wq5oKh0APEQjiL4Mknw==", "dev": true, "peer": true, "dependencies": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", - "@react-native-community/cli-tools": "^6.1.0", + "@react-native-community/cli-tools": "^6.2.0", "compression": "^1.7.1", "connect": "^3.6.5", "errorhandler": "^1.5.0", @@ -3111,13 +2887,6 @@ "node": ">= 10" } }, - "node_modules/@react-native-community/cli-server-api/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true - }, "node_modules/@react-native-community/cli-server-api/node_modules/ws": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", @@ -3130,37 +2899,22 @@ } }, "node_modules/@react-native-community/cli-tools": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-6.1.0.tgz", - "integrity": "sha512-MT8syhvk0vpfyYyHlcDoGicKcqMtBN7WPmDeyW16u+eKBtw/+EKq+86cFCuOHCfHK20ujG1mZqA1txxlCbu8GA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz", + "integrity": "sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA==", "dev": true, "peer": true, "dependencies": { "appdirsjs": "^1.2.4", - "chalk": "^3.0.0", + "chalk": "^4.1.2", "lodash": "^4.17.15", "mime": "^2.4.1", - "mkdirp": "^0.5.1", "node-fetch": "^2.6.0", "open": "^6.2.0", "semver": "^6.3.0", "shell-quote": "1.6.1" } }, - "node_modules/@react-native-community/cli-tools/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-tools/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -3171,19 +2925,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@react-native-community/cli-tools/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-types": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-6.0.0.tgz", @@ -3211,47 +2952,16 @@ "node": ">= 10.14.2" } }, - "node_modules/@react-native-community/cli/node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@react-native-community/cli/node_modules/@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "node_modules/@react-native-community/cli/node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, "peer": true, "dependencies": { "@types/yargs-parser": "*" } }, - "node_modules/@react-native-community/cli/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -3315,20 +3025,6 @@ "node": ">=6" } }, - "node_modules/@react-native-community/cli/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli/node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -3352,19 +3048,6 @@ "node": ">=0.10.0" } }, - "node_modules/@react-native-community/cli/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli/node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -3378,35 +3061,6 @@ "node": ">=4" } }, - "node_modules/@react-native-community/cli/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@react-native-community/cli/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "peer": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -3433,13 +3087,6 @@ "node": ">= 10" } }, - "node_modules/@react-native-community/cli/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true - }, "node_modules/@react-native-community/cli/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -3496,19 +3143,6 @@ "node": ">=6" } }, - "node_modules/@react-native-community/cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -3549,9 +3183,9 @@ "integrity": "sha512-+pYGvPFAk7wUR+ONMOlc6A+LUN4kOCFwyPLjyaeS7wVibADPHWYJNYsNtyIAwjF1AXQkuaXElnIc4XjKt55QZA==" }, "node_modules/@sideway/address": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", - "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", + "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", "dev": true, "peer": true, "dependencies": { @@ -3582,9 +3216,9 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", - "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.7.0" @@ -3624,9 +3258,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "version": "7.1.17", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", + "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -3665,27 +3299,27 @@ } }, "node_modules/@types/component-emitter": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", - "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", "dev": true }, "node_modules/@types/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", "dev": true }, "node_modules/@types/cors": { - "version": "2.8.10", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", - "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==", + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", "dev": true }, "node_modules/@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", + "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", "dev": true, "dependencies": { "@types/estree": "*", @@ -3693,9 +3327,9 @@ } }, "node_modules/@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.2.tgz", + "integrity": "sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ==", "dev": true, "dependencies": { "@types/eslint": "*", @@ -3703,9 +3337,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", "dev": true }, "node_modules/@types/graceful-fs": { @@ -3742,9 +3376,9 @@ } }, "node_modules/@types/jest": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.2.tgz", - "integrity": "sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA==", + "version": "27.0.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", + "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", "dev": true, "dependencies": { "jest-diff": "^27.0.0", @@ -3752,9 +3386,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, "node_modules/@types/json5": { @@ -3764,15 +3398,15 @@ "dev": true }, "node_modules/@types/node": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", - "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.1.tgz", + "integrity": "sha512-NXKvBVUzIbs6ylBwmOwHFkZS2EXCcjnqr8ZCRNaXBkHAf+3mn/rPcJxwrzuc6movh8fxQAsUUfYklJ/EG+hZqQ==", "dev": true }, "node_modules/@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", + "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", "dev": true }, "node_modules/@types/stack-utils": { @@ -3803,155 +3437,155 @@ "dev": true }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/ast": "1.11.1", "@xtuc/long": "4.2.2" } }, "node_modules/@webpack-cli/configtest": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz", - "integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", + "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", "dev": true, "peerDependencies": { "webpack": "4.x.x || 5.x.x", @@ -3959,9 +3593,9 @@ } }, "node_modules/@webpack-cli/info": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.4.tgz", - "integrity": "sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", + "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", "dev": true, "dependencies": { "envinfo": "^7.7.3" @@ -3971,9 +3605,9 @@ } }, "node_modules/@webpack-cli/serve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz", - "integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", + "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", "dev": true, "peerDependencies": { "webpack-cli": "4.x.x" @@ -4036,9 +3670,9 @@ } }, "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", + "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4057,28 +3691,40 @@ "acorn-walk": "^7.1.1" } }, - "node_modules/acorn-globals/node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { "node": ">=0.4.0" } }, + "node_modules/acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, "engines": { "node": ">=0.4.0" @@ -4152,18 +3798,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-fragments": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", @@ -4250,10 +3884,13 @@ "dev": true }, "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } }, "node_modules/arr-diff": { "version": "4.0.0", @@ -4293,16 +3930,16 @@ "peer": true }, "node_modules/array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", + "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" + "is-string": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -4336,14 +3973,14 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "es-abstract": "^1.19.0" }, "engines": { "node": ">= 0.4" @@ -4353,15 +3990,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", + "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", "dev": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" + "es-abstract": "^1.19.0" }, "engines": { "node": ">= 0.4" @@ -4414,15 +4050,20 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true, + "peer": true, "engines": { "node": ">=4" } }, "node_modules/async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.14" + } }, "node_modules/async-limiter": { "version": "1.0.1", @@ -4473,16 +4114,16 @@ } }, "node_modules/babel-jest": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz", - "integrity": "sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", + "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", "dev": true, "dependencies": { - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", + "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -4546,9 +4187,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -4561,14 +4202,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", - "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", + "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", "dev": true, "peer": true, "dependencies": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.2", + "@babel/helper-define-polyfill-provider": "^0.3.0", "semver": "^6.1.1" }, "peerDependencies": { @@ -4586,27 +4227,27 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz", - "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", + "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.2", - "core-js-compat": "^3.16.2" + "@babel/helper-define-polyfill-provider": "^0.3.0", + "core-js-compat": "^3.18.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", - "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", + "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.2" + "@babel/helper-define-polyfill-provider": "^0.3.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -4682,12 +4323,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.2.0", + "babel-plugin-jest-hoist": "^27.4.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -4736,9 +4377,9 @@ } }, "node_modules/base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", "dev": true, "engines": { "node": ">= 0.6.0" @@ -4775,9 +4416,9 @@ } }, "node_modules/big-integer": { - "version": "1.6.50", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz", - "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==", + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", "dev": true, "peer": true, "engines": { @@ -4793,22 +4434,28 @@ "node": ">=8" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", "dev": true, "dependencies": { - "bytes": "3.1.0", + "bytes": "3.1.1", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" }, "engines": { "node": ">= 0.8" @@ -4823,18 +4470,6 @@ "ms": "2.0.0" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4908,13 +4543,13 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.5.tgz", - "integrity": "sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001271", - "electron-to-chromium": "^1.3.878", + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", "escalade": "^3.1.1", "node-releases": "^2.0.1", "picocolors": "^1.0.0" @@ -4952,15 +4587,15 @@ } }, "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", "dev": true, "engines": { "node": ">= 0.8" @@ -5046,21 +4681,18 @@ } }, "node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001272", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001272.tgz", - "integrity": "sha512-DV1j9Oot5dydyH1v28g25KoVm7l8MTxazwuiH3utWiAS6iL/9Nh//TGwqFEeqqN8nnWYQ8HHhUq+o4QPt9kvYw==", + "version": "1.0.30001291", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001291.tgz", + "integrity": "sha512-roMV5V0HNGgJ88s42eE70sstqGW/gwFndosYrikHthw98N5tLnOTxFqMLQjZVRxTWFlJ4rn+MsgXrR7MDPY4jA==", "dev": true, "funding": { "type": "opencollective", @@ -5080,6 +4712,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -5098,9 +4742,9 @@ } }, "node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5113,18 +4757,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -5153,24 +4785,24 @@ } }, "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.3.1" + "fsevents": "~2.3.2" } }, "node_modules/chrome-trace-event": { @@ -5183,9 +4815,9 @@ } }, "node_modules/ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", "dev": true }, "node_modules/cjs-module-lexer": { @@ -5337,49 +4969,20 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true, + "peer": true, "engines": { - "node": ">=8" + "node": ">=0.8" } }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "dependencies": { "is-plain-object": "^2.0.4", @@ -5439,10 +5042,11 @@ "dev": true }, "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true, + "peer": true }, "node_modules/colors": { "version": "1.4.0", @@ -5553,13 +5157,6 @@ "dev": true, "peer": true }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5596,15 +5193,6 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "node_modules/contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -5623,12 +5211,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", @@ -5649,13 +5231,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.0.tgz", - "integrity": "sha512-R09rKZ56ccGBebjTLZHvzDxhz93YPT37gBm6qUhnwj3Kt7aCjjZWD1injyNbyeFHxNKfeZBSyds6O9n3MKq1sw==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.0.tgz", + "integrity": "sha512-relrah5h+sslXssTTOkvqcC/6RURifB0W5yhYBdBkaPYa5/2KBMiog3XiD+s3TwEHWxInWVv4Jx2/Lw0vng+IQ==", "dev": true, "peer": true, "dependencies": { - "browserslist": "^4.17.5", + "browserslist": "^4.19.1", "semver": "7.0.0" }, "funding": { @@ -5709,68 +5291,6 @@ "node": ">=4" } }, - "node_modules/cosmiconfig/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/cosmiconfig/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "peer": true, - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/cosmiconfig/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "peer": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -5861,9 +5381,9 @@ "peer": true }, "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -5877,12 +5397,6 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", @@ -5930,9 +5444,9 @@ } }, "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "node_modules/deepmerge": { @@ -6037,9 +5551,9 @@ } }, "node_modules/diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6097,9 +5611,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.3.883", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.883.tgz", - "integrity": "sha512-goyjNx4wB9j911PBteb+AXNbErug7rJVkmDXWdw5SCVn2JlARBwsqucPkvp1h5mXWxHUbBRK3bwXTrqSxSiAIQ==", + "version": "1.4.24", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.24.tgz", + "integrity": "sha512-erwx5r69B/WFfFuF2jcNN0817BfDBdC4765kQ6WltOMuwsimlQo3JTEq0Cle+wpHralwdeX3OfAtw/mHxPK0Wg==", "dev": true }, "node_modules/emittery": { @@ -6115,9 +5629,9 @@ } }, "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/encodeurl": { @@ -6140,39 +5654,63 @@ } }, "node_modules/engine.io": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz", - "integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz", + "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", "dev": true, "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~4.0.0", - "ws": "~7.4.2" + "engine.io-parser": "~5.0.0", + "ws": "~8.2.3" }, "engines": { "node": ">=10.0.0" } }, "node_modules/engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", "dev": true, "dependencies": { - "base64-arraybuffer": "0.1.4" + "base64-arraybuffer": "~1.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -6200,6 +5738,12 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, + "node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -6246,22 +5790,25 @@ } }, "node_modules/es-abstract": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", - "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", - "is-callable": "^1.2.3", + "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", @@ -6277,9 +5824,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", "dev": true }, "node_modules/es-to-primitive": { @@ -6348,74 +5895,14 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.13.0.tgz", - "integrity": "sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", + "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.1", + "@eslint/eslintrc": "^0.3.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -6425,10 +5912,10 @@ "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", + "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", @@ -6439,7 +5926,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -6448,7 +5935,7 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", + "table": "^6.0.4", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, @@ -6463,9 +5950,9 @@ } }, "node_modules/eslint-config-standard": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.2.tgz", - "integrity": "sha512-fx3f1rJDsl9bY7qzyX8SAtP8GBSk6MfXFaTfaGgk12aAYW4gJSyRm7dM790L6cbXv63fvjY4XeSzXnb4WM+SKw==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", "dev": true, "funding": [ { @@ -6485,7 +5972,7 @@ "eslint": "^7.12.1", "eslint-plugin-import": "^2.22.1", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1" + "eslint-plugin-promise": "^4.2.1 || ^5.0.0" } }, "node_modules/eslint-config-standard-jsx": { @@ -6513,37 +6000,32 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "dependencies": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "node_modules/eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", + "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", "dev": true, "dependencies": { "debug": "^3.2.7", + "find-up": "^2.1.0", "pkg-dir": "^2.0.0" }, "engines": { @@ -6559,6 +6041,85 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-module-utils/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/eslint-plugin-es": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", @@ -6579,24 +6140,26 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "dependencies": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", "has": "^1.0.3", + "is-core-module": "^2.6.0", "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" }, "engines": { "node": ">=4" @@ -6615,24 +6178,90 @@ } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-import/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/eslint-plugin-import/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "node_modules/eslint-plugin-import/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -6654,9 +6283,9 @@ } }, "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -6672,31 +6301,36 @@ } }, "node_modules/eslint-plugin-promise": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", + "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", "dev": true, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0" } }, "node_modules/eslint-plugin-react": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", - "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.25.3.tgz", + "integrity": "sha512-ZMbFvZ1WAYSZKY662MBVEWR45VaBT6KSJCiupjrNlcdakB90juaZeDCbJq19e73JZQubqFtgETohwgAt8u5P6w==", "dev": true, "dependencies": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", "doctrine": "^2.1.0", - "has": "^1.0.3", + "estraverse": "^5.2.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.hasown": "^1.0.0", + "object.values": "^1.1.4", "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" }, "engines": { "node": ">=4" @@ -6717,6 +6351,19 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -6727,62 +6374,149 @@ "estraverse": "^4.1.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/eslint/node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">= 0.8.0" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint/node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/eslint/node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/eslint/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=8" } }, "node_modules/espree": { @@ -6799,6 +6533,18 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/espree/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", @@ -6833,15 +6579,6 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -6854,19 +6591,10 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -6924,9 +6652,9 @@ "peer": true }, "node_modules/execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", @@ -7105,17 +6833,17 @@ "peer": true }, "node_modules/expect": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz", - "integrity": "sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", + "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6" + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -7243,15 +6971,15 @@ } }, "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/fill-range": { @@ -7355,22 +7083,6 @@ "node": ">=6" } }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/find-cache-dir/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -7428,19 +7140,16 @@ } }, "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", + "locate-path": "^5.0.0", "path-exists": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/flat": { @@ -7453,19 +7162,24 @@ } }, "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flat-cache/node_modules/flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, "node_modules/flatted": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", @@ -7483,9 +7197,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", "dev": true, "funding": [ { @@ -7675,6 +7389,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -7686,9 +7416,9 @@ } }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -7724,24 +7454,18 @@ "dev": true }, "node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "node_modules/growl": { @@ -7949,27 +7673,21 @@ "dev": true }, "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "dependencies": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.6" } }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", @@ -8021,12 +7739,12 @@ } }, "node_modules/iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" @@ -8060,96 +7778,40 @@ "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, + "peer": true, "dependencies": { - "p-try": "^2.0.0" + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/import-local/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, + "peer": true, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { "node": ">=8" @@ -8256,10 +7918,13 @@ "dev": true }, "node_modules/is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8277,12 +7942,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -8298,9 +7964,9 @@ "dev": true }, "node_modules/is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true, "engines": { "node": ">= 0.4" @@ -8330,9 +7996,9 @@ "peer": true }, "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -8355,10 +8021,13 @@ } }, "node_modules/is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -8418,6 +8087,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -8447,9 +8117,9 @@ } }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" @@ -8459,9 +8129,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, "engines": { "node": ">= 0.4" @@ -8480,10 +8150,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -8519,13 +8192,13 @@ "dev": true }, "node_modules/is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -8534,20 +8207,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -8595,6 +8283,30 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -8619,7 +8331,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "peer": true }, "node_modules/isbinaryfile": { "version": "4.0.8", @@ -8695,18 +8408,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", @@ -8722,9 +8423,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.1.tgz", + "integrity": "sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -8735,14 +8436,14 @@ } }, "node_modules/jest": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.1.tgz", - "integrity": "sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", + "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", "dev": true, "dependencies": { - "@jest/core": "^27.3.1", + "@jest/core": "^27.4.5", "import-local": "^3.0.2", - "jest-cli": "^27.3.1" + "jest-cli": "^27.4.5" }, "bin": { "jest": "bin/jest.js" @@ -8760,12 +8461,12 @@ } }, "node_modules/jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "execa": "^5.0.0", "throat": "^6.0.1" }, @@ -8774,27 +8475,27 @@ } }, "node_modules/jest-circus": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz", - "integrity": "sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", + "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" @@ -8804,21 +8505,21 @@ } }, "node_modules/jest-cli": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz", - "integrity": "sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", + "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", "dev": true, "dependencies": { - "@jest/core": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/core": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-config": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "prompts": "^2.0.1", "yargs": "^16.2.0" }, @@ -8838,32 +8539,33 @@ } }, "node_modules/jest-config": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz", - "integrity": "sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", + "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.1", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.1", + "@jest/test-sequencer": "^27.4.5", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.5", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.3.1", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-jasmine2": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-circus": "^27.4.5", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.2", + "slash": "^3.0.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -8878,24 +8580,24 @@ } }, "node_modules/jest-diff": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz", - "integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", + "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" @@ -8905,33 +8607,33 @@ } }, "node_modules/jest-each": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz", - "integrity": "sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", + "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-environment-jsdom": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz", - "integrity": "sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", + "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2", "jsdom": "^16.6.0" }, "engines": { @@ -8939,47 +8641,47 @@ } }, "node_modules/jest-environment-node": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz", - "integrity": "sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", + "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-get-type": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", - "integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-haste-map": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz", - "integrity": "sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", + "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "micromatch": "^4.0.4", "walker": "^1.0.7" }, @@ -8990,43 +8692,29 @@ "fsevents": "^2.3.2" } }, - "node_modules/jest-haste-map/node_modules/jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/jest-jasmine2": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz", - "integrity": "sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", + "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", "dev": true, "dependencies": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", "throat": "^6.0.1" }, "engines": { @@ -9034,46 +8722,46 @@ } }, "node_modules/jest-leak-detector": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz", - "integrity": "sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", + "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", "dev": true, "dependencies": { - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz", - "integrity": "sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", + "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-message-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz", - "integrity": "sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", + "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -9082,12 +8770,12 @@ } }, "node_modules/jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", + "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/node": "*" }, "engines": { @@ -9112,27 +8800,27 @@ } }, "node_modules/jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-resolve": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz", - "integrity": "sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", + "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", + "jest-haste-map": "^27.4.5", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" @@ -9142,45 +8830,45 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz", - "integrity": "sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", + "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.1" + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.5" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-runner": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz", - "integrity": "sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", + "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", "dev": true, "dependencies": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-leak-detector": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-haste-map": "^27.4.5", + "jest-leak-detector": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "source-map-support": "^0.5.6", "throat": "^6.0.1" }, @@ -9188,33 +8876,19 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/jest-runtime": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz", - "integrity": "sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg==", - "dev": true, - "dependencies": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/globals": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", + "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/globals": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", @@ -9223,14 +8897,14 @@ "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.2.0" @@ -9239,19 +8913,10 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", "dev": true, "dependencies": { "@types/node": "*", @@ -9262,9 +8927,9 @@ } }, "node_modules/jest-snapshot": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz", - "integrity": "sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", + "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", "dev": true, "dependencies": { "@babel/core": "^7.7.2", @@ -9273,23 +8938,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.5", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.2", "semver": "^7.3.2" }, "engines": { @@ -9297,12 +8962,12 @@ } }, "node_modules/jest-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz", - "integrity": "sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -9314,34 +8979,46 @@ } }, "node_modules/jest-validate": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz", - "integrity": "sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", + "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", + "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-watcher": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz", - "integrity": "sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", + "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", "dev": true, "dependencies": { - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.3.1", + "jest-util": "^27.4.2", "string-length": "^4.0.1" }, "engines": { @@ -9349,29 +9026,32 @@ } }, "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", + "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", "dev": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" }, "engines": { "node": ">= 10.13.0" } }, "node_modules/jest-worker/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/jetifier": { @@ -9387,15 +9067,15 @@ } }, "node_modules/joi": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.2.tgz", - "integrity": "sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw==", + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.5.0.tgz", + "integrity": "sha512-R7hR50COp7StzLnDi4ywOXHrBrgNXuUUfJWIR5lPY5Bm/pOD3jZaTwpluUXVLRWcoWZxkrHBBJ5hLxgnlehbdw==", "dev": true, "peer": true, "dependencies": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.0", + "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.0", "@sideway/pinpoint": "^2.0.0" } @@ -9413,17 +9093,27 @@ "dev": true }, "node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, "node_modules/jsc-android": { "version": "250230.2.1", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250230.2.1.tgz", @@ -9616,6 +9306,64 @@ "signal-exit": "^3.0.2" } }, + "node_modules/jsdoc": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", + "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.9.4", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.1", + "klaw": "^3.0.0", + "markdown-it": "^10.0.0", + "markdown-it-anchor": "^5.2.7", + "marked": "^2.0.3", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "taffydb": "2.6.2", + "underscore": "~1.13.1" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=8.15.0" + } + }, + "node_modules/jsdoc/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jsdoc/node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/jsdoc/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -9662,18 +9410,6 @@ } } }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -9705,15 +9441,18 @@ "dev": true }, "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "dependencies": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" }, "bin": { "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jsonfile": { @@ -9736,12 +9475,12 @@ } }, "node_modules/jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", + "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", "dev": true, "dependencies": { - "array-includes": "^3.1.2", + "array-includes": "^3.1.3", "object.assign": "^4.1.2" }, "engines": { @@ -9749,33 +9488,33 @@ } }, "node_modules/karma": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz", - "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==", + "version": "6.3.9", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.9.tgz", + "integrity": "sha512-E/MqdLM9uVIhfuyVnrhlGBu4miafBdXEAEqCmwdEMh3n17C7UWC/8Kvm3AYKr91gc7scutekZ0xv6rxRaUCtnw==", "dev": true, "dependencies": { "body-parser": "^1.19.0", "braces": "^3.0.2", - "chokidar": "^3.4.2", + "chokidar": "^3.5.1", "colors": "^1.4.0", "connect": "^3.7.0", "di": "^0.0.1", "dom-serialize": "^2.2.1", - "glob": "^7.1.6", - "graceful-fs": "^4.2.4", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.6", - "lodash": "^4.17.19", - "log4js": "^6.2.1", - "mime": "^2.4.5", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.3.0", + "mime": "^2.5.2", "minimatch": "^3.0.4", "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.1.0", + "socket.io": "^4.2.0", "source-map": "^0.6.1", - "tmp": "0.2.1", - "ua-parser-js": "^0.7.23", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", "yargs": "^16.1.1" }, "bin": { @@ -9850,21 +9589,6 @@ "source-map-support": "^0.5.5" } }, - "node_modules/karma/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -9903,13 +9627,13 @@ } }, "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { "node": ">= 0.8.0" @@ -9923,21 +9647,39 @@ "immediate": "~3.0.5" } }, + "node_modules/linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", + "parse-json": "^4.0.0", + "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "engines": { "node": ">=4" } }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", @@ -9948,26 +9690,23 @@ } }, "node_modules/localforage": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.9.0.tgz", - "integrity": "sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", "dependencies": { "lie": "3.1.1" } }, "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/lodash": { @@ -9996,16 +9735,26 @@ "dev": true, "peer": true }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "chalk": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log4js": { @@ -10039,16 +9788,6 @@ "logkitty": "bin/logkitty.js" } }, - "node_modules/logkitty/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/logkitty/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -10071,94 +9810,6 @@ "node": ">=0.10.0" } }, - "node_modules/logkitty/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true - }, - "node_modules/logkitty/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/logkitty/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/logkitty/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/logkitty/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/logkitty/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "peer": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/logkitty/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/logkitty/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -10304,6 +9955,43 @@ "node": ">=0.10.0" } }, + "node_modules/markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "dev": true, + "peerDependencies": { + "markdown-it": "*" + } + }, + "node_modules/marked": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true, + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -10315,6 +10003,12 @@ "is-buffer": "~1.1.6" } }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -10465,6 +10159,19 @@ "dev": true, "peer": true }, + "node_modules/metro-cache/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/metro-config": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.66.2.tgz", @@ -10507,6 +10214,19 @@ "@types/yargs-parser": "*" } }, + "node_modules/metro-config/node_modules/camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/metro-config/node_modules/jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", @@ -10551,13 +10271,6 @@ "node": ">= 10" } }, - "node_modules/metro-config/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true - }, "node_modules/metro-core": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.66.2.tgz", @@ -10667,6 +10380,21 @@ "node": ">= 10.14.2" } }, + "node_modules/metro-core/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, "node_modules/metro-hermes-compiler": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.66.2.tgz", @@ -10690,143 +10418,45 @@ "metro-inspector-proxy": "src/cli.js" } }, - "node_modules/metro-inspector-proxy/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/metro-inspector-proxy/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "peer": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/metro-inspector-proxy/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/metro-inspector-proxy/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/metro-inspector-proxy/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true - }, - "node_modules/metro-inspector-proxy/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/metro-inspector-proxy/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/metro-inspector-proxy/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/metro-inspector-proxy/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true - }, - "node_modules/metro-inspector-proxy/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "node_modules/metro-inspector-proxy/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/metro-inspector-proxy/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "peer": true, "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" + "ms": "2.0.0" } }, - "node_modules/metro-inspector-proxy/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/metro-inspector-proxy/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, + "node_modules/metro-inspector-proxy/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + }, "node_modules/metro-inspector-proxy/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -11116,26 +10746,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/metro/node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/metro/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/metro/node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -11175,27 +10785,6 @@ "node": ">=0.10.0" } }, - "node_modules/metro/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true - }, - "node_modules/metro/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/metro/node_modules/fs-extra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", @@ -11208,16 +10797,6 @@ "klaw": "^1.0.0" } }, - "node_modules/metro/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/metro/node_modules/jest-haste-map": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", @@ -11288,6 +10867,21 @@ "node": ">= 10.14.2" } }, + "node_modules/metro/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, "node_modules/metro/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -11298,19 +10892,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/metro/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/metro/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -11318,33 +10899,17 @@ "dev": true, "peer": true }, - "node_modules/metro/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/metro/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/metro/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "peer": true, "dependencies": { - "p-limit": "^2.2.0" + "glob": "^7.1.3" }, - "engines": { - "node": ">=8" + "bin": { + "rimraf": "bin.js" } }, "node_modules/metro/node_modules/source-map": { @@ -11357,21 +10922,6 @@ "node": ">=0.10.0" } }, - "node_modules/metro/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/metro/node_modules/throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -11463,9 +11013,9 @@ } }, "node_modules/mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, "bin": { "mime": "cli.js" @@ -11475,21 +11025,21 @@ } }, "node_modules/mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "dependencies": { - "mime-db": "1.47.0" + "mime-db": "1.51.0" }, "engines": { "node": ">= 0.6" @@ -11549,33 +11099,32 @@ } }, "node_modules/mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", "dev": true, "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", + "chokidar": "3.5.2", + "debug": "4.3.2", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.6", + "glob": "7.1.7", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", "minimatch": "3.0.4", "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", + "nanoid": "3.1.25", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", + "workerpool": "6.1.5", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -11585,75 +11134,197 @@ "mocha": "bin/mocha" }, "engines": { - "node": ">= 10.12.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha-junit-reporter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.2.tgz", + "integrity": "sha512-vYwWq5hh3v1lG0gdQCBxwNipBfvDiAM1PHroQRNp96+2l72e9wEUTw+mzoK+O0SudgfQ7WvTQZ9Nh3qkAYAjfg==", + "dev": true, + "dependencies": { + "debug": "^2.2.0", + "md5": "^2.1.0", + "mkdirp": "~0.5.1", + "strip-ansi": "^6.0.1", + "xml": "^1.0.0" + }, + "peerDependencies": { + "mocha": ">=2.2.5" + } + }, + "node_modules/mocha-junit-reporter/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/mocha-junit-reporter/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha-junit-reporter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.0.tgz", - "integrity": "sha512-20HoWh2HEfhqmigfXOKUhZQyX23JImskc37ZOhIjBKoBEsb+4cAFRJpAVhFpnvsztLklW/gFVzsrobjLwmX4lA==", + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "debug": "^2.2.0", - "md5": "^2.1.0", - "mkdirp": "~0.5.1", - "strip-ansi": "^4.0.0", - "xml": "^1.0.0" + "yocto-queue": "^0.1.0" }, - "peerDependencies": { - "mocha": ">=2.2.5" - } - }, - "node_modules/mocha-junit-reporter/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha-junit-reporter/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "ms": "2.0.0" + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha-junit-reporter/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/mocha-junit-reporter/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "ansi-regex": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -11737,9 +11408,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", "dev": true, "peer": true, "dependencies": { @@ -11780,15 +11451,6 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/node-releases": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", @@ -11973,9 +11635,9 @@ } }, "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12022,30 +11684,28 @@ } }, "node_modules/object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" + "es-abstract": "^1.19.1" }, "engines": { "node": ">= 0.4" @@ -12054,6 +11714,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.hasown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", + "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -12068,15 +11741,14 @@ } }, "node_modules/object.values": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", - "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" + "es-abstract": "^1.19.1" }, "engines": { "node": ">= 0.4" @@ -12145,17 +11817,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" }, "engines": { "node": ">= 0.8.0" @@ -12324,33 +11996,30 @@ } }, "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "yocto-queue": "^0.1.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/p-try": { @@ -12375,15 +12044,16 @@ } }, "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "dependencies": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/parse5": { @@ -12445,18 +12115,18 @@ } }, "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "dependencies": { - "pify": "^2.0.0" + "pify": "^3.0.0" }, "engines": { "node": ">=4" @@ -12478,9 +12148,9 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true, "engines": { "node": ">=8.6" @@ -12490,22 +12160,19 @@ } }, "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", + "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", "dev": true, - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, "engines": { "node": ">= 6" } @@ -12564,21 +12231,6 @@ "node": ">=6" } }, - "node_modules/pkg-conf/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pkg-conf/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -12591,19 +12243,6 @@ "node": ">=6" } }, - "node_modules/pkg-conf/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/pkg-conf/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -12622,6 +12261,15 @@ "node": ">=6" } }, + "node_modules/pkg-conf/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/pkg-conf/node_modules/type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", @@ -12632,9 +12280,21 @@ } }, "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, "dependencies": { "find-up": "^2.1.0" @@ -12643,7 +12303,7 @@ "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/find-up": { + "node_modules/pkg-up/node_modules/find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", @@ -12655,7 +12315,7 @@ "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/locate-path": { + "node_modules/pkg-up/node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", @@ -12668,7 +12328,7 @@ "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/p-limit": { + "node_modules/pkg-up/node_modules/p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", @@ -12680,7 +12340,7 @@ "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/p-locate": { + "node_modules/pkg-up/node_modules/p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", @@ -12692,7 +12352,7 @@ "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/p-try": { + "node_modules/pkg-up/node_modules/p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", @@ -12701,7 +12361,7 @@ "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/path-exists": { + "node_modules/pkg-up/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", @@ -12745,21 +12405,21 @@ } }, "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/pretty-format": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", - "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", + "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" @@ -12780,12 +12440,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -12845,6 +12499,12 @@ "react-is": "^16.8.1" } }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -12881,12 +12541,15 @@ } }, "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", "dev": true, "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/randombytes": { @@ -12908,13 +12571,13 @@ } }, "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "dev": true, "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -12922,18 +12585,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -12949,9 +12600,9 @@ } }, "node_modules/react-devtools-core": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.20.2.tgz", - "integrity": "sha512-ep2j84M1ZtDFWsTtFrKyLyg4GEbnw4gFj/8brA+BZtsINgKHhWEVzscz5E/bFWRdyTM8mWdcaKQAk2hR+IezPw==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.22.1.tgz", + "integrity": "sha512-pvpNDHE7p0FtcCmIWGazoY8LLVfBI9sw0Kf10kdHhPI9Tzt3OG/qEt16GrAbE0keuna5WzX3r1qPKVjqOqsuUg==", "dev": true, "peer": true, "dependencies": { @@ -12960,15 +12611,15 @@ } }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, "node_modules/react-native": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.66.1.tgz", - "integrity": "sha512-BBvytmqlOLL+bRcO0jBiYfg16lYRsYDOC8/5E+bpnhb3EGtU+YCQAYfszw6JL7Hfy0ftnQNP5yj8pt+vqMHXIA==", + "version": "0.66.4", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.66.4.tgz", + "integrity": "sha512-9vx5dlSfQlKbbDtr8+xMon6qsmSu7jvjdXWZpEKh3XVKpUidbbODv7048gwVKX8YAel1egeR7hN8vzSeI6ssTw==", "dev": true, "peer": true, "dependencies": { @@ -13069,13 +12720,6 @@ "node": ">= 10" } }, - "node_modules/react-native/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true - }, "node_modules/react-native/node_modules/ws": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", @@ -13097,27 +12741,27 @@ } }, "node_modules/read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "dependencies": { - "load-json-file": "^2.0.0", + "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "path-type": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "dependencies": { "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "read-pkg": "^3.0.0" }, "engines": { "node": ">=4" @@ -13206,17 +12850,10 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true - }, "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { "picomatch": "^2.2.1" @@ -13249,9 +12886,9 @@ } }, "node_modules/rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, "dependencies": { "resolve": "^1.9.0" @@ -13328,9 +12965,9 @@ } }, "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { "node": ">=8" @@ -13423,6 +13060,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -13436,6 +13082,15 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "node_modules/requizzle": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", + "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -13461,7 +13116,7 @@ "node": ">=8" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", @@ -13470,15 +13125,6 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -13550,15 +13196,18 @@ "dev": true }, "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rsvp": { @@ -13572,24 +13221,10 @@ } }, "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/safe-regex": { "version": "1.1.0", @@ -13954,12 +13589,12 @@ } }, "node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.6", + "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" }, @@ -13987,9 +13622,9 @@ } }, "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dev": true, "peer": true, "dependencies": { @@ -14000,9 +13635,9 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "1.8.1", "mime": "1.6.0", - "ms": "2.1.1", + "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" @@ -14042,9 +13677,9 @@ } }, "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "peer": true }, @@ -14059,25 +13694,25 @@ } }, "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dev": true, "peer": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.17.2" }, "engines": { "node": ">= 0.8.0" @@ -14136,9 +13771,9 @@ "dev": true }, "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "node_modules/shallow-clone": { @@ -14202,9 +13837,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, "node_modules/simple-plist": { @@ -14239,6 +13874,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", @@ -14253,6 +13889,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "peer": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -14265,6 +13902,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -14273,7 +13911,8 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "dev": true, + "peer": true }, "node_modules/snapdragon": { "version": "0.8.2", @@ -14490,29 +14129,26 @@ } }, "node_modules/socket.io": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", - "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.0.tgz", + "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", "dev": true, "dependencies": { - "@types/cookie": "^0.4.0", - "@types/cors": "^2.8.8", - "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "~2.0.0", - "debug": "~4.3.1", - "engine.io": "~4.1.0", - "socket.io-adapter": "~2.1.0", - "socket.io-parser": "~4.0.3" + "debug": "~4.3.2", + "engine.io": "~6.1.0", + "socket.io-adapter": "~2.3.3", + "socket.io-parser": "~4.0.4" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-adapter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", - "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", + "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==", "dev": true }, "node_modules/socket.io-parser": { @@ -14529,12 +14165,6 @@ "node": ">=10.0.0" } }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -14574,6 +14204,18 @@ "webpack": "^5.0.0" } }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-resolve": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", @@ -14589,9 +14231,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -14632,9 +14274,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", - "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, "node_modules/split-string": { @@ -14708,9 +14350,9 @@ } }, "node_modules/standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/standard/-/standard-16.0.3.tgz", - "integrity": "sha512-70F7NH0hSkNXosXRltjSv6KpTAOkUkSfyu3ynyM5dtRUiLtR+yX9EGZ7RKwuGUqCJiX/cnkceVM6HTZ4JpaqDg==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/standard/-/standard-16.0.4.tgz", + "integrity": "sha512-2AGI874RNClW4xUdM+bg1LRXVlYLzTNEkHmTG5mhyn45OhbgwA+6znowkOGYy+WMb5HRyELvtNy39kcdMQMcYQ==", "dev": true, "funding": [ { @@ -14727,20 +14369,20 @@ } ], "dependencies": { - "eslint": "~7.13.0", - "eslint-config-standard": "16.0.2", + "eslint": "~7.18.0", + "eslint-config-standard": "16.0.3", "eslint-config-standard-jsx": "10.0.0", - "eslint-plugin-import": "~2.22.1", + "eslint-plugin-import": "~2.24.2", "eslint-plugin-node": "~11.1.0", - "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.21.5", + "eslint-plugin-promise": "~5.1.0", + "eslint-plugin-react": "~7.25.1", "standard-engine": "^14.0.1" }, "bin": { "standard": "bin/cmd.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10.12.0" } }, "node_modules/standard-engine": { @@ -14928,13 +14570,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -14949,50 +14584,39 @@ } }, "node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/string.prototype.matchall": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz", - "integrity": "sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", + "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has-symbols": "^1.0.1", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", "regexp.prototype.flags": "^1.3.1", "side-channel": "^1.0.4" @@ -15040,12 +14664,12 @@ } }, "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-eof": { @@ -15087,18 +14711,15 @@ "peer": true }, "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=8" } }, "node_modules/supports-hyperlinks": { @@ -15114,43 +14735,95 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/table": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", + "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "node_modules/table/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, "node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, "engines": { "node": ">=6" @@ -15197,34 +14870,41 @@ } }, "node_modules/terser": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", - "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", "dev": true, "dependencies": { "commander": "^2.20.0", "source-map": "~0.7.2", - "source-map-support": "~0.5.19" + "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" }, "engines": { "node": ">=10" + }, + "peerDependencies": { + "acorn": "^8.5.0" + }, + "peerDependenciesMeta": { + "acorn": { + "optional": true + } } }, "node_modules/terser-webpack-plugin": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz", - "integrity": "sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz", + "integrity": "sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==", "dev": true, "dependencies": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", + "jest-worker": "^27.4.1", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", "source-map": "^0.6.1", - "terser": "^5.7.0" + "terser": "^5.7.2" }, "engines": { "node": ">= 10.13.0" @@ -15235,6 +14915,17 @@ }, "peerDependencies": { "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } } }, "node_modules/terser/node_modules/commander": { @@ -15313,21 +15004,6 @@ "node": ">=8.17.0" } }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -15398,9 +15074,9 @@ } }, "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "engines": { "node": ">=0.6" @@ -15433,9 +15109,9 @@ } }, "node_modules/ts-jest": { - "version": "27.0.7", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", - "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", + "version": "27.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.2.tgz", + "integrity": "sha512-eSOiJOWq6Hhs6Khzk5wKC5sgWIXgXqOCiIl1+3lfnearu58Hj4QpE5tUhQcA3xtZrELbcvAGCsd6HB8OsaVaTA==", "dev": true, "dependencies": { "bs-logger": "0.x", @@ -15457,6 +15133,7 @@ "@babel/core": ">=7.0.0-beta.0 <8", "@types/jest": "^27.0.0", "babel-jest": ">=27.0.0 <28", + "esbuild": "~0.14.0", "jest": "^27.0.0", "typescript": ">=3.8 <5.0" }, @@ -15469,28 +15146,16 @@ }, "babel-jest": { "optional": true + }, + "esbuild": { + "optional": true } } }, - "node_modules/ts-jest/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/ts-node": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", - "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.7.0", @@ -15528,14 +15193,11 @@ } } }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, "engines": { "node": ">=0.4.0" } @@ -15550,9 +15212,9 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", @@ -15561,6 +15223,27 @@ "strip-bom": "^3.0.0" } }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -15569,12 +15252,12 @@ "peer": true }, "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1" + "prelude-ls": "~1.1.2" }, "engines": { "node": ">= 0.8.0" @@ -15590,12 +15273,15 @@ } }, "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/type-is": { @@ -15621,9 +15307,9 @@ } }, "node_modules/typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -15634,9 +15320,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.7.28", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", - "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==", + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", + "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", "dev": true, "funding": [ { @@ -15652,6 +15338,12 @@ "node": "*" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "node_modules/uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -15699,6 +15391,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/underscore": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -16015,9 +15713,9 @@ } }, "node_modules/watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", + "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -16047,22 +15745,23 @@ } }, "node_modules/webpack": { - "version": "5.37.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.37.0.tgz", - "integrity": "sha512-yvdhgcI6QkQkDe1hINBAJ1UNevqNGTVaCkD2SSJcB8rcrNNl922RI8i2DXUAuNfANoxwsiXXEA4ZPZI9q2oGLA==", + "version": "5.65.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", + "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.2.1", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.4", @@ -16070,11 +15769,11 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", + "schema-utils": "^3.1.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.1", + "webpack-sources": "^3.2.2" }, "bin": { "webpack": "bin/webpack.js" @@ -16093,23 +15792,22 @@ } }, "node_modules/webpack-cli": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.0.tgz", - "integrity": "sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", + "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.3", - "@webpack-cli/info": "^1.2.4", - "@webpack-cli/serve": "^1.4.0", - "colorette": "^1.2.1", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", "commander": "^7.0.0", "execa": "^5.0.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^2.2.0", "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", "webpack-merge": "^5.7.3" }, "bin": { @@ -16136,10 +15834,16 @@ } } }, + "node_modules/webpack-cli/node_modules/colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, "node_modules/webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", @@ -16150,30 +15854,14 @@ } }, "node_modules/webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", + "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", "dev": true, - "dependencies": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - }, "engines": { "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -16183,18 +15871,6 @@ "iconv-lite": "0.4.24" } }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/whatwg-fetch": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", @@ -16280,49 +15956,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -16339,9 +15972,9 @@ } }, "node_modules/workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", "dev": true }, "node_modules/wrap-ansi": { @@ -16361,53 +15994,12 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -16421,9 +16013,9 @@ } }, "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", "dev": true, "engines": { "node": ">=8.3.0" @@ -16491,6 +16083,12 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "node_modules/xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", @@ -16608,33 +16206,16 @@ "node": ">=10" } }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "node": ">=10" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yn": { @@ -16661,35 +16242,35 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.0" } }, "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", "dev": true }, "@babel/core": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", + "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helpers": "^7.16.5", + "@babel/parser": "^7.16.5", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -16698,15 +16279,6 @@ "source-map": "^0.5.0" }, "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -16722,12 +16294,12 @@ } }, "@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", + "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", "dev": true, "requires": { - "@babel/types": "^7.15.6", + "@babel/types": "^7.16.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -16741,35 +16313,35 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", - "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", + "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", "dev": true, "peer": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-explode-assignable-expression": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", + "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", + "@babel/compat-data": "^7.16.0", "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "browserslist": "^4.17.5", "semver": "^6.3.0" }, "dependencies": { @@ -16782,35 +16354,36 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", - "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", + "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", "dev": true, "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4" + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", + "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", "dev": true, "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-annotate-as-pure": "^7.16.0", "regexpu-core": "^4.7.1" } }, "@babel/helper-define-polyfill-provider": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", - "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", + "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", "dev": true, "peer": true, "requires": { @@ -16833,144 +16406,157 @@ } } }, + "@babel/helper-environment-visitor": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", + "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, "@babel/helper-explode-assignable-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", - "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", + "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", + "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", + "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", + "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", + "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", "dev": true, + "peer": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", + "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" } }, "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", + "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", "dev": true, + "peer": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", + "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", - "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", + "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", "dev": true, "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-wrap-function": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-wrap-function": "^7.16.5", + "@babel/types": "^7.16.0" } }, "@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", + "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", "dev": true, + "peer": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" } }, "@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", + "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", - "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, "peer": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", + "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-validator-identifier": { @@ -16986,36 +16572,36 @@ "dev": true }, "@babel/helper-wrap-function": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", - "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", + "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", "dev": true, "peer": true, "requires": { - "@babel/helper-function-name": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-function-name": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" } }, "@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", + "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", "dev": true, "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" } }, "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -17079,205 +16665,215 @@ } }, "@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "version": "7.16.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", + "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", "dev": true }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", + "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz", - "integrity": "sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", + "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", "dev": true, "peer": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", - "@babel/plugin-proposal-optional-chaining": "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz", - "integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", + "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.15.4", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", - "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", + "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz", - "integrity": "sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", + "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", - "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", + "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-default-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.14.5.tgz", - "integrity": "sha512-T8KZ5abXvKMjF6JcoXjgac3ElmXf0AWzJwi2O/42Jk+HmCky3D9+i1B7NPP1FblyceqTevKeV/9szeikFoaMDg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.5.tgz", + "integrity": "sha512-pU4aCS+AzGjDD/6LnwSmeelmtqfMSjzQxs7+/AS673bYsshK1XZm9eth6OkgivVscQM8XdkVYhrb6tPFVTBVHA==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-export-default-from": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-export-default-from": "^7.16.5" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", - "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", + "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", + "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", - "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", + "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", + "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", + "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", - "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", + "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", "dev": true, "peer": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" + "@babel/plugin-transform-parameters": "^7.16.5" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", + "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", + "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", - "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", + "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", - "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", + "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", "dev": true, "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", - "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", + "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-syntax-async-generators": { @@ -17328,13 +16924,13 @@ } }, "@babel/plugin-syntax-export-default-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.14.5.tgz", - "integrity": "sha512-snWDxjuaPEobRBnhpqEfZ8RMxDbHt8+87fiEioGuE+Uc0xAKgSD8QiuL3lF93hPVQfZFAcYwrrf+H5qUhike3Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.5.tgz", + "integrity": "sha512-tvY55nhq4mSG9WbM7IZcLIhdc5jzIZu0PQKJHtZ16+dF7oBxKbqV/Z0e9ta2zaLMvUjH+3rJv1hbZ0+lpXzuFQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-syntax-export-namespace-from": { @@ -17348,13 +16944,13 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", - "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.5.tgz", + "integrity": "sha512-Nrx+7EAJx1BieBQseZa2pavVH2Rp7hADK2xn7coYqVbWRu9C2OFizYcsKo6TrrqJkJl+qF/+Qqzrk/+XDu4GnA==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-syntax-import-meta": { @@ -17376,13 +16972,13 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", - "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz", + "integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -17459,344 +17055,336 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", + "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", + "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", + "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", "dev": true, "peer": true, "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5" + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", + "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", - "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", + "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-classes": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", - "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", + "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", "dev": true, "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0", "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "peer": true - } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", + "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-destructuring": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", + "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", - "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", + "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", - "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", + "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", + "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", "dev": true, "peer": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", - "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.5.tgz", + "integrity": "sha512-skE02E/MptkZdBS4HwoRhjWXqeKQj0BWKEAPfPC+8R4/f6bjQqQ9Nftv/+HkxWwnVxh/E2NV9TNfzLN5H/oiBw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-flow": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-flow": "^7.16.5" } }, "@babel/plugin-transform-for-of": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", - "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", + "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", - "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", + "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", + "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", - "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", + "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", - "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", + "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", - "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", + "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-simple-access": "^7.16.0", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", - "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", + "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", "dev": true, "peer": true, "requires": { - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-identifier": "^7.15.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", - "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", + "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", "dev": true, "peer": true, "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", - "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", + "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0" } }, "@babel/plugin-transform-new-target": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", - "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", + "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-object-assign": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz", - "integrity": "sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.5.tgz", + "integrity": "sha512-KVuJ7sWf6bcXawKVH6ZDQFYcOulObt1IOvl/gvNrkNXzmFf1IdgKOy4thmVomReleXqffMbptmXXMl3zPI7zHw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-object-super": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", + "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5" } }, "@babel/plugin-transform-parameters": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", - "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", + "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", + "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-react-display-name": { - "version": "7.15.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.15.1.tgz", - "integrity": "sha512-yQZ/i/pUCJAHI/LbtZr413S3VT26qNrEm0M5RRxQJA947/YNYwbZbBaXGDrq6CG5QsZycI1VIP6d7pQaBfP+8Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.5.tgz", + "integrity": "sha512-dHYCOnzSsXFz8UcdNQIHGvg94qPL/teF7CCiCEMRxmA1G2p5Mq4JnKVowCDxYfiQ9D7RstaAp9kwaSI+sXbnhw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.9.tgz", - "integrity": "sha512-30PeETvS+AeD1f58i1OVyoDlVYQhap/K20ZrMjLmmzmC2AYR/G43D4sdJAaDAqCD3MYpSWbmrz3kES158QSLjw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.5.tgz", + "integrity": "sha512-+arLIz1d7kmwX0fKxTxbnoeG85ONSnLpvdODa4P3pc1sS7CV1hfmtYWufkW/oYsPnkDrEeQFxhUWcFnrXW7jQQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-jsx": "^7.14.5", - "@babel/types": "^7.14.9" + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-jsx": "^7.16.5", + "@babel/types": "^7.16.0" } }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.14.9.tgz", - "integrity": "sha512-Fqqu0f8zv9W+RyOnx29BX/RlEsBRANbOf5xs5oxb2aHP4FKbLXxIaVPUiCti56LAR1IixMH4EyaixhUsKqoBHw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.5.tgz", + "integrity": "sha512-fvwq+jir1Vn4f5oBS0H/J/gD5CneTD53MHs+NMjlHcha4Sq35fwxI5RtmJGEBXO+M93f/eeD9cAhRPhmLyJiVw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.5.tgz", - "integrity": "sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.5.tgz", + "integrity": "sha512-/eP+nZywJntGLjSPjksAnM9/ELIs3RbiEuTu2/zAOzwwBcfiu+m/iptEq1lERUUtSXubYSHVnVHMr13GR+TwPw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-regenerator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", + "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", "dev": true, "peer": true, "requires": { @@ -17804,27 +17392,27 @@ } }, "@babel/plugin-transform-reserved-words": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", - "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", + "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-runtime": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.8.tgz", - "integrity": "sha512-+6zsde91jMzzvkzuEA3k63zCw+tm/GvuuabkpisgbDMTPQsIMHllE3XczJFFtEHLjjhKQFZmGQVRdELetlWpVw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz", + "integrity": "sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw==", "dev": true, "peer": true, "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "babel-plugin-polyfill-corejs2": "^0.2.2", - "babel-plugin-polyfill-corejs3": "^0.2.5", - "babel-plugin-polyfill-regenerator": "^0.2.2", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", "semver": "^6.3.0" }, "dependencies": { @@ -17838,116 +17426,117 @@ } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", + "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-spread": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz", - "integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", + "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", + "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-template-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", + "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", + "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-typescript": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", - "integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", + "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-create-class-features-plugin": "^7.16.0", "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.14.5" + "@babel/plugin-syntax-typescript": "^7.16.0" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", - "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", + "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", + "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, "@babel/preset-env": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz", - "integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", + "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", "dev": true, "peer": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4", - "@babel/plugin-proposal-async-generator-functions": "^7.15.8", - "@babel/plugin-proposal-class-properties": "^7.14.5", - "@babel/plugin-proposal-class-static-block": "^7.15.4", - "@babel/plugin-proposal-dynamic-import": "^7.14.5", - "@babel/plugin-proposal-export-namespace-from": "^7.14.5", - "@babel/plugin-proposal-json-strings": "^7.14.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", - "@babel/plugin-proposal-numeric-separator": "^7.14.5", - "@babel/plugin-proposal-object-rest-spread": "^7.15.6", - "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", - "@babel/plugin-proposal-optional-chaining": "^7.14.5", - "@babel/plugin-proposal-private-methods": "^7.14.5", - "@babel/plugin-proposal-private-property-in-object": "^7.15.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-async-generator-functions": "^7.16.5", + "@babel/plugin-proposal-class-properties": "^7.16.5", + "@babel/plugin-proposal-class-static-block": "^7.16.5", + "@babel/plugin-proposal-dynamic-import": "^7.16.5", + "@babel/plugin-proposal-export-namespace-from": "^7.16.5", + "@babel/plugin-proposal-json-strings": "^7.16.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", + "@babel/plugin-proposal-numeric-separator": "^7.16.5", + "@babel/plugin-proposal-object-rest-spread": "^7.16.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", + "@babel/plugin-proposal-optional-chaining": "^7.16.5", + "@babel/plugin-proposal-private-methods": "^7.16.5", + "@babel/plugin-proposal-private-property-in-object": "^7.16.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", @@ -17962,44 +17551,44 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.14.5", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/plugin-transform-block-scoped-functions": "^7.14.5", - "@babel/plugin-transform-block-scoping": "^7.15.3", - "@babel/plugin-transform-classes": "^7.15.4", - "@babel/plugin-transform-computed-properties": "^7.14.5", - "@babel/plugin-transform-destructuring": "^7.14.7", - "@babel/plugin-transform-dotall-regex": "^7.14.5", - "@babel/plugin-transform-duplicate-keys": "^7.14.5", - "@babel/plugin-transform-exponentiation-operator": "^7.14.5", - "@babel/plugin-transform-for-of": "^7.15.4", - "@babel/plugin-transform-function-name": "^7.14.5", - "@babel/plugin-transform-literals": "^7.14.5", - "@babel/plugin-transform-member-expression-literals": "^7.14.5", - "@babel/plugin-transform-modules-amd": "^7.14.5", - "@babel/plugin-transform-modules-commonjs": "^7.15.4", - "@babel/plugin-transform-modules-systemjs": "^7.15.4", - "@babel/plugin-transform-modules-umd": "^7.14.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9", - "@babel/plugin-transform-new-target": "^7.14.5", - "@babel/plugin-transform-object-super": "^7.14.5", - "@babel/plugin-transform-parameters": "^7.15.4", - "@babel/plugin-transform-property-literals": "^7.14.5", - "@babel/plugin-transform-regenerator": "^7.14.5", - "@babel/plugin-transform-reserved-words": "^7.14.5", - "@babel/plugin-transform-shorthand-properties": "^7.14.5", - "@babel/plugin-transform-spread": "^7.15.8", - "@babel/plugin-transform-sticky-regex": "^7.14.5", - "@babel/plugin-transform-template-literals": "^7.14.5", - "@babel/plugin-transform-typeof-symbol": "^7.14.5", - "@babel/plugin-transform-unicode-escapes": "^7.14.5", - "@babel/plugin-transform-unicode-regex": "^7.14.5", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.15.6", - "babel-plugin-polyfill-corejs2": "^0.2.2", - "babel-plugin-polyfill-corejs3": "^0.2.5", - "babel-plugin-polyfill-regenerator": "^0.2.2", - "core-js-compat": "^3.16.0", + "@babel/plugin-transform-arrow-functions": "^7.16.5", + "@babel/plugin-transform-async-to-generator": "^7.16.5", + "@babel/plugin-transform-block-scoped-functions": "^7.16.5", + "@babel/plugin-transform-block-scoping": "^7.16.5", + "@babel/plugin-transform-classes": "^7.16.5", + "@babel/plugin-transform-computed-properties": "^7.16.5", + "@babel/plugin-transform-destructuring": "^7.16.5", + "@babel/plugin-transform-dotall-regex": "^7.16.5", + "@babel/plugin-transform-duplicate-keys": "^7.16.5", + "@babel/plugin-transform-exponentiation-operator": "^7.16.5", + "@babel/plugin-transform-for-of": "^7.16.5", + "@babel/plugin-transform-function-name": "^7.16.5", + "@babel/plugin-transform-literals": "^7.16.5", + "@babel/plugin-transform-member-expression-literals": "^7.16.5", + "@babel/plugin-transform-modules-amd": "^7.16.5", + "@babel/plugin-transform-modules-commonjs": "^7.16.5", + "@babel/plugin-transform-modules-systemjs": "^7.16.5", + "@babel/plugin-transform-modules-umd": "^7.16.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", + "@babel/plugin-transform-new-target": "^7.16.5", + "@babel/plugin-transform-object-super": "^7.16.5", + "@babel/plugin-transform-parameters": "^7.16.5", + "@babel/plugin-transform-property-literals": "^7.16.5", + "@babel/plugin-transform-regenerator": "^7.16.5", + "@babel/plugin-transform-reserved-words": "^7.16.5", + "@babel/plugin-transform-shorthand-properties": "^7.16.5", + "@babel/plugin-transform-spread": "^7.16.5", + "@babel/plugin-transform-sticky-regex": "^7.16.5", + "@babel/plugin-transform-template-literals": "^7.16.5", + "@babel/plugin-transform-typeof-symbol": "^7.16.5", + "@babel/plugin-transform-unicode-escapes": "^7.16.5", + "@babel/plugin-transform-unicode-regex": "^7.16.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.0", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.19.1", "semver": "^6.3.0" }, "dependencies": { @@ -18013,15 +17602,15 @@ } }, "@babel/preset-flow": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.14.5.tgz", - "integrity": "sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.16.5.tgz", + "integrity": "sha512-rmC6Nznp4V55N4Zfec87jwd14TdREqwKVJFM/6Z2wTwoeZQr56czjaPRCezqzqc8TsHF7aLP1oczjadIQ058gw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-flow-strip-types": "^7.14.5" + "@babel/plugin-transform-flow-strip-types": "^7.16.5" } }, "@babel/preset-modules": { @@ -18039,21 +17628,21 @@ } }, "@babel/preset-typescript": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", - "integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", + "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.15.0" + "@babel/plugin-transform-typescript": "^7.16.1" } }, "@babel/register": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.15.3.tgz", - "integrity": "sha512-mj4IY1ZJkorClxKTImccn4T81+UKTo4Ux0+OFSV9hME1ooqS9UV+pJ6BjD0qXPK4T3XW/KNa79XByjeEMZz+fw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.5.tgz", + "integrity": "sha512-NpluD+cToBiZiDsG3y9rtIcqDyivsahpaM9csfyfiq1qQWduSmihUZ+ruIqqSDGjZKZMJfgAElo9x2YWlOQuRw==", "dev": true, "peer": true, "requires": { @@ -18092,9 +17681,9 @@ } }, "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", "dev": true, "peer": true, "requires": { @@ -18102,48 +17691,41 @@ } }, "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", + "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", + "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.5", + "@babel/types": "^7.16.0", "debug": "^4.1.0", "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } } }, "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" } }, @@ -18180,15 +17762,15 @@ } }, "@discoveryjs/json-ext": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", - "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", + "integrity": "sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==", "dev": true }, "@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", + "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -18198,29 +17780,41 @@ "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "type-fest": "^0.8.1" } }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -18252,76 +17846,6 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } } }, "@istanbuljs/schema": { @@ -18331,124 +17855,113 @@ "dev": true }, "@jest/console": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz", - "integrity": "sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", + "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.3.1", - "jest-util": "^27.3.1", + "jest-message-util": "^27.4.2", + "jest-util": "^27.4.2", "slash": "^3.0.0" } }, "@jest/core": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz", - "integrity": "sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", + "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", "dev": true, "requires": { - "@jest/console": "^27.3.1", - "@jest/reporters": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/reporters": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-resolve-dependencies": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "jest-watcher": "^27.3.1", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.5", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-resolve-dependencies": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "jest-watcher": "^27.4.2", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "@jest/create-cache-key-function": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.3.1.tgz", - "integrity": "sha512-21lx0HRgkznc5Tc2WGiXVYQQ6Vdfohs6CkLV2FLogLRb52f6v9SiSIjTNflu23lzEmY4EalLgQLxCfhgvREV6w==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.4.2.tgz", + "integrity": "sha512-aSSCAJwUNX4R1hJQoyimsND5l+2EsFgzlepS8NuOJJHjXij/UdxYFngac44tmv9IYdI+kglAyORg0plt4/aFMQ==", "dev": true, "peer": true, "requires": { - "@jest/types": "^27.2.5" + "@jest/types": "^27.4.2" } }, "@jest/environment": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz", - "integrity": "sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", + "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", "dev": true, "requires": { - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0" + "jest-mock": "^27.4.2" } }, "@jest/fake-timers": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz", - "integrity": "sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", + "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" } }, "@jest/globals": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz", - "integrity": "sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", + "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", "dev": true, "requires": { - "@jest/environment": "^27.3.1", - "@jest/types": "^27.2.5", - "expect": "^27.3.1" + "@jest/environment": "^27.4.4", + "@jest/types": "^27.4.2", + "expect": "^27.4.2" } }, "@jest/reporters": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz", - "integrity": "sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", + "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -18460,34 +17973,21 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", "v8-to-istanbul": "^8.1.0" - }, - "dependencies": { - "jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - } } }, "@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -18496,45 +17996,45 @@ } }, "@jest/test-result": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz", - "integrity": "sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", + "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", "dev": true, "requires": { - "@jest/console": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz", - "integrity": "sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", + "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", "dev": true, "requires": { - "@jest/test-result": "^27.3.1", + "@jest/test-result": "^27.4.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-runtime": "^27.3.1" + "jest-haste-map": "^27.4.5", + "jest-runtime": "^27.4.5" } }, "@jest/transform": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz", - "integrity": "sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", + "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -18543,9 +18043,9 @@ } }, "@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -18556,29 +18056,29 @@ } }, "@react-native-async-storage/async-storage": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.9.tgz", - "integrity": "sha512-LrVPfhKqodRiDWCgZp7J2X55JQqOhdQUxbl17RrktIGCZ0ud2XHdNoTIvyI1VccqHoF/CZK6v+G0IoX5NYZ1JA==", + "version": "1.15.14", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.14.tgz", + "integrity": "sha512-eJF2horabXazwszCyyXDe4w7sBSWlB0WPA8akKXuN2n7WXKHYeQJPN41lS9OahrhSZuZwqftNFE9VWgPXA8wyA==", "dev": true, "requires": { "merge-options": "^3.0.4" } }, "@react-native-community/cli": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-6.1.0.tgz", - "integrity": "sha512-Ck1XjvsnYYVYqooxmSlvRvGMGgxj3t+evUGlg80b+TxnurhlGq8D8pW7++L/sECChI43YWMBtLIdAYG/lGkN8Q==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-6.3.1.tgz", + "integrity": "sha512-UQ77AkGvPzdwJt6qhYXUyDMP1v2rdCcIlrhU48FOcAhGX+N/LCL9Cp/Ic6CkiiSHJdktbgiEEJ2srprXH8nzVg==", "dev": true, "peer": true, "requires": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", - "@react-native-community/cli-hermes": "^6.1.0", - "@react-native-community/cli-plugin-metro": "^6.1.0", - "@react-native-community/cli-server-api": "^6.1.0", - "@react-native-community/cli-tools": "^6.1.0", + "@react-native-community/cli-hermes": "^6.3.0", + "@react-native-community/cli-plugin-metro": "^6.2.0", + "@react-native-community/cli-server-api": "^6.2.0", + "@react-native-community/cli-tools": "^6.2.0", "@react-native-community/cli-types": "^6.0.0", "appdirsjs": "^1.2.4", - "chalk": "^3.0.0", + "chalk": "^4.1.2", "command-exists": "^1.2.8", "commander": "^2.19.0", "cosmiconfig": "^5.1.0", @@ -18593,7 +18093,6 @@ "leven": "^3.1.0", "lodash": "^4.17.15", "minimist": "^1.2.0", - "mkdirp": "^0.5.1", "node-stream-zip": "^1.9.1", "ora": "^3.4.0", "pretty-format": "^26.6.2", @@ -18617,19 +18116,6 @@ "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } } }, "@types/yargs": { @@ -18642,17 +18128,6 @@ "@types/yargs-parser": "*" } }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -18706,17 +18181,6 @@ "strip-eof": "^1.0.0" } }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -18734,16 +18198,6 @@ "dev": true, "peer": true }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^4.1.0" - } - }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -18754,26 +18208,6 @@ "path-key": "^2.0.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "peer": true, - "requires": { - "p-limit": "^2.2.0" - } - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -18794,13 +18228,6 @@ "react-is": "^17.0.1" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -18844,16 +18271,6 @@ } } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -18877,51 +18294,28 @@ } }, "@react-native-community/cli-hermes": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-6.1.0.tgz", - "integrity": "sha512-BJyzGlUqnggbBL4Vh4cIC08oKOK4PoelxZFEo7TjFjfdBKvbM6955JN77ExJ7IdeLuGVpY4vaMwAJdx5l7LxKg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-6.3.0.tgz", + "integrity": "sha512-Uhbm9bubyZLZ12vFCIfWbE/Qi3SBTbYIN/TC08EudTLhv/KbPomCQnmFsnJ7AXQFuOZJs73mBxoEAYSbRbwyVA==", "dev": true, "peer": true, "requires": { - "@react-native-community/cli-platform-android": "^6.1.0", - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", + "@react-native-community/cli-platform-android": "^6.3.0", + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", "hermes-profile-transformer": "^0.0.6", "ip": "^1.1.5" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "@react-native-community/cli-platform-android": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-6.1.0.tgz", - "integrity": "sha512-MBYGfgCpieoqskKc5QyQYIPc74DBEW60JaacQLntHjPLCEXG+hPsJi3AuXeNTJYPki5pyiSp3kviqciUvrS96A==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.0.tgz", + "integrity": "sha512-d5ufyYcvrZoHznYm5bjBXaiHIJv552t5gYtQpnUsxBhHSQ8QlaNmlLUyeSPRDfOw4ND9b0tPHqs4ufwx6vp/fQ==", "dev": true, "peer": true, "requires": { - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", "execa": "^1.0.0", "fs-extra": "^8.1.0", "glob": "^7.1.3", @@ -18932,17 +18326,6 @@ "xmldoc": "^1.1.2" }, "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -19028,143 +18411,66 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "peer": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "@react-native-community/cli-platform-ios": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.1.0.tgz", - "integrity": "sha512-whIm55fUeJUHrqZ2ecZ6FycZ5c/R3ZK8ViHwZQ+wM4uhXY8YSkrjnrJPUg68Q8inLkrAliLisypfm1z+VqJljw==", - "dev": true, - "peer": true, - "requires": { - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", - "glob": "^7.1.3", - "js-yaml": "^3.13.1", - "lodash": "^4.17.15", - "plist": "^3.0.2", - "xcode": "^2.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } + "dev": true, + "peer": true }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "peer": true, "requires": { - "has-flag": "^4.0.0" + "isexe": "^2.0.0" } } } }, + "@react-native-community/cli-platform-ios": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.2.0.tgz", + "integrity": "sha512-k15MhExxLiLDDZOeuPgvTxbp0CsoLQQpk2Du0HjZDePqqWcKJylQqMZru1o8HuQHPcEr+b71HIs5V+lKyFYpfg==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", + "glob": "^7.1.3", + "js-yaml": "^3.13.1", + "lodash": "^4.17.15", + "ora": "^3.4.0", + "plist": "^3.0.2", + "xcode": "^2.0.0" + } + }, "@react-native-community/cli-plugin-metro": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-6.1.0.tgz", - "integrity": "sha512-ltHJquEgA6H4OTIUqWIkNm/xxAB9D4DK2K9M0jie9FfkOoqBXA7QS2WnC8GEa6a+3VIDwevB0RJsch218FdZCw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-6.2.0.tgz", + "integrity": "sha512-JfmzuFNzOr+dFTUQJo1rV0t87XAqgHRTMYXNleQVt8otOVCk1FSCgKlgqMdvQc/FCx2ZjoMWEEV/g0LrPI8Etw==", "dev": true, "peer": true, "requires": { - "@react-native-community/cli-server-api": "^6.1.0", - "@react-native-community/cli-tools": "^6.1.0", - "chalk": "^3.0.0", + "@react-native-community/cli-server-api": "^6.2.0", + "@react-native-community/cli-tools": "^6.2.0", + "chalk": "^4.1.2", "metro": "^0.66.1", "metro-config": "^0.66.1", "metro-core": "^0.66.1", "metro-react-native-babel-transformer": "^0.66.1", "metro-resolver": "^0.66.1", "metro-runtime": "^0.66.1", - "mkdirp": "^0.5.1", "readline": "^1.3.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "@react-native-community/cli-server-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-6.1.0.tgz", - "integrity": "sha512-WEJzdoF4JNUogZAd+Gdgbr+D/S/PHGjxH+PDjk3ST9pAUxEHb6naNwEl5dSJUY/ecBV63latNZkKunRyvFAx9A==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-6.2.0.tgz", + "integrity": "sha512-OnbnYclhoDpjge33QO5Slhfn0DsmLzzAgyrSCnb24HhSqwq7ObjMHaLpoEhpajzLG71wq5oKh0APEQjiL4Mknw==", "dev": true, "peer": true, "requires": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", - "@react-native-community/cli-tools": "^6.1.0", + "@react-native-community/cli-tools": "^6.2.0", "compression": "^1.7.1", "connect": "^3.6.5", "errorhandler": "^1.5.0", @@ -19211,13 +18517,6 @@ "react-is": "^17.0.1" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true - }, "ws": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", @@ -19232,50 +18531,28 @@ } }, "@react-native-community/cli-tools": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-6.1.0.tgz", - "integrity": "sha512-MT8syhvk0vpfyYyHlcDoGicKcqMtBN7WPmDeyW16u+eKBtw/+EKq+86cFCuOHCfHK20ujG1mZqA1txxlCbu8GA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz", + "integrity": "sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA==", "dev": true, "peer": true, "requires": { "appdirsjs": "^1.2.4", - "chalk": "^3.0.0", + "chalk": "^4.1.2", "lodash": "^4.17.15", "mime": "^2.4.1", - "mkdirp": "^0.5.1", "node-fetch": "^2.6.0", "open": "^6.2.0", "semver": "^6.3.0", "shell-quote": "1.6.1" }, "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "peer": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } } } }, @@ -19316,9 +18593,9 @@ "integrity": "sha512-+pYGvPFAk7wUR+ONMOlc6A+LUN4kOCFwyPLjyaeS7wVibADPHWYJNYsNtyIAwjF1AXQkuaXElnIc4XjKt55QZA==" }, "@sideway/address": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", - "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", + "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", "dev": true, "peer": true, "requires": { @@ -19349,9 +18626,9 @@ } }, "@sinonjs/fake-timers": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", - "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" @@ -19388,9 +18665,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "version": "7.1.17", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", + "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -19429,27 +18706,27 @@ } }, "@types/component-emitter": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", - "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", "dev": true }, "@types/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", "dev": true }, "@types/cors": { - "version": "2.8.10", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", - "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==", + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", "dev": true }, "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", + "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", "dev": true, "requires": { "@types/estree": "*", @@ -19457,9 +18734,9 @@ } }, "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.2.tgz", + "integrity": "sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ==", "dev": true, "requires": { "@types/eslint": "*", @@ -19467,9 +18744,9 @@ } }, "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", "dev": true }, "@types/graceful-fs": { @@ -19506,9 +18783,9 @@ } }, "@types/jest": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.2.tgz", - "integrity": "sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA==", + "version": "27.0.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", + "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", "dev": true, "requires": { "jest-diff": "^27.0.0", @@ -19516,9 +18793,9 @@ } }, "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, "@types/json5": { @@ -19528,15 +18805,15 @@ "dev": true }, "@types/node": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", - "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.1.tgz", + "integrity": "sha512-NXKvBVUzIbs6ylBwmOwHFkZS2EXCcjnqr8ZCRNaXBkHAf+3mn/rPcJxwrzuc6movh8fxQAsUUfYklJ/EG+hZqQ==", "dev": true }, "@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", + "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", "dev": true }, "@types/stack-utils": { @@ -19567,171 +18844,171 @@ "dev": true }, "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/ast": "1.11.1", "@xtuc/long": "4.2.2" } }, "@webpack-cli/configtest": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz", - "integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", + "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", "dev": true, "requires": {} }, "@webpack-cli/info": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.4.tgz", - "integrity": "sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", + "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", "dev": true, "requires": { "envinfo": "^7.7.3" } }, "@webpack-cli/serve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz", - "integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", + "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", "dev": true, "requires": {} }, @@ -19781,9 +19058,9 @@ } }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", + "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", "dev": true }, "acorn-globals": { @@ -19796,25 +19073,32 @@ "acorn-walk": "^7.1.1" }, "dependencies": { - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true } } }, + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true, + "requires": {} + }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, "agent-base": { @@ -19865,14 +19149,6 @@ "dev": true, "requires": { "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } } }, "ansi-fragments": { @@ -19945,10 +19221,13 @@ "dev": true }, "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } }, "arr-diff": { "version": "4.0.0", @@ -19979,16 +19258,16 @@ "peer": true }, "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", + "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" + "is-string": "^1.0.7" } }, "array-map": { @@ -20013,26 +19292,25 @@ "peer": true }, "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "es-abstract": "^1.19.0" } }, "array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", + "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" + "es-abstract": "^1.19.0" } }, "asap": { @@ -20069,12 +19347,18 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true + "dev": true, + "peer": true }, "async": { - "version": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "peer": true, + "requires": { + "lodash": "^4.17.14" + } }, "async-limiter": { "version": "1.0.1", @@ -20111,16 +19395,16 @@ "requires": {} }, "babel-jest": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz", - "integrity": "sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", + "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", "dev": true, "requires": { - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", + "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -20171,9 +19455,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -20183,14 +19467,14 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", - "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", + "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", "dev": true, "peer": true, "requires": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.2", + "@babel/helper-define-polyfill-provider": "^0.3.0", "semver": "^6.1.1" }, "dependencies": { @@ -20204,24 +19488,24 @@ } }, "babel-plugin-polyfill-corejs3": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz", - "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", + "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", "dev": true, "peer": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.2", - "core-js-compat": "^3.16.2" + "@babel/helper-define-polyfill-provider": "^0.3.0", + "core-js-compat": "^3.18.0" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", - "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", + "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", "dev": true, "peer": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.2" + "@babel/helper-define-polyfill-provider": "^0.3.0" } }, "babel-plugin-syntax-trailing-function-commas": { @@ -20288,12 +19572,12 @@ } }, "babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.2.0", + "babel-plugin-jest-hoist": "^27.4.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -20332,9 +19616,9 @@ } }, "base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", "dev": true }, "base64-js": { @@ -20351,9 +19635,9 @@ "dev": true }, "big-integer": { - "version": "1.6.50", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz", - "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==", + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", "dev": true, "peer": true }, @@ -20363,22 +19647,28 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", "dev": true, "requires": { - "bytes": "3.1.0", + "bytes": "3.1.1", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" }, "dependencies": { "debug": { @@ -20390,15 +19680,6 @@ "ms": "2.0.0" } }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -20468,13 +19749,13 @@ "dev": true }, "browserslist": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.5.tgz", - "integrity": "sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001271", - "electron-to-chromium": "^1.3.878", + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", "escalade": "^3.1.1", "node-releases": "^2.0.1", "picocolors": "^1.0.0" @@ -20499,15 +19780,15 @@ } }, "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", "dev": true }, "cache-base": { @@ -20574,15 +19855,15 @@ "dev": true }, "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "caniuse-lite": { - "version": "1.0.30001272", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001272.tgz", - "integrity": "sha512-DV1j9Oot5dydyH1v28g25KoVm7l8MTxazwuiH3utWiAS6iL/9Nh//TGwqFEeqqN8nnWYQ8HHhUq+o4QPt9kvYw==", + "version": "1.0.30001291", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001291.tgz", + "integrity": "sha512-roMV5V0HNGgJ88s42eE70sstqGW/gwFndosYrikHthw98N5tLnOTxFqMLQjZVRxTWFlJ4rn+MsgXrR7MDPY4jA==", "dev": true }, "capture-exit": { @@ -20595,6 +19876,15 @@ "rsvp": "^4.8.4" } }, + "catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, "chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -20610,24 +19900,13 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "char-regex": { @@ -20649,19 +19928,19 @@ "dev": true }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" } }, "chrome-trace-event": { @@ -20671,9 +19950,9 @@ "dev": true }, "ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", "dev": true }, "cjs-module-lexer": { @@ -20796,31 +20075,6 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } } }, "clone": { @@ -20880,10 +20134,11 @@ "dev": true }, "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true, + "peer": true }, "colors": { "version": "1.4.0", @@ -20975,13 +20230,6 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true, "peer": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true } } }, @@ -21020,12 +20268,6 @@ } } }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -21039,14 +20281,6 @@ "dev": true, "requires": { "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } } }, "cookie": { @@ -21063,13 +20297,13 @@ "peer": true }, "core-js-compat": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.0.tgz", - "integrity": "sha512-R09rKZ56ccGBebjTLZHvzDxhz93YPT37gBm6qUhnwj3Kt7aCjjZWD1injyNbyeFHxNKfeZBSyds6O9n3MKq1sw==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.0.tgz", + "integrity": "sha512-relrah5h+sslXssTTOkvqcC/6RURifB0W5yhYBdBkaPYa5/2KBMiog3XiD+s3TwEHWxInWVv4Jx2/Lw0vng+IQ==", "dev": true, "peer": true, "requires": { - "browserslist": "^4.17.5", + "browserslist": "^4.19.1", "semver": "7.0.0" }, "dependencies": { @@ -21091,77 +20325,25 @@ }, "cors": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "peer": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "peer": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "peer": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true, - "peer": true - } + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" } }, "create-require": { @@ -21241,20 +20423,12 @@ "peer": true }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "decamelize": { @@ -21292,9 +20466,9 @@ } }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "deepmerge": { @@ -21378,9 +20552,9 @@ "dev": true }, "diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", "dev": true }, "doctrine": { @@ -21428,9 +20602,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.883", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.883.tgz", - "integrity": "sha512-goyjNx4wB9j911PBteb+AXNbErug7rJVkmDXWdw5SCVn2JlARBwsqucPkvp1h5mXWxHUbBRK3bwXTrqSxSiAIQ==", + "version": "1.4.24", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.24.tgz", + "integrity": "sha512-erwx5r69B/WFfFuF2jcNN0817BfDBdC4765kQ6WltOMuwsimlQo3JTEq0Cle+wpHralwdeX3OfAtw/mHxPK0Wg==", "dev": true }, "emittery": { @@ -21440,9 +20614,9 @@ "dev": true }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "encodeurl": { @@ -21462,33 +20636,45 @@ } }, "engine.io": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz", - "integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz", + "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", "dev": true, "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~4.0.0", - "ws": "~7.4.2" + "engine.io-parser": "~5.0.0", + "ws": "~8.2.3" + }, + "dependencies": { + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "requires": {} + } } }, "engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", "dev": true, "requires": { - "base64-arraybuffer": "0.1.4" + "base64-arraybuffer": "~1.0.1" } }, "enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -21510,6 +20696,12 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, "envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -21547,22 +20739,25 @@ } }, "es-abstract": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", - "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", - "is-callable": "^1.2.3", + "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", @@ -21572,9 +20767,9 @@ } }, "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", "dev": true }, "es-to-primitive": { @@ -21617,63 +20812,16 @@ "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } } }, "eslint": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.13.0.tgz", - "integrity": "sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", + "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.1", + "@eslint/eslintrc": "^0.3.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -21683,10 +20831,10 @@ "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", + "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", @@ -21697,7 +20845,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -21706,36 +20854,87 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", + "table": "^6.0.4", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "type-fest": "^0.8.1" } }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "prelude-ls": "^1.2.1" } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, "eslint-config-standard": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.2.tgz", - "integrity": "sha512-fx3f1rJDsl9bY7qzyX8SAtP8GBSk6MfXFaTfaGgk12aAYW4gJSyRm7dM790L6cbXv63fvjY4XeSzXnb4WM+SKw==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", "dev": true, "requires": {} }, @@ -21747,39 +20946,34 @@ "requires": {} }, "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, "eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", + "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", "dev": true, "requires": { "debug": "^3.2.7", + "find-up": "^2.1.0", "pkg-dir": "^2.0.0" }, "dependencies": { @@ -21791,6 +20985,64 @@ "requires": { "ms": "^2.1.1" } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } } } }, @@ -21805,24 +21057,26 @@ } }, "eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "requires": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", "has": "^1.0.3", + "is-core-module": "^2.6.0", "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" }, "dependencies": { "debug": { @@ -21835,13 +21089,31 @@ } }, "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "ms": { @@ -21849,6 +21121,36 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true } } }, @@ -21867,9 +21169,9 @@ }, "dependencies": { "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "semver": { @@ -21881,28 +21183,31 @@ } }, "eslint-plugin-promise": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", - "dev": true + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", + "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", + "dev": true, + "requires": {} }, "eslint-plugin-react": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", - "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.25.3.tgz", + "integrity": "sha512-ZMbFvZ1WAYSZKY662MBVEWR45VaBT6KSJCiupjrNlcdakB90juaZeDCbJq19e73JZQubqFtgETohwgAt8u5P6w==", "dev": true, "requires": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", "doctrine": "^2.1.0", - "has": "^1.0.3", + "estraverse": "^5.2.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.hasown": "^1.0.0", + "object.values": "^1.1.4", "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" }, "dependencies": { "doctrine": { @@ -21913,6 +21218,16 @@ "requires": { "esutils": "^2.0.2" } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } } } }, @@ -21924,6 +21239,14 @@ "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } } }, "eslint-utils": { @@ -21960,6 +21283,12 @@ "eslint-visitor-keys": "^1.3.0" }, "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", @@ -21980,15 +21309,7 @@ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "estraverse": "^5.1.0" } }, "esrecurse": { @@ -21998,20 +21319,12 @@ "dev": true, "requires": { "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } } }, "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "esutils": { @@ -22054,9 +21367,9 @@ "peer": true }, "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -22202,17 +21515,17 @@ } }, "expect": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz", - "integrity": "sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", + "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6" + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0" }, "dependencies": { "ansi-styles": { @@ -22320,12 +21633,12 @@ } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "fill-range": { @@ -22413,16 +21726,6 @@ "semver": "^5.6.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -22467,12 +21770,12 @@ } }, "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^6.0.0", + "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, @@ -22483,14 +21786,21 @@ "dev": true }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + } } }, "flatted": { @@ -22507,9 +21817,9 @@ "peer": true }, "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", "dev": true }, "for-in": { @@ -22636,6 +21946,16 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -22644,9 +21964,9 @@ "peer": true }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -22673,18 +21993,15 @@ "dev": true }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "growl": { @@ -22847,24 +22164,16 @@ "dev": true }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "requires": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } + "toidentifier": "1.0.1" } }, "http-proxy": { @@ -22906,12 +22215,12 @@ "dev": true }, "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore": { @@ -22933,71 +22242,33 @@ "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, + "peer": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + } } }, "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", "dev": true, "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } } }, "imurmurhash": { @@ -23083,10 +22354,13 @@ "dev": true }, "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } }, "is-binary-path": { "version": "2.1.0", @@ -23098,12 +22372,13 @@ } }, "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-buffer": { @@ -23113,9 +22388,9 @@ "dev": true }, "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-ci": { @@ -23138,9 +22413,9 @@ } }, "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "requires": { "has": "^1.0.3" @@ -23157,10 +22432,13 @@ } }, "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-descriptor": { "version": "1.0.2", @@ -23201,7 +22479,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "dev": true, + "peer": true }, "is-generator-fn": { "version": "2.1.0", @@ -23219,18 +22498,18 @@ } }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, "is-number": { @@ -23240,10 +22519,13 @@ "dev": true }, "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-plain-obj": { "version": "2.1.0", @@ -23267,26 +22549,35 @@ "dev": true }, "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" + "has-tostringtag": "^1.0.0" } }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-symbol": { "version": "1.0.4", @@ -23316,6 +22607,21 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -23334,7 +22640,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "peer": true }, "isbinaryfile": { "version": "4.0.8", @@ -23389,17 +22696,6 @@ "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "istanbul-lib-source-maps": { @@ -23414,9 +22710,9 @@ } }, "istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.1.tgz", + "integrity": "sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -23424,278 +22720,266 @@ } }, "jest": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.1.tgz", - "integrity": "sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", + "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", "dev": true, "requires": { - "@jest/core": "^27.3.1", + "@jest/core": "^27.4.5", "import-local": "^3.0.2", - "jest-cli": "^27.3.1" + "jest-cli": "^27.4.5" } }, "jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "execa": "^5.0.0", "throat": "^6.0.1" } }, "jest-circus": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz", - "integrity": "sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", + "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", "dev": true, "requires": { - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" } }, "jest-cli": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz", - "integrity": "sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", + "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", "dev": true, "requires": { - "@jest/core": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/core": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-config": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "prompts": "^2.0.1", "yargs": "^16.2.0" } }, "jest-config": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz", - "integrity": "sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", + "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.1", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.1", + "@jest/test-sequencer": "^27.4.5", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.5", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.3.1", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-jasmine2": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-circus": "^27.4.5", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.2", + "slash": "^3.0.0" } }, "jest-diff": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz", - "integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", + "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" } }, "jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz", - "integrity": "sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", + "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2" } }, "jest-environment-jsdom": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz", - "integrity": "sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", + "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", "dev": true, "requires": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2", "jsdom": "^16.6.0" } }, "jest-environment-node": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz", - "integrity": "sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", + "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", "dev": true, "requires": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" } }, "jest-get-type": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", - "integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", "dev": true }, "jest-haste-map": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz", - "integrity": "sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", + "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "micromatch": "^4.0.4", "walker": "^1.0.7" - }, - "dependencies": { - "jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - } } }, "jest-jasmine2": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz", - "integrity": "sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", + "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", "throat": "^6.0.1" } }, "jest-leak-detector": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz", - "integrity": "sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", + "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", "dev": true, "requires": { - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" } }, "jest-matcher-utils": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz", - "integrity": "sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", + "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" } }, "jest-message-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz", - "integrity": "sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", + "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", + "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/node": "*" } }, @@ -23707,96 +22991,83 @@ "requires": {} }, "jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", "dev": true }, "jest-resolve": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz", - "integrity": "sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", + "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", + "jest-haste-map": "^27.4.5", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz", - "integrity": "sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", + "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", "dev": true, "requires": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.1" + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.5" } }, "jest-runner": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz", - "integrity": "sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", + "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", "dev": true, "requires": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-leak-detector": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-haste-map": "^27.4.5", + "jest-leak-detector": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "source-map-support": "^0.5.6", "throat": "^6.0.1" - }, - "dependencies": { - "jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - } } }, "jest-runtime": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz", - "integrity": "sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg==", - "dev": true, - "requires": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/globals": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", + "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "dev": true, + "requires": { + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/globals": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", @@ -23805,31 +23076,23 @@ "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.2.0" - }, - "dependencies": { - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - } } }, "jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", "dev": true, "requires": { "@types/node": "*", @@ -23837,9 +23100,9 @@ } }, "jest-snapshot": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz", - "integrity": "sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", + "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", "dev": true, "requires": { "@babel/core": "^7.7.2", @@ -23848,33 +23111,33 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.5", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz", - "integrity": "sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -23883,49 +23146,57 @@ } }, "jest-validate": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz", - "integrity": "sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", + "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", + "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.2" + }, + "dependencies": { + "camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true + } } }, "jest-watcher": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz", - "integrity": "sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", + "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", "dev": true, "requires": { - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.3.1", + "jest-util": "^27.4.2", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", + "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", "dev": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" }, "dependencies": { "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -23941,15 +23212,15 @@ "peer": true }, "joi": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.2.tgz", - "integrity": "sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw==", + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.5.0.tgz", + "integrity": "sha512-R7hR50COp7StzLnDi4ywOXHrBrgNXuUUfJWIR5lPY5Bm/pOD3jZaTwpluUXVLRWcoWZxkrHBBJ5hLxgnlehbdw==", "dev": true, "peer": true, "requires": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.0", + "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.0", "@sideway/pinpoint": "^2.0.0" } @@ -23967,12 +23238,22 @@ "dev": true }, "js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { - "argparse": "^2.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.4" } }, "jsc-android": { @@ -24142,6 +23423,51 @@ } } }, + "jsdoc": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", + "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", + "dev": true, + "requires": { + "@babel/parser": "^7.9.4", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.1", + "klaw": "^3.0.0", + "markdown-it": "^10.0.0", + "markdown-it-anchor": "^5.2.7", + "marked": "^2.0.3", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "taffydb": "2.6.2", + "underscore": "~1.13.1" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -24175,14 +23501,6 @@ "whatwg-url": "^8.5.0", "ws": "^7.4.6", "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - } } }, "jsesc": { @@ -24210,12 +23528,12 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" } }, "jsonfile": { @@ -24235,55 +23553,44 @@ "peer": true }, "jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", + "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", "dev": true, "requires": { - "array-includes": "^3.1.2", + "array-includes": "^3.1.3", "object.assign": "^4.1.2" } }, "karma": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz", - "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==", + "version": "6.3.9", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.9.tgz", + "integrity": "sha512-E/MqdLM9uVIhfuyVnrhlGBu4miafBdXEAEqCmwdEMh3n17C7UWC/8Kvm3AYKr91gc7scutekZ0xv6rxRaUCtnw==", "dev": true, "requires": { "body-parser": "^1.19.0", "braces": "^3.0.2", - "chokidar": "^3.4.2", + "chokidar": "^3.5.1", "colors": "^1.4.0", "connect": "^3.7.0", "di": "^0.0.1", "dom-serialize": "^2.2.1", - "glob": "^7.1.6", - "graceful-fs": "^4.2.4", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.6", - "lodash": "^4.17.19", - "log4js": "^6.2.1", - "mime": "^2.4.5", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.3.0", + "mime": "^2.5.2", "minimatch": "^3.0.4", "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.1.0", + "socket.io": "^4.2.0", "source-map": "^0.6.1", - "tmp": "0.2.1", - "ua-parser-js": "^0.7.23", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", "yargs": "^16.1.1" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "karma-chai": { @@ -24370,13 +23677,13 @@ "dev": true }, "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "lie": { @@ -24387,16 +23694,33 @@ "immediate": "~3.0.5" } }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", + "parse-json": "^4.0.0", + "pify": "^3.0.0", "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "loader-runner": { @@ -24406,20 +23730,20 @@ "dev": true }, "localforage": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.9.0.tgz", - "integrity": "sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", "requires": { "lie": "3.1.1" } }, "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^5.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -24448,13 +23772,20 @@ "dev": true, "peer": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "chalk": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" } }, "log4js": { @@ -24482,13 +23813,6 @@ "yargs": "^15.1.0" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -24508,73 +23832,6 @@ "dev": true, "peer": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "peer": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "peer": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -24694,6 +23951,32 @@ "object-visit": "^1.0.0" } }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "dev": true, + "requires": {} + }, + "marked": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true + }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -24705,6 +23988,12 @@ "is-buffer": "~1.1.6" } }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -24811,23 +24100,6 @@ "@types/yargs-parser": "*" } }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "peer": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -24864,24 +24136,6 @@ "dev": true, "peer": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "fs-extra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", @@ -24894,13 +24148,6 @@ "klaw": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "peer": true - }, "jest-haste-map": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", @@ -24957,24 +24204,26 @@ "micromatch": "^4.0.2" } }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "peer": true, "requires": { - "graceful-fs": "^4.1.6" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "peer": true, "requires": { - "p-locate": "^4.1.0" + "graceful-fs": "^4.1.6" } }, "ms": { @@ -24984,24 +24233,14 @@ "dev": true, "peer": true }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "peer": true, "requires": { - "p-limit": "^2.2.0" + "glob": "^7.1.3" } }, "source-map": { @@ -25011,18 +24250,6 @@ "dev": true, "peer": true }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -25142,6 +24369,18 @@ "metro-core": "0.66.2", "mkdirp": "^0.5.1", "rimraf": "^2.5.4" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "peer": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "metro-cache-key": { @@ -25190,6 +24429,13 @@ "@types/yargs-parser": "*" } }, + "camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true, + "peer": true + }, "jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", @@ -25224,13 +24470,6 @@ "ansi-styles": "^4.0.0", "react-is": "^17.0.1" } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true } } }, @@ -25325,6 +24564,18 @@ "is-ci": "^2.0.0", "micromatch": "^4.0.2" } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } } } }, @@ -25348,13 +24599,6 @@ "yargs": "^15.3.1" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -25384,41 +24628,6 @@ "dev": true, "peer": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "peer": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "peer": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^4.1.0" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -25426,38 +24635,6 @@ "dev": true, "peer": true }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "peer": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -25710,24 +24887,24 @@ } }, "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true }, "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true }, "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "requires": { - "mime-db": "1.47.0" + "mime-db": "1.51.0" } }, "mimic-fn": { @@ -25772,57 +24949,150 @@ } }, "mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", + "chokidar": "3.5.2", + "debug": "4.3.2", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.6", + "glob": "7.1.7", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", "minimatch": "3.0.4", "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", + "nanoid": "3.1.25", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", + "workerpool": "6.1.5", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "mocha-junit-reporter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.0.tgz", - "integrity": "sha512-20HoWh2HEfhqmigfXOKUhZQyX23JImskc37ZOhIjBKoBEsb+4cAFRJpAVhFpnvsztLklW/gFVzsrobjLwmX4lA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.2.tgz", + "integrity": "sha512-vYwWq5hh3v1lG0gdQCBxwNipBfvDiAM1PHroQRNp96+2l72e9wEUTw+mzoK+O0SudgfQ7WvTQZ9Nh3qkAYAjfg==", "dev": true, "requires": { "debug": "^2.2.0", "md5": "^2.1.0", "mkdirp": "~0.5.1", - "strip-ansi": "^4.0.0", + "strip-ansi": "^6.0.1", "xml": "^1.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -25837,28 +25107,19 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } } } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", "dev": true }, "nanomatch": { @@ -25924,9 +25185,9 @@ } }, "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", "dev": true, "peer": true, "requires": { @@ -25966,12 +25227,6 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, "node-releases": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", @@ -26122,9 +25377,9 @@ } }, "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true }, "object-keys": { @@ -26156,27 +25411,35 @@ } }, "object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" + "es-abstract": "^1.19.1" + } + }, + "object.hasown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", + "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" } }, "object.pick": { @@ -26190,15 +25453,14 @@ } }, "object.values": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", - "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "on-finished": { @@ -26246,17 +25508,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" } }, "options": { @@ -26388,21 +25650,21 @@ "peer": true }, "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "yocto-queue": "^0.1.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^3.0.2" + "p-limit": "^2.2.0" } }, "p-try": { @@ -26421,12 +25683,13 @@ } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parse5": { @@ -26473,18 +25736,18 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "pify": "^2.0.0" + "pify": "^3.0.0" } }, "pathval": { @@ -26500,25 +25763,22 @@ "dev": true }, "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", + "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", + "dev": true }, "pkg-conf": { "version": "3.1.0", @@ -26562,15 +25822,6 @@ "path-exists": "^3.0.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -26580,16 +25831,6 @@ "p-limit": "^2.0.0" } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -26602,6 +25843,12 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", @@ -26611,9 +25858,18 @@ } }, "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "pkg-up": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, "requires": { "find-up": "^2.1.0" @@ -26698,18 +25954,18 @@ "peer": true }, "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "pretty-format": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", - "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", + "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" @@ -26720,12 +25976,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true } } }, @@ -26777,6 +26027,14 @@ "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.8.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + } } }, "psl": { @@ -26809,9 +26067,9 @@ "dev": true }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", "dev": true }, "randombytes": { @@ -26830,26 +26088,15 @@ "dev": true }, "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } } }, "react": { @@ -26864,9 +26111,9 @@ } }, "react-devtools-core": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.20.2.tgz", - "integrity": "sha512-ep2j84M1ZtDFWsTtFrKyLyg4GEbnw4gFj/8brA+BZtsINgKHhWEVzscz5E/bFWRdyTM8mWdcaKQAk2hR+IezPw==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.22.1.tgz", + "integrity": "sha512-pvpNDHE7p0FtcCmIWGazoY8LLVfBI9sw0Kf10kdHhPI9Tzt3OG/qEt16GrAbE0keuna5WzX3r1qPKVjqOqsuUg==", "dev": true, "peer": true, "requires": { @@ -26875,15 +26122,15 @@ } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, "react-native": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.66.1.tgz", - "integrity": "sha512-BBvytmqlOLL+bRcO0jBiYfg16lYRsYDOC8/5E+bpnhb3EGtU+YCQAYfszw6JL7Hfy0ftnQNP5yj8pt+vqMHXIA==", + "version": "0.66.4", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.66.4.tgz", + "integrity": "sha512-9vx5dlSfQlKbbDtr8+xMon6qsmSu7jvjdXWZpEKh3XVKpUidbbODv7048gwVKX8YAel1egeR7hN8vzSeI6ssTw==", "dev": true, "peer": true, "requires": { @@ -26957,13 +26204,6 @@ "react-is": "^17.0.1" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "peer": true - }, "ws": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", @@ -26996,24 +26236,24 @@ "peer": true }, "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { - "load-json-file": "^2.0.0", + "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "path-type": "^3.0.0" } }, "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "read-pkg": "^3.0.0" }, "dependencies": { "find-up": { @@ -27081,21 +26321,12 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true - } } }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -27122,9 +26353,9 @@ } }, "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, "requires": { "resolve": "^1.9.0" @@ -27186,9 +26417,9 @@ } }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "regexpu-core": { @@ -27259,6 +26490,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -27272,6 +26509,15 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "requizzle": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", + "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -27289,20 +26535,12 @@ "dev": true, "requires": { "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } } }, "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, "resolve-url": { @@ -27362,9 +26600,9 @@ "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -27378,9 +26616,9 @@ "peer": true }, "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "safe-regex": { @@ -27684,12 +26922,12 @@ } }, "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dev": true, "requires": { - "@types/json-schema": "^7.0.6", + "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } @@ -27704,9 +26942,9 @@ } }, "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dev": true, "peer": true, "requires": { @@ -27717,9 +26955,9 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "1.8.1", "mime": "1.6.0", - "ms": "2.1.1", + "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" @@ -27752,9 +26990,9 @@ "peer": true }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "peer": true } @@ -27768,25 +27006,25 @@ "peer": true }, "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" } }, "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dev": true, "peer": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.17.2" } }, "set-blocking": { @@ -27835,9 +27073,9 @@ "dev": true }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "shallow-clone": { @@ -27889,9 +27127,9 @@ } }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, "simple-plist": { @@ -27923,6 +27161,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, + "peer": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", @@ -27934,6 +27173,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "peer": true, "requires": { "color-convert": "^1.9.0" } @@ -27943,6 +27183,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "peer": true, "requires": { "color-name": "1.1.3" } @@ -27951,7 +27192,8 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "dev": true, + "peer": true } } }, @@ -28135,26 +27377,23 @@ } }, "socket.io": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", - "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.0.tgz", + "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", "dev": true, "requires": { - "@types/cookie": "^0.4.0", - "@types/cors": "^2.8.8", - "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "~2.0.0", - "debug": "~4.3.1", - "engine.io": "~4.1.0", - "socket.io-adapter": "~2.1.0", - "socket.io-parser": "~4.0.3" + "debug": "~4.3.2", + "engine.io": "~6.1.0", + "socket.io-adapter": "~2.3.3", + "socket.io-parser": "~4.0.4" } }, "socket.io-adapter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", - "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", + "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==", "dev": true }, "socket.io-parser": { @@ -28168,12 +27407,6 @@ "debug": "~4.3.1" } }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -28195,6 +27428,17 @@ "abab": "^2.0.5", "iconv-lite": "^0.6.2", "source-map-js": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } } }, "source-map-resolve": { @@ -28212,9 +27456,9 @@ } }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -28255,9 +27499,9 @@ } }, "spdx-license-ids": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", - "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, "split-string": { @@ -28320,18 +27564,18 @@ } }, "standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/standard/-/standard-16.0.3.tgz", - "integrity": "sha512-70F7NH0hSkNXosXRltjSv6KpTAOkUkSfyu3ynyM5dtRUiLtR+yX9EGZ7RKwuGUqCJiX/cnkceVM6HTZ4JpaqDg==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/standard/-/standard-16.0.4.tgz", + "integrity": "sha512-2AGI874RNClW4xUdM+bg1LRXVlYLzTNEkHmTG5mhyn45OhbgwA+6znowkOGYy+WMb5HRyELvtNy39kcdMQMcYQ==", "dev": true, "requires": { - "eslint": "~7.13.0", - "eslint-config-standard": "16.0.2", + "eslint": "~7.18.0", + "eslint-config-standard": "16.0.3", "eslint-config-standard-jsx": "10.0.0", - "eslint-plugin-import": "~2.22.1", + "eslint-plugin-import": "~2.24.2", "eslint-plugin-node": "~11.1.0", - "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.21.5", + "eslint-plugin-promise": "~5.1.0", + "eslint-plugin-react": "~7.25.1", "standard-engine": "^14.0.1" } }, @@ -28473,15 +27717,6 @@ "peer": true, "requires": { "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "peer": true - } } }, "string-length": { @@ -28495,43 +27730,35 @@ } }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } } } }, "string.prototype.matchall": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz", - "integrity": "sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", + "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has-symbols": "^1.0.1", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", "regexp.prototype.flags": "^1.3.1", "side-channel": "^1.0.4" @@ -28567,9 +27794,9 @@ } }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, "strip-eof": { @@ -28599,9 +27826,9 @@ "peer": true }, "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -28615,17 +27842,6 @@ "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "symbol-tree": { @@ -28635,21 +27851,71 @@ "dev": true }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", + "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } } }, + "taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true }, "temp": { @@ -28683,14 +27949,14 @@ } }, "terser": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", - "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", "dev": true, "requires": { "commander": "^2.20.0", "source-map": "~0.7.2", - "source-map-support": "~0.5.19" + "source-map-support": "~0.5.20" }, "dependencies": { "commander": { @@ -28708,17 +27974,16 @@ } }, "terser-webpack-plugin": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz", - "integrity": "sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz", + "integrity": "sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==", "dev": true, "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", + "jest-worker": "^27.4.1", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", "source-map": "^0.6.1", - "terser": "^5.7.0" + "terser": "^5.7.2" } }, "test-exclude": { @@ -28771,17 +28036,6 @@ "dev": true, "requires": { "rimraf": "^3.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "tmpl": { @@ -28841,9 +28095,9 @@ } }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, "tough-cookie": { @@ -28867,9 +28121,9 @@ } }, "ts-jest": { - "version": "27.0.7", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", - "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", + "version": "27.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.2.tgz", + "integrity": "sha512-eSOiJOWq6Hhs6Khzk5wKC5sgWIXgXqOCiIl1+3lfnearu58Hj4QpE5tUhQcA3xtZrELbcvAGCsd6HB8OsaVaTA==", "dev": true, "requires": { "bs-logger": "0.x", @@ -28880,23 +28134,12 @@ "make-error": "1.x", "semver": "7.x", "yargs-parser": "20.x" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } } }, "ts-node": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", - "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.7.0", @@ -28913,10 +28156,10 @@ "yn": "3.1.1" }, "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "diff": { @@ -28928,15 +28171,32 @@ } }, "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", "dev": true, "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "tslib": { @@ -28947,12 +28207,12 @@ "peer": true }, "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "^1.2.1" + "prelude-ls": "~1.1.2" } }, "type-detect": { @@ -28962,9 +28222,9 @@ "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, "type-is": { @@ -28987,15 +28247,21 @@ } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", "dev": true }, "ua-parser-js": { - "version": "0.7.28", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", - "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==", + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", + "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", "dev": true }, "uglify-es": { @@ -29037,6 +28303,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "underscore": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -29296,9 +28568,9 @@ } }, "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", + "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -29322,22 +28594,23 @@ "dev": true }, "webpack": { - "version": "5.37.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.37.0.tgz", - "integrity": "sha512-yvdhgcI6QkQkDe1hINBAJ1UNevqNGTVaCkD2SSJcB8rcrNNl922RI8i2DXUAuNfANoxwsiXXEA4ZPZI9q2oGLA==", + "version": "5.65.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", + "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.2.1", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.4", @@ -29345,46 +28618,45 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", + "schema-utils": "^3.1.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - }, - "dependencies": { - "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", - "dev": true - } + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.1", + "webpack-sources": "^3.2.2" } }, "webpack-cli": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.0.tgz", - "integrity": "sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", + "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.3", - "@webpack-cli/info": "^1.2.4", - "@webpack-cli/serve": "^1.4.0", - "colorette": "^1.2.1", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", "commander": "^7.0.0", "execa": "^5.0.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^2.2.0", "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", "webpack-merge": "^5.7.3" + }, + "dependencies": { + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + } } }, "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "dev": true, "requires": { "clone-deep": "^4.0.1", @@ -29392,14 +28664,10 @@ } }, "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "dev": true, - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", + "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "dev": true }, "whatwg-encoding": { "version": "1.0.5", @@ -29408,17 +28676,6 @@ "dev": true, "requires": { "iconv-lite": "0.4.24" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } } }, "whatwg-fetch": { @@ -29488,42 +28745,6 @@ "is-typed-array": "^1.1.7" } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -29537,9 +28758,9 @@ "dev": true }, "workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", "dev": true }, "wrap-ansi": { @@ -29551,31 +28772,6 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } } }, "wrappy": { @@ -29584,15 +28780,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -29606,9 +28793,9 @@ } }, "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", "dev": true, "requires": {} }, @@ -29653,6 +28840,12 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", @@ -29731,31 +28924,6 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } } }, "yargs-parser": { @@ -29774,6 +28942,14 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true + } } }, "yn": { diff --git a/package.json b/package.json index 9028670..d478b6f 100755 --- a/package.json +++ b/package.json @@ -53,13 +53,14 @@ "events": "^3.3.0", "jest": "^27.3.1", "jquery": "^3.6.0", + "jsdoc": "^3.6.7", "karma": "^6.3.2", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.0", "karma-junit-reporter": "^2.0.1", "karma-mocha": "^2.0.1", "karma-source-map-support": "^1.4.0", - "mocha": "^8.4.0", + "mocha": "^9.1.3", "mocha-junit-reporter": "^2.0.0", "path-browserify": "^1.0.1", "process": "^0.11.10", @@ -84,7 +85,8 @@ "test:browser": "xvfb-maybe karma start karma.conf.local.js", "test:react-native": "jest test/react-native", "test:typings": "ts-node ./typings-tests.ts", - "prepublishOnly": "npm run build:browser" + "prepublishOnly": "npm run build:browser", + "generateDocs": "jsdoc -c jsdoc.conf.js" }, "main": "index.js", "browser": { diff --git a/test/db.async.test.js b/test/db.async.test.js index 7e10b5a..0625fc9 100644 --- a/test/db.async.test.js +++ b/test/db.async.test.js @@ -760,7 +760,7 @@ describe('Database async', function () { affectedDocuments: affectedDocumentsEmpty } = await d.updateAsync({ impossible: 'db is empty anyway' }, { newDoc: true }, {}) assert.equal(numAffectedEmpty, 0) - assert.equal(affectedDocumentsEmpty, undefined) + assert.equal(affectedDocumentsEmpty, null) const docsEmpty = await d.findAsync({}) assert.equal(docsEmpty.length, 0) // Default option for upsert is false @@ -1095,8 +1095,8 @@ describe('Database async', function () { // returnUpdatedDocs set to false const { numAffected, affectedDocuments, upsert } = await d.updateAsync({ a: 1 }, { $set: { b: 20 } }, {}) assert.equal(numAffected, 1) - assert.equal(affectedDocuments, undefined) - assert.equal(upsert, undefined) + assert.equal(affectedDocuments, null) + assert.equal(upsert, false) // returnUpdatedDocs set to true const { @@ -1107,7 +1107,7 @@ describe('Database async', function () { assert.equal(numAffected2, 1) assert.equal(affectedDocuments2.a, 1) assert.equal(affectedDocuments2.b, 21) - assert.equal(upsert2, undefined) + assert.equal(upsert2, false) }) it('Regular update, multi true', async () => { @@ -1121,8 +1121,8 @@ describe('Database async', function () { upsert } = await d.updateAsync({}, { $set: { b: 20 } }, { multi: true }) assert.equal(numAffected, 2) - assert.equal(affectedDocuments, undefined) - assert.equal(upsert, undefined) + assert.equal(affectedDocuments, null) + assert.equal(upsert, false) // returnUpdatedDocs set to true const { @@ -1135,7 +1135,7 @@ describe('Database async', function () { }) assert.equal(numAffected2, 2) assert.equal(affectedDocuments2.length, 2) - assert.equal(upsert2, undefined) + assert.equal(upsert2, false) }) it('Upsert', async () => { @@ -1145,8 +1145,8 @@ describe('Database async', function () { // Upsert flag not set const { numAffected, affectedDocuments, upsert } = await d.updateAsync({ a: 3 }, { $set: { b: 20 } }, {}) assert.equal(numAffected, 0) - assert.equal(affectedDocuments, undefined) - assert.equal(upsert, undefined) + assert.equal(affectedDocuments, null) + assert.equal(upsert, false) // Upsert flag set const { diff --git a/test/db.test.js b/test/db.test.js index 82332d2..9a2d22c 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -1293,10 +1293,10 @@ describe('Database', function () { describe('Upserts', function () { it('Can perform upserts if needed', function (done) { - d.update({ impossible: 'db is empty anyway' }, { newDoc: true }, {}, function (err, nr, upsert) { + d.update({ impossible: 'db is empty anyway' }, { newDoc: true }, {}, function (err, nr, affectedDocuments) { assert.isNull(err) nr.should.equal(0) - assert.isUndefined(upsert) + assert.isNull(affectedDocuments) // eslint-disable-next-line node/handle-callback-err d.find({}, function (err, docs) { @@ -1791,8 +1791,8 @@ describe('Database', function () { d.update({ a: 1 }, { $set: { b: 20 } }, {}, function (err, numAffected, affectedDocuments, upsert) { assert.isNull(err) numAffected.should.equal(1) - assert.isUndefined(affectedDocuments) - assert.isUndefined(upsert) + assert.isNull(affectedDocuments) + assert.isFalse(upsert) // returnUpdatedDocs set to true d.update({ a: 1 }, { $set: { b: 21 } }, { returnUpdatedDocs: true }, function (err, numAffected, affectedDocuments, upsert) { @@ -1800,7 +1800,7 @@ describe('Database', function () { numAffected.should.equal(1) affectedDocuments.a.should.equal(1) affectedDocuments.b.should.equal(21) - assert.isUndefined(upsert) + assert.isFalse(upsert) done() }) @@ -1815,8 +1815,8 @@ describe('Database', function () { d.update({}, { $set: { b: 20 } }, { multi: true }, function (err, numAffected, affectedDocuments, upsert) { assert.isNull(err) numAffected.should.equal(2) - assert.isUndefined(affectedDocuments) - assert.isUndefined(upsert) + assert.isNull(affectedDocuments) + assert.isFalse(upsert) // returnUpdatedDocs set to true d.update({}, { $set: { b: 21 } }, { @@ -1826,7 +1826,7 @@ describe('Database', function () { assert.isNull(err) numAffected.should.equal(2) affectedDocuments.length.should.equal(2) - assert.isUndefined(upsert) + assert.isFalse(upsert) done() }) @@ -1841,8 +1841,8 @@ describe('Database', function () { d.update({ a: 3 }, { $set: { b: 20 } }, {}, function (err, numAffected, affectedDocuments, upsert) { assert.isNull(err) numAffected.should.equal(0) - assert.isUndefined(affectedDocuments) - assert.isUndefined(upsert) + assert.isNull(affectedDocuments) + assert.isFalse(upsert) // Upsert flag set d.update({ a: 3 }, { $set: { b: 21 } }, { upsert: true }, function (err, numAffected, affectedDocuments, upsert) { diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index de70922..3ff9e0e 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -65,7 +65,7 @@ describe('Persistence async', function () { model.serialize({ _id: '3', nested: { today: now } }) const treatedData = d.persistence.treatRawData(rawData).data - treatedData.sort(function (a, b) { return a._id - b._id }) + treatedData.sort((a, b) => a._id - b._id) assert.equal(treatedData.length, 2) assert.deepEqual(treatedData[0], { _id: '1', a: 2, ages: [1, 5, 12] }) assert.deepEqual(treatedData[1], { _id: '3', nested: { today: now } }) From 7709369e49d08ed1e057b2c6274f6cffa3ec37a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Wed, 22 Dec 2021 22:47:51 +0100 Subject: [PATCH 31/65] JSDoc --- lib/executor.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/executor.js b/lib/executor.js index 6f0cf34..61275be 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -1,15 +1,41 @@ /** * Responsible for sequentially executing actions on the database + * @private */ class Waterfall { constructor () { + /** + * This is the internal Promise object which resolves when all the tasks of the `Waterfall` are done. + * + * It will change any time `this.waterfall` is called, this is why there is a getter `this.guardian` which retrieves + * the latest version of the guardian. + * @type {Promise} + * @private + */ this._guardian = Promise.resolve() } + /** + * Returns a Promise which resolves when all tasks up to when this function is called are done. + * + * This Promise cannot reject. + * @return {Promise} + */ get guardian () { return this._guardian } + /** + * @callback Waterfall~function + * @param {...[*]} args + * @return {Promise<*>} + */ + + /** + * + * @param {Waterfall~function} func + * @return {Waterfall~function} + */ waterfall (func) { return (...args) => { this._guardian = this.guardian.then(() => { From 07e60b09dc1619eb722ed5937ed86b02bb9e0a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Wed, 22 Dec 2021 22:47:57 +0100 Subject: [PATCH 32/65] 3.0.0-0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c6c6c01..7361ac3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seald-io/nedb", - "version": "2.2.1", + "version": "3.0.0-0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@seald-io/nedb", - "version": "2.2.1", + "version": "3.0.0-0", "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", diff --git a/package.json b/package.json index d478b6f..cdcfe5b 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seald-io/nedb", - "version": "2.2.1", + "version": "3.0.0-0", "files": [ "lib/**/*.js", "browser-version/**/*.js", From 90f52e4cda7b5fb6c93ca079296bd0b4f5701b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Wed, 5 Jan 2022 16:16:17 +0100 Subject: [PATCH 33/65] add docs for Cursor, customUtils, Executor, Persistence and utils --- lib/cursor.js | 56 ++++++++++++++++++----- lib/customUtils.js | 2 + lib/executor.js | 47 ++++++++++++------- lib/persistence.js | 109 ++++++++++++++++++++++++++++++++++++++++----- lib/utils.js | 40 ++++++++++++++--- 5 files changed, 207 insertions(+), 47 deletions(-) diff --git a/lib/cursor.js b/lib/cursor.js index 603b844..0882d88 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -33,10 +33,16 @@ class Cursor { this.query = query || {} if (execFn) this.execFn = execFn if (async) this.async = true + this._limit = null + this._skip = null + this._sort = null + this._projection = null } /** * Set a limit to the number of results + * @param {Number} limit + * @return {Cursor} */ limit (limit) { this._limit = limit @@ -44,7 +50,9 @@ class Cursor { } /** - * Skip a the number of results + * Skip a number of results + * @param {Number} skip + * @return {Cursor} */ skip (skip) { this._skip = skip @@ -53,7 +61,8 @@ class Cursor { /** * Sort results of the query - * @param {SortQuery} sortQuery - SortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending + * @param {Object.} sortQuery - sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending + * @return {Cursor} */ sort (sortQuery) { this._sort = sortQuery @@ -62,8 +71,9 @@ class Cursor { /** * Add the use of a projection - * @param {Object} projection - MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 - * { key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits + * @param {Object.} projection - MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 + * { key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits. + * @return {Cursor} */ projection (projection) { this._projection = projection @@ -72,6 +82,8 @@ class Cursor { /** * Apply the projection + * @param {document[]} candidates + * @return {document[]} */ project (candidates) { const res = [] @@ -118,9 +130,8 @@ class Cursor { /** * Get all matching elements * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne - * This is an internal function, use exec which uses the executor - * - * @param {Function} callback - Signature: err, results + * This is an internal function, use execAsync which uses the executor + * @return {document[]|Promise<*>} */ async _execAsync () { let res = [] @@ -180,16 +191,39 @@ class Cursor { else return res } + /** + * @callback Cursor~execCallback + * @param {Error} err + * @param {document[]|*} res If an execFn was given to the Cursor, then the type of this parameter is the one returned by the execFn. + */ + + /** + * Get all matching elements + * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne + * This is an internal function, use exec which uses the executor + * @param { Cursor~execCallback} _callback + */ _exec (_callback) { callbackify(this._execAsync.bind(this))(_callback) } - exec (...args) { - this.db.executor.push({ this: this, fn: this._exec, arguments: args }) + /** + * Get all matching elements + * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne + * @param { Cursor~execCallback} _callback + */ + exec (_callback) { + this.db.executor.push({ this: this, fn: this._exec, arguments: [_callback] }) } - execAsync (...args) { - return this.db.executor.pushAsync(() => this._execAsync(...args)) + /** + * Get all matching elements + * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne + * @return {Promise} + * @async + */ + execAsync () { + return this.db.executor.pushAsync(() => this._execAsync()) } then (onFulfilled, onRejected) { diff --git a/lib/customUtils.js b/lib/customUtils.js index da538e7..a3fc1f0 100755 --- a/lib/customUtils.js +++ b/lib/customUtils.js @@ -7,6 +7,8 @@ const crypto = require('crypto') * that's not an issue here * The probability of a collision is extremely small (need 3*10^12 documents to have one chance in a million of a collision) * See http://en.wikipedia.org/wiki/Birthday_problem + * @param {number} len + * @return {string} */ const uid = len => crypto.randomBytes(Math.ceil(Math.max(8, len * 2))) .toString('base64') diff --git a/lib/executor.js b/lib/executor.js index 61275be..872553f 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -1,3 +1,9 @@ +/** + * @callback AsyncFunction + * @param {...[*]} args + * @return {Promise<*>} + */ + /** * Responsible for sequentially executing actions on the database * @private @@ -9,7 +15,7 @@ class Waterfall { * * It will change any time `this.waterfall` is called, this is why there is a getter `this.guardian` which retrieves * the latest version of the guardian. - * @type {Promise} + * @type {Promise} * @private */ this._guardian = Promise.resolve() @@ -19,26 +25,20 @@ class Waterfall { * Returns a Promise which resolves when all tasks up to when this function is called are done. * * This Promise cannot reject. - * @return {Promise} + * @return {Promise} */ get guardian () { return this._guardian } - /** - * @callback Waterfall~function - * @param {...[*]} args - * @return {Promise<*>} - */ - /** * - * @param {Waterfall~function} func - * @return {Waterfall~function} + * @param {AsyncFunction} func + * @return {AsyncFunction} */ waterfall (func) { return (...args) => { - this._guardian = this.guardian.then(() => { + this._guardian = this.guardian.then(async () => { return func(...args) .then(result => ({ error: false, result }), result => ({ error: true, result })) }) @@ -49,6 +49,11 @@ class Waterfall { } } + /** + * Shorthand for chaining a promise to the Waterfall + * @param promise + * @return {Promise} + */ chain (promise) { return this.waterfall(() => promise)() } @@ -68,11 +73,11 @@ class Executor { * If executor is ready, queue task (and process it immediately if executor was idle) * If not, buffer task for later processing * @param {Object} task - * task.this - Object to use as this - * task.fn - Function to execute - * task.arguments - Array of arguments, IMPORTANT: only the last argument may be a function (the callback) - * and the last argument cannot be false/undefined/null - * @param {Boolean} forceQueuing Optional (defaults to false) force executor to queue task even if it is not ready + * @param {Object} task.this - Object to use as this + * @param {function} task.fn - Function to execute + * @param {Array} task.arguments - Array of arguments, IMPORTANT: only the last argument may be a function + * (the callback) and the last argument cannot be false/undefined/null + * @param {Boolean} [forceQueuing = false] Optional (defaults to false) force executor to queue task even if it is not ready */ push (task, forceQueuing) { const func = async () => { @@ -102,7 +107,15 @@ class Executor { this.pushAsync(func, forceQueuing) } - pushAsync (task, forceQueuing) { + /** + * If executor is ready, queue task (and process it immediately if executor was idle) + * If not, buffer task for later processing + * @param {AsyncFunction} task + * @param {boolean} [forceQueuing = false] + * @return {Promise<*>} + * @async + */ + pushAsync (task, forceQueuing = false) { if (this.ready || forceQueuing) return this.queue.waterfall(task)() else return this.buffer.waterfall(task)() } diff --git a/lib/persistence.js b/lib/persistence.js index ac22eb4..93731c6 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -61,16 +61,29 @@ class Persistence { } } + /** + * @callback Persistence~persistCachedDatabaseCallback + * @param {Error?} err + */ + /** * Persist cached database * This serves as a compaction function since the cache always contains only the number of documents in the collection * while the data file is append-only so it may grow larger - * @param {Function} callback Optional callback, signature: err + * This is an internal function, use compactDataFile which uses the executor + * @param {Persistence~persistCachedDatabaseCallback} callback Optional callback, signature: err */ persistCachedDatabase (callback = () => {}) { return callbackify(this.persistCachedDatabaseAsync.bind(this))(callback) } + /** + * Persist cached database + * This serves as a compaction function since the cache always contains only the number of documents in the collection + * while the data file is append-only so it may grow larger + * This is an internal function, use compactDataFileAsync which uses the executor + * @return {Promise} + */ async persistCachedDatabaseAsync () { const lines = [] @@ -95,13 +108,23 @@ class Persistence { this.db.emit('compaction.done') } + /** + * @callback Persistence~compactDataFileCallback + * @param {Error?} err + */ + /** * Queue a rewrite of the datafile + * @param {Persistence~compactDataFileCallback} [callback = () => {}] Optional callback, signature: err */ - compactDatafile () { - this.db.executor.push({ this: this, fn: this.persistCachedDatabase, arguments: [] }) + compactDatafile (callback = () => {}) { + this.db.executor.push({ this: this, fn: this.persistCachedDatabase, arguments: [callback] }) } + /** + * Queue a rewrite of the datafile + * @async + */ compactDatafileAsync () { return this.db.executor.pushAsync(() => this.persistCachedDatabaseAsync()) } @@ -128,16 +151,27 @@ class Persistence { if (this.autocompactionIntervalId) clearInterval(this.autocompactionIntervalId) } + /** + * @callback Persistence~persistNewStateCallback + * @param {Error?} err + */ + /** * Persist new state for the given newDocs (can be insertion, update or removal) * Use an append-only format - * @param {Array} newDocs Can be empty if no doc was updated/removed - * @param {Function} callback Optional, signature: err + * @param {string[]} newDocs Can be empty if no doc was updated/removed + * @param {Persistence~persistNewStateCallback} [callback = () => {}] Optional, signature: err */ persistNewState (newDocs, callback = () => {}) { callbackify(this.persistNewStateAsync.bind(this))(newDocs, err => callback(err)) } + /** + * Persist new state for the given newDocs (can be insertion, update or removal) + * Use an append-only format + * @param {string[]} newDocs Can be empty if no doc was updated/removed + * @return {Promise} + */ async persistNewStateAsync (newDocs) { let toPersist = '' @@ -154,8 +188,16 @@ class Persistence { } /** - * From a database's raw data, return the corresponding - * machine understandable collection + * @typedef rawIndex + * @property {string} fieldName + * @property {boolean} [unique] + * @property {boolean} [sparse] + */ + + /** + * From a database's raw data, return the corresponding machine understandable collection + * @param {string} rawData database file + * @return {{data: document[], indexes: Object.}} */ treatRawData (rawData) { const data = rawData.split('\n') @@ -190,8 +232,15 @@ class Persistence { } /** - * From a database's raw stream, return the corresponding - * machine understandable collection + * @callback Persistence~treatRawStreamCallback + * @param {Error?} err + * @param {{data: document[], indexes: Object.}} data + */ + + /** + * From a database's raw data stream, return the corresponding machine understandable collection + * @param {Readable} rawStream + * @param {Persistence~treatRawStreamCallback} cb */ treatRawStream (rawStream, cb) { const dataById = {} @@ -236,10 +285,21 @@ class Persistence { }) } - async treatRawStreamAsync (rawStream) { + /** + * From a database's raw data stream, return the corresponding machine understandable collection + * @param {Readable} rawStream + * @return {Promise<{data: document[], indexes: Object.}>} + * @async + */ + treatRawStreamAsync (rawStream) { return promisify(this.treatRawStream.bind(this))(rawStream) } + /** + * @callback Persistence~loadDatabaseCallback + * @param {Error?} err + */ + /** * Load the database * 1) Create all indexes @@ -248,12 +308,22 @@ class Persistence { * This means pulling data out of the data file or creating it if it doesn't exist * Also, all data is persisted right away, which has the effect of compacting the database file * This operation is very quick at startup for a big collection (60ms for ~10k docs) - * @param {Function} callback Optional callback, signature: err + * @param {Persistence~loadDatabaseCallback} callback Optional callback, signature: err */ loadDatabase (callback = () => {}) { callbackify(this.loadDatabaseAsync.bind(this))(err => callback(err)) } + /** + * Load the database + * 1) Create all indexes + * 2) Insert all data + * 3) Compact the database + * This means pulling data out of the data file or creating it if it doesn't exist + * Also, all data is persisted right away, which has the effect of compacting the database file + * This operation is very quick at startup for a big collection (60ms for ~10k docs) + * @return {Promise} + */ async loadDatabaseAsync () { this.db.resetIndexes() @@ -289,14 +359,25 @@ class Persistence { this.db.executor.processBuffer() } + /** + * @callback Persistence~ensureDirectoryExistsCallback + * @param {Error?} err + */ + /** * Check if a directory stat and create it on the fly if it is not the case - * cb is optional, signature: err + * @param {string} dir + * @param {Persistence~ensureDirectoryExistsCallback} [callback = () => {}] optional callback, signature: err */ static ensureDirectoryExists (dir, callback = () => {}) { storage.mkdir(dir, { recursive: true }, err => { callback(err) }) } + /** + * Check if a directory stat and create it on the fly if it is not the case + * @param {string} dir + * @return {Promise} + */ static async ensureDirectoryExistsAsync (dir) { await storage.mkdirAsync(dir, { recursive: true }) } @@ -304,6 +385,10 @@ class Persistence { /** * Return the path the datafile if the given filename is relative to the directory where Node Webkit stores * data for this application. Probably the best place to store data + * @param {string} appName + * @param {string} relativeFilename + * @return {string} + * @deprecated */ static getNWAppFilename (appName, relativeFilename) { return deprecate(() => { diff --git a/lib/utils.js b/lib/utils.js index d3d1735..2f86f70 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,15 +1,41 @@ -const uniq = (array, iterator) => { - if (iterator) return [...(new Map(array.map(x => [iterator(x), x]))).values()] +/** + * Produces a duplicate-free version of the array, using === to test object equality. In particular only the first + * occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee + * function. + * Heavily inspired by https://underscorejs.org/#uniq + * @param {Array} array + * @param {function} [iteratee] transformation applied to every element before checking for duplicates. This will not + * transform the items in the result. + * @return {Array} + */ +const uniq = (array, iteratee) => { + if (iteratee) return [...(new Map(array.map(x => [iteratee(x), x]))).values()] else return [...new Set(array)] } - -const objectToString = o => Object.prototype.toString.call(o) - +/** + * Returns true if arg is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings + * and numbers are not. + * Heavily inspired by https://underscorejs.org/#isObject + * @param {*} arg + * @return {boolean} + */ const isObject = arg => typeof arg === 'object' && arg !== null -const isDate = d => isObject(d) && objectToString(d) === '[object Date]' +/** + * Returns true if d is a Date. + * Heavily inspired by https://underscorejs.org/#isDate + * @param {*} d + * @return {boolean} + */ +const isDate = d => isObject(d) && Object.prototype.toString.call(d) === '[object Date]' -const isRegExp = re => isObject(re) && objectToString(re) === '[object RegExp]' +/** + * Returns true if re is a RegExp. + * Heavily inspired by https://underscorejs.org/#isRegExp + * @param {*} re + * @return {boolean} + */ +const isRegExp = re => isObject(re) && Object.prototype.toString.call(re) === '[object RegExp]' module.exports.uniq = uniq module.exports.isDate = isDate From 0b8aab73468c7ca2dcaad4adb18e94bef31bdf5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Wed, 5 Jan 2022 17:03:07 +0100 Subject: [PATCH 34/65] add doc to model, fix persistence doc, fix error in cursor and unecessary async in executor --- lib/cursor.js | 8 +- lib/executor.js | 2 +- lib/model.js | 186 ++++++++++++++++++++++++++++++++++++--------- lib/persistence.js | 14 ++-- 4 files changed, 164 insertions(+), 46 deletions(-) diff --git a/lib/cursor.js b/lib/cursor.js index 0882d88..8873cda 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -33,10 +33,10 @@ class Cursor { this.query = query || {} if (execFn) this.execFn = execFn if (async) this.async = true - this._limit = null - this._skip = null - this._sort = null - this._projection = null + this._limit = undefined + this._skip = undefined + this._sort = undefined + this._projection = undefined } /** diff --git a/lib/executor.js b/lib/executor.js index 872553f..e272ca1 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -38,7 +38,7 @@ class Waterfall { */ waterfall (func) { return (...args) => { - this._guardian = this.guardian.then(async () => { + this._guardian = this.guardian.then(() => { return func(...args) .then(result => ({ error: false, result }), result => ({ error: true, result })) }) diff --git a/lib/model.js b/lib/model.js index 3d24b96..2c6eeb1 100755 --- a/lib/model.js +++ b/lib/model.js @@ -5,7 +5,13 @@ * Querying, update */ const { uniq, isDate, isRegExp } = require('./utils.js') +/** + * @type {Object.} + */ const modifierFunctions = {} +/** + * @type {Object.} + */ const lastStepModifierFunctions = {} const comparisonFunctions = {} const logicalOperators = {} @@ -13,8 +19,8 @@ const arrayComparisonFunctions = {} /** * Check a key, throw an error if the key is non valid - * @param {String} k key - * @param {Model} v value, needed to treat the Date edge case + * @param {string} k key + * @param {document} v value, needed to treat the Date edge case * Non-treatable edge cases here: if part of the object if of the form { $$date: number } or { $$deleted: true } * Its serialized-then-deserialized version it will transformed into a Date object * But you really need to want it to trigger such behaviour, even when warned not to use '$' at the beginning of the field names... @@ -36,6 +42,7 @@ const checkKey = (k, v) => { /** * Check a DB object and throw an error if it's not valid * Works by applying the above checkKey function to all fields recursively + * @param {document|document[]} obj */ const checkObject = obj => { if (Array.isArray(obj)) { @@ -61,6 +68,8 @@ const checkObject = obj => { * so eval and the like are not safe * Accepted primitive types: Number, String, Boolean, Date, null * Accepted secondary types: Objects, Arrays + * @param {document} obj + * @return {string} */ const serialize = obj => { return JSON.stringify(obj, function (k, v) { @@ -80,6 +89,8 @@ const serialize = obj => { /** * From a one-line representation of an object generate by the serialize function * Return the object itself + * @param {string} rawData + * @return {document} */ const deserialize = rawData => JSON.parse(rawData, function (k, v) { if (k === '$$date') return new Date(v) @@ -98,6 +109,9 @@ const deserialize = rawData => JSON.parse(rawData, function (k, v) { * Deep copy a DB object * The optional strictKeys flag (defaulting to false) indicates whether to copy everything or only fields * where the keys are valid, i.e. don't begin with $ and don't contain a . + * @param {?document} obj + * @param {boolean} [strictKeys=false] + * @return {?document} */ function deepCopy (obj, strictKeys) { if ( @@ -129,6 +143,8 @@ function deepCopy (obj, strictKeys) { /** * Tells if an object is a primitive type or a "real" object * Arrays are considered primitive + * @param {*} obj + * @return {boolean} */ const isPrimitiveType = obj => ( typeof obj === 'boolean' || @@ -143,6 +159,9 @@ const isPrimitiveType = obj => ( * Utility functions for comparing things * Assumes type checking was already done (a and b already have the same type) * compareNSB works for numbers, strings and booleans + * @param {number|string|boolean} a + * @param {number|string|boolean} b + * @return {number} 0 if a == b, 1 i a > b, -1 if a < b */ const compareNSB = (a, b) => { if (a < b) return -1 @@ -150,6 +169,14 @@ const compareNSB = (a, b) => { return 0 } +/** + * Utility function for comparing array + * Assumes type checking was already done (a and b already have the same type) + * compareNSB works for numbers, strings and booleans + * @param {Array} a + * @param {Array} b + * @return {number} 0 if arrays have the same length and all elements equal one another. Else either 1 or -1. + */ const compareArrays = (a, b) => { const minLength = Math.min(a.length, b.length) for (let i = 0; i < minLength; i += 1) { @@ -169,8 +196,10 @@ const compareArrays = (a, b) => { * In the case of objects and arrays, we deep-compare * If two objects dont have the same type, the (arbitrary) type hierarchy is: undefined, null, number, strings, boolean, dates, arrays, objects * Return -1 if a < b, 1 if a > b and 0 if a = b (note that equality here is NOT the same as defined in areThingsEqual!) - * - * @param {Function} _compareStrings String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters) + * @param {*} a + * @param {*} b + * @param {Function} [_compareStrings] String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters) + * @return {number} */ const compareThings = (a, b, _compareStrings) => { const compareStrings = _compareStrings || compareNSB @@ -221,16 +250,18 @@ const compareThings = (a, b, _compareStrings) => { // ============================================================== /** + * @callback Model~modifierFunction * The signature of modifier functions is as follows * Their structure is always the same: recursively follow the dot notation while creating * the nested documents if needed, then apply the "last step modifier" * @param {Object} obj The model to modify * @param {String} field Can contain dots, in that case that means we will set a subfield recursively - * @param {Model} value + * @param {document} value */ /** * Set a field to a new value + * @type Model~modifierFunction */ lastStepModifierFunctions.$set = (obj, field, value) => { obj[field] = value @@ -238,6 +269,7 @@ lastStepModifierFunctions.$set = (obj, field, value) => { /** * Unset a field + * @type Model~modifierFunction */ lastStepModifierFunctions.$unset = (obj, field, value) => { delete obj[field] @@ -248,6 +280,7 @@ lastStepModifierFunctions.$unset = (obj, field, value) => { * Optional modifier $each instead of value to push several values * Optional modifier $slice to slice the resulting array, see https://docs.mongodb.org/manual/reference/operator/update/slice/ * Différeence with MongoDB: if $slice is specified and not $each, we act as if value is an empty array + * @type Model~modifierFunction */ lastStepModifierFunctions.$push = (obj, field, value) => { // Create the array if it doesn't exist @@ -298,6 +331,7 @@ lastStepModifierFunctions.$push = (obj, field, value) => { * Add an element to an array field only if it is not already in it * No modification if the element is already in the array * Note that it doesn't check whether the original array contains duplicates + * @type Model~modifierFunction */ lastStepModifierFunctions.$addToSet = (obj, field, value) => { // Create the array if it doesn't exist @@ -323,6 +357,7 @@ lastStepModifierFunctions.$addToSet = (obj, field, value) => { /** * Remove the first or last element of an array + * @type Model~modifierFunction */ lastStepModifierFunctions.$pop = (obj, field, value) => { if (!Array.isArray(obj[field])) throw new Error('Can\'t $pop an element from non-array values') @@ -335,6 +370,7 @@ lastStepModifierFunctions.$pop = (obj, field, value) => { /** * Removes all instances of a value from an existing array + * @type Model~modifierFunction */ lastStepModifierFunctions.$pull = (obj, field, value) => { if (!Array.isArray(obj[field])) throw new Error('Can\'t $pull an element from non-array values') @@ -347,6 +383,7 @@ lastStepModifierFunctions.$pull = (obj, field, value) => { /** * Increment a numeric field's value + * @type Model~modifierFunction */ lastStepModifierFunctions.$inc = (obj, field, value) => { if (typeof value !== 'number') throw new Error(`${value} must be a number`) @@ -359,6 +396,7 @@ lastStepModifierFunctions.$inc = (obj, field, value) => { /** * Updates the value of the field, only if specified field is greater than the current value of the field + * @type Model~modifierFunction */ lastStepModifierFunctions.$max = (obj, field, value) => { if (typeof obj[field] === 'undefined') obj[field] = value @@ -367,13 +405,18 @@ lastStepModifierFunctions.$max = (obj, field, value) => { /** * Updates the value of the field, only if specified field is smaller than the current value of the field + * @type Model~modifierFunction */ lastStepModifierFunctions.$min = (obj, field, value) => { if (typeof obj[field] === 'undefined') obj[field] = value else if (value < obj[field]) obj[field] = value } -// Given its name, create the complete modifier function +/** + * Create the complete modifier function + * @param {string} modifier one of lastStepModifierFunctions keys + * @return {Model~modifierFunction} + */ const createModifierFunction = modifier => (obj, field, value) => { const fieldParts = typeof field === 'string' ? field.split('.') : field @@ -394,6 +437,9 @@ Object.keys(lastStepModifierFunctions).forEach(modifier => { /** * Modify a DB object according to an update query + * @param {document} obj + * @param {query} updateQuery + * @return {document} */ const modify = (obj, updateQuery) => { const keys = Object.keys(updateQuery) @@ -441,8 +487,9 @@ const modify = (obj, updateQuery) => { /** * Get a value from object with dot notation - * @param {Object} obj - * @param {String} field + * @param {object} obj + * @param {string} field + * @return {*} */ const getDotValue = (obj, field) => { const fieldParts = typeof field === 'string' ? field.split('.') : field @@ -468,6 +515,9 @@ const getDotValue = (obj, field) => { * Things are defined as any native types (string, number, boolean, null, date) and objects * In the case of object, we check deep equality * Returns true if they are, false otherwise + * @param {*} a + * @param {*} a + * @return {boolean} */ const areThingsEqual = (a, b) => { // Strings, booleans, numbers, null @@ -513,6 +563,9 @@ const areThingsEqual = (a, b) => { /** * Check that two values are comparable + * @param {*} a + * @param {*} a + * @return {boolean} */ const areComparable = (a, b) => { if ( @@ -530,20 +583,47 @@ const areComparable = (a, b) => { } /** + * @callback Model~comparisonOperator * Arithmetic and comparison operators - * @param {Native value} a Value in the object - * @param {Native value} b Value in the query + * @param {*} a Value in the object + * @param {*} b Value in the query + * @return {boolean} + */ + +/** + * Lower than + * @type Model~comparisonOperator */ comparisonFunctions.$lt = (a, b) => areComparable(a, b) && a < b +/** + * Lower than or equals + * @type Model~comparisonOperator + */ comparisonFunctions.$lte = (a, b) => areComparable(a, b) && a <= b +/** + * Greater than + * @type Model~comparisonOperator + */ comparisonFunctions.$gt = (a, b) => areComparable(a, b) && a > b +/** + * Greater than or equals + * @type Model~comparisonOperator + */ comparisonFunctions.$gte = (a, b) => areComparable(a, b) && a >= b +/** + * Does not equal + * @type Model~comparisonOperator + */ comparisonFunctions.$ne = (a, b) => a === undefined || !areThingsEqual(a, b) +/** + * Is in Array + * @type Model~comparisonOperator + */ comparisonFunctions.$in = (a, b) => { if (!Array.isArray(b)) throw new Error('$in operator called with a non-array') @@ -553,13 +633,20 @@ comparisonFunctions.$in = (a, b) => { return false } - +/** + * Is not in Array + * @type Model~comparisonOperator + */ comparisonFunctions.$nin = (a, b) => { if (!Array.isArray(b)) throw new Error('$nin operator called with a non-array') return !comparisonFunctions.$in(a, b) } +/** + * Matches Regexp + * @type Model~comparisonOperator + */ comparisonFunctions.$regex = (a, b) => { if (!isRegExp(b)) throw new Error('$regex operator called with non regular expression') @@ -567,27 +654,38 @@ comparisonFunctions.$regex = (a, b) => { else return b.test(a) } -comparisonFunctions.$exists = (value, exists) => { +/** + * Returns true if field exists + * @type Model~comparisonOperator + */ +comparisonFunctions.$exists = (a, b) => { // This will be true for all values of stat except false, null, undefined and 0 // That's strange behaviour (we should only use true/false) but that's the way Mongo does it... - if (exists || exists === '') exists = true - else exists = false + if (b || b === '') b = true + else b = false - if (value === undefined) return !exists - else return exists + if (a === undefined) return !b + else return b } -// Specific to arrays -comparisonFunctions.$size = (obj, value) => { - if (!Array.isArray(obj)) return false - if (value % 1 !== 0) throw new Error('$size operator called without an integer') +/** + * Specific to Arrays, returns true if a length equals b + * @type Model~comparisonOperator + */ +comparisonFunctions.$size = (a, b) => { + if (!Array.isArray(a)) return false + if (b % 1 !== 0) throw new Error('$size operator called without an integer') - return obj.length === value + return a.length === b } -comparisonFunctions.$elemMatch = (obj, value) => { - if (!Array.isArray(obj)) return false - return obj.some(el => match(el, value)) +/** + * Specific to Arrays, returns true if some elements of a match the query b + * @type Model~comparisonOperator + */ +comparisonFunctions.$elemMatch = (a, b) => { + if (!Array.isArray(a)) return false + return a.some(el => match(el, b)) } arrayComparisonFunctions.$size = true @@ -595,8 +693,9 @@ arrayComparisonFunctions.$elemMatch = true /** * Match any of the subqueries - * @param {Model} obj - * @param {Array of Queries} query + * @param {document} obj + * @param {query[]} query + * @return {boolean} */ logicalOperators.$or = (obj, query) => { if (!Array.isArray(query)) throw new Error('$or operator used without an array') @@ -610,8 +709,9 @@ logicalOperators.$or = (obj, query) => { /** * Match all of the subqueries - * @param {Model} obj - * @param {Array of Queries} query + * @param {document} obj + * @param {query[]} query + * @return {boolean} */ logicalOperators.$and = (obj, query) => { if (!Array.isArray(query)) throw new Error('$and operator used without an array') @@ -625,15 +725,23 @@ logicalOperators.$and = (obj, query) => { /** * Inverted match of the query - * @param {Model} obj - * @param {Query} query + * @param {document} obj + * @param {query} query + * @return {boolean} */ logicalOperators.$not = (obj, query) => !match(obj, query) +/** + * @callback Model~whereCallback + * @param {document} obj + * @return {boolean} + */ + /** * Use a function to match - * @param {Model} obj - * @param {Query} query + * @param {document} obj + * @param {Model~whereCallback} fn + * @return {boolean} */ logicalOperators.$where = (obj, fn) => { if (typeof fn !== 'function') throw new Error('$where operator used without a function') @@ -646,8 +754,9 @@ logicalOperators.$where = (obj, fn) => { /** * Tell if a given document matches a query - * @param {Object} obj Document to check - * @param {Object} query + * @param {document} obj Document to check + * @param {query} query + * @return {boolean} */ const match = (obj, query) => { // Primitive query against a primitive type @@ -673,6 +782,15 @@ const match = (obj, query) => { * Match an object against a specific { key: value } part of a query * if the treatObjAsValue flag is set, don't try to match every part separately, but the array as a whole */ +/** + * Match an object against a specific { key: value } part of a query + * if the treatObjAsValue flag is set, don't try to match every part separately, but the array as a whole + * @param {object} obj + * @param {string} queryKey + * @param {*} queryValue + * @param {boolean} [treatObjAsValue=false] + * @return {boolean} + */ function matchQueryPart (obj, queryKey, queryValue, treatObjAsValue) { const objValue = getDotValue(obj, queryKey) diff --git a/lib/persistence.js b/lib/persistence.js index 93731c6..c7e0200 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -63,7 +63,7 @@ class Persistence { /** * @callback Persistence~persistCachedDatabaseCallback - * @param {Error?} err + * @param {?Error} err */ /** @@ -110,7 +110,7 @@ class Persistence { /** * @callback Persistence~compactDataFileCallback - * @param {Error?} err + * @param {?Error} err */ /** @@ -153,7 +153,7 @@ class Persistence { /** * @callback Persistence~persistNewStateCallback - * @param {Error?} err + * @param {?Error} err */ /** @@ -233,8 +233,8 @@ class Persistence { /** * @callback Persistence~treatRawStreamCallback - * @param {Error?} err - * @param {{data: document[], indexes: Object.}} data + * @param {?Error} err + * @param {{data: document[], indexes: Object.}?} data */ /** @@ -297,7 +297,7 @@ class Persistence { /** * @callback Persistence~loadDatabaseCallback - * @param {Error?} err + * @param {?Error} err */ /** @@ -361,7 +361,7 @@ class Persistence { /** * @callback Persistence~ensureDirectoryExistsCallback - * @param {Error?} err + * @param {?Error} err */ /** From 6d43867c209db3258b11f25c41ae0a10428e4df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Wed, 5 Jan 2022 17:29:51 +0100 Subject: [PATCH 35/65] document storage and customUtils, and rewrite byline with ES6 --- browser-version/lib/customUtils.js | 6 + lib/byline.js | 176 +++++++++++------------------ lib/storage.js | 79 ++++++++++--- 3 files changed, 137 insertions(+), 124 deletions(-) diff --git a/browser-version/lib/customUtils.js b/browser-version/lib/customUtils.js index 13021df..0e23bc7 100755 --- a/browser-version/lib/customUtils.js +++ b/browser-version/lib/customUtils.js @@ -6,6 +6,8 @@ * Taken from the crypto-browserify module * https://github.com/dominictarr/crypto-browserify * NOTE: Math.random() does not guarantee "cryptographic quality" but we actually don't need it + * @param {number} size in bytes + * @return {array} */ const randomBytes = size => { const bytes = new Array(size) @@ -21,6 +23,8 @@ const randomBytes = size => { /** * Taken from the base64-js module * https://github.com/beatgammit/base64-js/ + * @param {array} uint8 + * @return {string} */ const byteArrayToBase64 = uint8 => { const lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' @@ -60,6 +64,8 @@ const byteArrayToBase64 = uint8 => { * that's not an issue here * The probability of a collision is extremely small (need 3*10^12 documents to have one chance in a million of a collision) * See http://en.wikipedia.org/wiki/Birthday_problem + * @param {number} len + * @return {string} */ const uid = len => byteArrayToBase64(randomBytes(Math.ceil(Math.max(8, len * 2)))).replace(/[+/]/g, '').slice(0, len) diff --git a/lib/byline.js b/lib/byline.js index 19bff8b..21e2437 100644 --- a/lib/byline.js +++ b/lib/byline.js @@ -21,133 +21,93 @@ // IN THE SOFTWARE. const stream = require('stream') -const util = require('util') const timers = require('timers') -// convinience API -module.exports = function (readStream, options) { - return module.exports.createStream(readStream, options) -} - -// basic API -module.exports.createStream = function (readStream, options) { - if (readStream) { - return createLineStream(readStream, options) - } else { - return new LineStream(options) - } -} - -// deprecated API -module.exports.createLineStream = function (readStream) { - console.log('WARNING: byline#createLineStream is deprecated and will be removed soon') - return createLineStream(readStream) -} - -function createLineStream (readStream, options) { - if (!readStream) { - throw new Error('expected readStream') - } - if (!readStream.readable) { - throw new Error('readStream must be readable') - } +const createLineStream = (readStream, options) => { + if (!readStream) throw new Error('expected readStream') + if (!readStream.readable) throw new Error('readStream must be readable') const ls = new LineStream(options) readStream.pipe(ls) return ls } -// -// using the new node v0.10 "streams2" API -// +class LineStream extends stream.Transform { + constructor (options) { + super(options) + options = options || {} + + // use objectMode to stop the output from being buffered + // which re-concatanates the lines, just without newlines. + this._readableState.objectMode = true + this._lineBuffer = [] + this._keepEmptyLines = options.keepEmptyLines || false + this._lastChunkEndedWithCR = false + + // take the source's encoding if we don't have one + this.once('pipe', src => { + if (!this.encoding && src instanceof stream.Readable) this.encoding = src._readableState.encoding // but we can't do this for old-style streams + }) + } -module.exports.LineStream = LineStream + _transform (chunk, encoding, done) { + // decode binary chunks as UTF-8 + encoding = encoding || 'utf8' -function LineStream (options) { - stream.Transform.call(this, options) - options = options || {} - - // use objectMode to stop the output from being buffered - // which re-concatanates the lines, just without newlines. - this._readableState.objectMode = true - this._lineBuffer = [] - this._keepEmptyLines = options.keepEmptyLines || false - this._lastChunkEndedWithCR = false - - // take the source's encoding if we don't have one - const self = this - this.on('pipe', function (src) { - if (!self.encoding) { - // but we can't do this for old-style streams - if (src instanceof stream.Readable) { - self.encoding = src._readableState.encoding - } + if (Buffer.isBuffer(chunk)) { + if (encoding === 'buffer') { + chunk = chunk.toString() // utf8 + encoding = 'utf8' + } else chunk = chunk.toString(encoding) } - }) -} -util.inherits(LineStream, stream.Transform) - -LineStream.prototype._transform = function (chunk, encoding, done) { - // decode binary chunks as UTF-8 - encoding = encoding || 'utf8' - - if (Buffer.isBuffer(chunk)) { - if (encoding === 'buffer') { - chunk = chunk.toString() // utf8 - encoding = 'utf8' - } else { - chunk = chunk.toString(encoding) - } - } - this._chunkEncoding = encoding + this._chunkEncoding = encoding - // see: http://www.unicode.org/reports/tr18/#Line_Boundaries - const lines = chunk.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g) + // see: http://www.unicode.org/reports/tr18/#Line_Boundaries + const lines = chunk.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g) - // don't split CRLF which spans chunks - if (this._lastChunkEndedWithCR && chunk[0] === '\n') { - lines.shift() - } + // don't split CRLF which spans chunks + if (this._lastChunkEndedWithCR && chunk[0] === '\n') lines.shift() - if (this._lineBuffer.length > 0) { - this._lineBuffer[this._lineBuffer.length - 1] += lines[0] - lines.shift() - } + if (this._lineBuffer.length > 0) { + this._lineBuffer[this._lineBuffer.length - 1] += lines[0] + lines.shift() + } - this._lastChunkEndedWithCR = chunk[chunk.length - 1] === '\r' - this._lineBuffer = this._lineBuffer.concat(lines) - this._pushBuffer(encoding, 1, done) -} + this._lastChunkEndedWithCR = chunk[chunk.length - 1] === '\r' + this._lineBuffer = this._lineBuffer.concat(lines) + this._pushBuffer(encoding, 1, done) + } -LineStream.prototype._pushBuffer = function (encoding, keep, done) { - // always buffer the last (possibly partial) line - while (this._lineBuffer.length > keep) { - const line = this._lineBuffer.shift() - // skip empty lines - if (this._keepEmptyLines || line.length > 0) { - if (!this.push(this._reencode(line, encoding))) { - // when the high-water mark is reached, defer pushes until the next tick - timers.setImmediate(() => { - this._pushBuffer(encoding, keep, done) - }) - return + _pushBuffer (encoding, keep, done) { + // always buffer the last (possibly partial) line + while (this._lineBuffer.length > keep) { + const line = this._lineBuffer.shift() + // skip empty lines + if (this._keepEmptyLines || line.length > 0) { + if (!this.push(this._reencode(line, encoding))) { + // when the high-water mark is reached, defer pushes until the next tick + timers.setImmediate(() => { this._pushBuffer(encoding, keep, done) }) + return + } } } + done() } - done() -} -LineStream.prototype._flush = function (done) { - this._pushBuffer(this._chunkEncoding, 0, done) -} + _flush (done) { + this._pushBuffer(this._chunkEncoding, 0, done) + } -// see Readable::push -LineStream.prototype._reencode = function (line, chunkEncoding) { - if (this.encoding && this.encoding !== chunkEncoding) { - return Buffer.from(line, chunkEncoding).toString(this.encoding) - } else if (this.encoding) { - // this should be the most common case, i.e. we're using an encoded source stream - return line - } else { - return Buffer.from(line, chunkEncoding) + // see Readable::push + _reencode (line, chunkEncoding) { + if (this.encoding && this.encoding !== chunkEncoding) return Buffer.from(line, chunkEncoding).toString(this.encoding) + else if (this.encoding) return line // this should be the most common case, i.e. we're using an encoded source stream + else return Buffer.from(line, chunkEncoding) } } + +// convenience API +module.exports = (readStream, options) => module.exports.createStream(readStream, options) + +// basic API +module.exports.createStream = (readStream, options) => readStream ? createLineStream(readStream, options) : new LineStream(options) +module.exports.LineStream = LineStream diff --git a/lib/storage.js b/lib/storage.js index 43bf3de..54e4e0e 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -13,9 +13,22 @@ const { callbackify, promisify } = require('util') const storage = {} const { Readable } = require('stream') +/** + * @callback Storage~existsCallback + * @param {boolean} exists + */ + +/** + * @param {string} file + * @param {Storage~existsCallback} cb + */ // eslint-disable-next-line node/no-callback-literal -storage.exists = (path, cb) => fs.access(path, fs.constants.F_OK, (err) => { cb(!err) }) -storage.existsAsync = path => fsPromises.access(path, fs.constants.F_OK).then(() => true, () => false) +storage.exists = (file, cb) => fs.access(file, fs.constants.F_OK, (err) => { cb(!err) }) +/** + * @param {string} file + * @return {Promise} + */ +storage.existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() => true, () => false) storage.rename = fs.rename storage.renameAsync = fsPromises.rename storage.writeFile = fs.writeFile @@ -32,22 +45,40 @@ storage.mkdir = fs.mkdir storage.mkdirAsync = fsPromises.mkdir /** - * Explicit name ... + * @param {string} file + * @return {Promise} */ storage.ensureFileDoesntExistAsync = async file => { if (await storage.existsAsync(file)) await storage.unlinkAsync(file) } +/** + * @callback Storage~errorCallback + * @param {?Error} err + */ + +/** + * @param {string} file + * @param {Storage~errorCallback} callback + */ storage.ensureFileDoesntExist = (file, callback) => callbackify(storage.ensureFileDoesntExistAsync)(file, err => callback(err)) /** * Flush data in OS buffer to storage if corresponding option is set - * @param {String} options.filename - * @param {Boolean} options.isDir Optional, defaults to false - * If options is a string, it is assumed that the flush of the file (not dir) called options was requested + * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested + * @param {string} [options.filename] + * @param {boolean} [options.isDir = false] Optional, defaults to false + * @param {Storage~errorCallback} callback */ storage.flushToStorage = (options, callback) => callbackify(storage.flushToStorageAsync)(options, callback) +/** + * Flush data in OS buffer to storage if corresponding option is set + * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested + * @param {string} [options.filename] + * @param {boolean} [options.isDir = false] Optional, defaults to false + * @return {Promise} + */ storage.flushToStorageAsync = async (options) => { let filename let flags @@ -98,9 +129,9 @@ storage.flushToStorageAsync = async (options) => { /** * Fully write or rewrite the datafile - * @param {String} filename - * @param {String[]} lines - * @param {Function} callback + * @param {string} filename + * @param {string[]} lines + * @param {Storage~errorCallback} callback */ storage.writeFileLines = (filename, lines, callback = () => {}) => { try { @@ -122,19 +153,30 @@ storage.writeFileLines = (filename, lines, callback = () => {}) => { callback(err) } } - +/** + * Fully write or rewrite the datafile + * @param {string} filename + * @param {string[]} lines + * @return {Promise} + * @async + */ storage.writeFileLinesAsync = (filename, lines) => promisify(storage.writeFileLines)(filename, lines) /** * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) - * @param {String} filename - * @param {String[]} lines - * @param {Function} callback Optional callback, signature: err + * @param {string} filename + * @param {string[]} lines + * @param {Storage~errorCallback} callback Optional callback, signature: err */ storage.crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { callbackify(storage.crashSafeWriteFileLinesAsync)(filename, lines, callback) } - +/** + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * @param {string} filename + * @param {string[]} lines + * @return {Promise} + */ storage.crashSafeWriteFileLinesAsync = async (filename, lines) => { const tempFilename = filename + '~' @@ -154,11 +196,16 @@ storage.crashSafeWriteFileLinesAsync = async (filename, lines) => { /** * Ensure the datafile contains all the data, even if there was a crash during a full file write - * @param {String} filename - * @param {Function} callback signature: err + * @param {string} filename + * @param {Storage~errorCallback} callback signature: err */ storage.ensureDatafileIntegrity = (filename, callback) => callbackify(storage.ensureDatafileIntegrityAsync)(filename, callback) +/** + * Ensure the datafile contains all the data, even if there was a crash during a full file write + * @param {string} filename + * @return {Promise} + */ storage.ensureDatafileIntegrityAsync = async filename => { const tempFilename = filename + '~' From 0e9e5c7f4d32602d45a7f368e265da91c1f67483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 6 Jan 2022 15:31:15 +0100 Subject: [PATCH 36/65] massive update of the JSDoc, rewrite of the model & storage modules to clarify --- browser-version/lib/customUtils.js | 5 +- browser-version/lib/storage.browser.js | 183 ++++++- browser-version/lib/storage.react-native.js | 174 +++++- index.d.ts | 33 +- jsdoc.conf.js | 11 - lib/cursor.js | 6 +- lib/customUtils.js | 6 + lib/datastore.js | 119 ++--- lib/executor.js | 15 +- lib/indexes.js | 8 +- lib/model.js | 563 +++++++++----------- lib/persistence.js | 48 +- lib/storage.js | 289 ++++++++-- lib/utils.js | 10 + package-lock.json | 326 ------------ package.json | 4 +- 16 files changed, 962 insertions(+), 838 deletions(-) delete mode 100644 jsdoc.conf.js diff --git a/browser-version/lib/customUtils.js b/browser-version/lib/customUtils.js index 0e23bc7..61d4ae5 100755 --- a/browser-version/lib/customUtils.js +++ b/browser-version/lib/customUtils.js @@ -1,5 +1,7 @@ /** - * Specific customUtils for the browser, where we don't have access to the Crypto and Buffer modules + * Utility functions that need to be reimplemented for each environment. + * This is the version for the browser & React-Native + * @module customUtilsBrowser */ /** @@ -66,6 +68,7 @@ const byteArrayToBase64 = uint8 => { * See http://en.wikipedia.org/wiki/Birthday_problem * @param {number} len * @return {string} + * @alias module:customUtilsNode.uid */ const uid = len => byteArrayToBase64(randomBytes(Math.ceil(Math.max(8, len * 2)))).replace(/[+/]/g, '').slice(0, len) diff --git a/browser-version/lib/storage.browser.js b/browser-version/lib/storage.browser.js index c12abf1..e2c3f35 100755 --- a/browser-version/lib/storage.browser.js +++ b/browser-version/lib/storage.browser.js @@ -1,13 +1,14 @@ /** * Way data is stored for this database * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) - * For a react-native database, we use @react-native-async-storage/async-storage + * For a browser-side database it's localforage which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage) * * This version is the browser version + * @module storageBrowser */ + const localforage = require('localforage') -const { callbackify } = require('util') +const { callbackify } = require('util') // TODO: util is not a dependency, this would fail if util is not polyfilled // Configure localforage to display NeDB name for now. Would be a good idea to let user use his own app name const store = localforage.createInstance({ @@ -15,9 +16,16 @@ const store = localforage.createInstance({ storeName: 'nedbdata' }) -const existsAsync = async filename => { +/** + * Returns Promise if file exists + * @param {string} file + * @return {Promise} + * @async + * @alias module:storageBrowser.existsAsync + */ +const existsAsync = async file => { try { - const value = await store.getItem(filename) + const value = await store.getItem(file) if (value !== null) return true // Even if value is undefined, localforage returns null return false } catch (error) { @@ -25,34 +33,91 @@ const existsAsync = async filename => { } } +/** + * @callback module:storageBrowser~existsCallback + * @param {boolean} exists + */ + +/** + * Callback returns true if file exists + * @function + * @param {string} file + * @param {module:storageBrowser~existsCallback} cb + * @alias module:storageBrowser.exists + */ const exists = callbackify(existsAsync) -const renameAsync = async (filename, newFilename) => { +/** + * Moves the item from one path to another + * @param {string} oldPath + * @param {string} newPath + * @return {Promise} + * @alias module:storageBrowser.renameAsync + * @async + */ +const renameAsync = async (oldPath, newPath) => { try { - const value = await store.getItem(filename) - if (value === null) await store.removeItem(newFilename) + const value = await store.getItem(oldPath) + if (value === null) await store.removeItem(newPath) else { - await store.setItem(newFilename, value) - await store.removeItem(filename) + await store.setItem(newPath, value) + await store.removeItem(oldPath) } } catch (err) { console.warn('An error happened while renaming, skip') } } +/** + * Moves the item from one path to another + * @function + * @param {string} oldPath + * @param {string} newPath + * @param {NoParamCallback} c + * @return {void} + * @alias module:storageBrowser.rename + */ const rename = callbackify(renameAsync) -const writeFileAsync = async (filename, contents, options) => { +/** + * Saves the item at given path + * @param {string} file + * @param {string} data + * @param {object} [options] + * @return {Promise} + * @alias module:storageBrowser.writeFileAsync + * @async + */ +const writeFileAsync = async (file, data, options) => { // Options do not matter in browser setup try { - await store.setItem(filename, contents) + await store.setItem(file, data) } catch (error) { console.warn('An error happened while writing, skip') } } +/** + * Saves the item at given path + * @function + * @param {string} path + * @param {string} data + * @param {object} options + * @param {function} callback + * @alias module:storageBrowser.writeFile + */ const writeFile = callbackify(writeFileAsync) +/** + * Append to the item at given path + * @function + * @param {string} filename + * @param {string} toAppend + * @param {object} [options] + * @return {Promise} + * @alias module:storageBrowser.appendFileAsync + * @async + */ const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup try { @@ -63,8 +128,26 @@ const appendFileAsync = async (filename, toAppend, options) => { } } +/** + * Append to the item at given path + * @function + * @param {string} filename + * @param {string} toAppend + * @param {object} [options] + * @param {function} callback + * @alias module:storageBrowser.appendFile + */ const appendFile = callbackify(appendFileAsync) +/** + * Read data at given path + * @function + * @param {string} filename + * @param {object} [options] + * @return {Promise} + * @alias module:storageBrowser.readFileAsync + * @async + */ const readFileAsync = async (filename, options) => { try { return (await store.getItem(filename)) || '' @@ -73,9 +156,24 @@ const readFileAsync = async (filename, options) => { return '' } } - +/** + * Read data at given path + * @function + * @param {string} filename + * @param {object} options + * @param {function} callback + * @alias module:storageBrowser.readFile + */ const readFile = callbackify(readFileAsync) +/** + * Remove the data at given path + * @function + * @param {string} filename + * @return {Promise} + * @async + * @alias module:storageBrowser.unlinkAsync + */ const unlinkAsync = async filename => { try { await store.removeItem(filename) @@ -84,23 +182,74 @@ const unlinkAsync = async filename => { } } +/** + * Remove the data at given path + * @function + * @param {string} path + * @param {function} callback + * @alias module:storageBrowser.unlink + */ const unlink = callbackify(unlinkAsync) -// Nothing to do, no directories will be used on the browser -const mkdirAsync = (dir, options) => Promise.resolve() - +/** + * Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser + * @function + * @param {string} path + * @param {object} [options] + * @return {Promise} + * @alias module:storageBrowser.mkdirAsync + * @async + */ +const mkdirAsync = (path, options) => Promise.resolve() +/** + * Shim for storage.mkdir, nothing to do, no directories will be used on the browser + * @function + * @param {string} path + * @param {object} options + * @param {function} callback + * @alias module:storageBrowser.mkdir + */ const mkdir = callbackify(mkdirAsync) -// Nothing to do, no data corruption possible in the browser +/** + * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Nothing to do, no data corruption possible in the browser + * @param {string} filename + * @return {Promise} + * @alias module:storageBrowser.ensureDatafileIntegrityAsync + */ const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() +/** + * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Nothing to do, no data corruption possible in the browser + * @function + * @param {string} filename + * @param {NoParamCallback} callback signature: err + * @alias module:storageBrowser.ensureDatafileIntegrity + */ const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) +/** + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * @param {string} filename + * @param {string[]} lines + * @return {Promise} + * @alias module:storageBrowser.crashSafeWriteFileLinesAsync + */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line await writeFileAsync(filename, lines.join('\n')) } +/** + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * @function + * @param {string} filename + * @param {string[]} lines + * @param {NoParamCallback} [callback] Optional callback, signature: err + * @alias module:storageBrowser.crashSafeWriteFileLines + */ const crashSafeWriteFileLines = callbackify(crashSafeWriteFileLinesAsync) // Interface diff --git a/browser-version/lib/storage.react-native.js b/browser-version/lib/storage.react-native.js index f132910..6c5dbba 100755 --- a/browser-version/lib/storage.react-native.js +++ b/browser-version/lib/storage.react-native.js @@ -5,48 +5,112 @@ * For a react-native database, we use @react-native-async-storage/async-storage * * This version is the react-native version + * @module storageReactNative */ const AsyncStorage = require('@react-native-async-storage/async-storage').default -const { callbackify } = require('util') +const { callbackify } = require('util') // TODO: util is not a dependency, this would fail if util is not polyfilled -const existsAsync = async filename => { +/** + * Returns Promise if file exists + * @param {string} file + * @return {Promise} + * @async + * @alias module:storageReactNative.existsAsync + */ +const existsAsync = async file => { try { - const value = await AsyncStorage.getItem(filename) + const value = await AsyncStorage.getItem(file) if (value !== null) return true // Even if value is undefined, localforage returns null return false } catch (error) { return false } } +/** + * @callback module:storageReactNative~existsCallback + * @param {boolean} exists + */ +/** + * Callback returns true if file exists + * @function + * @param {string} file + * @param {module:storageReactNative~existsCallback} cb + * @alias module:storageReactNative.exists + */ const exists = callbackify(existsAsync) -const renameAsync = async (filename, newFilename) => { +/** + * Moves the item from one path to another + * @param {string} oldPath + * @param {string} newPath + * @return {Promise} + * @alias module:storageReactNative.renameAsync + * @async + */ +const renameAsync = async (oldPath, newPath) => { try { - const value = await AsyncStorage.getItem(filename) - if (value === null) await AsyncStorage.removeItem(newFilename) + const value = await AsyncStorage.getItem(oldPath) + if (value === null) await AsyncStorage.removeItem(newPath) else { - await AsyncStorage.setItem(newFilename, value) - await AsyncStorage.removeItem(filename) + await AsyncStorage.setItem(newPath, value) + await AsyncStorage.removeItem(oldPath) } } catch (err) { console.warn('An error happened while renaming, skip') } } +/** + * Moves the item from one path to another + * @function + * @param {string} oldPath + * @param {string} newPath + * @param {NoParamCallback} c + * @return {void} + * @alias module:storageReactNative.rename + */ const rename = callbackify(renameAsync) -const writeFileAsync = async (filename, contents, options) => { +/** + * Saves the item at given path + * @param {string} file + * @param {string} data + * @param {object} [options] + * @return {Promise} + * @alias module:storageReactNative.writeFileAsync + * @async + */ +const writeFileAsync = async (file, data, options) => { // Options do not matter in browser setup try { - await AsyncStorage.setItem(filename, contents) + await AsyncStorage.setItem(file, data) } catch (error) { console.warn('An error happened while writing, skip') } } +/** + * Saves the item at given path + * @function + * @param {string} path + * @param {string} data + * @param {object} options + * @param {function} callback + * @alias module:storageReactNative.writeFile + */ const writeFile = callbackify(writeFileAsync) +/** + * Append to the item at given path + * @function + * @param {string} filename + * @param {string} toAppend + * @param {object} [options] + * @return {Promise} + * @alias module:storageReactNative.appendFileAsync + * @async + */ const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup try { @@ -57,8 +121,26 @@ const appendFileAsync = async (filename, toAppend, options) => { } } +/** + * Append to the item at given path + * @function + * @param {string} filename + * @param {string} toAppend + * @param {object} [options] + * @param {function} callback + * @alias module:storageReactNative.appendFile + */ const appendFile = callbackify(appendFileAsync) +/** + * Read data at given path + * @function + * @param {string} filename + * @param {object} [options] + * @return {Promise} + * @alias module:storageReactNative.readFileAsync + * @async + */ const readFileAsync = async (filename, options) => { try { return (await AsyncStorage.getItem(filename)) || '' @@ -68,8 +150,24 @@ const readFileAsync = async (filename, options) => { } } +/** + * Read data at given path + * @function + * @param {string} filename + * @param {object} options + * @param {function} callback + * @alias module:storageReactNative.readFile + */ const readFile = callbackify(readFileAsync) +/** + * Remove the data at given path + * @function + * @param {string} filename + * @return {Promise} + * @async + * @alias module:storageReactNative.unlinkAsync + */ const unlinkAsync = async filename => { try { await AsyncStorage.removeItem(filename) @@ -78,23 +176,75 @@ const unlinkAsync = async filename => { } } +/** + * Remove the data at given path + * @function + * @param {string} path + * @param {function} callback + * @alias module:storageReactNative.unlink + */ const unlink = callbackify(unlinkAsync) -// Nothing to do, no directories will be used on react-native +/** + * Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser + * @function + * @param {string} dir + * @param {object} [options] + * @return {Promise} + * @alias module:storageReactNative.mkdirAsync + * @async + */ const mkdirAsync = (dir, options) => Promise.resolve() +/** + * Shim for storage.mkdir, nothing to do, no directories will be used on the browser + * @function + * @param {string} path + * @param {object} options + * @param {function} callback + * @alias module:storageReactNative.mkdir + */ const mkdir = callbackify(mkdirAsync) -// Nothing to do, no data corruption possible in the browser +/** + * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Nothing to do, no data corruption possible in the browser + * @param {string} filename + * @return {Promise} + * @alias module:storageReactNative.ensureDatafileIntegrityAsync + */ const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() +/** + * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Nothing to do, no data corruption possible in the browser + * @function + * @param {string} filename + * @param {NoParamCallback} callback signature: err + * @alias module:storageReactNative.ensureDatafileIntegrity + */ const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) +/** + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * @param {string} filename + * @param {string[]} lines + * @return {Promise} + * @alias module:storageReactNative.crashSafeWriteFileLinesAsync + */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line await writeFileAsync(filename, lines.join('\n')) } +/** + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * @function + * @param {string} filename + * @param {string[]} lines + * @param {NoParamCallback} [callback] Optional callback, signature: err + * @alias module:storageReactNative.crashSafeWriteFileLines + */ const crashSafeWriteFileLines = callbackify(crashSafeWriteFileLinesAsync) // Interface diff --git a/index.d.ts b/index.d.ts index 6ff68df..5a65f75 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,6 +1,7 @@ // Type definitions for @seald-io/nedb 2.1.0 // Project: https://github.com/seald/nedb forked from https://github.com/louischatriot/nedb -// Definitions by: Mehdi Kouhen +// Definitions by: Timothée Rebours +// Mehdi Kouhen // Stefan Steinhart // Anthony Nichols // Alejandro Fernandez Haro @@ -17,16 +18,24 @@ declare class Nedb extends EventEmitter { persistence: Nedb.Persistence; + autoloadPromise: Promise|null; + loadDatabase(): void; + loadDatabaseAsync(): Promise; + getAllData(): T[]; resetIndexes(newData?: any): void; ensureIndex(options: Nedb.EnsureIndexOptions, callback?: (err: Error | null) => void): void; + ensureIndexAsync(options: Nedb.EnsureIndexOptions): Promise; + removeIndex(fieldName: string, callback?: (err: Error | null) => void): void; + removeIndexAsync(fieldName: string): Promise; + addToIndexes(doc: T | T[]): void; removeFromIndexes(doc: T | T[]): void; @@ -36,24 +45,39 @@ declare class Nedb extends EventEmitter { getCandidates(query: any, dontExpireStaleDocs: boolean, callback?: (err: Error | null, candidates: T[]) => void): void; + getCandidatesAsync(query: any, dontExpireStaleDocs: boolean): Promise; + insert(newDoc: T, callback?: (err: Error | null, document: T) => void): void; insert(newDocs: T[], callback?: (err: Error | null, documents: T[]) => void): void; + insertAsync(newDoc: T): Promise; + insertAsync(newDocs: T[]): Promise; + count(query: any, callback: (err: Error | null, n: number) => void): void; count(query: any): Nedb.CursorCount; + countAsync(query: any): Nedb.Cursor; + find(query: any, projection: any, callback?: (err: Error | null, documents: T[]) => void): void; find(query: any, projection?: any): Nedb.Cursor; find(query: any, callback: (err: Error | null, documents: T[]) => void): void; + findAsync(query: any, projection?: any): Nedb.Cursor; + findOne(query: any, projection: any, callback: (err: Error | null, document: T) => void): void; findOne(query: any, callback: (err: Error | null, document: T) => void): void; + findOneAsync(query: any, projection?: any): Nedb.Cursor; + update(query: any, updateQuery: any, options?: Nedb.UpdateOptions, callback?: (err: Error | null, numberOfUpdated: number, affectedDocuments: T | T[] | null, upsert: boolean | null) => void): void; + updateAsync(query: any, updateQuery: any, options?: Nedb.UpdateOptions): Promise<{numAffected: number, affectedDocuments: T|T[]|null, upsert: boolean}>; + remove(query: any, options: Nedb.RemoveOptions, callback?: (err: Error | null, n: number) => void): void; remove(query: any, callback?: (err: Error | null, n: number) => void): void; + removeAsync(query: any, options: Nedb.RemoveOptions): Promise; + addListener(event: 'compaction.done', listener: () => void): this; on(event: 'compaction.done', listener: () => void): this; once(event: 'compaction.done', listener: () => void): this; @@ -67,12 +91,13 @@ declare class Nedb extends EventEmitter { } declare namespace Nedb { - interface Cursor { + interface Cursor extends Promise { sort(query: any): Cursor; skip(n: number): Cursor; limit(n: number): Cursor; projection(query: any): Cursor; exec(callback: (err: Error | null, documents: T[]) => void): void; + execAsync(): Promise; } interface CursorCount { @@ -83,13 +108,14 @@ declare namespace Nedb { filename?: string; timestampData?: boolean; inMemoryOnly?: boolean; - nodeWebkitAppName?: string; autoload?: boolean; onload?(error: Error | null): any; beforeDeserialization?(line: string): string; afterSerialization?(line: string): string; corruptAlertThreshold?: number; compareStrings?(a: string, b: string): number; + /** @deprecated */ + nodeWebkitAppName?: string; } interface UpdateOptions { @@ -111,6 +137,7 @@ declare namespace Nedb { interface Persistence { compactDatafile(): void; + compactDatafileAsync(): Promise; setAutocompactionInterval(interval: number): void; stopAutocompaction(): void; } diff --git a/jsdoc.conf.js b/jsdoc.conf.js deleted file mode 100644 index db450cd..0000000 --- a/jsdoc.conf.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -module.exports = { - plugins: ['plugins/markdown'], - source: { - include: ['./lib'] - }, - opts: { - destination: './docs' - } -} diff --git a/lib/cursor.js b/lib/cursor.js index 8873cda..4e8cfe0 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -1,6 +1,3 @@ -/** - * Manage access to data, be it to find, update or remove it - */ const model = require('./model.js') const { callbackify, promisify } = require('util') @@ -17,6 +14,9 @@ const { callbackify, promisify } = require('util') */ /** + * Manage access to data, be it to find, update or remove it. + * + * It extends Promise so that its methods are chainable & awaitable. * @extends Promise */ class Cursor { diff --git a/lib/customUtils.js b/lib/customUtils.js index a3fc1f0..e94c741 100755 --- a/lib/customUtils.js +++ b/lib/customUtils.js @@ -1,3 +1,8 @@ +/** + * Utility functions that need to be reimplemented for each environment. + * This is the version for Node.js + * @module customUtilsNode + */ const crypto = require('crypto') /** @@ -9,6 +14,7 @@ const crypto = require('crypto') * See http://en.wikipedia.org/wiki/Birthday_problem * @param {number} len * @return {string} + * @alias module:customUtilsNode.uid */ const uid = len => crypto.randomBytes(Math.ceil(Math.max(8, len * 2))) .toString('base64') diff --git a/lib/datastore.js b/lib/datastore.js index a7f7319..7ff6050 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -9,12 +9,9 @@ const Persistence = require('./persistence.js') const { isDate } = require('./utils.js') /** - * Compaction event. Happens when the Datastore's Persistence has been compacted. - * It happens when calling `datastore.persistence.compactDatafile`, which is called periodically if you have called - * `datastore.persistence.setAutocompactionInterval`. - * - * @event Datastore#event:"compaction.done" - * @type {undefined} + * Callback with no parameter + * @callback NoParamCallback + * @param {?Error} err */ /** @@ -30,13 +27,43 @@ const { isDate } = require('./utils.js') * @return {number} */ +/** + * Callback that returns an Array of documents + * @callback MultipleDocumentsCallback + * @param {?Error} err + * @param {?document[]} docs + */ + +/** + * Callback that returns a single document + * @callback SingleDocumentCallback + * @param {?Error} err + * @param {?document} docs + */ + +/** + * Generic async function + * @callback AsyncFunction + * @param {...*} args + * @return {Promise<*>} + */ + +/** + * Compaction event. Happens when the Datastore's Persistence has been compacted. + * It happens when calling `datastore.persistence.compactDatafile`, which is called periodically if you have called + * `datastore.persistence.setAutocompactionInterval`. + * + * @event Datastore.event:"compaction.done" + * @type {undefined} + */ + /** * Generic document in NeDB. * It consists of an Object with anything you want inside. * @typedef document - * @property {?string} _id Internal `_id` of the document, which can be `null` at some points (when not inserted yet - * for example). - * @type {object.} + * @property {?string} [_id] Internal `_id` of the document, which can be `null` or undefined at some points (when not + * inserted yet for example). + * @type {Object.} */ /** @@ -72,7 +99,7 @@ const { isDate } = require('./utils.js') * } } * ``` * @typedef query - * @type {object.} + * @type {Object.} */ /** @@ -87,7 +114,7 @@ const { isDate } = require('./utils.js') * To reference subfields, you can use the dot-notation. * * @typedef projection - * @type {object.} + * @type {Object.} */ /** @@ -148,7 +175,7 @@ class Datastore extends EventEmitter { * OS X and Windows. Now that you can use `require('nw.gui').App.dataPath` in Node Webkit to get the path to the data * directory for your application, you should not use this option anymore and it will be removed. * - * @fires Datastore#event:"compaction.done" + * @fires Datastore.event:"compaction.done" */ constructor (options) { super() @@ -254,7 +281,7 @@ class Datastore extends EventEmitter { * A Promise that resolves when the autoload has finished. * * The onload callback is not awaited by this Promise, it is started immediately after that. - * @type {Promise} + * @type {?Promise} */ this.autoloadPromise = this.loadDatabaseAsync() this.autoloadPromise @@ -301,11 +328,6 @@ class Datastore extends EventEmitter { } } - /** - * @callback Datastore~ensureIndexCallback - * @param {?Error} err - */ - /** * Ensure an index is kept for this field. Same parameters as lib/indexes * This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the @@ -316,7 +338,7 @@ class Datastore extends EventEmitter { * @param {boolean} [options.unique = false] Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined. * @param {boolean} [options.sparse = false] don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined. * @param {number} [options.expireAfterSeconds] - if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored - * @param {Datastore~ensureIndexCallback} callback Callback, signature: err + * @param {NoParamCallback} callback Callback, signature: err */ // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state ensureIndex (options = {}, callback = () => {}) { @@ -358,17 +380,12 @@ class Datastore extends EventEmitter { await this.persistence.persistNewStateAsync([{ $$indexCreated: options }]) } - /** - * @callback Datastore~removeIndexCallback - * @param {?Error} err - */ - /** * Remove an index * Previous versions said explicitly the callback was optional, it is now recommended setting one. * @param {string} fieldName Field name of the index to remove. Use the dot notation to remove an index referring to a * field in a nested document. - * @param {Datastore~removeIndexCallback} callback Optional callback, signature: err + * @param {NoParamCallback} callback Optional callback, signature: err */ // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state removeIndex (fieldName, callback = () => {}) { @@ -502,12 +519,6 @@ class Datastore extends EventEmitter { return this.getAllData() } - /** - * @callback Datastore~getCandidatesCallback - * @param {?Error} err - * @param {?document[]} candidates - */ - /** * Return the list of candidates for a given query * Crude implementation for now, we return the candidates given by the first usable index if any @@ -520,7 +531,7 @@ class Datastore extends EventEmitter { * @param {query} query * @param {boolean|function} [dontExpireStaleDocs = false] If true don't remove stale docs. Useful for the remove * function which shouldn't be impacted by expirations. If argument is not given, it is used as the callback. - * @param {Datastore~getCandidatesCallback} callback Signature err, candidates + * @param {MultipleDocumentsCallback} callback Signature err, candidates * * @private */ @@ -570,17 +581,11 @@ class Datastore extends EventEmitter { return validDocs } - /** - * @callback Datastore~insertCallback - * @param {?Error} err - * @param {?document} insertedDoc - */ - /** * Insert a new document * Private Use Datastore.insert which has the same signature - * @param {?document} newDoc - * @param {Datastore~insertCallback} callback Optional callback, signature: err, insertedDoc + * @param {document|document[]} newDoc + * @param {SingleDocumentCallback} [callback = () => {}] Optional callback, signature: err, insertedDoc * * @private */ @@ -591,8 +596,8 @@ class Datastore extends EventEmitter { /** * Insert a new document * Private Use Datastore.insertAsync which has the same signature - * @param {document} newDoc - * @return {Promise} + * @param {document|document[]} newDoc + * @return {Promise} * @private */ async _insertAsync (newDoc) { @@ -682,8 +687,8 @@ class Datastore extends EventEmitter { /** * Insert a new document * Private Use Datastore.insert which has the same signature - * @param {document} newDoc - * @param {Datastore~insertCallback} callback Optional callback, signature: err, insertedDoc + * @param {document|document[]} newDoc + * @param {SingleDocumentCallback} [callback = () => {}] Optional callback, signature: err, insertedDoc * * @private */ @@ -694,7 +699,7 @@ class Datastore extends EventEmitter { /** * Insert a new document * Private Use Datastore.insertAsync which has the same signature - * @param {document} newDoc + * @param {document|document[]} newDoc * @return {Promise} * @async */ @@ -731,19 +736,13 @@ class Datastore extends EventEmitter { return new Cursor(this, query, async docs => docs.length, true) // this is a trick, Cursor itself is a thenable, which allows to await it } - /** - * @callback Datastore~findCallback - * @param {?Error} err - * @param {document[]} docs - */ - /** * Find all documents matching the query * If no callback is passed, we return the cursor so that user can limit, skip and finally exec * @param {query} query MongoDB-style query - * @param {projection|Datastore~findCallback} [projection = {}] MongoDB-style projection. If not given, will be + * @param {projection|MultipleDocumentsCallback} [projection = {}] MongoDB-style projection. If not given, will be * interpreted as the callback. - * @param {Datastore~findCallback} [callback] Optional callback, signature: err, docs + * @param {MultipleDocumentsCallback} [callback] Optional callback, signature: err, docs * @return {Cursor|undefined} */ find (query, projection, callback) { @@ -788,7 +787,7 @@ class Datastore extends EventEmitter { * Find one document matching the query * @param {query} query MongoDB-style query * @param {projection} projection MongoDB-style projection - * @param {Datastore~findOneCallback} callback Optional callback, signature: err, doc + * @param {SingleDocumentCallback} callback Optional callback, signature: err, doc * @return {Cursor|undefined} */ findOne (query, projection, callback) { @@ -862,7 +861,7 @@ class Datastore extends EventEmitter { * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, * will return the array of documents matched by the find query and updated. Updated documents will be returned even * if the update did not actually modify them. - * @param {Datastore~updateCallback} [cb] Optional callback + * @param {Datastore~updateCallback} [cb = () => {}] Optional callback * * @private */ @@ -900,7 +899,7 @@ class Datastore extends EventEmitter { * will return the array of documents matched by the find query and updated. Updated documents will be returned even * if the update did not actually modify them. * - * @return {Promise<{numAffected: number, affectedDocuments: document[]|document, upsert: boolean}>} + * @return {Promise<{numAffected: number, affectedDocuments: document[]|document|null, upsert: boolean}>} * * @private */ @@ -987,7 +986,7 @@ class Datastore extends EventEmitter { * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, * will return the array of documents matched by the find query and updated. Updated documents will be returned even * if the update did not actually modify them. - * @param {Datastore~updateCallback} [cb] Optional callback + * @param {Datastore~updateCallback} [cb = () => {}] Optional callback * */ update (...args) { @@ -1014,7 +1013,7 @@ class Datastore extends EventEmitter { * will return the array of documents matched by the find query and updated. Updated documents will be returned even * if the update did not actually modify them. * @async - * @return {Promise<{numAffected: number, affectedDocuments: document[]|document, upsert: boolean}>} + * @return {Promise<{numAffected: number, affectedDocuments: document[]|document|null, upsert: boolean}>} */ updateAsync (...args) { return this.executor.pushAsync(() => this._updateAsync(...args)) @@ -1033,7 +1032,7 @@ class Datastore extends EventEmitter { * @param {query} query * @param {object} [options] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {Datastore~removeCallback} [cb] + * @param {Datastore~removeCallback} [cb = () => {}] * * @private */ @@ -1080,7 +1079,7 @@ class Datastore extends EventEmitter { * @param {query} query * @param {object} [options] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {Datastore~removeCallback} [cb] Optional callback, signature: err, numRemoved + * @param {Datastore~removeCallback} [cb = () => {}] Optional callback, signature: err, numRemoved */ remove (...args) { this.executor.push({ this: this, fn: this._remove, arguments: args }) diff --git a/lib/executor.js b/lib/executor.js index e272ca1..a1acd5a 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -1,9 +1,3 @@ -/** - * @callback AsyncFunction - * @param {...[*]} args - * @return {Promise<*>} - */ - /** * Responsible for sequentially executing actions on the database * @private @@ -59,7 +53,14 @@ class Waterfall { } } +/** + * Executes operations sequentially. + * Has an option for a buffer that can be triggered afterwards. + */ class Executor { + /** + * Instantiates a new Executor. + */ constructor () { this.ready = false this.queue = new Waterfall() @@ -110,7 +111,7 @@ class Executor { /** * If executor is ready, queue task (and process it immediately if executor was idle) * If not, buffer task for later processing - * @param {AsyncFunction} task + * @param {function(...*):Promise<*>} task * @param {boolean} [forceQueuing = false] * @return {Promise<*>} * @async diff --git a/lib/indexes.js b/lib/indexes.js index 21eb8cf..df53228 100755 --- a/lib/indexes.js +++ b/lib/indexes.js @@ -7,6 +7,7 @@ const { uniq, isDate } = require('./utils.js') * @param {*} a * @param {*} b * @return {boolean} + * @private */ const checkValueEquality = (a, b) => a === b @@ -14,8 +15,9 @@ const checkValueEquality = (a, b) => a === b * Type-aware projection * @param {*} elt * @return {string|*} + * @private */ -function projectForUnique (elt) { +const projectForUnique = elt => { if (elt === null) return '$null' if (typeof elt === 'string') return '$string' + elt if (typeof elt === 'boolean') return '$boolean' + elt @@ -25,6 +27,10 @@ function projectForUnique (elt) { return elt // Arrays and objects, will check for pointer equality } +/** + * Indexes on field names, with atomic operations and which can optionally enforce a unique constraint or allow indexed + * fields to be undefined + */ class Index { /** * Create a new index diff --git a/lib/model.js b/lib/model.js index 2c6eeb1..6d97830 100755 --- a/lib/model.js +++ b/lib/model.js @@ -3,19 +3,9 @@ * Serialization/deserialization * Copying * Querying, update + * @module model */ const { uniq, isDate, isRegExp } = require('./utils.js') -/** - * @type {Object.} - */ -const modifierFunctions = {} -/** - * @type {Object.} - */ -const lastStepModifierFunctions = {} -const comparisonFunctions = {} -const logicalOperators = {} -const arrayComparisonFunctions = {} /** * Check a key, throw an error if the key is non valid @@ -24,6 +14,7 @@ const arrayComparisonFunctions = {} * Non-treatable edge cases here: if part of the object if of the form { $$date: number } or { $$deleted: true } * Its serialized-then-deserialized version it will transformed into a Date object * But you really need to want it to trigger such behaviour, even when warned not to use '$' at the beginning of the field names... + * @private */ const checkKey = (k, v) => { if (typeof k === 'number') k = k.toString() @@ -43,6 +34,7 @@ const checkKey = (k, v) => { * Check a DB object and throw an error if it's not valid * Works by applying the above checkKey function to all fields recursively * @param {document|document[]} obj + * @alias module:model.checkObject */ const checkObject = obj => { if (Array.isArray(obj)) { @@ -70,6 +62,7 @@ const checkObject = obj => { * Accepted secondary types: Objects, Arrays * @param {document} obj * @return {string} + * @alias module:model.serialize */ const serialize = obj => { return JSON.stringify(obj, function (k, v) { @@ -91,6 +84,7 @@ const serialize = obj => { * Return the object itself * @param {string} rawData * @return {document} + * @alias module:model.deserialize */ const deserialize = rawData => JSON.parse(rawData, function (k, v) { if (k === '$$date') return new Date(v) @@ -112,6 +106,7 @@ const deserialize = rawData => JSON.parse(rawData, function (k, v) { * @param {?document} obj * @param {boolean} [strictKeys=false] * @return {?document} + * @alias module:modelel:(.*) */ function deepCopy (obj, strictKeys) { if ( @@ -145,6 +140,7 @@ function deepCopy (obj, strictKeys) { * Arrays are considered primitive * @param {*} obj * @return {boolean} + * @alias module:modelel:(.*) */ const isPrimitiveType = obj => ( typeof obj === 'boolean' || @@ -162,6 +158,7 @@ const isPrimitiveType = obj => ( * @param {number|string|boolean} a * @param {number|string|boolean} b * @return {number} 0 if a == b, 1 i a > b, -1 if a < b + * @private */ const compareNSB = (a, b) => { if (a < b) return -1 @@ -176,6 +173,7 @@ const compareNSB = (a, b) => { * @param {Array} a * @param {Array} b * @return {number} 0 if arrays have the same length and all elements equal one another. Else either 1 or -1. + * @private */ const compareArrays = (a, b) => { const minLength = Math.min(a.length, b.length) @@ -198,8 +196,9 @@ const compareArrays = (a, b) => { * Return -1 if a < b, 1 if a > b and 0 if a = b (note that equality here is NOT the same as defined in areThingsEqual!) * @param {*} a * @param {*} b - * @param {Function} [_compareStrings] String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters) + * @param {compareStrings} [_compareStrings] String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters) * @return {number} + * @alias module:model.compareThings */ const compareThings = (a, b, _compareStrings) => { const compareStrings = _compareStrings || compareNSB @@ -250,7 +249,7 @@ const compareThings = (a, b, _compareStrings) => { // ============================================================== /** - * @callback Model~modifierFunction + * @callback modifierFunction * The signature of modifier functions is as follows * Their structure is always the same: recursively follow the dot notation while creating * the nested documents if needed, then apply the "last step modifier" @@ -260,80 +259,29 @@ const compareThings = (a, b, _compareStrings) => { */ /** - * Set a field to a new value - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$set = (obj, field, value) => { - obj[field] = value -} - -/** - * Unset a field - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$unset = (obj, field, value) => { - delete obj[field] -} - -/** - * Push an element to the end of an array field - * Optional modifier $each instead of value to push several values - * Optional modifier $slice to slice the resulting array, see https://docs.mongodb.org/manual/reference/operator/update/slice/ - * Différeence with MongoDB: if $slice is specified and not $each, we act as if value is an empty array - * @type Model~modifierFunction + * Create the complete modifier function + * @param {function} lastStepModifierFunction a lastStepModifierFunction + * @param {boolean} [unset = false] Bad looking specific fix, needs to be generalized modifiers that behave like $unset are implemented + * @return {modifierFunction} + * @private */ -lastStepModifierFunctions.$push = (obj, field, value) => { - // Create the array if it doesn't exist - if (!Object.prototype.hasOwnProperty.call(obj, field)) obj[field] = [] +const createModifierFunction = (lastStepModifierFunction, unset = false) => (obj, field, value) => { + const func = (obj, field, value) => { + const fieldParts = typeof field === 'string' ? field.split('.') : field - if (!Array.isArray(obj[field])) throw new Error('Can\'t $push an element on non-array values') - - if ( - value !== null && - typeof value === 'object' && - value.$slice && - value.$each === undefined - ) value.$each = [] - - if (value !== null && typeof value === 'object' && value.$each) { - if ( - Object.keys(value).length >= 3 || - (Object.keys(value).length === 2 && value.$slice === undefined) - ) throw new Error('Can only use $slice in cunjunction with $each when $push to array') - if (!Array.isArray(value.$each)) throw new Error('$each requires an array value') - - value.$each.forEach(v => { - obj[field].push(v) - }) - - if (value.$slice === undefined || typeof value.$slice !== 'number') return - - if (value.$slice === 0) obj[field] = [] + if (fieldParts.length === 1) lastStepModifierFunction(obj, field, value) else { - let start - let end - const n = obj[field].length - if (value.$slice < 0) { - start = Math.max(0, n + value.$slice) - end = n - } else if (value.$slice > 0) { - start = 0 - end = Math.min(n, value.$slice) + if (obj[fieldParts[0]] === undefined) { + if (unset) return + obj[fieldParts[0]] = {} } - obj[field] = obj[field].slice(start, end) + func(obj[fieldParts[0]], fieldParts.slice(1), value) } - } else { - obj[field].push(value) } + return func(obj, field, value) } -/** - * Add an element to an array field only if it is not already in it - * No modification if the element is already in the array - * Note that it doesn't check whether the original array contains duplicates - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$addToSet = (obj, field, value) => { +const $addToSetPartial = (obj, field, value) => { // Create the array if it doesn't exist if (!Object.prototype.hasOwnProperty.call(obj, field)) { obj[field] = [] } @@ -344,7 +292,7 @@ lastStepModifierFunctions.$addToSet = (obj, field, value) => { if (!Array.isArray(value.$each)) throw new Error('$each requires an array value') value.$each.forEach(v => { - lastStepModifierFunctions.$addToSet(obj, field, v) + $addToSetPartial(obj, field, v) }) } else { let addToSet = true @@ -356,90 +304,133 @@ lastStepModifierFunctions.$addToSet = (obj, field, value) => { } /** - * Remove the first or last element of an array - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$pop = (obj, field, value) => { - if (!Array.isArray(obj[field])) throw new Error('Can\'t $pop an element from non-array values') - if (typeof value !== 'number') throw new Error(`${value} isn't an integer, can't use it with $pop`) - if (value === 0) return - - if (value > 0) obj[field] = obj[field].slice(0, obj[field].length - 1) - else obj[field] = obj[field].slice(1) -} - -/** - * Removes all instances of a value from an existing array - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$pull = (obj, field, value) => { - if (!Array.isArray(obj[field])) throw new Error('Can\'t $pull an element from non-array values') - - const arr = obj[field] - for (let i = arr.length - 1; i >= 0; i -= 1) { - if (match(arr[i], value)) arr.splice(i, 1) - } -} - -/** - * Increment a numeric field's value - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$inc = (obj, field, value) => { - if (typeof value !== 'number') throw new Error(`${value} must be a number`) - - if (typeof obj[field] !== 'number') { - if (!Object.prototype.hasOwnProperty.call(obj, field)) obj[field] = value - else throw new Error('Don\'t use the $inc modifier on non-number fields') - } else obj[field] += value -} + * @enum {modifierFunction} + */ +const modifierFunctions = { + /** + * Set a field to a new value + */ + $set: createModifierFunction((obj, field, value) => { + obj[field] = value + }), + /** + * Unset a field + */ + $unset: createModifierFunction((obj, field, value) => { + delete obj[field] + }, true), + /** + * Updates the value of the field, only if specified field is smaller than the current value of the field + */ + $min: createModifierFunction((obj, field, value) => { + if (typeof obj[field] === 'undefined') obj[field] = value + else if (value < obj[field]) obj[field] = value + }), + /** + * Updates the value of the field, only if specified field is greater than the current value of the field + */ + $max: createModifierFunction((obj, field, value) => { + if (typeof obj[field] === 'undefined') obj[field] = value + else if (value > obj[field]) obj[field] = value + }), + /** + * Increment a numeric field's value + */ + $inc: createModifierFunction((obj, field, value) => { + if (typeof value !== 'number') throw new Error(`${value} must be a number`) + + if (typeof obj[field] !== 'number') { + if (!Object.prototype.hasOwnProperty.call(obj, field)) obj[field] = value + else throw new Error('Don\'t use the $inc modifier on non-number fields') + } else obj[field] += value + }), + /** + * Removes all instances of a value from an existing array + */ + $pull: createModifierFunction((obj, field, value) => { + if (!Array.isArray(obj[field])) throw new Error('Can\'t $pull an element from non-array values') + + const arr = obj[field] + for (let i = arr.length - 1; i >= 0; i -= 1) { + if (match(arr[i], value)) arr.splice(i, 1) + } + }), + /** + * Remove the first or last element of an array + */ + $pop: createModifierFunction((obj, field, value) => { + if (!Array.isArray(obj[field])) throw new Error('Can\'t $pop an element from non-array values') + if (typeof value !== 'number') throw new Error(`${value} isn't an integer, can't use it with $pop`) + if (value === 0) return + + if (value > 0) obj[field] = obj[field].slice(0, obj[field].length - 1) + else obj[field] = obj[field].slice(1) + }), + /** + * Add an element to an array field only if it is not already in it + * No modification if the element is already in the array + * Note that it doesn't check whether the original array contains duplicates + */ + $addToSet: createModifierFunction($addToSetPartial), + /** + * Push an element to the end of an array field + * Optional modifier $each instead of value to push several values + * Optional modifier $slice to slice the resulting array, see https://docs.mongodb.org/manual/reference/operator/update/slice/ + * Difference with MongoDB: if $slice is specified and not $each, we act as if value is an empty array + */ + $push: createModifierFunction((obj, field, value) => { + // Create the array if it doesn't exist + if (!Object.prototype.hasOwnProperty.call(obj, field)) obj[field] = [] + + if (!Array.isArray(obj[field])) throw new Error('Can\'t $push an element on non-array values') -/** - * Updates the value of the field, only if specified field is greater than the current value of the field - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$max = (obj, field, value) => { - if (typeof obj[field] === 'undefined') obj[field] = value - else if (value > obj[field]) obj[field] = value -} + if ( + value !== null && + typeof value === 'object' && + value.$slice && + value.$each === undefined + ) value.$each = [] -/** - * Updates the value of the field, only if specified field is smaller than the current value of the field - * @type Model~modifierFunction - */ -lastStepModifierFunctions.$min = (obj, field, value) => { - if (typeof obj[field] === 'undefined') obj[field] = value - else if (value < obj[field]) obj[field] = value -} + if (value !== null && typeof value === 'object' && value.$each) { + if ( + Object.keys(value).length >= 3 || + (Object.keys(value).length === 2 && value.$slice === undefined) + ) throw new Error('Can only use $slice in cunjunction with $each when $push to array') + if (!Array.isArray(value.$each)) throw new Error('$each requires an array value') -/** - * Create the complete modifier function - * @param {string} modifier one of lastStepModifierFunctions keys - * @return {Model~modifierFunction} - */ -const createModifierFunction = modifier => (obj, field, value) => { - const fieldParts = typeof field === 'string' ? field.split('.') : field + value.$each.forEach(v => { + obj[field].push(v) + }) - if (fieldParts.length === 1) lastStepModifierFunctions[modifier](obj, field, value) - else { - if (obj[fieldParts[0]] === undefined) { - if (modifier === '$unset') return // Bad looking specific fix, needs to be generalized modifiers that behave like $unset are implemented - obj[fieldParts[0]] = {} + if (value.$slice === undefined || typeof value.$slice !== 'number') return + + if (value.$slice === 0) obj[field] = [] + else { + let start + let end + const n = obj[field].length + if (value.$slice < 0) { + start = Math.max(0, n + value.$slice) + end = n + } else if (value.$slice > 0) { + start = 0 + end = Math.min(n, value.$slice) + } + obj[field] = obj[field].slice(start, end) + } + } else { + obj[field].push(value) } - modifierFunctions[modifier](obj[fieldParts[0]], fieldParts.slice(1), value) - } -} + }) -// Actually create all modifier functions -Object.keys(lastStepModifierFunctions).forEach(modifier => { - modifierFunctions[modifier] = createModifierFunction(modifier) -}) +} /** * Modify a DB object according to an update query * @param {document} obj * @param {query} updateQuery * @return {document} + * @alias module:model.modify */ const modify = (obj, updateQuery) => { const keys = Object.keys(updateQuery) @@ -490,6 +481,7 @@ const modify = (obj, updateQuery) => { * @param {object} obj * @param {string} field * @return {*} + * @alias module:model.getDotValue */ const getDotValue = (obj, field) => { const fieldParts = typeof field === 'string' ? field.split('.') : field @@ -518,6 +510,7 @@ const getDotValue = (obj, field) => { * @param {*} a * @param {*} a * @return {boolean} + * @alias module:model.areThingsEqual */ const areThingsEqual = (a, b) => { // Strings, booleans, numbers, null @@ -566,6 +559,7 @@ const areThingsEqual = (a, b) => { * @param {*} a * @param {*} a * @return {boolean} + * @private */ const areComparable = (a, b) => { if ( @@ -583,7 +577,7 @@ const areComparable = (a, b) => { } /** - * @callback Model~comparisonOperator + * @callback comparisonOperator * Arithmetic and comparison operators * @param {*} a Value in the object * @param {*} b Value in the query @@ -591,165 +585,130 @@ const areComparable = (a, b) => { */ /** - * Lower than - * @type Model~comparisonOperator - */ -comparisonFunctions.$lt = (a, b) => areComparable(a, b) && a < b - -/** - * Lower than or equals - * @type Model~comparisonOperator - */ -comparisonFunctions.$lte = (a, b) => areComparable(a, b) && a <= b - -/** - * Greater than - * @type Model~comparisonOperator - */ -comparisonFunctions.$gt = (a, b) => areComparable(a, b) && a > b - -/** - * Greater than or equals - * @type Model~comparisonOperator - */ -comparisonFunctions.$gte = (a, b) => areComparable(a, b) && a >= b - -/** - * Does not equal - * @type Model~comparisonOperator + * @enum {comparisonOperator} */ -comparisonFunctions.$ne = (a, b) => a === undefined || !areThingsEqual(a, b) +const comparisonFunctions = { + /** Lower than */ + $lt: (a, b) => areComparable(a, b) && a < b, + /** Lower than or equals */ + $lte: (a, b) => areComparable(a, b) && a <= b, + /** Greater than */ + $gt: (a, b) => areComparable(a, b) && a > b, + /** Greater than or equals */ + $gte: (a, b) => areComparable(a, b) && a >= b, + /** Does not equal */ + $ne: (a, b) => a === undefined || !areThingsEqual(a, b), + /** Is in Array */ + $in: (a, b) => { + if (!Array.isArray(b)) throw new Error('$in operator called with a non-array') -/** - * Is in Array - * @type Model~comparisonOperator - */ -comparisonFunctions.$in = (a, b) => { - if (!Array.isArray(b)) throw new Error('$in operator called with a non-array') + for (const el of b) { + if (areThingsEqual(a, el)) return true + } - for (const el of b) { - if (areThingsEqual(a, el)) return true + return false + }, + /** Is not in Array */ + $nin: (a, b) => { + if (!Array.isArray(b)) throw new Error('$nin operator called with a non-array') + + return !comparisonFunctions.$in(a, b) + }, + /** Matches Regexp */ + $regex: (a, b) => { + if (!isRegExp(b)) throw new Error('$regex operator called with non regular expression') + + if (typeof a !== 'string') return false + else return b.test(a) + }, + /** Returns true if field exists */ + $exists: (a, b) => { + // This will be true for all values of stat except false, null, undefined and 0 + // That's strange behaviour (we should only use true/false) but that's the way Mongo does it... + if (b || b === '') b = true + else b = false + + if (a === undefined) return !b + else return b + }, + /** Specific to Arrays, returns true if a length equals b */ + $size: (a, b) => { + if (!Array.isArray(a)) return false + if (b % 1 !== 0) throw new Error('$size operator called without an integer') + + return a.length === b + }, + /** Specific to Arrays, returns true if some elements of a match the query b */ + $elemMatch: (a, b) => { + if (!Array.isArray(a)) return false + return a.some(el => match(el, b)) } - - return false } -/** - * Is not in Array - * @type Model~comparisonOperator - */ -comparisonFunctions.$nin = (a, b) => { - if (!Array.isArray(b)) throw new Error('$nin operator called with a non-array') - return !comparisonFunctions.$in(a, b) -} +const arrayComparisonFunctions = { $size: true, $elemMatch: true } /** - * Matches Regexp - * @type Model~comparisonOperator + * @enum */ -comparisonFunctions.$regex = (a, b) => { - if (!isRegExp(b)) throw new Error('$regex operator called with non regular expression') +const logicalOperators = { + /** + * Match any of the subqueries + * @param {document} obj + * @param {query[]} query + * @return {boolean} + */ + $or: (obj, query) => { + if (!Array.isArray(query)) throw new Error('$or operator used without an array') - if (typeof a !== 'string') return false - else return b.test(a) -} - -/** - * Returns true if field exists - * @type Model~comparisonOperator - */ -comparisonFunctions.$exists = (a, b) => { - // This will be true for all values of stat except false, null, undefined and 0 - // That's strange behaviour (we should only use true/false) but that's the way Mongo does it... - if (b || b === '') b = true - else b = false - - if (a === undefined) return !b - else return b -} - -/** - * Specific to Arrays, returns true if a length equals b - * @type Model~comparisonOperator - */ -comparisonFunctions.$size = (a, b) => { - if (!Array.isArray(a)) return false - if (b % 1 !== 0) throw new Error('$size operator called without an integer') - - return a.length === b -} - -/** - * Specific to Arrays, returns true if some elements of a match the query b - * @type Model~comparisonOperator - */ -comparisonFunctions.$elemMatch = (a, b) => { - if (!Array.isArray(a)) return false - return a.some(el => match(el, b)) -} - -arrayComparisonFunctions.$size = true -arrayComparisonFunctions.$elemMatch = true - -/** - * Match any of the subqueries - * @param {document} obj - * @param {query[]} query - * @return {boolean} - */ -logicalOperators.$or = (obj, query) => { - if (!Array.isArray(query)) throw new Error('$or operator used without an array') - - for (let i = 0; i < query.length; i += 1) { - if (match(obj, query[i])) return true - } - - return false -} + for (let i = 0; i < query.length; i += 1) { + if (match(obj, query[i])) return true + } -/** - * Match all of the subqueries - * @param {document} obj - * @param {query[]} query - * @return {boolean} - */ -logicalOperators.$and = (obj, query) => { - if (!Array.isArray(query)) throw new Error('$and operator used without an array') + return false + }, + /** + * Match all of the subqueries + * @param {document} obj + * @param {query[]} query + * @return {boolean} + */ + $and: (obj, query) => { + if (!Array.isArray(query)) throw new Error('$and operator used without an array') + + for (let i = 0; i < query.length; i += 1) { + if (!match(obj, query[i])) return false + } - for (let i = 0; i < query.length; i += 1) { - if (!match(obj, query[i])) return false + return true + }, + /** + * Inverted match of the query + * @param {document} obj + * @param {query} query + * @return {boolean} + */ + $not: (obj, query) => !match(obj, query), + + /** + * @callback whereCallback + * @param {document} obj + * @return {boolean} + */ + + /** + * Use a function to match + * @param {document} obj + * @param {whereCallback} fn + * @return {boolean} + */ + $where: (obj, fn) => { + if (typeof fn !== 'function') throw new Error('$where operator used without a function') + + const result = fn.call(obj) + if (typeof result !== 'boolean') throw new Error('$where function must return boolean') + + return result } - - return true -} - -/** - * Inverted match of the query - * @param {document} obj - * @param {query} query - * @return {boolean} - */ -logicalOperators.$not = (obj, query) => !match(obj, query) - -/** - * @callback Model~whereCallback - * @param {document} obj - * @return {boolean} - */ - -/** - * Use a function to match - * @param {document} obj - * @param {Model~whereCallback} fn - * @return {boolean} - */ -logicalOperators.$where = (obj, fn) => { - if (typeof fn !== 'function') throw new Error('$where operator used without a function') - - const result = fn.call(obj) - if (typeof result !== 'boolean') throw new Error('$where function must return boolean') - - return result } /** @@ -757,6 +716,7 @@ logicalOperators.$where = (obj, fn) => { * @param {document} obj Document to check * @param {query} query * @return {boolean} + * @alias module:model.match */ const match = (obj, query) => { // Primitive query against a primitive type @@ -778,10 +738,6 @@ const match = (obj, query) => { return true } -/** - * Match an object against a specific { key: value } part of a query - * if the treatObjAsValue flag is set, don't try to match every part separately, but the array as a whole - */ /** * Match an object against a specific { key: value } part of a query * if the treatObjAsValue flag is set, don't try to match every part separately, but the array as a whole @@ -790,6 +746,7 @@ const match = (obj, query) => { * @param {*} queryValue * @param {boolean} [treatObjAsValue=false] * @return {boolean} + * @private */ function matchQueryPart (obj, queryKey, queryValue, treatObjAsValue) { const objValue = getDotValue(obj, queryKey) diff --git a/lib/persistence.js b/lib/persistence.js index c7e0200..f3b4853 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -1,9 +1,3 @@ -/** - * Handle every persistence-related task - * The interface Datastore expects to be implemented is - * * Persistence.loadDatabase(callback) and callback has signature err - * * Persistence.persistNewState(newDocs, callback) where newDocs is an array of documents and callback has signature err - */ const path = require('path') const { callbackify, promisify, deprecate } = require('util') const byline = require('./byline') @@ -12,12 +6,17 @@ const Index = require('./indexes.js') const model = require('./model.js') const storage = require('./storage.js') +/** + * Handle every persistence-related task + */ class Persistence { /** * Create a new Persistence object for database options.db * @param {Datastore} options.db * @param {Number} [options.corruptAlertThreshold] Optional, threshold after which an alert is thrown if too much data is corrupt * @param {string} [options.nodeWebkitAppName] Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion) + * @param {function} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and before it is written to disk. + * @param {function} [options.afterSerialization] Inverse of `afterSerialization`. */ constructor (options) { this.db = options.db @@ -61,17 +60,12 @@ class Persistence { } } - /** - * @callback Persistence~persistCachedDatabaseCallback - * @param {?Error} err - */ - /** * Persist cached database * This serves as a compaction function since the cache always contains only the number of documents in the collection * while the data file is append-only so it may grow larger * This is an internal function, use compactDataFile which uses the executor - * @param {Persistence~persistCachedDatabaseCallback} callback Optional callback, signature: err + * @param {NoParamCallback} callback Optional callback, signature: err */ persistCachedDatabase (callback = () => {}) { return callbackify(this.persistCachedDatabaseAsync.bind(this))(callback) @@ -108,14 +102,9 @@ class Persistence { this.db.emit('compaction.done') } - /** - * @callback Persistence~compactDataFileCallback - * @param {?Error} err - */ - /** * Queue a rewrite of the datafile - * @param {Persistence~compactDataFileCallback} [callback = () => {}] Optional callback, signature: err + * @param {NoParamCallback} [callback = () => {}] Optional callback, signature: err */ compactDatafile (callback = () => {}) { this.db.executor.push({ this: this, fn: this.persistCachedDatabase, arguments: [callback] }) @@ -151,16 +140,11 @@ class Persistence { if (this.autocompactionIntervalId) clearInterval(this.autocompactionIntervalId) } - /** - * @callback Persistence~persistNewStateCallback - * @param {?Error} err - */ - /** * Persist new state for the given newDocs (can be insertion, update or removal) * Use an append-only format * @param {string[]} newDocs Can be empty if no doc was updated/removed - * @param {Persistence~persistNewStateCallback} [callback = () => {}] Optional, signature: err + * @param {NoParamCallback} [callback = () => {}] Optional, signature: err */ persistNewState (newDocs, callback = () => {}) { callbackify(this.persistNewStateAsync.bind(this))(newDocs, err => callback(err)) @@ -169,7 +153,7 @@ class Persistence { /** * Persist new state for the given newDocs (can be insertion, update or removal) * Use an append-only format - * @param {string[]} newDocs Can be empty if no doc was updated/removed + * @param {document[]} newDocs Can be empty if no doc was updated/removed * @return {Promise} */ async persistNewStateAsync (newDocs) { @@ -295,11 +279,6 @@ class Persistence { return promisify(this.treatRawStream.bind(this))(rawStream) } - /** - * @callback Persistence~loadDatabaseCallback - * @param {?Error} err - */ - /** * Load the database * 1) Create all indexes @@ -308,7 +287,7 @@ class Persistence { * This means pulling data out of the data file or creating it if it doesn't exist * Also, all data is persisted right away, which has the effect of compacting the database file * This operation is very quick at startup for a big collection (60ms for ~10k docs) - * @param {Persistence~loadDatabaseCallback} callback Optional callback, signature: err + * @param {NoParamCallback} callback Optional callback, signature: err */ loadDatabase (callback = () => {}) { callbackify(this.loadDatabaseAsync.bind(this))(err => callback(err)) @@ -359,15 +338,10 @@ class Persistence { this.db.executor.processBuffer() } - /** - * @callback Persistence~ensureDirectoryExistsCallback - * @param {?Error} err - */ - /** * Check if a directory stat and create it on the fly if it is not the case * @param {string} dir - * @param {Persistence~ensureDirectoryExistsCallback} [callback = () => {}] optional callback, signature: err + * @param {NoParamCallback} [callback = () => {}] optional callback, signature: err */ static ensureDirectoryExists (dir, callback = () => {}) { storage.mkdir(dir, { recursive: true }, err => { callback(err) }) diff --git a/lib/storage.js b/lib/storage.js index 54e4e0e..5022279 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -1,76 +1,212 @@ /** * Way data is stored for this database * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage) + * For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) + * For a react-native database, we use @react-native-async-storage/async-storage * * This version is the Node.js/Node Webkit version * It's essentially fs, mkdirp and crash safe write and read functions + * @module storage */ const fs = require('fs') const fsPromises = fs.promises const path = require('path') const { callbackify, promisify } = require('util') -const storage = {} const { Readable } = require('stream') /** - * @callback Storage~existsCallback + * @callback module:storage~existsCallback * @param {boolean} exists */ /** + * Callback returns true if file exists * @param {string} file - * @param {Storage~existsCallback} cb + * @param {module:storage~existsCallback} cb + * @alias module:storage.exists */ // eslint-disable-next-line node/no-callback-literal -storage.exists = (file, cb) => fs.access(file, fs.constants.F_OK, (err) => { cb(!err) }) +const exists = (file, cb) => fs.access(file, fs.constants.F_OK, (err) => { cb(!err) }) + /** + * Returns Promise if file exists * @param {string} file * @return {Promise} + * @async + * @alias module:storage.existsAsync */ -storage.existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() => true, () => false) -storage.rename = fs.rename -storage.renameAsync = fsPromises.rename -storage.writeFile = fs.writeFile -storage.writeFileAsync = fsPromises.writeFile -storage.writeFileStream = fs.createWriteStream -storage.unlink = fs.unlink -storage.unlinkAsync = fsPromises.unlink -storage.appendFile = fs.appendFile -storage.appendFileAsync = fsPromises.appendFile -storage.readFile = fs.readFile -storage.readFileAsync = fsPromises.readFile -storage.readFileStream = fs.createReadStream -storage.mkdir = fs.mkdir -storage.mkdirAsync = fsPromises.mkdir +const existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() => true, () => false) /** - * @param {string} file + * Node.js' fs.rename + * @function + * @param {string} oldPath + * @param {string} newPath + * @param {NoParamCallback} c + * @return {void} + * @alias module:storage.rename + */ +const rename = fs.rename + +/** + * Node.js' fs.promises.rename + * @function + * @param {string} oldPath + * @param {string} newPath * @return {Promise} + * @alias module:storage.renameAsync + * @async */ -storage.ensureFileDoesntExistAsync = async file => { - if (await storage.existsAsync(file)) await storage.unlinkAsync(file) -} +const renameAsync = fsPromises.rename + +/** + * Node.js' fs.writeFile + * @function + * @param {string} path + * @param {string} data + * @param {object} options + * @param {function} callback + * @alias module:storage.writeFile + */ +const writeFile = fs.writeFile + +/** + * Node.js' fs.promises.writeFile + * @function + * @param {string} path + * @param {string} data + * @param {object} [options] + * @return {Promise} + * @alias module:storage.writeFileAsync + * @async + */ +const writeFileAsync = fsPromises.writeFile + +/** + * Node.js' fs.createWriteStream + * @function + * @param {string} path + * @param {Object} [options] + * @return {fs.WriteStream} + * @alias module:storage.writeFileStream + */ +const writeFileStream = fs.createWriteStream + +/** + * Node.js' fs.unlink + * @function + * @param {string} path + * @param {function} callback + * @alias module:storage.unlink + */ +const unlink = fs.unlink + +/** + * Node.js' fs.promises.unlink + * @function + * @param {string} path + * @return {Promise} + * @async + * @alias module:storage.unlinkAsync + */ +const unlinkAsync = fsPromises.unlink + +/** + * Node.js' fs.appendFile + * @function + * @param {string} path + * @param {string} data + * @param {object} options + * @param {function} callback + * @alias module:storage.appendFile + */ +const appendFile = fs.appendFile + +/** + * Node.js' fs.promises.appendFile + * @function + * @param {string} path + * @param {string} data + * @param {object} [options] + * @return {Promise} + * @alias module:storage.appendFileAsync + * @async + */ +const appendFileAsync = fsPromises.appendFile +/** + * Node.js' fs.readFile + * @function + * @param {string} path + * @param {object} options + * @param {function} callback + * @alias module:storage.readFile + */ +const readFile = fs.readFile +/** + * Node.js' fs.promises.readFile + * @function + * @param {string} path + * @param {object} [options] + * @return {Promise} + * @alias module:storage.readFileAsync + * @async + */ +const readFileAsync = fsPromises.readFile +/** + * Node.js' fs.createReadStream + * @function + * @param {string} path + * @param {Object} [options] + * @return {fs.ReadStream} + * @alias module:storage.readFileStream + */ +const readFileStream = fs.createReadStream +/** + * Node.js' fs.mkdir + * @function + * @param {string} path + * @param {object} options + * @param {function} callback + * @alias module:storage.mkdir + */ +const mkdir = fs.mkdir +/** + * Node.js' fs.promises.mkdir + * @function + * @param {string} path + * @param {object} options + * @return {Promise} + * @alias module:storage.mkdirAsync + * @async + */ +const mkdirAsync = fsPromises.mkdir /** - * @callback Storage~errorCallback - * @param {?Error} err + * @param {string} file + * @return {Promise} + * @alias module:storage.ensureFileDoesntExistAsync + * @async */ +const ensureFileDoesntExistAsync = async file => { + if (await existsAsync(file)) await unlinkAsync(file) +} /** * @param {string} file - * @param {Storage~errorCallback} callback + * @param {NoParamCallback} callback + * @alias module:storage.ensureFileDoesntExist */ -storage.ensureFileDoesntExist = (file, callback) => callbackify(storage.ensureFileDoesntExistAsync)(file, err => callback(err)) +const ensureFileDoesntExist = (file, callback) => callbackify(ensureFileDoesntExistAsync)(file, err => callback(err)) /** * Flush data in OS buffer to storage if corresponding option is set * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested * @param {string} [options.filename] * @param {boolean} [options.isDir = false] Optional, defaults to false - * @param {Storage~errorCallback} callback + * @param {NoParamCallback} callback + * @alias module:storage.flushToStorage */ -storage.flushToStorage = (options, callback) => callbackify(storage.flushToStorageAsync)(options, callback) +const flushToStorage = (options, callback) => callbackify(flushToStorageAsync)(options, callback) /** * Flush data in OS buffer to storage if corresponding option is set @@ -78,8 +214,10 @@ storage.flushToStorage = (options, callback) => callbackify(storage.flushToStora * @param {string} [options.filename] * @param {boolean} [options.isDir = false] Optional, defaults to false * @return {Promise} + * @alias module:storage.flushToStorageAsync + * @async */ -storage.flushToStorageAsync = async (options) => { +const flushToStorageAsync = async (options) => { let filename let flags if (typeof options === 'string') { @@ -131,11 +269,12 @@ storage.flushToStorageAsync = async (options) => { * Fully write or rewrite the datafile * @param {string} filename * @param {string[]} lines - * @param {Storage~errorCallback} callback + * @param {NoParamCallback} callback + * @alias module:storage.writeFileLines */ -storage.writeFileLines = (filename, lines, callback = () => {}) => { +const writeFileLines = (filename, lines, callback = () => {}) => { try { - const stream = storage.writeFileStream(filename) + const stream = writeFileStream(filename) const readable = Readable.from(lines) readable.on('data', (line) => { try { @@ -158,67 +297,109 @@ storage.writeFileLines = (filename, lines, callback = () => {}) => { * @param {string} filename * @param {string[]} lines * @return {Promise} + * @alias module:storage.writeFileLinesAsync * @async */ -storage.writeFileLinesAsync = (filename, lines) => promisify(storage.writeFileLines)(filename, lines) +const writeFileLinesAsync = (filename, lines) => promisify(writeFileLines)(filename, lines) /** * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) * @param {string} filename * @param {string[]} lines - * @param {Storage~errorCallback} callback Optional callback, signature: err + * @param {NoParamCallback} [callback] Optional callback, signature: err + * @alias module:storage.crashSafeWriteFileLines */ -storage.crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { - callbackify(storage.crashSafeWriteFileLinesAsync)(filename, lines, callback) +const crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { + callbackify(crashSafeWriteFileLinesAsync)(filename, lines, callback) } /** * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) * @param {string} filename * @param {string[]} lines * @return {Promise} + * @alias module:storage.crashSafeWriteFileLinesAsync */ -storage.crashSafeWriteFileLinesAsync = async (filename, lines) => { +const crashSafeWriteFileLinesAsync = async (filename, lines) => { const tempFilename = filename + '~' - await storage.flushToStorageAsync({ filename: path.dirname(filename), isDir: true }) + await flushToStorageAsync({ filename: path.dirname(filename), isDir: true }) - const exists = await storage.existsAsync(filename) - if (exists) await storage.flushToStorageAsync({ filename }) + const exists = await existsAsync(filename) + if (exists) await flushToStorageAsync({ filename }) - await storage.writeFileLinesAsync(tempFilename, lines) + await writeFileLinesAsync(tempFilename, lines) - await storage.flushToStorageAsync(tempFilename) + await flushToStorageAsync(tempFilename) - await storage.renameAsync(tempFilename, filename) + await renameAsync(tempFilename, filename) - await storage.flushToStorageAsync({ filename: path.dirname(filename), isDir: true }) + await flushToStorageAsync({ filename: path.dirname(filename), isDir: true }) } /** * Ensure the datafile contains all the data, even if there was a crash during a full file write * @param {string} filename - * @param {Storage~errorCallback} callback signature: err + * @param {NoParamCallback} callback signature: err + * @alias module:storage.ensureDatafileIntegrity */ -storage.ensureDatafileIntegrity = (filename, callback) => callbackify(storage.ensureDatafileIntegrityAsync)(filename, callback) +const ensureDatafileIntegrity = (filename, callback) => callbackify(ensureDatafileIntegrityAsync)(filename, callback) /** * Ensure the datafile contains all the data, even if there was a crash during a full file write * @param {string} filename * @return {Promise} + * @alias module:storage.ensureDatafileIntegrityAsync */ -storage.ensureDatafileIntegrityAsync = async filename => { +const ensureDatafileIntegrityAsync = async filename => { const tempFilename = filename + '~' - const filenameExists = await storage.existsAsync(filename) + const filenameExists = await existsAsync(filename) // Write was successful if (filenameExists) return - const oldFilenameExists = await storage.existsAsync(tempFilename) + const oldFilenameExists = await existsAsync(tempFilename) // New database - if (!oldFilenameExists) await storage.writeFileAsync(filename, '', 'utf8') + if (!oldFilenameExists) await writeFileAsync(filename, '', 'utf8') // Write failed, use old version - else await storage.renameAsync(tempFilename, filename) + else await renameAsync(tempFilename, filename) } // Interface -module.exports = storage +module.exports.exists = exists +module.exports.existsAsync = existsAsync + +module.exports.rename = rename +module.exports.renameAsync = renameAsync + +module.exports.writeFile = writeFile +module.exports.writeFileAsync = writeFileAsync + +module.exports.writeFileLines = writeFileLines +module.exports.writeFileLinesAsync = writeFileLinesAsync + +module.exports.crashSafeWriteFileLines = crashSafeWriteFileLines +module.exports.crashSafeWriteFileLinesAsync = crashSafeWriteFileLinesAsync + +module.exports.appendFile = appendFile +module.exports.appendFileAsync = appendFileAsync + +module.exports.readFile = readFile +module.exports.readFileAsync = readFileAsync + +module.exports.unlink = unlink +module.exports.unlinkAsync = unlinkAsync + +module.exports.mkdir = mkdir +module.exports.mkdirAsync = mkdirAsync + +module.exports.readFileStream = writeFileStream +module.exports.readFileStream = readFileStream + +module.exports.flushToStorage = flushToStorage +module.exports.flushToStorageAsync = flushToStorageAsync + +module.exports.ensureDatafileIntegrity = ensureDatafileIntegrity +module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync + +module.exports.ensureFileDoesntExist = ensureFileDoesntExist +module.exports.ensureFileDoesntExistAsync = ensureFileDoesntExistAsync diff --git a/lib/utils.js b/lib/utils.js index 2f86f70..1700790 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,3 +1,10 @@ +/** + * Utility functions for all environments. + * This replaces the underscore dependency. + * + * @module utils + */ + /** * Produces a duplicate-free version of the array, using === to test object equality. In particular only the first * occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee @@ -7,6 +14,7 @@ * @param {function} [iteratee] transformation applied to every element before checking for duplicates. This will not * transform the items in the result. * @return {Array} + * @alias module:utils.uniq */ const uniq = (array, iteratee) => { if (iteratee) return [...(new Map(array.map(x => [iteratee(x), x]))).values()] @@ -26,6 +34,7 @@ const isObject = arg => typeof arg === 'object' && arg !== null * Heavily inspired by https://underscorejs.org/#isDate * @param {*} d * @return {boolean} + * @alias module:utils.isDate */ const isDate = d => isObject(d) && Object.prototype.toString.call(d) === '[object Date]' @@ -34,6 +43,7 @@ const isDate = d => isObject(d) && Object.prototype.toString.call(d) === '[objec * Heavily inspired by https://underscorejs.org/#isRegExp * @param {*} re * @return {boolean} + * @alias module:utils.isRegExp */ const isRegExp = re => isObject(re) && Object.prototype.toString.call(re) === '[object RegExp]' diff --git a/package-lock.json b/package-lock.json index 7361ac3..0e7f9b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,6 @@ "events": "^3.3.0", "jest": "^27.3.1", "jquery": "^3.6.0", - "jsdoc": "^3.6.7", "karma": "^6.3.2", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.0", @@ -4434,12 +4433,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "node_modules/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", @@ -4712,18 +4705,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -5738,12 +5719,6 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, - "node_modules/entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -9105,15 +9080,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "dev": true, - "dependencies": { - "xmlcreate": "^2.0.4" - } - }, "node_modules/jsc-android": { "version": "250230.2.1", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250230.2.1.tgz", @@ -9306,64 +9272,6 @@ "signal-exit": "^3.0.2" } }, - "node_modules/jsdoc": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", - "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.9.4", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.1", - "klaw": "^3.0.0", - "markdown-it": "^10.0.0", - "markdown-it-anchor": "^5.2.7", - "marked": "^2.0.3", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", - "underscore": "~1.13.1" - }, - "bin": { - "jsdoc": "jsdoc.js" - }, - "engines": { - "node": ">=8.15.0" - } - }, - "node_modules/jsdoc/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jsdoc/node_modules/klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/jsdoc/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -9647,15 +9555,6 @@ "immediate": "~3.0.5" } }, - "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "dependencies": { - "uc.micro": "^1.0.1" - } - }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -9955,43 +9854,6 @@ "node": ">=0.10.0" } }, - "node_modules/markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", - "dev": true, - "peerDependencies": { - "markdown-it": "*" - } - }, - "node_modules/marked": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", - "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", - "dev": true, - "bin": { - "marked": "bin/marked" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -10003,12 +9865,6 @@ "is-buffer": "~1.1.6" } }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -13082,15 +12938,6 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, - "node_modules/requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -14814,12 +14661,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -15338,12 +15179,6 @@ "node": "*" } }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, "node_modules/uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -15391,12 +15226,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/underscore": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", - "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", - "dev": true - }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -16083,12 +15912,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - }, "node_modules/xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", @@ -19647,12 +19470,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", @@ -19876,15 +19693,6 @@ "rsvp": "^4.8.4" } }, - "catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, "chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -20696,12 +20504,6 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - }, "envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -23247,15 +23049,6 @@ "esprima": "^4.0.0" } }, - "js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "dev": true, - "requires": { - "xmlcreate": "^2.0.4" - } - }, "jsc-android": { "version": "250230.2.1", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250230.2.1.tgz", @@ -23423,51 +23216,6 @@ } } }, - "jsdoc": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", - "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", - "dev": true, - "requires": { - "@babel/parser": "^7.9.4", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.1", - "klaw": "^3.0.0", - "markdown-it": "^10.0.0", - "markdown-it-anchor": "^5.2.7", - "marked": "^2.0.3", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", - "underscore": "~1.13.1" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -23694,15 +23442,6 @@ "immediate": "~3.0.5" } }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -23951,32 +23690,6 @@ "object-visit": "^1.0.0" } }, - "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", - "dev": true, - "requires": {} - }, - "marked": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", - "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", - "dev": true - }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -23988,12 +23701,6 @@ "is-buffer": "~1.1.6" } }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -26509,15 +26216,6 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, - "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -27906,12 +27604,6 @@ } } }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -28258,12 +27950,6 @@ "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", "dev": true }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -28303,12 +27989,6 @@ "which-boxed-primitive": "^1.0.2" } }, - "underscore": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", - "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", - "dev": true - }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -28840,12 +28520,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - }, "xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", diff --git a/package.json b/package.json index cdcfe5b..01ca97a 100755 --- a/package.json +++ b/package.json @@ -53,7 +53,6 @@ "events": "^3.3.0", "jest": "^27.3.1", "jquery": "^3.6.0", - "jsdoc": "^3.6.7", "karma": "^6.3.2", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.0", @@ -85,8 +84,7 @@ "test:browser": "xvfb-maybe karma start karma.conf.local.js", "test:react-native": "jest test/react-native", "test:typings": "ts-node ./typings-tests.ts", - "prepublishOnly": "npm run build:browser", - "generateDocs": "jsdoc -c jsdoc.conf.js" + "prepublishOnly": "npm run build:browser" }, "main": "index.js", "browser": { From efef10e0e94f702d85e0f8c6003029c52be30523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 6 Jan 2022 16:50:02 +0100 Subject: [PATCH 37/65] auto-generate docs in markdown and html --- .gitignore | 2 +- docs/Cursor.md | 163 ++++ docs/Datastore.md | 420 ++++++++++ docs/Executor.md | 88 ++ docs/Index.md | 166 ++++ docs/Persistence.md | 241 ++++++ docs/Waterfall.md | 53 ++ docs/customUtilsBrowser.md | 36 + docs/customUtilsNode.md | 43 + docs/model.md | 217 +++++ docs/storage.md | 369 +++++++++ docs/storageBrowser.md | 266 ++++++ docs/storageReactNative.md | 267 ++++++ docs/utils.md | 67 ++ jsdoc.conf.js | 8 + jsdoc2md.js | 43 + lib/executor.js | 81 +- lib/waterfall.js | 58 ++ package-lock.json | 1606 +++++++++++++++++++++++++++++++++++- package.json | 6 +- 20 files changed, 4107 insertions(+), 93 deletions(-) create mode 100644 docs/Cursor.md create mode 100644 docs/Datastore.md create mode 100644 docs/Executor.md create mode 100644 docs/Index.md create mode 100644 docs/Persistence.md create mode 100644 docs/Waterfall.md create mode 100644 docs/customUtilsBrowser.md create mode 100644 docs/customUtilsNode.md create mode 100644 docs/model.md create mode 100644 docs/storage.md create mode 100644 docs/storageBrowser.md create mode 100644 docs/storageReactNative.md create mode 100644 docs/utils.md create mode 100644 jsdoc.conf.js create mode 100644 jsdoc2md.js create mode 100644 lib/waterfall.js diff --git a/.gitignore b/.gitignore index add07a4..81b6ed6 100755 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ browser-version/node_modules browser-version/out test-results -docs +docs-html diff --git a/docs/Cursor.md b/docs/Cursor.md new file mode 100644 index 0000000..d3303f5 --- /dev/null +++ b/docs/Cursor.md @@ -0,0 +1,163 @@ + + +## Cursor ⇐ Promise +

Manage access to data, be it to find, update or remove it.

+

It extends Promise so that its methods are chainable & awaitable.

+ +**Kind**: global class +**Extends**: Promise + +* [Cursor](#Cursor) ⇐ Promise + * [new Cursor(db, query, [execFn], [async])](#new_Cursor_new) + * _instance_ + * [.limit(limit)](#Cursor+limit) ⇒ [Cursor](#Cursor) + * [.skip(skip)](#Cursor+skip) ⇒ [Cursor](#Cursor) + * [.sort(sortQuery)](#Cursor+sort) ⇒ [Cursor](#Cursor) + * [.projection(projection)](#Cursor+projection) ⇒ [Cursor](#Cursor) + * [.project(candidates)](#Cursor+project) ⇒ [Array.<document>](#document) + * [._execAsync()](#Cursor+_execAsync) ⇒ [Array.<document>](#document) \| Promise.<\*> + * [._exec(_callback)](#Cursor+_exec) + * [.exec(_callback)](#Cursor+exec) + * [.execAsync()](#Cursor+execAsync) ⇒ Promise.<(Array.<document>\|\*)> + * _inner_ + * [~execFn](#Cursor..execFn) : function + * [~execFnAsync](#Cursor..execFnAsync) ⇒ Promise + * [~execCallback](#Cursor..execCallback) : function + + + +### new Cursor(db, query, [execFn], [async]) +

Create a new cursor for this collection

+ + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| db | [Datastore](#Datastore) | |

The datastore this cursor is bound to

| +| query | [query](#query) | |

The query this cursor will operate on

| +| [execFn] | [execFn](#Cursor..execFn) \| [execFnAsync](#Cursor..execFnAsync) | |

Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove

| +| [async] | boolean | false |

If true, specifies that the execFn is of type [execFnAsync](#Cursor..execFnAsync) rather than [execFn](#Cursor..execFn).

| + + + +### cursor.limit(limit) ⇒ [Cursor](#Cursor) +

Set a limit to the number of results

+ +**Kind**: instance method of [Cursor](#Cursor) + +| Param | Type | +| --- | --- | +| limit | Number | + + + +### cursor.skip(skip) ⇒ [Cursor](#Cursor) +

Skip a number of results

+ +**Kind**: instance method of [Cursor](#Cursor) + +| Param | Type | +| --- | --- | +| skip | Number | + + + +### cursor.sort(sortQuery) ⇒ [Cursor](#Cursor) +

Sort results of the query

+ +**Kind**: instance method of [Cursor](#Cursor) + +| Param | Type | Description | +| --- | --- | --- | +| sortQuery | Object.<string, number> |

sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending

| + + + +### cursor.projection(projection) ⇒ [Cursor](#Cursor) +

Add the use of a projection

+ +**Kind**: instance method of [Cursor](#Cursor) + +| Param | Type | Description | +| --- | --- | --- | +| projection | Object.<string, number> |

MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 { key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits.

| + + + +### cursor.project(candidates) ⇒ [Array.<document>](#document) +

Apply the projection

+ +**Kind**: instance method of [Cursor](#Cursor) + +| Param | Type | +| --- | --- | +| candidates | [Array.<document>](#document) | + + + +### cursor.\_execAsync() ⇒ [Array.<document>](#document) \| Promise.<\*> +

Get all matching elements +Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne +This is an internal function, use execAsync which uses the executor

+ +**Kind**: instance method of [Cursor](#Cursor) + + +### cursor.\_exec(_callback) +

Get all matching elements +Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne +This is an internal function, use exec which uses the executor

+ +**Kind**: instance method of [Cursor](#Cursor) + +| Param | Type | +| --- | --- | +| _callback | [execCallback](#Cursor..execCallback) | + + + +### cursor.exec(_callback) +

Get all matching elements +Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

+ +**Kind**: instance method of [Cursor](#Cursor) + +| Param | Type | +| --- | --- | +| _callback | [execCallback](#Cursor..execCallback) | + + + +### cursor.execAsync() ⇒ Promise.<(Array.<document>\|\*)> +

Get all matching elements +Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

+ +**Kind**: instance method of [Cursor](#Cursor) + + +### Cursor~execFn : function +**Kind**: inner typedef of [Cursor](#Cursor) + +| Param | Type | +| --- | --- | +| err | Error | +| res | [?Array.<document>](#document) \| [document](#document) | + + + +### Cursor~execFnAsync ⇒ Promise +**Kind**: inner typedef of [Cursor](#Cursor) + +| Param | Type | +| --- | --- | +| res | [?Array.<document>](#document) \| [document](#document) | + + + +### Cursor~execCallback : function +**Kind**: inner typedef of [Cursor](#Cursor) + +| Param | Type | Description | +| --- | --- | --- | +| err | Error | | +| res | [Array.<document>](#document) \| \* |

If an execFn was given to the Cursor, then the type of this parameter is the one returned by the execFn.

| + diff --git a/docs/Datastore.md b/docs/Datastore.md new file mode 100644 index 0000000..83ca95b --- /dev/null +++ b/docs/Datastore.md @@ -0,0 +1,420 @@ + + +## Datastore ⇐ EventEmitter +

The Datastore class is the main class of NeDB.

+ +**Kind**: global class +**Extends**: EventEmitter +**Emits**: Datastore.event:"compaction.done" + +* [Datastore](#Datastore) ⇐ EventEmitter + * [new Datastore(options)](#new_Datastore_new) + * _instance_ + * [.persistence](#Datastore+persistence) : [Persistence](#Persistence) + * [.executor](#Datastore+executor) : [Executor](#Executor) + * [.autoloadPromise](#Datastore+autoloadPromise) : Promise + * [.loadDatabase(callback)](#Datastore+loadDatabase) + * [.loadDatabaseAsync()](#Datastore+loadDatabaseAsync) ⇒ Promise + * [.getAllData()](#Datastore+getAllData) ⇒ [Array.<document>](#document) + * [.resetIndexes()](#Datastore+resetIndexes) + * [.ensureIndex(options, callback)](#Datastore+ensureIndex) + * [.ensureIndexAsync(options)](#Datastore+ensureIndexAsync) ⇒ Promise.<void> + * [.removeIndex(fieldName, callback)](#Datastore+removeIndex) + * [.removeIndexAsync(fieldName)](#Datastore+removeIndexAsync) ⇒ Promise.<void> + * [.removeFromIndexes(doc)](#Datastore+removeFromIndexes) + * [.updateIndexes(oldDoc, [newDoc])](#Datastore+updateIndexes) + * [.insertAsync(newDoc)](#Datastore+insertAsync) ⇒ [Promise.<document>](#document) + * [.count(query, [callback])](#Datastore+count) ⇒ Cursor.<number> \| undefined + * [.countAsync(query)](#Datastore+countAsync) ⇒ Cursor.<number> + * [.find(query, [projection], [callback])](#Datastore+find) ⇒ Cursor.<Array.<document>> \| undefined + * [.findAsync(query, [projection])](#Datastore+findAsync) ⇒ Cursor.<Array.<document>> + * [.findOne(query, projection, callback)](#Datastore+findOne) ⇒ [Cursor.<document>](#document) \| undefined + * [.findOneAsync(query, projection)](#Datastore+findOneAsync) ⇒ [Cursor.<document>](#document) + * [.update(query, update, [options], [cb])](#Datastore+update) + * [.updateAsync(query, update, [options])](#Datastore+updateAsync) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> + * [.remove(query, [options], [cb])](#Datastore+remove) + * [.removeAsync(query, [options])](#Datastore+removeAsync) ⇒ Promise.<number> + * _static_ + * ["event:compaction.done"](#Datastore.event_compaction.done) + * _inner_ + * [~countCallback](#Datastore..countCallback) : function + * [~findOneCallback](#Datastore..findOneCallback) : function + * [~updateCallback](#Datastore..updateCallback) : function + * [~removeCallback](#Datastore..removeCallback) : function + + + +### new Datastore(options) +

Create a new collection, either persistent or in-memory.

+

If you use a persistent datastore without the autoload option, you need to call loadDatabase manually. This +function fetches the data from datafile and prepares the database. Don't forget it! If you use a persistent +datastore, no command (insert, find, update, remove) will be executed before loadDatabase is called, so make sure +to call it yourself or use the autoload option.

+ + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| options | object \| string | |

Can be an object or a string. If options is a string, the behavior is the same as in v0.6: it will be interpreted as options.filename. Giving a string is deprecated, and will be removed in the next major version.

| +| [options.filename] | string | null |

Path to the file where the data is persisted. If left blank, the datastore is automatically considered in-memory only. It cannot end with a ~ which is used in the temporary files NeDB uses to perform crash-safe writes.

| +| [options.inMemoryOnly] | boolean | false |

If set to true, no data will be written in storage.

| +| [options.timestampData] | boolean | false |

If set to true, createdAt and updatedAt will be created and populated automatically (if not specified by user)

| +| [options.autoload] | boolean | false |

If used, the database will automatically be loaded from the datafile upon creation (you don't need to call loadDatabase). Any command issued before load is finished is buffered and will be executed when load is done. When autoloading is done, you can either use the onload callback, or you can use this.autoloadPromise which resolves (or rejects) when autloading is done.

| +| [options.onload] | function | |

If you use autoloading, this is the handler called after the loadDatabase. It takes one error argument. If you use autoloading without specifying this handler, and an error happens during load, an error will be thrown.

| +| [options.beforeDeserialization] | function | |

Hook you can use to transform data after it was serialized and before it is written to disk. Can be used for example to encrypt data before writing database to disk. This function takes a string as parameter (one line of an NeDB data file) and outputs the transformed string, which must absolutely not contain a \n character (or data will be lost).

| +| [options.afterSerialization] | function | |

Inverse of afterSerialization. Make sure to include both and not just one, or you risk data loss. For the same reason, make sure both functions are inverses of one another. Some failsafe mechanisms are in place to prevent data loss if you misuse the serialization hooks: NeDB checks that never one is declared without the other, and checks that they are reverse of one another by testing on random strings of various lengths. In addition, if too much data is detected as corrupt, NeDB will refuse to start as it could mean you're not using the deserialization hook corresponding to the serialization hook used before.

| +| [options.corruptAlertThreshold] | number | 0.1 |

Between 0 and 1, defaults to 10%. NeDB will refuse to start if more than this percentage of the datafile is corrupt. 0 means you don't tolerate any corruption, 1 means you don't care.

| +| [options.compareStrings] | [compareStrings](#compareStrings) | |

If specified, it overrides default string comparison which is not well adapted to non-US characters in particular accented letters. Native localCompare will most of the time be the right choice.

| +| [options.nodeWebkitAppName] | string | |

Deprecated: if you are using NeDB from whithin a Node Webkit app, specify its name (the same one you use in the package.json) in this field and the filename will be relative to the directory Node Webkit uses to store the rest of the application's data (local storage etc.). It works on Linux, OS X and Windows. Now that you can use require('nw.gui').App.dataPath in Node Webkit to get the path to the data directory for your application, you should not use this option anymore and it will be removed.

| + + + +### datastore.persistence : [Persistence](#Persistence) +

The Persistence instance for this Datastore.

+ +**Kind**: instance property of [Datastore](#Datastore) + + +### datastore.executor : [Executor](#Executor) +

The Executor instance for this Datastore. It is used in all methods exposed by the Datastore, any Cursor +produced by the Datastore and by this.persistence.compactDataFile & this.persistence.compactDataFileAsync +to ensure operations are performed sequentially in the database.

+ +**Kind**: instance property of [Datastore](#Datastore) + + +### datastore.autoloadPromise : Promise +

A Promise that resolves when the autoload has finished.

+

The onload callback is not awaited by this Promise, it is started immediately after that.

+ +**Kind**: instance property of [Datastore](#Datastore) + + +### datastore.loadDatabase(callback) +

Load the database from the datafile, and trigger the execution of buffered commands if any.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | +| --- | --- | +| callback | function | + + + +### datastore.loadDatabaseAsync() ⇒ Promise +

Load the database from the datafile, and trigger the execution of buffered commands if any.

+ +**Kind**: instance method of [Datastore](#Datastore) + + +### datastore.getAllData() ⇒ [Array.<document>](#document) +

Get an array of all the data in the database

+ +**Kind**: instance method of [Datastore](#Datastore) + + +### datastore.resetIndexes() +

Reset all currently defined indexes

+ +**Kind**: instance method of [Datastore](#Datastore) + + +### datastore.ensureIndex(options, callback) +

Ensure an index is kept for this field. Same parameters as lib/indexes +This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the +executor. +Previous versions said explicitly the callback was optional, it is now recommended setting one.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| options | object | | | +| options.fieldName | string | |

Name of the field to index. Use the dot notation to index a field in a nested document.

| +| [options.unique] | boolean | false |

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

| +| [options.sparse] | boolean | false |

don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

| +| [options.expireAfterSeconds] | number | |

if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

| +| callback | [NoParamCallback](#NoParamCallback) | |

Callback, signature: err

| + + + +### datastore.ensureIndexAsync(options) ⇒ Promise.<void> +

Ensure an index is kept for this field. Same parameters as lib/indexes +This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the +executor. +Previous versions said explicitly the callback was optional, it is now recommended setting one.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| options | object | | | +| options.fieldName | string | |

Name of the field to index. Use the dot notation to index a field in a nested document.

| +| [options.unique] | boolean | false |

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

| +| [options.sparse] | boolean | false |

Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

| +| [options.expireAfterSeconds] | number | |

If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

| + + + +### datastore.removeIndex(fieldName, callback) +

Remove an index +Previous versions said explicitly the callback was optional, it is now recommended setting one.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Description | +| --- | --- | --- | +| fieldName | string |

Field name of the index to remove. Use the dot notation to remove an index referring to a field in a nested document.

| +| callback | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| + + + +### datastore.removeIndexAsync(fieldName) ⇒ Promise.<void> +

Remove an index +Previous versions said explicitly the callback was optional, it is now recommended setting one.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Description | +| --- | --- | --- | +| fieldName | string |

Field name of the index to remove. Use the dot notation to remove an index referring to a field in a nested document.

| + + + +### datastore.removeFromIndexes(doc) +

Remove one or several document(s) from all indexes

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | +| --- | --- | +| doc | [document](#document) | + + + +### datastore.updateIndexes(oldDoc, [newDoc]) +

Update one or several documents in all indexes +To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs +If one update violates a constraint, all changes are rolled back

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Description | +| --- | --- | --- | +| oldDoc | [document](#document) \| Array.<{oldDoc: document, newDoc: document}> |

Document to update, or an Array of {oldDoc, newDoc} pairs.

| +| [newDoc] | [document](#document) |

Document to replace the oldDoc with. If the first argument is an Array of {oldDoc, newDoc} pairs, this second argument is ignored.

| + + + +### datastore.insertAsync(newDoc) ⇒ [Promise.<document>](#document) +

Insert a new document +Private Use Datastore.insertAsync which has the same signature

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | +| --- | --- | +| newDoc | [document](#document) \| [Array.<document>](#document) | + + + +### datastore.count(query, [callback]) ⇒ Cursor.<number> \| undefined +

Count all documents matching the query

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Description | +| --- | --- | --- | +| query | [query](#query) |

MongoDB-style query

| +| [callback] | [countCallback](#Datastore..countCallback) |

If given, the function will return undefined, otherwise it will return the Cursor.

| + + + +### datastore.countAsync(query) ⇒ Cursor.<number> +

Count all documents matching the query

+ +**Kind**: instance method of [Datastore](#Datastore) +**Returns**: Cursor.<number> -

count

+ +| Param | Type | Description | +| --- | --- | --- | +| query | [query](#query) |

MongoDB-style query

| + + + +### datastore.find(query, [projection], [callback]) ⇒ Cursor.<Array.<document>> \| undefined +

Find all documents matching the query +If no callback is passed, we return the cursor so that user can limit, skip and finally exec

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| query | [query](#query) | |

MongoDB-style query

| +| [projection] | [projection](#projection) \| [MultipleDocumentsCallback](#MultipleDocumentsCallback) | {} |

MongoDB-style projection. If not given, will be interpreted as the callback.

| +| [callback] | [MultipleDocumentsCallback](#MultipleDocumentsCallback) | |

Optional callback, signature: err, docs

| + + + +### datastore.findAsync(query, [projection]) ⇒ Cursor.<Array.<document>> +

Find all documents matching the query +If no callback is passed, we return the cursor so that user can limit, skip and finally exec

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| query | [query](#query) | |

MongoDB-style query

| +| [projection] | [projection](#projection) | {} |

MongoDB-style projection

| + + + +### datastore.findOne(query, projection, callback) ⇒ [Cursor.<document>](#document) \| undefined +

Find one document matching the query

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Description | +| --- | --- | --- | +| query | [query](#query) |

MongoDB-style query

| +| projection | [projection](#projection) |

MongoDB-style projection

| +| callback | [SingleDocumentCallback](#SingleDocumentCallback) |

Optional callback, signature: err, doc

| + + + +### datastore.findOneAsync(query, projection) ⇒ [Cursor.<document>](#document) +

Find one document matching the query

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Description | +| --- | --- | --- | +| query | [query](#query) |

MongoDB-style query

| +| projection | [projection](#projection) |

MongoDB-style projection

| + + + +### datastore.update(query, update, [options], [cb]) +

Update all docs matching query.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| query | [query](#query) | |

is the same kind of finding query you use with find and findOne

| +| update | [document](#document) \| update | |

specifies how the documents should be modified. It is either a new document or a set of modifiers (you cannot use both together, it doesn't make sense!):

  • A new document will replace the matched docs
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a field's value and $min/$max to change field's value, only if provided value is less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
| +| [options] | Object | |

Optional options

| +| [options.multi] | boolean | false |

If true, can update multiple documents

| +| [options.upsert] | boolean | false |

If true, can insert a new document corresponding to the update rules if your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted document. In the other case, the query is stripped from all operator recursively, and the update is applied to it.

| +| [options.returnUpdatedDocs] | boolean | false |

(not Mongo-DB compatible) If true and update is not an upsert, will return the array of documents matched by the find query and updated. Updated documents will be returned even if the update did not actually modify them.

| +| [cb] | [updateCallback](#Datastore..updateCallback) | () => {} |

Optional callback

| + + + +### datastore.updateAsync(query, update, [options]) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> +

Update all docs matching query.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| query | [query](#query) | |

is the same kind of finding query you use with find and findOne

| +| update | [document](#document) \| update | |

specifies how the documents should be modified. It is either a new document or a set of modifiers (you cannot use both together, it doesn't make sense!):

  • A new document will replace the matched docs
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a field's value and $min/$max to change field's value, only if provided value is less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
| +| [options] | Object | |

Optional options

| +| [options.multi] | boolean | false |

If true, can update multiple documents

| +| [options.upsert] | boolean | false |

If true, can insert a new document corresponding to the update rules if your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted document. In the other case, the query is stripped from all operator recursively, and the update is applied to it.

| +| [options.returnUpdatedDocs] | boolean | false |

(not Mongo-DB compatible) If true and update is not an upsert, will return the array of documents matched by the find query and updated. Updated documents will be returned even if the update did not actually modify them.

| + + + +### datastore.remove(query, [options], [cb]) +

Remove all docs matching the query.

+ +**Kind**: instance method of [Datastore](#Datastore) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| query | [query](#query) | | | +| [options] | object | |

Optional options

| +| [options.multi] | boolean | false |

If true, can update multiple documents

| +| [cb] | [removeCallback](#Datastore..removeCallback) | () => {} |

Optional callback, signature: err, numRemoved

| + + + +### datastore.removeAsync(query, [options]) ⇒ Promise.<number> +

Remove all docs matching the query. +Use Datastore.removeAsync which has the same signature

+ +**Kind**: instance method of [Datastore](#Datastore) +**Returns**: Promise.<number> -

How many documents were removed

+ +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| query | [query](#query) | | | +| [options] | object | |

Optional options

| +| [options.multi] | boolean | false |

If true, can update multiple documents

| + + + +### "event:compaction.done" +

Compaction event. Happens when the Datastore's Persistence has been compacted. +It happens when calling datastore.persistence.compactDatafile, which is called periodically if you have called +datastore.persistence.setAutocompactionInterval.

+ +**Kind**: event emitted by [Datastore](#Datastore) + + +### Datastore~countCallback : function +**Kind**: inner typedef of [Datastore](#Datastore) + +| Param | Type | +| --- | --- | +| err | Error | +| count | number | + + + +### Datastore~findOneCallback : function +**Kind**: inner typedef of [Datastore](#Datastore) + +| Param | Type | +| --- | --- | +| err | Error | +| doc | [document](#document) | + + + +### Datastore~updateCallback : function +

If update was an upsert, upsert flag is set to true, affectedDocuments can be one of the following:

+
    +
  • For an upsert, the upserted document
  • +
  • For an update with returnUpdatedDocs option false, null
  • +
  • For an update with returnUpdatedDocs true and multi false, the updated document
  • +
  • For an update with returnUpdatedDocs true and multi true, the array of updated documents
  • +
+

WARNING: The API was changed between v1.7.4 and v1.8, for consistency and readability reasons. Prior and +including to v1.7.4, the callback signature was (err, numAffected, updated) where updated was the updated document +in case of an upsert or the array of updated documents for an update if the returnUpdatedDocs option was true. That +meant that the type of affectedDocuments in a non multi update depended on whether there was an upsert or not, +leaving only two ways for the user to check whether an upsert had occured: checking the type of affectedDocuments +or running another find query on the whole dataset to check its size. Both options being ugly, the breaking change +was necessary.

+ +**Kind**: inner typedef of [Datastore](#Datastore) + +| Param | Type | +| --- | --- | +| err | Error | +| numAffected | number | +| affectedDocuments | [?Array.<document>](#document) \| [document](#document) | +| upsert | boolean | + + + +### Datastore~removeCallback : function +**Kind**: inner typedef of [Datastore](#Datastore) + +| Param | Type | +| --- | --- | +| err | Error | +| numRemoved | number | + diff --git a/docs/Executor.md b/docs/Executor.md new file mode 100644 index 0000000..47ca3f7 --- /dev/null +++ b/docs/Executor.md @@ -0,0 +1,88 @@ + + +## Executor +

Executes operations sequentially. +Has an option for a buffer that can be triggered afterwards.

+ +**Kind**: global class + +* [Executor](#Executor) + * [new Executor()](#new_Executor_new) + * [.ready](#Executor+ready) : boolean + * [.queue](#Executor+queue) : [Waterfall](#Waterfall) + * [.buffer](#Executor+buffer) : [Waterfall](#Waterfall) + * [._triggerBuffer()](#Executor+_triggerBuffer) + * [.push(task, [forceQueuing])](#Executor+push) + * [.pushAsync(task, [forceQueuing])](#Executor+pushAsync) ⇒ Promise.<\*> + * [.processBuffer()](#Executor+processBuffer) + + + +### new Executor() +

Instantiates a new Executor.

+ + + +### executor.ready : boolean +

If this.ready is false, then every task pushed will be buffered until this.processBuffer is called.

+ +**Kind**: instance property of [Executor](#Executor) +**Access**: protected + + +### executor.queue : [Waterfall](#Waterfall) +

The main queue

+ +**Kind**: instance property of [Executor](#Executor) +**Access**: protected + + +### executor.buffer : [Waterfall](#Waterfall) +

The buffer queue

+ +**Kind**: instance property of [Executor](#Executor) +**Access**: protected + + +### executor.\_triggerBuffer() +

Method to trigger the buffer processing.

+

Do not be use directly, use this.processBuffer instead.

+ +**Kind**: instance method of [Executor](#Executor) +**Access**: protected + + +### executor.push(task, [forceQueuing]) +

If executor is ready, queue task (and process it immediately if executor was idle) +If not, buffer task for later processing

+ +**Kind**: instance method of [Executor](#Executor) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| task | Object | | | +| task.this | Object | |

Object to use as this

| +| task.fn | function | |

Function to execute

| +| task.arguments | Array | |

Array of arguments, IMPORTANT: only the last argument may be a function (the callback) and the last argument cannot be false/undefined/null

| +| [forceQueuing] | Boolean | false |

Optional (defaults to false) force executor to queue task even if it is not ready

| + + + +### executor.pushAsync(task, [forceQueuing]) ⇒ Promise.<\*> +

If executor is ready, queue task (and process it immediately if executor was idle) +If not, buffer task for later processing

+ +**Kind**: instance method of [Executor](#Executor) + +| Param | Type | Default | +| --- | --- | --- | +| task | function | | +| [forceQueuing] | boolean | false | + + + +### executor.processBuffer() +

Queue all tasks in buffer (in the same order they came in) +Automatically sets executor as ready

+ +**Kind**: instance method of [Executor](#Executor) diff --git a/docs/Index.md b/docs/Index.md new file mode 100644 index 0000000..202cea0 --- /dev/null +++ b/docs/Index.md @@ -0,0 +1,166 @@ + + +## Index +

Indexes on field names, with atomic operations and which can optionally enforce a unique constraint or allow indexed +fields to be undefined

+ +**Kind**: global class + +* [Index](#Index) + * [new Index(options)](#new_Index_new) + * [.fieldName](#Index+fieldName) : string + * [.unique](#Index+unique) : boolean + * [.sparse](#Index+sparse) : boolean + * [.treeOptions](#Index+treeOptions) : Object + * [.tree](#Index+tree) : AVLTree + * [.reset([newData])](#Index+reset) + * [.insert(doc)](#Index+insert) + * [.remove(doc)](#Index+remove) + * [.update(oldDoc, [newDoc])](#Index+update) + * [.revertUpdate(oldDoc, [newDoc])](#Index+revertUpdate) + * [.getMatching(value)](#Index+getMatching) ⇒ [Array.<document>](#document) + * [.getBetweenBounds(query)](#Index+getBetweenBounds) ⇒ [Array.<document>](#document) + * [.getAll()](#Index+getAll) ⇒ [Array.<document>](#document) + + + +### new Index(options) +

Create a new index +All methods on an index guarantee that either the whole operation was successful and the index changed +or the operation was unsuccessful and an error is thrown while the index is unchanged

+ + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| options | object | | | +| options.fieldName | string | |

On which field should the index apply (can use dot notation to index on sub fields)

| +| [options.unique] | boolean | false |

Enforces a unique constraint

| +| [options.sparse] | boolean | false |

Allows a sparse index (we can have documents for which fieldName is undefined)

| + + + +### index.fieldName : string +

On which field the index applies to (may use dot notation to index on sub fields).

+ +**Kind**: instance property of [Index](#Index) + + +### index.unique : boolean +

Defines if the index enforces a unique constraint for this index.

+ +**Kind**: instance property of [Index](#Index) + + +### index.sparse : boolean +

Defines if we can have documents for which fieldName is undefined

+ +**Kind**: instance property of [Index](#Index) + + +### index.treeOptions : Object +

Options object given to the underlying BinarySearchTree.

+ +**Kind**: instance property of [Index](#Index) + + +### index.tree : AVLTree +

Underlying BinarySearchTree for this index. Uses an AVLTree for optimization.

+ +**Kind**: instance property of [Index](#Index) + + +### index.reset([newData]) +

Reset an index

+ +**Kind**: instance method of [Index](#Index) + +| Param | Type | Description | +| --- | --- | --- | +| [newData] | [document](#document) \| [?Array.<document>](#document) |

Data to initialize the index with. If an error is thrown during insertion, the index is not modified.

| + + + +### index.insert(doc) +

Insert a new document in the index +If an array is passed, we insert all its elements (if one insertion fails the index is not modified) +O(log(n))

+ +**Kind**: instance method of [Index](#Index) + +| Param | Type | Description | +| --- | --- | --- | +| doc | [document](#document) \| [Array.<document>](#document) |

The document, or array of documents, to insert.

| + + + +### index.remove(doc) +

Removes a document from the index. +If an array is passed, we remove all its elements +The remove operation is safe with regards to the 'unique' constraint +O(log(n))

+ +**Kind**: instance method of [Index](#Index) + +| Param | Type | Description | +| --- | --- | --- | +| doc | [Array.<document>](#document) \| [document](#document) |

The document, or Array of documents, to remove.

| + + + +### index.update(oldDoc, [newDoc]) +

Update a document in the index +If a constraint is violated, changes are rolled back and an error thrown +Naive implementation, still in O(log(n))

+ +**Kind**: instance method of [Index](#Index) + +| Param | Type | Description | +| --- | --- | --- | +| oldDoc | [document](#document) \| Array.<{oldDoc: document, newDoc: document}> |

Document to update, or an Array of {oldDoc, newDoc} pairs.

| +| [newDoc] | [document](#document) |

Document to replace the oldDoc with. If the first argument is an Array of {oldDoc, newDoc} pairs, this second argument is ignored.

| + + + +### index.revertUpdate(oldDoc, [newDoc]) +

Revert an update

+ +**Kind**: instance method of [Index](#Index) + +| Param | Type | Description | +| --- | --- | --- | +| oldDoc | [document](#document) \| Array.<{oldDoc: document, newDoc: document}> |

Document to revert to, or an Array of {oldDoc, newDoc} pairs.

| +| [newDoc] | [document](#document) |

Document to revert from. If the first argument is an Array of {oldDoc, newDoc}, this second argument is ignored.

| + + + +### index.getMatching(value) ⇒ [Array.<document>](#document) +

Get all documents in index whose key match value (if it is a Thing) or one of the elements of value (if it is an array of Things)

+ +**Kind**: instance method of [Index](#Index) + +| Param | Type | Description | +| --- | --- | --- | +| value | Array.<\*> \| \* |

Value to match the key against

| + + + +### index.getBetweenBounds(query) ⇒ [Array.<document>](#document) +

Get all documents in index whose key is between bounds are they are defined by query +Documents are sorted by key

+ +**Kind**: instance method of [Index](#Index) + +| Param | Type | Description | +| --- | --- | --- | +| query | object |

An object with at least one matcher among $gt, $gte, $lt, $lte.

| +| [query.$gt] | \* |

Greater than matcher.

| +| [query.$gte] | \* |

Greater than or equal matcher.

| +| [query.$lt] | \* |

Lower than matcher.

| +| [query.$lte] | \* |

Lower than or equal matcher.

| + + + +### index.getAll() ⇒ [Array.<document>](#document) +

Get all elements in the index

+ +**Kind**: instance method of [Index](#Index) diff --git a/docs/Persistence.md b/docs/Persistence.md new file mode 100644 index 0000000..d660e09 --- /dev/null +++ b/docs/Persistence.md @@ -0,0 +1,241 @@ + + +## Persistence +

Handle every persistence-related task

+ +**Kind**: global class + +* [Persistence](#Persistence) + * [new Persistence()](#new_Persistence_new) + * _instance_ + * [.persistCachedDatabase(callback)](#Persistence+persistCachedDatabase) + * [.persistCachedDatabaseAsync()](#Persistence+persistCachedDatabaseAsync) ⇒ Promise.<void> + * [.compactDatafile([callback])](#Persistence+compactDatafile) + * [.compactDatafileAsync()](#Persistence+compactDatafileAsync) + * [.setAutocompactionInterval(interval)](#Persistence+setAutocompactionInterval) + * [.stopAutocompaction()](#Persistence+stopAutocompaction) + * [.persistNewState(newDocs, [callback])](#Persistence+persistNewState) + * [.persistNewStateAsync(newDocs)](#Persistence+persistNewStateAsync) ⇒ Promise + * [.treatRawData(rawData)](#Persistence+treatRawData) ⇒ Object + * [.treatRawStream(rawStream, cb)](#Persistence+treatRawStream) + * [.treatRawStreamAsync(rawStream)](#Persistence+treatRawStreamAsync) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> + * [.loadDatabase(callback)](#Persistence+loadDatabase) + * [.loadDatabaseAsync()](#Persistence+loadDatabaseAsync) ⇒ Promise.<void> + * _static_ + * [.ensureDirectoryExists(dir, [callback])](#Persistence.ensureDirectoryExists) + * [.ensureDirectoryExistsAsync(dir)](#Persistence.ensureDirectoryExistsAsync) ⇒ Promise.<void> + * ~~[.getNWAppFilename(appName, relativeFilename)](#Persistence.getNWAppFilename) ⇒ string~~ + * _inner_ + * [~treatRawStreamCallback](#Persistence..treatRawStreamCallback) : function + + + +### new Persistence() +

Create a new Persistence object for database options.db

+ + +| Param | Type | Description | +| --- | --- | --- | +| options.db | [Datastore](#Datastore) | | +| [options.corruptAlertThreshold] | Number |

Optional, threshold after which an alert is thrown if too much data is corrupt

| +| [options.nodeWebkitAppName] | string |

Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion)

| +| [options.beforeDeserialization] | function |

Hook you can use to transform data after it was serialized and before it is written to disk.

| +| [options.afterSerialization] | function |

Inverse of afterSerialization.

| + + + +### persistence.persistCachedDatabase(callback) +

Persist cached database +This serves as a compaction function since the cache always contains only the number of documents in the collection +while the data file is append-only so it may grow larger +This is an internal function, use compactDataFile which uses the executor

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | Description | +| --- | --- | --- | +| callback | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| + + + +### persistence.persistCachedDatabaseAsync() ⇒ Promise.<void> +

Persist cached database +This serves as a compaction function since the cache always contains only the number of documents in the collection +while the data file is append-only so it may grow larger +This is an internal function, use compactDataFileAsync which uses the executor

+ +**Kind**: instance method of [Persistence](#Persistence) + + +### persistence.compactDatafile([callback]) +

Queue a rewrite of the datafile

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| [callback] | [NoParamCallback](#NoParamCallback) | () => {} |

Optional callback, signature: err

| + + + +### persistence.compactDatafileAsync() +

Queue a rewrite of the datafile

+ +**Kind**: instance method of [Persistence](#Persistence) + + +### persistence.setAutocompactionInterval(interval) +

Set automatic compaction every interval ms

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | Description | +| --- | --- | --- | +| interval | Number |

in milliseconds, with an enforced minimum of 5 seconds

| + + + +### persistence.stopAutocompaction() +

Stop autocompaction (do nothing if autocompaction was not running)

+ +**Kind**: instance method of [Persistence](#Persistence) + + +### persistence.persistNewState(newDocs, [callback]) +

Persist new state for the given newDocs (can be insertion, update or removal) +Use an append-only format

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| newDocs | Array.<string> | |

Can be empty if no doc was updated/removed

| +| [callback] | [NoParamCallback](#NoParamCallback) | () => {} |

Optional, signature: err

| + + + +### persistence.persistNewStateAsync(newDocs) ⇒ Promise +

Persist new state for the given newDocs (can be insertion, update or removal) +Use an append-only format

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | Description | +| --- | --- | --- | +| newDocs | [Array.<document>](#document) |

Can be empty if no doc was updated/removed

| + + + +### persistence.treatRawData(rawData) ⇒ Object +

From a database's raw data, return the corresponding machine understandable collection

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | Description | +| --- | --- | --- | +| rawData | string |

database file

| + + + +### persistence.treatRawStream(rawStream, cb) +

From a database's raw data stream, return the corresponding machine understandable collection

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | +| --- | --- | +| rawStream | Readable | +| cb | [treatRawStreamCallback](#Persistence..treatRawStreamCallback) | + + + +### persistence.treatRawStreamAsync(rawStream) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> +

From a database's raw data stream, return the corresponding machine understandable collection

+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | +| --- | --- | +| rawStream | Readable | + + + +### persistence.loadDatabase(callback) +

Load the database

+
    +
  1. Create all indexes
  2. +
  3. Insert all data
  4. +
  5. Compact the database +This means pulling data out of the data file or creating it if it doesn't exist +Also, all data is persisted right away, which has the effect of compacting the database file +This operation is very quick at startup for a big collection (60ms for ~10k docs)
  6. +
+ +**Kind**: instance method of [Persistence](#Persistence) + +| Param | Type | Description | +| --- | --- | --- | +| callback | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| + + + +### persistence.loadDatabaseAsync() ⇒ Promise.<void> +

Load the database

+
    +
  1. Create all indexes
  2. +
  3. Insert all data
  4. +
  5. Compact the database +This means pulling data out of the data file or creating it if it doesn't exist +Also, all data is persisted right away, which has the effect of compacting the database file +This operation is very quick at startup for a big collection (60ms for ~10k docs)
  6. +
+ +**Kind**: instance method of [Persistence](#Persistence) + + +### Persistence.ensureDirectoryExists(dir, [callback]) +

Check if a directory stat and create it on the fly if it is not the case

+ +**Kind**: static method of [Persistence](#Persistence) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| dir | string | | | +| [callback] | [NoParamCallback](#NoParamCallback) | () => {} |

optional callback, signature: err

| + + + +### Persistence.ensureDirectoryExistsAsync(dir) ⇒ Promise.<void> +

Check if a directory stat and create it on the fly if it is not the case

+ +**Kind**: static method of [Persistence](#Persistence) + +| Param | Type | +| --- | --- | +| dir | string | + + + +### ~~Persistence.getNWAppFilename(appName, relativeFilename) ⇒ string~~ +***Deprecated*** + +

Return the path the datafile if the given filename is relative to the directory where Node Webkit stores +data for this application. Probably the best place to store data

+ +**Kind**: static method of [Persistence](#Persistence) + +| Param | Type | +| --- | --- | +| appName | string | +| relativeFilename | string | + + + +### Persistence~treatRawStreamCallback : function +**Kind**: inner typedef of [Persistence](#Persistence) + +| Param | Type | +| --- | --- | +| err | Error | +| data | Object | + diff --git a/docs/Waterfall.md b/docs/Waterfall.md new file mode 100644 index 0000000..4091ea2 --- /dev/null +++ b/docs/Waterfall.md @@ -0,0 +1,53 @@ + + +## Waterfall +**Kind**: global class + +* [Waterfall](#Waterfall) + * [new Waterfall()](#new_Waterfall_new) + * [._guardian](#Waterfall+_guardian) : Promise + * [.guardian](#Waterfall+guardian) ⇒ Promise + * [.waterfall(func)](#Waterfall+waterfall) ⇒ [AsyncFunction](#AsyncFunction) + * [.chain(promise)](#Waterfall+chain) ⇒ Promise + + + +### new Waterfall() +

Instantiate a new Waterfall.

+ + + +### waterfall.\_guardian : Promise +

This is the internal Promise object which resolves when all the tasks of the Waterfall are done.

+

It will change any time this.waterfall is called.

+

Use [guardian](#Waterfall+guardian) instead which retrievethe latest version of the guardian.

+ +**Kind**: instance property of [Waterfall](#Waterfall) +**Access**: protected + + +### waterfall.guardian ⇒ Promise +

Getter that gives a Promise which resolves when all tasks up to when this function is called are done.

+

This Promise cannot reject.

+ +**Kind**: instance property of [Waterfall](#Waterfall) + + +### waterfall.waterfall(func) ⇒ [AsyncFunction](#AsyncFunction) +**Kind**: instance method of [Waterfall](#Waterfall) + +| Param | Type | +| --- | --- | +| func | [AsyncFunction](#AsyncFunction) | + + + +### waterfall.chain(promise) ⇒ Promise +

Shorthand for chaining a promise to the Waterfall

+ +**Kind**: instance method of [Waterfall](#Waterfall) + +| Param | Type | +| --- | --- | +| promise | Promise | + diff --git a/docs/customUtilsBrowser.md b/docs/customUtilsBrowser.md new file mode 100644 index 0000000..b0f6f31 --- /dev/null +++ b/docs/customUtilsBrowser.md @@ -0,0 +1,36 @@ + + +## customUtilsBrowser +

Utility functions that need to be reimplemented for each environment. +This is the version for the browser & React-Native

+ + +* [customUtilsBrowser](#module_customUtilsBrowser) + * [~randomBytes(size)](#module_customUtilsBrowser..randomBytes) ⇒ array.<number> + * [~byteArrayToBase64(uint8)](#module_customUtilsBrowser..byteArrayToBase64) ⇒ string + + + +### customUtilsBrowser~randomBytes(size) ⇒ array.<number> +

Taken from the crypto-browserify module +https://github.com/dominictarr/crypto-browserify +NOTE: Math.random() does not guarantee "cryptographic quality" but we actually don't need it

+ +**Kind**: inner method of [customUtilsBrowser](#module_customUtilsBrowser) + +| Param | Type | Description | +| --- | --- | --- | +| size | number |

in bytes

| + + + +### customUtilsBrowser~byteArrayToBase64(uint8) ⇒ string +

Taken from the base64-js module +https://github.com/beatgammit/base64-js/

+ +**Kind**: inner method of [customUtilsBrowser](#module_customUtilsBrowser) + +| Param | Type | +| --- | --- | +| uint8 | array | + diff --git a/docs/customUtilsNode.md b/docs/customUtilsNode.md new file mode 100644 index 0000000..5c86017 --- /dev/null +++ b/docs/customUtilsNode.md @@ -0,0 +1,43 @@ + + +## customUtilsNode +

Utility functions that need to be reimplemented for each environment. +This is the version for Node.js

+ + +* [customUtilsNode](#module_customUtilsNode) + * [.uid(len)](#module_customUtilsNode.uid) ⇒ string + * [.uid(len)](#module_customUtilsNode.uid) ⇒ string + + + +### customUtilsNode.uid(len) ⇒ string +

Return a random alphanumerical string of length len +There is a very small probability (less than 1/1,000,000) for the length to be less than len +(il the base64 conversion yields too many pluses and slashes) but +that's not an issue here +The probability of a collision is extremely small (need 3*10^12 documents to have one chance in a million of a collision) +See http://en.wikipedia.org/wiki/Birthday_problem

+ +**Kind**: static method of [customUtilsNode](#module_customUtilsNode) + +| Param | Type | +| --- | --- | +| len | number | + + + +### customUtilsNode.uid(len) ⇒ string +

Return a random alphanumerical string of length len +There is a very small probability (less than 1/1,000,000) for the length to be less than len +(il the base64 conversion yields too many pluses and slashes) but +that's not an issue here +The probability of a collision is extremely small (need 3*10^12 documents to have one chance in a million of a collision) +See http://en.wikipedia.org/wiki/Birthday_problem

+ +**Kind**: static method of [customUtilsNode](#module_customUtilsNode) + +| Param | Type | +| --- | --- | +| len | number | + diff --git a/docs/model.md b/docs/model.md new file mode 100644 index 0000000..3acaa33 --- /dev/null +++ b/docs/model.md @@ -0,0 +1,217 @@ + + +## model +

Handle models (i.e. docs) +Serialization/deserialization +Copying +Querying, update

+ + +* [model](#module_model) + * _static_ + * [.checkObject(obj)](#module_model.checkObject) + * [.serialize(obj)](#module_model.serialize) ⇒ string + * [.deserialize(rawData)](#module_model.deserialize) ⇒ [document](#document) + * [.compareThings(a, b, [_compareStrings])](#module_model.compareThings) ⇒ number + * [.modify(obj, updateQuery)](#module_model.modify) ⇒ [document](#document) + * [.getDotValue(obj, field)](#module_model.getDotValue) ⇒ \* + * [.areThingsEqual(a, a)](#module_model.areThingsEqual) ⇒ boolean + * [.match(obj, query)](#module_model.match) ⇒ boolean + * _inner_ + * [~modifierFunctions](#module_model..modifierFunctions) : enum + * [~comparisonFunctions](#module_model..comparisonFunctions) : enum + * [~logicalOperators](#module_model..logicalOperators) + * [~modifierFunction](#module_model..modifierFunction) : function + * [~comparisonOperator](#module_model..comparisonOperator) ⇒ boolean + * [~whereCallback](#module_model..whereCallback) ⇒ boolean + + + +### model.checkObject(obj) +

Check a DB object and throw an error if it's not valid +Works by applying the above checkKey function to all fields recursively

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | +| --- | --- | +| obj | [document](#document) \| [Array.<document>](#document) | + + + +### model.serialize(obj) ⇒ string +

Serialize an object to be persisted to a one-line string +For serialization/deserialization, we use the native JSON parser and not eval or Function +That gives us less freedom but data entered in the database may come from users +so eval and the like are not safe +Accepted primitive types: Number, String, Boolean, Date, null +Accepted secondary types: Objects, Arrays

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | +| --- | --- | +| obj | [document](#document) | + + + +### model.deserialize(rawData) ⇒ [document](#document) +

From a one-line representation of an object generate by the serialize function +Return the object itself

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | +| --- | --- | +| rawData | string | + + + +### model.compareThings(a, b, [_compareStrings]) ⇒ number +

Compare { things U undefined } +Things are defined as any native types (string, number, boolean, null, date) and objects +We need to compare with undefined as it will be used in indexes +In the case of objects and arrays, we deep-compare +If two objects dont have the same type, the (arbitrary) type hierarchy is: undefined, null, number, strings, boolean, dates, arrays, objects +Return -1 if a < b, 1 if a > b and 0 if a = b (note that equality here is NOT the same as defined in areThingsEqual!)

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | Description | +| --- | --- | --- | +| a | \* | | +| b | \* | | +| [_compareStrings] | [compareStrings](#compareStrings) |

String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters)

| + + + +### model.modify(obj, updateQuery) ⇒ [document](#document) +

Modify a DB object according to an update query

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | +| --- | --- | +| obj | [document](#document) | +| updateQuery | [query](#query) | + + + +### model.getDotValue(obj, field) ⇒ \* +

Get a value from object with dot notation

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | +| --- | --- | +| obj | object | +| field | string | + + + +### model.areThingsEqual(a, a) ⇒ boolean +

Check whether 'things' are equal +Things are defined as any native types (string, number, boolean, null, date) and objects +In the case of object, we check deep equality +Returns true if they are, false otherwise

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | +| --- | --- | +| a | \* | +| a | \* | + + + +### model.match(obj, query) ⇒ boolean +

Tell if a given document matches a query

+ +**Kind**: static method of [model](#module_model) + +| Param | Type | Description | +| --- | --- | --- | +| obj | [document](#document) |

Document to check

| +| query | [query](#query) | | + + + +### model~modifierFunctions : enum +**Kind**: inner enum of [model](#module_model) +**Properties** + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| $set | modifierFunction | |

Set a field to a new value

| +| $unset | modifierFunction | |

Unset a field

| +| $min | modifierFunction | |

Updates the value of the field, only if specified field is smaller than the current value of the field

| +| $max | modifierFunction | |

Updates the value of the field, only if specified field is greater than the current value of the field

| +| $inc | modifierFunction | |

Increment a numeric field's value

| +| $pull | modifierFunction | |

Removes all instances of a value from an existing array

| +| $pop | modifierFunction | |

Remove the first or last element of an array

| +| $addToSet | modifierFunction | |

Add an element to an array field only if it is not already in it No modification if the element is already in the array Note that it doesn't check whether the original array contains duplicates

| +| $push | modifierFunction | |

Push an element to the end of an array field Optional modifier $each instead of value to push several values Optional modifier $slice to slice the resulting array, see https://docs.mongodb.org/manual/reference/operator/update/slice/ Difference with MongoDB: if $slice is specified and not $each, we act as if value is an empty array

| + + + +### model~comparisonFunctions : enum +**Kind**: inner enum of [model](#module_model) +**Properties** + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| $lt | comparisonOperator | |

Lower than

| +| $lte | comparisonOperator | |

Lower than or equals

| +| $gt | comparisonOperator | |

Greater than

| +| $gte | comparisonOperator | |

Greater than or equals

| +| $ne | comparisonOperator | |

Does not equal

| +| $in | comparisonOperator | |

Is in Array

| +| $nin | comparisonOperator | |

Is not in Array

| +| $regex | comparisonOperator | |

Matches Regexp

| +| $exists | comparisonOperator | |

Returns true if field exists

| +| $size | comparisonOperator | |

Specific to Arrays, returns true if a length equals b

| +| $elemMatch | comparisonOperator | |

Specific to Arrays, returns true if some elements of a match the query b

| + + + +### model~logicalOperators +**Kind**: inner enum of [model](#module_model) +**Properties** + +| Name | Default | Description | +| --- | --- | --- | +| $or | |

Match any of the subqueries

| +| $and | |

Match all of the subqueries

| +| $not | |

Inverted match of the query

| +| $where | |

Use a function to match

| + + + +### model~modifierFunction : function +**Kind**: inner typedef of [model](#module_model) + +| Param | Type | Description | +| --- | --- | --- | +| obj | Object |

The model to modify

| +| field | String |

Can contain dots, in that case that means we will set a subfield recursively

| +| value | [document](#document) | | + + + +### model~comparisonOperator ⇒ boolean +**Kind**: inner typedef of [model](#module_model) + +| Param | Type | Description | +| --- | --- | --- | +| a | \* |

Value in the object

| +| b | \* |

Value in the query

| + + + +### model~whereCallback ⇒ boolean +**Kind**: inner typedef of [model](#module_model) + +| Param | Type | +| --- | --- | +| obj | [document](#document) | + diff --git a/docs/storage.md b/docs/storage.md new file mode 100644 index 0000000..dffd9d7 --- /dev/null +++ b/docs/storage.md @@ -0,0 +1,369 @@ + + +## storage +

Way data is stored for this database +For a Node.js/Node Webkit database it's the file system +For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) +For a react-native database, we use @react-native-async-storage/async-storage

+

This version is the Node.js/Node Webkit version +It's essentially fs, mkdirp and crash safe write and read functions

+ + +* [storage](#module_storage) + * _static_ + * [.exists(file, cb)](#module_storage.exists) + * [.existsAsync(file)](#module_storage.existsAsync) ⇒ Promise.<boolean> + * [.rename(oldPath, newPath, c)](#module_storage.rename) ⇒ void + * [.renameAsync(oldPath, newPath)](#module_storage.renameAsync) ⇒ Promise.<void> + * [.writeFile(path, data, options, callback)](#module_storage.writeFile) + * [.writeFileAsync(path, data, [options])](#module_storage.writeFileAsync) ⇒ Promise.<void> + * [.writeFileStream(path, [options])](#module_storage.writeFileStream) ⇒ fs.WriteStream + * [.unlink(path, callback)](#module_storage.unlink) + * [.unlinkAsync(path)](#module_storage.unlinkAsync) ⇒ Promise.<void> + * [.appendFile(path, data, options, callback)](#module_storage.appendFile) + * [.appendFileAsync(path, data, [options])](#module_storage.appendFileAsync) ⇒ Promise.<void> + * [.readFile(path, options, callback)](#module_storage.readFile) + * [.readFileAsync(path, [options])](#module_storage.readFileAsync) ⇒ Promise.<Buffer> + * [.readFileStream(path, [options])](#module_storage.readFileStream) ⇒ fs.ReadStream + * [.mkdir(path, options, callback)](#module_storage.mkdir) + * [.mkdirAsync(path, options)](#module_storage.mkdirAsync) ⇒ Promise.<(void\|string)> + * [.ensureFileDoesntExistAsync(file)](#module_storage.ensureFileDoesntExistAsync) ⇒ Promise.<void> + * [.ensureFileDoesntExist(file, callback)](#module_storage.ensureFileDoesntExist) + * [.flushToStorage(options, callback)](#module_storage.flushToStorage) + * [.flushToStorageAsync(options)](#module_storage.flushToStorageAsync) ⇒ Promise.<void> + * [.writeFileLines(filename, lines, callback)](#module_storage.writeFileLines) + * [.writeFileLinesAsync(filename, lines)](#module_storage.writeFileLinesAsync) ⇒ Promise.<void> + * [.crashSafeWriteFileLines(filename, lines, [callback])](#module_storage.crashSafeWriteFileLines) + * [.crashSafeWriteFileLinesAsync(filename, lines)](#module_storage.crashSafeWriteFileLinesAsync) ⇒ Promise.<void> + * [.ensureDatafileIntegrity(filename, callback)](#module_storage.ensureDatafileIntegrity) + * [.ensureDatafileIntegrityAsync(filename)](#module_storage.ensureDatafileIntegrityAsync) ⇒ Promise.<void> + * _inner_ + * [~existsCallback](#module_storage..existsCallback) : function + + + +### storage.exists(file, cb) +

Callback returns true if file exists

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| file | string | +| cb | [existsCallback](#module_storage..existsCallback) | + + + +### storage.existsAsync(file) ⇒ Promise.<boolean> +

Returns Promise if file exists

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| file | string | + + + +### storage.rename(oldPath, newPath, c) ⇒ void +

Node.js' fs.rename

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| oldPath | string | +| newPath | string | +| c | [NoParamCallback](#NoParamCallback) | + + + +### storage.renameAsync(oldPath, newPath) ⇒ Promise.<void> +

Node.js' fs.promises.rename

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| oldPath | string | +| newPath | string | + + + +### storage.writeFile(path, data, options, callback) +

Node.js' fs.writeFile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| data | string | +| options | object | +| callback | function | + + + +### storage.writeFileAsync(path, data, [options]) ⇒ Promise.<void> +

Node.js' fs.promises.writeFile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| data | string | +| [options] | object | + + + +### storage.writeFileStream(path, [options]) ⇒ fs.WriteStream +

Node.js' fs.createWriteStream

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| [options] | Object | + + + +### storage.unlink(path, callback) +

Node.js' fs.unlink

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| callback | function | + + + +### storage.unlinkAsync(path) ⇒ Promise.<void> +

Node.js' fs.promises.unlink

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | + + + +### storage.appendFile(path, data, options, callback) +

Node.js' fs.appendFile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| data | string | +| options | object | +| callback | function | + + + +### storage.appendFileAsync(path, data, [options]) ⇒ Promise.<void> +

Node.js' fs.promises.appendFile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| data | string | +| [options] | object | + + + +### storage.readFile(path, options, callback) +

Node.js' fs.readFile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| options | object | +| callback | function | + + + +### storage.readFileAsync(path, [options]) ⇒ Promise.<Buffer> +

Node.js' fs.promises.readFile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| [options] | object | + + + +### storage.readFileStream(path, [options]) ⇒ fs.ReadStream +

Node.js' fs.createReadStream

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| [options] | Object | + + + +### storage.mkdir(path, options, callback) +

Node.js' fs.mkdir

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| options | object | +| callback | function | + + + +### storage.mkdirAsync(path, options) ⇒ Promise.<(void\|string)> +

Node.js' fs.promises.mkdir

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| path | string | +| options | object | + + + +### storage.ensureFileDoesntExistAsync(file) ⇒ Promise.<void> +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| file | string | + + + +### storage.ensureFileDoesntExist(file, callback) +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| file | string | +| callback | [NoParamCallback](#NoParamCallback) | + + + +### storage.flushToStorage(options, callback) +

Flush data in OS buffer to storage if corresponding option is set

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| options | object \| string | |

If options is a string, it is assumed that the flush of the file (not dir) called options was requested

| +| [options.filename] | string | | | +| [options.isDir] | boolean | false |

Optional, defaults to false

| +| callback | [NoParamCallback](#NoParamCallback) | | | + + + +### storage.flushToStorageAsync(options) ⇒ Promise.<void> +

Flush data in OS buffer to storage if corresponding option is set

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| options | object \| string | |

If options is a string, it is assumed that the flush of the file (not dir) called options was requested

| +| [options.filename] | string | | | +| [options.isDir] | boolean | false |

Optional, defaults to false

| + + + +### storage.writeFileLines(filename, lines, callback) +

Fully write or rewrite the datafile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| filename | string | +| lines | Array.<string> | +| callback | [NoParamCallback](#NoParamCallback) | + + + +### storage.writeFileLinesAsync(filename, lines) ⇒ Promise.<void> +

Fully write or rewrite the datafile

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| filename | string | +| lines | Array.<string> | + + + +### storage.crashSafeWriteFileLines(filename, lines, [callback]) +

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | Description | +| --- | --- | --- | +| filename | string | | +| lines | Array.<string> | | +| [callback] | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| + + + +### storage.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> +

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| filename | string | +| lines | Array.<string> | + + + +### storage.ensureDatafileIntegrity(filename, callback) +

Ensure the datafile contains all the data, even if there was a crash during a full file write

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | Description | +| --- | --- | --- | +| filename | string | | +| callback | [NoParamCallback](#NoParamCallback) |

signature: err

| + + + +### storage.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> +

Ensure the datafile contains all the data, even if there was a crash during a full file write

+ +**Kind**: static method of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| filename | string | + + + +### storage~existsCallback : function +**Kind**: inner typedef of [storage](#module_storage) + +| Param | Type | +| --- | --- | +| exists | boolean | + diff --git a/docs/storageBrowser.md b/docs/storageBrowser.md new file mode 100644 index 0000000..e7d620c --- /dev/null +++ b/docs/storageBrowser.md @@ -0,0 +1,266 @@ + + +## storageBrowser +

Way data is stored for this database +For a Node.js/Node Webkit database it's the file system +For a browser-side database it's localforage which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage)

+

This version is the browser version

+ + +* [storageBrowser](#module_storageBrowser) + * _static_ + * [.existsAsync(file)](#module_storageBrowser.existsAsync) ⇒ Promise.<boolean> + * [.exists(file, cb)](#module_storageBrowser.exists) + * [.renameAsync(oldPath, newPath)](#module_storageBrowser.renameAsync) ⇒ Promise.<void> + * [.rename(oldPath, newPath, c)](#module_storageBrowser.rename) ⇒ void + * [.writeFileAsync(file, data, [options])](#module_storageBrowser.writeFileAsync) ⇒ Promise.<void> + * [.writeFile(path, data, options, callback)](#module_storageBrowser.writeFile) + * [.appendFileAsync(filename, toAppend, [options])](#module_storageBrowser.appendFileAsync) ⇒ Promise.<void> + * [.appendFile(filename, toAppend, [options], callback)](#module_storageBrowser.appendFile) + * [.readFileAsync(filename, [options])](#module_storageBrowser.readFileAsync) ⇒ Promise.<Buffer> + * [.readFile(filename, options, callback)](#module_storageBrowser.readFile) + * [.unlinkAsync(filename)](#module_storageBrowser.unlinkAsync) ⇒ Promise.<void> + * [.unlink(path, callback)](#module_storageBrowser.unlink) + * [.mkdirAsync(path, [options])](#module_storageBrowser.mkdirAsync) ⇒ Promise.<(void\|string)> + * [.mkdir(path, options, callback)](#module_storageBrowser.mkdir) + * [.ensureDatafileIntegrityAsync(filename)](#module_storageBrowser.ensureDatafileIntegrityAsync) ⇒ Promise.<void> + * [.ensureDatafileIntegrity(filename, callback)](#module_storageBrowser.ensureDatafileIntegrity) + * [.crashSafeWriteFileLinesAsync(filename, lines)](#module_storageBrowser.crashSafeWriteFileLinesAsync) ⇒ Promise.<void> + * [.crashSafeWriteFileLines(filename, lines, [callback])](#module_storageBrowser.crashSafeWriteFileLines) + * _inner_ + * [~existsCallback](#module_storageBrowser..existsCallback) : function + + + +### storageBrowser.existsAsync(file) ⇒ Promise.<boolean> +

Returns Promise if file exists

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| file | string | + + + +### storageBrowser.exists(file, cb) +

Callback returns true if file exists

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| file | string | +| cb | [existsCallback](#module_storageBrowser..existsCallback) | + + + +### storageBrowser.renameAsync(oldPath, newPath) ⇒ Promise.<void> +

Moves the item from one path to another

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| oldPath | string | +| newPath | string | + + + +### storageBrowser.rename(oldPath, newPath, c) ⇒ void +

Moves the item from one path to another

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| oldPath | string | +| newPath | string | +| c | [NoParamCallback](#NoParamCallback) | + + + +### storageBrowser.writeFileAsync(file, data, [options]) ⇒ Promise.<void> +

Saves the item at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| file | string | +| data | string | +| [options] | object | + + + +### storageBrowser.writeFile(path, data, options, callback) +

Saves the item at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| path | string | +| data | string | +| options | object | +| callback | function | + + + +### storageBrowser.appendFileAsync(filename, toAppend, [options]) ⇒ Promise.<void> +

Append to the item at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| filename | string | +| toAppend | string | +| [options] | object | + + + +### storageBrowser.appendFile(filename, toAppend, [options], callback) +

Append to the item at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| filename | string | +| toAppend | string | +| [options] | object | +| callback | function | + + + +### storageBrowser.readFileAsync(filename, [options]) ⇒ Promise.<Buffer> +

Read data at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| filename | string | +| [options] | object | + + + +### storageBrowser.readFile(filename, options, callback) +

Read data at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| filename | string | +| options | object | +| callback | function | + + + +### storageBrowser.unlinkAsync(filename) ⇒ Promise.<void> +

Remove the data at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| filename | string | + + + +### storageBrowser.unlink(path, callback) +

Remove the data at given path

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| path | string | +| callback | function | + + + +### storageBrowser.mkdirAsync(path, [options]) ⇒ Promise.<(void\|string)> +

Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| path | string | +| [options] | object | + + + +### storageBrowser.mkdir(path, options, callback) +

Shim for storage.mkdir, nothing to do, no directories will be used on the browser

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| path | string | +| options | object | +| callback | function | + + + +### storageBrowser.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> +

Ensure the datafile contains all the data, even if there was a crash during a full file write +Nothing to do, no data corruption possible in the browser

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| filename | string | + + + +### storageBrowser.ensureDatafileIntegrity(filename, callback) +

Ensure the datafile contains all the data, even if there was a crash during a full file write +Nothing to do, no data corruption possible in the browser

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | Description | +| --- | --- | --- | +| filename | string | | +| callback | [NoParamCallback](#NoParamCallback) |

signature: err

| + + + +### storageBrowser.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> +

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| filename | string | +| lines | Array.<string> | + + + +### storageBrowser.crashSafeWriteFileLines(filename, lines, [callback]) +

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+ +**Kind**: static method of [storageBrowser](#module_storageBrowser) + +| Param | Type | Description | +| --- | --- | --- | +| filename | string | | +| lines | Array.<string> | | +| [callback] | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| + + + +### storageBrowser~existsCallback : function +**Kind**: inner typedef of [storageBrowser](#module_storageBrowser) + +| Param | Type | +| --- | --- | +| exists | boolean | + diff --git a/docs/storageReactNative.md b/docs/storageReactNative.md new file mode 100644 index 0000000..405e4b5 --- /dev/null +++ b/docs/storageReactNative.md @@ -0,0 +1,267 @@ + + +## storageReactNative +

Way data is stored for this database +For a Node.js/Node Webkit database it's the file system +For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) +For a react-native database, we use @react-native-async-storage/async-storage

+

This version is the react-native version

+ + +* [storageReactNative](#module_storageReactNative) + * _static_ + * [.existsAsync(file)](#module_storageReactNative.existsAsync) ⇒ Promise.<boolean> + * [.exists(file, cb)](#module_storageReactNative.exists) + * [.renameAsync(oldPath, newPath)](#module_storageReactNative.renameAsync) ⇒ Promise.<void> + * [.rename(oldPath, newPath, c)](#module_storageReactNative.rename) ⇒ void + * [.writeFileAsync(file, data, [options])](#module_storageReactNative.writeFileAsync) ⇒ Promise.<void> + * [.writeFile(path, data, options, callback)](#module_storageReactNative.writeFile) + * [.appendFileAsync(filename, toAppend, [options])](#module_storageReactNative.appendFileAsync) ⇒ Promise.<void> + * [.appendFile(filename, toAppend, [options], callback)](#module_storageReactNative.appendFile) + * [.readFileAsync(filename, [options])](#module_storageReactNative.readFileAsync) ⇒ Promise.<string> + * [.readFile(filename, options, callback)](#module_storageReactNative.readFile) + * [.unlinkAsync(filename)](#module_storageReactNative.unlinkAsync) ⇒ Promise.<void> + * [.unlink(path, callback)](#module_storageReactNative.unlink) + * [.mkdirAsync(dir, [options])](#module_storageReactNative.mkdirAsync) ⇒ Promise.<(void\|string)> + * [.mkdir(path, options, callback)](#module_storageReactNative.mkdir) + * [.ensureDatafileIntegrityAsync(filename)](#module_storageReactNative.ensureDatafileIntegrityAsync) ⇒ Promise.<void> + * [.ensureDatafileIntegrity(filename, callback)](#module_storageReactNative.ensureDatafileIntegrity) + * [.crashSafeWriteFileLinesAsync(filename, lines)](#module_storageReactNative.crashSafeWriteFileLinesAsync) ⇒ Promise.<void> + * [.crashSafeWriteFileLines(filename, lines, [callback])](#module_storageReactNative.crashSafeWriteFileLines) + * _inner_ + * [~existsCallback](#module_storageReactNative..existsCallback) : function + + + +### storageReactNative.existsAsync(file) ⇒ Promise.<boolean> +

Returns Promise if file exists

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| file | string | + + + +### storageReactNative.exists(file, cb) +

Callback returns true if file exists

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| file | string | +| cb | [existsCallback](#module_storageReactNative..existsCallback) | + + + +### storageReactNative.renameAsync(oldPath, newPath) ⇒ Promise.<void> +

Moves the item from one path to another

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| oldPath | string | +| newPath | string | + + + +### storageReactNative.rename(oldPath, newPath, c) ⇒ void +

Moves the item from one path to another

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| oldPath | string | +| newPath | string | +| c | [NoParamCallback](#NoParamCallback) | + + + +### storageReactNative.writeFileAsync(file, data, [options]) ⇒ Promise.<void> +

Saves the item at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| file | string | +| data | string | +| [options] | object | + + + +### storageReactNative.writeFile(path, data, options, callback) +

Saves the item at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| path | string | +| data | string | +| options | object | +| callback | function | + + + +### storageReactNative.appendFileAsync(filename, toAppend, [options]) ⇒ Promise.<void> +

Append to the item at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| filename | string | +| toAppend | string | +| [options] | object | + + + +### storageReactNative.appendFile(filename, toAppend, [options], callback) +

Append to the item at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| filename | string | +| toAppend | string | +| [options] | object | +| callback | function | + + + +### storageReactNative.readFileAsync(filename, [options]) ⇒ Promise.<string> +

Read data at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| filename | string | +| [options] | object | + + + +### storageReactNative.readFile(filename, options, callback) +

Read data at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| filename | string | +| options | object | +| callback | function | + + + +### storageReactNative.unlinkAsync(filename) ⇒ Promise.<void> +

Remove the data at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| filename | string | + + + +### storageReactNative.unlink(path, callback) +

Remove the data at given path

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| path | string | +| callback | function | + + + +### storageReactNative.mkdirAsync(dir, [options]) ⇒ Promise.<(void\|string)> +

Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| dir | string | +| [options] | object | + + + +### storageReactNative.mkdir(path, options, callback) +

Shim for storage.mkdir, nothing to do, no directories will be used on the browser

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| path | string | +| options | object | +| callback | function | + + + +### storageReactNative.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> +

Ensure the datafile contains all the data, even if there was a crash during a full file write +Nothing to do, no data corruption possible in the browser

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| filename | string | + + + +### storageReactNative.ensureDatafileIntegrity(filename, callback) +

Ensure the datafile contains all the data, even if there was a crash during a full file write +Nothing to do, no data corruption possible in the browser

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | Description | +| --- | --- | --- | +| filename | string | | +| callback | [NoParamCallback](#NoParamCallback) |

signature: err

| + + + +### storageReactNative.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> +

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| filename | string | +| lines | Array.<string> | + + + +### storageReactNative.crashSafeWriteFileLines(filename, lines, [callback]) +

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+ +**Kind**: static method of [storageReactNative](#module_storageReactNative) + +| Param | Type | Description | +| --- | --- | --- | +| filename | string | | +| lines | Array.<string> | | +| [callback] | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| + + + +### storageReactNative~existsCallback : function +**Kind**: inner typedef of [storageReactNative](#module_storageReactNative) + +| Param | Type | +| --- | --- | +| exists | boolean | + diff --git a/docs/utils.md b/docs/utils.md new file mode 100644 index 0000000..11cd495 --- /dev/null +++ b/docs/utils.md @@ -0,0 +1,67 @@ + + +## utils +

Utility functions for all environments. +This replaces the underscore dependency.

+ + +* [utils](#module_utils) + * _static_ + * [.uniq(array, [iteratee])](#module_utils.uniq) ⇒ Array + * [.isDate(d)](#module_utils.isDate) ⇒ boolean + * [.isRegExp(re)](#module_utils.isRegExp) ⇒ boolean + * _inner_ + * [~isObject(arg)](#module_utils..isObject) ⇒ boolean + + + +### utils.uniq(array, [iteratee]) ⇒ Array +

Produces a duplicate-free version of the array, using === to test object equality. In particular only the first +occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee +function. +Heavily inspired by https://underscorejs.org/#uniq

+ +**Kind**: static method of [utils](#module_utils) + +| Param | Type | Description | +| --- | --- | --- | +| array | Array | | +| [iteratee] | function |

transformation applied to every element before checking for duplicates. This will not transform the items in the result.

| + + + +### utils.isDate(d) ⇒ boolean +

Returns true if d is a Date. +Heavily inspired by https://underscorejs.org/#isDate

+ +**Kind**: static method of [utils](#module_utils) + +| Param | Type | +| --- | --- | +| d | \* | + + + +### utils.isRegExp(re) ⇒ boolean +

Returns true if re is a RegExp. +Heavily inspired by https://underscorejs.org/#isRegExp

+ +**Kind**: static method of [utils](#module_utils) + +| Param | Type | +| --- | --- | +| re | \* | + + + +### utils~isObject(arg) ⇒ boolean +

Returns true if arg is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings +and numbers are not. +Heavily inspired by https://underscorejs.org/#isObject

+ +**Kind**: inner method of [utils](#module_utils) + +| Param | Type | +| --- | --- | +| arg | \* | + diff --git a/jsdoc.conf.js b/jsdoc.conf.js new file mode 100644 index 0000000..4615043 --- /dev/null +++ b/jsdoc.conf.js @@ -0,0 +1,8 @@ +'use strict' + +module.exports = { + plugins: ['plugins/markdown'], + source: { + include: ['./lib', './browser-version/lib'] + } +} diff --git a/jsdoc2md.js b/jsdoc2md.js new file mode 100644 index 0000000..681b462 --- /dev/null +++ b/jsdoc2md.js @@ -0,0 +1,43 @@ +'use strict' +const jsdoc2md = require('jsdoc-to-markdown') +const fs = require('fs') +const path = require('path') + +const jsdocConf = './jsdoc.conf.js' + +/* output path */ +const outputDir = './docs' + +const getJsdocDataOptions = { + /* same inpout path as jsdoc */ + files: require(jsdocConf).source.include, + configure: './jsdoc.conf.js', + 'no-cache': true +} + +fs.rmdirSync(outputDir, { recursive: true }) // clean docs dir +fs.mkdirSync(outputDir) // make docs dir + +/* get template data */ +const templateData = jsdoc2md.getTemplateDataSync(getJsdocDataOptions) + +/* reduce templateData to an array of class names */ +const classNames = templateData.filter(({kind}) => kind === 'class').map(({name}) => name) + +const moduleNames = templateData.filter(({kind}) => kind === 'module').map(({name}) => name) + +/* create a documentation file for each class */ +for (const className of classNames) { + const template = `{{#class name="${className}"}}{{>docs}}{{/class}}` + console.log(`rendering ${className}, template: ${template}`) + const output = jsdoc2md.renderSync({ data: templateData, template: template }) + fs.writeFileSync(path.resolve(outputDir, `${className}.md`), output) +} + +/* create a documentation file for each module */ +for (const moduleName of moduleNames) { + const template = `{{#module name="${moduleName}"}}{{>docs}}{{/module}}` + console.log(`rendering ${moduleName}, template: ${template}`) + const output = jsdoc2md.renderSync({ data: templateData, template: template }) + fs.writeFileSync(path.resolve(outputDir, `${moduleName}.md`), output) +} diff --git a/lib/executor.js b/lib/executor.js index a1acd5a..61f593f 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -1,57 +1,4 @@ -/** - * Responsible for sequentially executing actions on the database - * @private - */ -class Waterfall { - constructor () { - /** - * This is the internal Promise object which resolves when all the tasks of the `Waterfall` are done. - * - * It will change any time `this.waterfall` is called, this is why there is a getter `this.guardian` which retrieves - * the latest version of the guardian. - * @type {Promise} - * @private - */ - this._guardian = Promise.resolve() - } - - /** - * Returns a Promise which resolves when all tasks up to when this function is called are done. - * - * This Promise cannot reject. - * @return {Promise} - */ - get guardian () { - return this._guardian - } - - /** - * - * @param {AsyncFunction} func - * @return {AsyncFunction} - */ - waterfall (func) { - return (...args) => { - this._guardian = this.guardian.then(() => { - return func(...args) - .then(result => ({ error: false, result }), result => ({ error: true, result })) - }) - return this.guardian.then(({ error, result }) => { - if (error) return Promise.reject(result) - else return Promise.resolve(result) - }) - } - } - - /** - * Shorthand for chaining a promise to the Waterfall - * @param promise - * @return {Promise} - */ - chain (promise) { - return this.waterfall(() => promise)() - } -} +const Waterfall = require('./waterfall') /** * Executes operations sequentially. @@ -62,11 +9,33 @@ class Executor { * Instantiates a new Executor. */ constructor () { + /** + * If this.ready is `false`, then every task pushed will be buffered until this.processBuffer is called. + * @type {boolean} + * @protected + */ this.ready = false + /** + * The main queue + * @type {Waterfall} + * @protected + */ this.queue = new Waterfall() + /** + * The buffer queue + * @type {Waterfall} + * @protected + */ this.buffer = new Waterfall() this.buffer.chain(new Promise(resolve => { - this.triggerBuffer = resolve + /** + * Method to trigger the buffer processing. + * + * Do not be use directly, use `this.processBuffer` instead. + * @function + * @protected + */ + this._triggerBuffer = resolve })) } @@ -127,7 +96,7 @@ class Executor { */ processBuffer () { this.ready = true - this.triggerBuffer() + this._triggerBuffer() this.queue.waterfall(() => this.buffer.guardian) } } diff --git a/lib/waterfall.js b/lib/waterfall.js new file mode 100644 index 0000000..d44f8fc --- /dev/null +++ b/lib/waterfall.js @@ -0,0 +1,58 @@ +require('../jsdoc.conf') + +class Waterfall { + /** + * Instantiate a new Waterfall. + */ + constructor () { + /** + * This is the internal Promise object which resolves when all the tasks of the `Waterfall` are done. + * + * It will change any time `this.waterfall` is called. + * + * Use {@link Waterfall#guardian} instead which retrievethe latest version of the guardian. + * @type {Promise} + * @protected + */ + this._guardian = Promise.resolve() + } + + /** + * Getter that gives a Promise which resolves when all tasks up to when this function is called are done. + * + * This Promise cannot reject. + * @return {Promise} + */ + get guardian () { + return this._guardian + } + + /** + * + * @param {AsyncFunction} func + * @return {AsyncFunction} + */ + waterfall (func) { + return (...args) => { + this._guardian = this.guardian.then(() => { + return func(...args) + .then(result => ({ error: false, result }), result => ({ error: true, result })) + }) + return this.guardian.then(({ error, result }) => { + if (error) return Promise.reject(result) + else return Promise.resolve(result) + }) + } + } + + /** + * Shorthand for chaining a promise to the Waterfall + * @param {Promise} promise + * @return {Promise} + */ + chain (promise) { + return this.waterfall(() => promise)() + } +} + +module.exports = Waterfall diff --git a/package-lock.json b/package-lock.json index 0e7f9b8..34526aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,8 @@ "events": "^3.3.0", "jest": "^27.3.1", "jquery": "^3.6.0", + "jsdoc": "^3.6.7", + "jsdoc-to-markdown": "^7.1.0", "karma": "^6.3.2", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.0", @@ -3782,6 +3784,27 @@ "node": ">=6" } }, + "node_modules/ansi-escape-sequences": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz", + "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==", + "dev": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ansi-escape-sequences/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -3921,6 +3944,15 @@ "node": ">=0.10.0" } }, + "node_modules/array-back": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.0.tgz", + "integrity": "sha512-mixVv03GOOn/ubHE4STQ+uevX42ETdk0JoMVEjNkSOCT7WgERh7C8/+NyhWYNpE3BN69pxFyJIBcF7CxWz/+4A==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, "node_modules/array-filter": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", @@ -4433,6 +4465,12 @@ "node": ">=8" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", @@ -4615,6 +4653,29 @@ "node": ">=0.10.0" } }, + "node_modules/cache-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz", + "integrity": "sha512-4gkeHlFpSKgm3vm2gJN5sPqfmijYRFYCQ6tv5cLw0xVmT6r1z1vd4FNnpuOREco3cBs1G709sZ72LdgddKvL5w==", + "dev": true, + "dependencies": { + "array-back": "^4.0.1", + "fs-then-native": "^2.0.0", + "mkdirp2": "^1.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cache-point/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -4705,6 +4766,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -4984,6 +5057,19 @@ "node": ">= 0.12.0" } }, + "node_modules/collect-all": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", + "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==", + "dev": true, + "dependencies": { + "stream-connect": "^1.0.2", + "stream-via": "^1.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -5057,6 +5143,94 @@ "dev": true, "peer": true }, + "node_modules/command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A==", + "dev": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-args/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/command-line-args/node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-tool": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", + "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==", + "dev": true, + "dependencies": { + "ansi-escape-sequences": "^4.0.0", + "array-back": "^2.0.0", + "command-line-args": "^5.0.0", + "command-line-usage": "^4.1.0", + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-tool/node_modules/array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "dependencies": { + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz", + "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==", + "dev": true, + "dependencies": { + "ansi-escape-sequences": "^4.0.0", + "array-back": "^2.0.0", + "table-layout": "^0.4.2", + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "dependencies": { + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -5066,6 +5240,15 @@ "node": ">= 10" } }, + "node_modules/common-sequence": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", + "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -5144,6 +5327,24 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "node_modules/config-master": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz", + "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=", + "dev": true, + "dependencies": { + "walk-back": "^2.0.1" + } + }, + "node_modules/config-master/node_modules/walk-back": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz", + "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", @@ -5424,6 +5625,15 @@ "node": ">=0.12" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5540,6 +5750,38 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/dmd": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.0.0.tgz", + "integrity": "sha512-PwWZlqZnJPETwqZZ70haRa+UDZcD5jeBD3ywW1Kf+jYYv0MHu/S7Ri9jsSoeTMwkcMVW9hXOMA1IZUMEufBhOg==", + "dev": true, + "dependencies": { + "array-back": "^5.0.0", + "cache-point": "^2.0.0", + "common-sequence": "^2.0.0", + "file-set": "^4.0.1", + "handlebars": "^4.7.7", + "marked": "^2.0.0", + "object-get": "^2.1.1", + "reduce-flatten": "^3.0.0", + "reduce-unique": "^2.0.1", + "reduce-without": "^1.0.1", + "test-value": "^3.0.0", + "walk-back": "^5.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/dmd/node_modules/array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -5719,6 +5961,12 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, + "node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -6957,6 +7205,28 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-set": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/file-set/-/file-set-4.0.2.tgz", + "integrity": "sha512-fuxEgzk4L8waGXaAkd8cMr73Pm0FxOVkn8hztzUW7BAHhOGH90viQNXbiOsnecCWmfInqU6YmAMwxRMdKETceQ==", + "dev": true, + "dependencies": { + "array-back": "^5.0.0", + "glob": "^7.1.6" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/file-set/node_modules/array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -7114,6 +7384,27 @@ "semver": "bin/semver" } }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-replace/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -7258,6 +7549,15 @@ "node": ">=6 <7 || >=8" } }, + "node_modules/fs-then-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz", + "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7452,6 +7752,27 @@ "node": ">=4.x" } }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -9080,6 +9401,15 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, "node_modules/jsc-android": { "version": "250230.2.1", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250230.2.1.tgz", @@ -9272,6 +9602,122 @@ "signal-exit": "^3.0.2" } }, + "node_modules/jsdoc": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", + "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.9.4", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.1", + "klaw": "^3.0.0", + "markdown-it": "^10.0.0", + "markdown-it-anchor": "^5.2.7", + "marked": "^2.0.3", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "taffydb": "2.6.2", + "underscore": "~1.13.1" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=8.15.0" + } + }, + "node_modules/jsdoc-api": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-7.1.0.tgz", + "integrity": "sha512-yjIiZa6LFOgd0dyFW/R+3unnVUhhbU1CeBhisgjBPRHkar83rkgDtTMRdgQotSvt+pGlmknZqfwR5AQuMh9/6w==", + "dev": true, + "dependencies": { + "array-back": "^6.2.0", + "cache-point": "^2.0.0", + "collect-all": "^1.0.4", + "file-set": "^4.0.2", + "fs-then-native": "^2.0.0", + "jsdoc": "^3.6.7", + "object-to-spawn-args": "^2.0.1", + "temp-path": "^1.0.0", + "walk-back": "^5.1.0" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/jsdoc-parse": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.0.1.tgz", + "integrity": "sha512-ij3Az5y2dp+ajMxYnEJH7kjKK5v6+yZ3Cg/KtRdoT15pIm6qTk/W8q72QdNLZ9jQm/U2/ifENFXXTOe6xIxGeA==", + "dev": true, + "dependencies": { + "array-back": "^6.1.1", + "lodash.omit": "^4.5.0", + "lodash.pick": "^4.4.0", + "reduce-extract": "^1.0.0", + "sort-array": "^4.1.4", + "test-value": "^3.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jsdoc-to-markdown": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-7.1.0.tgz", + "integrity": "sha512-LJAiwrUaOpPqOmllqnVVqfBZh6KI/rHHfSwL7DerTpjLQWHfpndz/JUNlF5ngYjbL4aHNf7uJ1TuXl6xGfq5rg==", + "dev": true, + "dependencies": { + "array-back": "^6.2.0", + "command-line-tool": "^0.8.0", + "config-master": "^3.1.0", + "dmd": "^6.0.0", + "jsdoc-api": "^7.1.0", + "jsdoc-parse": "^6.0.1", + "walk-back": "^5.1.0" + }, + "bin": { + "jsdoc2md": "bin/cli.js" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/jsdoc/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jsdoc/node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/jsdoc/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -9555,6 +10001,15 @@ "immediate": "~3.0.5" } }, + "node_modules/linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -9614,6 +10069,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -9627,6 +10088,24 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "node_modules/lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", + "dev": true + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", + "dev": true + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -9854,6 +10333,43 @@ "node": ">=0.10.0" } }, + "node_modules/markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "dev": true, + "peerDependencies": { + "markdown-it": "*" + } + }, + "node_modules/marked": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true, + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -9865,6 +10381,12 @@ "is-buffer": "~1.1.6" } }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -10954,6 +11476,12 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp2": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.5.tgz", + "integrity": "sha512-xOE9xbICroUDmG1ye2h4bZ8WBie9EGmACaco8K8cx6RlkJJrxGIqjGqztAI+NMhexXBcdGbSEzI6N3EJPevxZw==", + "dev": true + }, "node_modules/mocha": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", @@ -11490,6 +12018,12 @@ "node": ">=0.10.0" } }, + "node_modules/object-get": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz", + "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==", + "dev": true + }, "node_modules/object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -11508,6 +12042,15 @@ "node": ">= 0.4" } }, + "node_modules/object-to-spawn-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.1.tgz", + "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -12706,51 +13249,143 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=", + "dev": true, + "peer": true + }, + "node_modules/recast": { + "version": "0.20.5", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", + "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", + "dev": true, + "peer": true, + "dependencies": { + "ast-types": "0.14.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/reduce-extract": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", + "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=", + "dev": true, + "dependencies": { + "test-value": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reduce-extract/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/reduce-extract/node_modules/test-value": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz", + "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=", + "dev": true, + "dependencies": { + "array-back": "^1.0.2", + "typical": "^2.4.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reduce-flatten": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz", + "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/reduce-unique": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz", + "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/reduce-without": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz", + "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=", "dev": true, "dependencies": { - "picomatch": "^2.2.1" + "test-value": "^2.0.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=0.10.0" } }, - "node_modules/readline": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", - "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=", - "dev": true, - "peer": true - }, - "node_modules/recast": { - "version": "0.20.5", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", - "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", + "node_modules/reduce-without/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, - "peer": true, "dependencies": { - "ast-types": "0.14.2", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" + "typical": "^2.6.0" }, "engines": { - "node": ">= 4" + "node": ">=0.12.0" } }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "node_modules/reduce-without/node_modules/test-value": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", + "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", "dev": true, "dependencies": { - "resolve": "^1.9.0" + "array-back": "^1.0.3", + "typical": "^2.6.0" }, "engines": { - "node": ">= 0.10" + "node": ">=0.10.0" } }, "node_modules/regenerate": { @@ -12938,6 +13573,15 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "node_modules/requizzle": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", + "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -14012,6 +14656,37 @@ "node": ">=10.0.0" } }, + "node_modules/sort-array": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.4.tgz", + "integrity": "sha512-GVFN6Y1sHKrWaSYOJTk9093ZnrBMc9sP3nuhANU44S4xg3rE6W5Z5WyamuT8VpMBbssnetx5faKCua0LEmUnSw==", + "dev": true, + "dependencies": { + "array-back": "^5.0.0", + "typical": "^6.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sort-array/node_modules/array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/sort-array/node_modules/typical": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-6.0.1.tgz", + "integrity": "sha512-+g3NEp7fJLe9DPa1TArHm9QAA7YciZmWnfAqEaFrBihQ7epOv9i99rjtgb6Iz0wh3WuQDjsCTDfgRoGnmHN81A==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -14384,6 +15059,39 @@ "node": ">= 0.10.0" } }, + "node_modules/stream-connect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz", + "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=", + "dev": true, + "dependencies": { + "array-back": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-connect/node_modules/array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "dependencies": { + "typical": "^2.6.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/stream-via": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", + "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/streamroller": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", @@ -14604,6 +15312,34 @@ "node": ">=10.0.0" } }, + "node_modules/table-layout": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", + "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==", + "dev": true, + "dependencies": { + "array-back": "^2.0.0", + "deep-extend": "~0.6.0", + "lodash.padend": "^4.6.1", + "typical": "^2.6.1", + "wordwrapjs": "^3.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "dependencies": { + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/table/node_modules/ajv": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", @@ -14661,6 +15397,12 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -14684,6 +15426,12 @@ "rimraf": "~2.2.6" } }, + "node_modules/temp-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz", + "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=", + "dev": true + }, "node_modules/temp/node_modules/rimraf": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", @@ -14798,6 +15546,31 @@ "node": ">=8" } }, + "node_modules/test-value": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", + "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", + "dev": true, + "dependencies": { + "array-back": "^2.0.0", + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/test-value/node_modules/array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "dependencies": { + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -15160,6 +15933,12 @@ "node": ">=4.2.0" } }, + "node_modules/typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + }, "node_modules/ua-parser-js": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", @@ -15179,6 +15958,12 @@ "node": "*" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "node_modules/uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -15204,6 +15989,19 @@ "dev": true, "peer": true }, + "node_modules/uglify-js": { + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz", + "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/ultron": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", @@ -15226,6 +16024,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/underscore": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -15532,6 +16336,15 @@ "node": ">=10" } }, + "node_modules/walk-back": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz", + "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -15800,6 +16613,34 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/wordwrapjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", + "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", + "dev": true, + "dependencies": { + "reduce-flatten": "^1.0.1", + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/reduce-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", + "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/workerpool": { "version": "6.1.5", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", @@ -15912,6 +16753,12 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "node_modules/xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", @@ -18965,6 +19812,23 @@ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, + "ansi-escape-sequences": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz", + "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==", + "dev": true, + "requires": { + "array-back": "^3.0.1" + }, + "dependencies": { + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + } + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -19073,6 +19937,12 @@ "dev": true, "peer": true }, + "array-back": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.0.tgz", + "integrity": "sha512-mixVv03GOOn/ubHE4STQ+uevX42ETdk0JoMVEjNkSOCT7WgERh7C8/+NyhWYNpE3BN69pxFyJIBcF7CxWz/+4A==", + "dev": true + }, "array-filter": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", @@ -19470,6 +20340,12 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", @@ -19626,6 +20502,25 @@ "unset-value": "^1.0.0" } }, + "cache-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz", + "integrity": "sha512-4gkeHlFpSKgm3vm2gJN5sPqfmijYRFYCQ6tv5cLw0xVmT6r1z1vd4FNnpuOREco3cBs1G709sZ72LdgddKvL5w==", + "dev": true, + "requires": { + "array-back": "^4.0.1", + "fs-then-native": "^2.0.0", + "mkdirp2": "^1.0.4" + }, + "dependencies": { + "array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true + } + } + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -19693,6 +20588,15 @@ "rsvp": "^4.8.4" } }, + "catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, "chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -19909,6 +20813,16 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "collect-all": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", + "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==", + "dev": true, + "requires": { + "stream-connect": "^1.0.2", + "stream-via": "^1.0.4" + } + }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -19970,12 +20884,91 @@ "dev": true, "peer": true }, + "command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A==", + "dev": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "dependencies": { + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true + } + } + }, + "command-line-tool": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", + "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==", + "dev": true, + "requires": { + "ansi-escape-sequences": "^4.0.0", + "array-back": "^2.0.0", + "command-line-args": "^5.0.0", + "command-line-usage": "^4.1.0", + "typical": "^2.6.1" + }, + "dependencies": { + "array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "requires": { + "typical": "^2.6.1" + } + } + } + }, + "command-line-usage": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz", + "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==", + "dev": true, + "requires": { + "ansi-escape-sequences": "^4.0.0", + "array-back": "^2.0.0", + "table-layout": "^0.4.2", + "typical": "^2.6.1" + }, + "dependencies": { + "array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "requires": { + "typical": "^2.6.1" + } + } + } + }, "commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true }, + "common-sequence": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", + "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -20041,12 +21034,29 @@ } } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "config-master": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz", + "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=", + "dev": true, + "requires": { + "walk-back": "^2.0.1" + }, + "dependencies": { + "walk-back": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz", + "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=", + "dev": true + } + } + }, "connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", @@ -20273,6 +21283,12 @@ "type-detect": "^4.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -20365,6 +21381,34 @@ "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", "dev": true }, + "dmd": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.0.0.tgz", + "integrity": "sha512-PwWZlqZnJPETwqZZ70haRa+UDZcD5jeBD3ywW1Kf+jYYv0MHu/S7Ri9jsSoeTMwkcMVW9hXOMA1IZUMEufBhOg==", + "dev": true, + "requires": { + "array-back": "^5.0.0", + "cache-point": "^2.0.0", + "common-sequence": "^2.0.0", + "file-set": "^4.0.1", + "handlebars": "^4.7.7", + "marked": "^2.0.0", + "object-get": "^2.1.1", + "reduce-flatten": "^3.0.0", + "reduce-unique": "^2.0.1", + "reduce-without": "^1.0.1", + "test-value": "^3.0.0", + "walk-back": "^5.0.0" + }, + "dependencies": { + "array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -20504,6 +21548,12 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, "envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -21443,6 +22493,24 @@ "flat-cache": "^3.0.4" } }, + "file-set": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/file-set/-/file-set-4.0.2.tgz", + "integrity": "sha512-fuxEgzk4L8waGXaAkd8cMr73Pm0FxOVkn8hztzUW7BAHhOGH90viQNXbiOsnecCWmfInqU6YmAMwxRMdKETceQ==", + "dev": true, + "requires": { + "array-back": "^5.0.0", + "glob": "^7.1.6" + }, + "dependencies": { + "array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true + } + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -21571,6 +22639,23 @@ } } }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "requires": { + "array-back": "^3.0.1" + }, + "dependencies": { + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + } + } + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -21676,6 +22761,12 @@ "universalify": "^0.1.0" } }, + "fs-then-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz", + "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -21812,6 +22903,19 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -23049,6 +24153,15 @@ "esprima": "^4.0.0" } }, + "js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.4" + } + }, "jsc-android": { "version": "250230.2.1", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250230.2.1.tgz", @@ -23216,6 +24329,97 @@ } } }, + "jsdoc": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", + "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", + "dev": true, + "requires": { + "@babel/parser": "^7.9.4", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.1", + "klaw": "^3.0.0", + "markdown-it": "^10.0.0", + "markdown-it-anchor": "^5.2.7", + "marked": "^2.0.3", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "taffydb": "2.6.2", + "underscore": "~1.13.1" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "jsdoc-api": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-7.1.0.tgz", + "integrity": "sha512-yjIiZa6LFOgd0dyFW/R+3unnVUhhbU1CeBhisgjBPRHkar83rkgDtTMRdgQotSvt+pGlmknZqfwR5AQuMh9/6w==", + "dev": true, + "requires": { + "array-back": "^6.2.0", + "cache-point": "^2.0.0", + "collect-all": "^1.0.4", + "file-set": "^4.0.2", + "fs-then-native": "^2.0.0", + "jsdoc": "^3.6.7", + "object-to-spawn-args": "^2.0.1", + "temp-path": "^1.0.0", + "walk-back": "^5.1.0" + } + }, + "jsdoc-parse": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.0.1.tgz", + "integrity": "sha512-ij3Az5y2dp+ajMxYnEJH7kjKK5v6+yZ3Cg/KtRdoT15pIm6qTk/W8q72QdNLZ9jQm/U2/ifENFXXTOe6xIxGeA==", + "dev": true, + "requires": { + "array-back": "^6.1.1", + "lodash.omit": "^4.5.0", + "lodash.pick": "^4.4.0", + "reduce-extract": "^1.0.0", + "sort-array": "^4.1.4", + "test-value": "^3.0.0" + } + }, + "jsdoc-to-markdown": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-7.1.0.tgz", + "integrity": "sha512-LJAiwrUaOpPqOmllqnVVqfBZh6KI/rHHfSwL7DerTpjLQWHfpndz/JUNlF5ngYjbL4aHNf7uJ1TuXl6xGfq5rg==", + "dev": true, + "requires": { + "array-back": "^6.2.0", + "command-line-tool": "^0.8.0", + "config-master": "^3.1.0", + "dmd": "^6.0.0", + "jsdoc-api": "^7.1.0", + "jsdoc-parse": "^6.0.1", + "walk-back": "^5.1.0" + } + }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -23442,6 +24646,15 @@ "immediate": "~3.0.5" } }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -23491,6 +24704,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -23504,6 +24723,24 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", + "dev": true + }, + "lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, "lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -23690,6 +24927,32 @@ "object-visit": "^1.0.0" } }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "dev": true, + "requires": {} + }, + "marked": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true + }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -23701,6 +24964,12 @@ "is-buffer": "~1.1.6" } }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -24655,6 +25924,12 @@ "minimist": "^1.2.5" } }, + "mkdirp2": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.5.tgz", + "integrity": "sha512-xOE9xbICroUDmG1ye2h4bZ8WBie9EGmACaco8K8cx6RlkJJrxGIqjGqztAI+NMhexXBcdGbSEzI6N3EJPevxZw==", + "dev": true + }, "mocha": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", @@ -25083,6 +26358,12 @@ } } }, + "object-get": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz", + "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==", + "dev": true + }, "object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -25095,6 +26376,12 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, + "object-to-spawn-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.1.tgz", + "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -26068,6 +27355,78 @@ "resolve": "^1.9.0" } }, + "reduce-extract": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", + "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=", + "dev": true, + "requires": { + "test-value": "^1.0.1" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + }, + "test-value": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz", + "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=", + "dev": true, + "requires": { + "array-back": "^1.0.2", + "typical": "^2.4.2" + } + } + } + }, + "reduce-flatten": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz", + "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==", + "dev": true + }, + "reduce-unique": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz", + "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==", + "dev": true + }, + "reduce-without": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz", + "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=", + "dev": true, + "requires": { + "test-value": "^2.0.0" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + }, + "test-value": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", + "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "dev": true, + "requires": { + "array-back": "^1.0.3", + "typical": "^2.6.0" + } + } + } + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -26216,6 +27575,15 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "requizzle": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", + "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -27105,6 +28473,30 @@ "debug": "~4.3.1" } }, + "sort-array": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.4.tgz", + "integrity": "sha512-GVFN6Y1sHKrWaSYOJTk9093ZnrBMc9sP3nuhANU44S4xg3rE6W5Z5WyamuT8VpMBbssnetx5faKCua0LEmUnSw==", + "dev": true, + "requires": { + "array-back": "^5.0.0", + "typical": "^6.0.1" + }, + "dependencies": { + "array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true + }, + "typical": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-6.0.1.tgz", + "integrity": "sha512-+g3NEp7fJLe9DPa1TArHm9QAA7YciZmWnfAqEaFrBihQ7epOv9i99rjtgb6Iz0wh3WuQDjsCTDfgRoGnmHN81A==", + "dev": true + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -27388,6 +28780,32 @@ "dev": true, "peer": true }, + "stream-connect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz", + "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=", + "dev": true, + "requires": { + "array-back": "^1.0.2" + }, + "dependencies": { + "array-back": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", + "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "dev": true, + "requires": { + "typical": "^2.6.0" + } + } + } + }, + "stream-via": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", + "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", + "dev": true + }, "streamroller": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", @@ -27604,6 +29022,36 @@ } } }, + "table-layout": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", + "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "deep-extend": "~0.6.0", + "lodash.padend": "^4.6.1", + "typical": "^2.6.1", + "wordwrapjs": "^3.0.0" + }, + "dependencies": { + "array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "requires": { + "typical": "^2.6.1" + } + } + } + }, + "taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -27630,6 +29078,12 @@ } } }, + "temp-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz", + "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=", + "dev": true + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -27689,6 +29143,27 @@ "minimatch": "^3.0.4" } }, + "test-value": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", + "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", + "dev": true, + "requires": { + "array-back": "^2.0.0", + "typical": "^2.6.1" + }, + "dependencies": { + "array-back": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", + "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "dev": true, + "requires": { + "typical": "^2.6.1" + } + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -27944,12 +29419,24 @@ "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", "dev": true }, + "typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + }, "ua-parser-js": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -27970,6 +29457,13 @@ } } }, + "uglify-js": { + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz", + "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==", + "dev": true, + "optional": true + }, "ultron": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", @@ -27989,6 +29483,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "underscore": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -28238,6 +29738,12 @@ "xml-name-validator": "^3.0.0" } }, + "walk-back": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz", + "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==", + "dev": true + }, "walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -28437,6 +29943,30 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wordwrapjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", + "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", + "dev": true, + "requires": { + "reduce-flatten": "^1.0.1", + "typical": "^2.6.1" + }, + "dependencies": { + "reduce-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", + "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", + "dev": true + } + } + }, "workerpool": { "version": "6.1.5", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", @@ -28520,6 +30050,12 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", diff --git a/package.json b/package.json index 01ca97a..c5590d2 100755 --- a/package.json +++ b/package.json @@ -53,6 +53,8 @@ "events": "^3.3.0", "jest": "^27.3.1", "jquery": "^3.6.0", + "jsdoc": "^3.6.7", + "jsdoc-to-markdown": "^7.1.0", "karma": "^6.3.2", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.0", @@ -84,7 +86,9 @@ "test:browser": "xvfb-maybe karma start karma.conf.local.js", "test:react-native": "jest test/react-native", "test:typings": "ts-node ./typings-tests.ts", - "prepublishOnly": "npm run build:browser" + "prepublishOnly": "npm run build:browser", + "generateDocs:markdown": "node jsdoc2md.js", + "generateDocs:html": "jsdoc -c jsdoc.conf.js -d docs-html --readme README.md lib/*.js browser-version/lib/*.js" }, "main": "index.js", "browser": { From c2651faebae1206be27fa953b6b9bde9687ce2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 6 Jan 2022 16:52:31 +0100 Subject: [PATCH 38/65] lint --- jsdoc2md.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsdoc2md.js b/jsdoc2md.js index 681b462..dea093c 100644 --- a/jsdoc2md.js +++ b/jsdoc2md.js @@ -22,9 +22,9 @@ fs.mkdirSync(outputDir) // make docs dir const templateData = jsdoc2md.getTemplateDataSync(getJsdocDataOptions) /* reduce templateData to an array of class names */ -const classNames = templateData.filter(({kind}) => kind === 'class').map(({name}) => name) +const classNames = templateData.filter(({ kind }) => kind === 'class').map(({ name }) => name) -const moduleNames = templateData.filter(({kind}) => kind === 'module').map(({name}) => name) +const moduleNames = templateData.filter(({ kind }) => kind === 'module').map(({ name }) => name) /* create a documentation file for each class */ for (const className of classNames) { From 3c60111c4848dbfa53b9784d3f711d40d03d45d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 6 Jan 2022 16:53:16 +0100 Subject: [PATCH 39/65] cleanup --- lib/waterfall.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/waterfall.js b/lib/waterfall.js index d44f8fc..b35e3cd 100644 --- a/lib/waterfall.js +++ b/lib/waterfall.js @@ -1,5 +1,6 @@ -require('../jsdoc.conf') - +/** + * Responsible for sequentially executing actions on the database + */ class Waterfall { /** * Instantiate a new Waterfall. From 8d628bfa6f031a5349dca0f1dc7c8b2f787c3d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 6 Jan 2022 17:58:18 +0100 Subject: [PATCH 40/65] cleanup JSDoc --- browser-version/lib/storage.browser.js | 41 ++++++---- browser-version/lib/storage.react-native.js | 39 +++++---- lib/executor.js | 17 ++-- lib/persistence.js | 88 ++++++++++++++------- lib/storage.js | 84 ++++++++++++-------- lib/utils.js | 12 ++- lib/waterfall.js | 2 +- package.json | 2 +- 8 files changed, 175 insertions(+), 110 deletions(-) diff --git a/browser-version/lib/storage.browser.js b/browser-version/lib/storage.browser.js index e2c3f35..b713a7d 100755 --- a/browser-version/lib/storage.browser.js +++ b/browser-version/lib/storage.browser.js @@ -1,10 +1,10 @@ /** * Way data is stored for this database - * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage) * - * This version is the browser version + * This version is the browser version and uses [localforage]{@link https://github.com/localForage/localForage} which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage). * @module storageBrowser + * @see module:storage + * @see module:storageReactNative */ const localforage = require('localforage') @@ -17,11 +17,14 @@ const store = localforage.createInstance({ }) /** - * Returns Promise if file exists + * Returns Promise if file exists. + * + * Async version of {@link module:storageBrowser.exists}. * @param {string} file * @return {Promise} * @async * @alias module:storageBrowser.existsAsync + * @see module:storageBrowser.exists */ const existsAsync = async file => { try { @@ -39,7 +42,7 @@ const existsAsync = async file => { */ /** - * Callback returns true if file exists + * Callback returns true if file exists. * @function * @param {string} file * @param {module:storageBrowser~existsCallback} cb @@ -48,12 +51,13 @@ const existsAsync = async file => { const exists = callbackify(existsAsync) /** - * Moves the item from one path to another + * Async version of {@link module:storageBrowser.rename}. * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storageBrowser.renameAsync * @async + * @see module:storageBrowser.rename */ const renameAsync = async (oldPath, newPath) => { try { @@ -80,13 +84,14 @@ const renameAsync = async (oldPath, newPath) => { const rename = callbackify(renameAsync) /** - * Saves the item at given path + * Async version of {@link module:storageBrowser.writeFile}. * @param {string} file * @param {string} data * @param {object} [options] * @return {Promise} * @alias module:storageBrowser.writeFileAsync * @async + * @see module:storageBrowser.writeFile */ const writeFileAsync = async (file, data, options) => { // Options do not matter in browser setup @@ -109,7 +114,7 @@ const writeFileAsync = async (file, data, options) => { const writeFile = callbackify(writeFileAsync) /** - * Append to the item at given path + * Async version of {@link module:storageBrowser.appendFile}. * @function * @param {string} filename * @param {string} toAppend @@ -117,6 +122,7 @@ const writeFile = callbackify(writeFileAsync) * @return {Promise} * @alias module:storageBrowser.appendFileAsync * @async + * @see module:storageBrowser.appendFile */ const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup @@ -140,13 +146,14 @@ const appendFileAsync = async (filename, toAppend, options) => { const appendFile = callbackify(appendFileAsync) /** - * Read data at given path + * Async version of {@link module:storageBrowser.readFile}. * @function * @param {string} filename * @param {object} [options] * @return {Promise} * @alias module:storageBrowser.readFileAsync * @async + * @see module:storageBrowser.readFile */ const readFileAsync = async (filename, options) => { try { @@ -167,12 +174,13 @@ const readFileAsync = async (filename, options) => { const readFile = callbackify(readFileAsync) /** - * Remove the data at given path + * Async version of {@link module:storageBrowser.unlink}. * @function * @param {string} filename * @return {Promise} * @async * @alias module:storageBrowser.unlinkAsync + * @see module:storageBrowser.unlink */ const unlinkAsync = async filename => { try { @@ -192,7 +200,7 @@ const unlinkAsync = async filename => { const unlink = callbackify(unlinkAsync) /** - * Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdirAsync}, nothing to do, no directories will be used on the browser. * @function * @param {string} path * @param {object} [options] @@ -202,7 +210,7 @@ const unlink = callbackify(unlinkAsync) */ const mkdirAsync = (path, options) => Promise.resolve() /** - * Shim for storage.mkdir, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdir}, nothing to do, no directories will be used on the browser. * @function * @param {string} path * @param {object} options @@ -212,8 +220,7 @@ const mkdirAsync = (path, options) => Promise.resolve() const mkdir = callbackify(mkdirAsync) /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the browser. * @param {string} filename * @return {Promise} * @alias module:storageBrowser.ensureDatafileIntegrityAsync @@ -221,8 +228,7 @@ const mkdir = callbackify(mkdirAsync) const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrity}, nothing to do, no data corruption possible in the browser. * @function * @param {string} filename * @param {NoParamCallback} callback signature: err @@ -231,11 +237,12 @@ const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Async version of {@link module:storageBrowser.crashSafeWriteFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storageBrowser.crashSafeWriteFileLinesAsync + * @see module:storageBrowser.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line diff --git a/browser-version/lib/storage.react-native.js b/browser-version/lib/storage.react-native.js index 6c5dbba..ca2c8d2 100755 --- a/browser-version/lib/storage.react-native.js +++ b/browser-version/lib/storage.react-native.js @@ -1,21 +1,22 @@ /** * Way data is stored for this database - * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) - * For a react-native database, we use @react-native-async-storage/async-storage * - * This version is the react-native version + * This version is the React-Native version and uses [@react-native-async-storage/async-storage]{@link https://github.com/react-native-async-storage/async-storage}. * @module storageReactNative + * @see module:storageBrowser + * @see module:storageReactNative */ + const AsyncStorage = require('@react-native-async-storage/async-storage').default const { callbackify } = require('util') // TODO: util is not a dependency, this would fail if util is not polyfilled /** - * Returns Promise if file exists + * Async version of {@link module:storageReactNative.exists}. * @param {string} file * @return {Promise} * @async * @alias module:storageReactNative.existsAsync + * @see module:storageReactNative.exists */ const existsAsync = async file => { try { @@ -41,12 +42,13 @@ const existsAsync = async file => { const exists = callbackify(existsAsync) /** - * Moves the item from one path to another + * Async version of {@link module:storageReactNative.rename}. * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storageReactNative.renameAsync * @async + * @see module:storageReactNative.rename */ const renameAsync = async (oldPath, newPath) => { try { @@ -73,13 +75,14 @@ const renameAsync = async (oldPath, newPath) => { const rename = callbackify(renameAsync) /** - * Saves the item at given path + * Async version of {@link module:storageReactNative.writeFile}. * @param {string} file * @param {string} data * @param {object} [options] * @return {Promise} * @alias module:storageReactNative.writeFileAsync * @async + * @see module:storageReactNative.writeFile */ const writeFileAsync = async (file, data, options) => { // Options do not matter in browser setup @@ -102,7 +105,7 @@ const writeFileAsync = async (file, data, options) => { const writeFile = callbackify(writeFileAsync) /** - * Append to the item at given path + * Async version of {@link module:storageReactNative.appendFile}. * @function * @param {string} filename * @param {string} toAppend @@ -110,6 +113,7 @@ const writeFile = callbackify(writeFileAsync) * @return {Promise} * @alias module:storageReactNative.appendFileAsync * @async + * @see module:storageReactNative.appendFile */ const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup @@ -133,13 +137,14 @@ const appendFileAsync = async (filename, toAppend, options) => { const appendFile = callbackify(appendFileAsync) /** - * Read data at given path + * Async version of {@link module:storageReactNative.readFile}. * @function * @param {string} filename * @param {object} [options] * @return {Promise} * @alias module:storageReactNative.readFileAsync * @async + * @see module:storageReactNative.readFile */ const readFileAsync = async (filename, options) => { try { @@ -161,12 +166,13 @@ const readFileAsync = async (filename, options) => { const readFile = callbackify(readFileAsync) /** - * Remove the data at given path + * Async version of {@link module:storageReactNative.unlink}. * @function * @param {string} filename * @return {Promise} * @async * @alias module:storageReactNative.unlinkAsync + * @see module:storageReactNative.unlink */ const unlinkAsync = async filename => { try { @@ -186,7 +192,7 @@ const unlinkAsync = async filename => { const unlink = callbackify(unlinkAsync) /** - * Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdirAsync}, nothing to do, no directories will be used on the browser. * @function * @param {string} dir * @param {object} [options] @@ -197,7 +203,7 @@ const unlink = callbackify(unlinkAsync) const mkdirAsync = (dir, options) => Promise.resolve() /** - * Shim for storage.mkdir, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdir}, nothing to do, no directories will be used on the browser. * @function * @param {string} path * @param {object} options @@ -207,8 +213,7 @@ const mkdirAsync = (dir, options) => Promise.resolve() const mkdir = callbackify(mkdirAsync) /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the browser. * @param {string} filename * @return {Promise} * @alias module:storageReactNative.ensureDatafileIntegrityAsync @@ -216,8 +221,7 @@ const mkdir = callbackify(mkdirAsync) const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrity}, nothing to do, no data corruption possible in the browser. * @function * @param {string} filename * @param {NoParamCallback} callback signature: err @@ -226,11 +230,12 @@ const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Async version of {@link module:storageReactNative.crashSafeWriteFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storageReactNative.crashSafeWriteFileLinesAsync + * @see module:storageReactNative.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line diff --git a/lib/executor.js b/lib/executor.js index 61f593f..531ced7 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -12,19 +12,19 @@ class Executor { /** * If this.ready is `false`, then every task pushed will be buffered until this.processBuffer is called. * @type {boolean} - * @protected + * @private */ this.ready = false /** * The main queue * @type {Waterfall} - * @protected + * @private */ this.queue = new Waterfall() /** * The buffer queue * @type {Waterfall} - * @protected + * @private */ this.buffer = new Waterfall() this.buffer.chain(new Promise(resolve => { @@ -33,7 +33,7 @@ class Executor { * * Do not be use directly, use `this.processBuffer` instead. * @function - * @protected + * @private */ this._triggerBuffer = resolve })) @@ -78,12 +78,15 @@ class Executor { } /** - * If executor is ready, queue task (and process it immediately if executor was idle) - * If not, buffer task for later processing - * @param {function(...*):Promise<*>} task + * Async version of {@link Executor#push}. + * This version is way simpler than its callbackEquivalent: you give it an async function `task`, it is executed when + * all the previous tasks are done, and then resolves or rejects and when it is finished with its original result or + * error. + * @param {AsyncFunction} task * @param {boolean} [forceQueuing = false] * @return {Promise<*>} * @async + * @see Executor#push */ pushAsync (task, forceQueuing = false) { if (this.ready || forceQueuing) return this.queue.waterfall(task)() diff --git a/lib/persistence.js b/lib/persistence.js index f3b4853..414a14e 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -15,8 +15,8 @@ class Persistence { * @param {Datastore} options.db * @param {Number} [options.corruptAlertThreshold] Optional, threshold after which an alert is thrown if too much data is corrupt * @param {string} [options.nodeWebkitAppName] Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion) - * @param {function} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and before it is written to disk. - * @param {function} [options.afterSerialization] Inverse of `afterSerialization`. + * @param {serializationHook} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and before it is written to disk. + * @param {serializationHook} [options.afterSerialization] Inverse of `afterSerialization`. */ constructor (options) { this.db = options.db @@ -64,19 +64,22 @@ class Persistence { * Persist cached database * This serves as a compaction function since the cache always contains only the number of documents in the collection * while the data file is append-only so it may grow larger - * This is an internal function, use compactDataFile which uses the executor - * @param {NoParamCallback} callback Optional callback, signature: err + * + * This is an internal function, use {@link Persistence#compactDatafile} which uses the [executor]{@link Datastore#executor}. + * @param {NoParamCallback} [callback = () => {}] + * @protected */ persistCachedDatabase (callback = () => {}) { return callbackify(this.persistCachedDatabaseAsync.bind(this))(callback) } /** - * Persist cached database - * This serves as a compaction function since the cache always contains only the number of documents in the collection - * while the data file is append-only so it may grow larger - * This is an internal function, use compactDataFileAsync which uses the executor + * Async version of {@link Persistence#persistCachedDatabase}. + * + * This is an internal function, use {@link Persistence#compactDatafileAsync} which uses the [executor]{@link Datastore#executor}. * @return {Promise} + * @protected + * @see Persistence#persistCachedDatabase */ async persistCachedDatabaseAsync () { const lines = [] @@ -104,23 +107,25 @@ class Persistence { /** * Queue a rewrite of the datafile - * @param {NoParamCallback} [callback = () => {}] Optional callback, signature: err + * @param {NoParamCallback} [callback = () => {}] + * @see Persistence#persistCachedDatabase */ compactDatafile (callback = () => {}) { this.db.executor.push({ this: this, fn: this.persistCachedDatabase, arguments: [callback] }) } /** - * Queue a rewrite of the datafile + * Async version of {@link Persistence#compactDatafile}. * @async + * @see Persistence#compactDatafile */ compactDatafileAsync () { return this.db.executor.pushAsync(() => this.persistCachedDatabaseAsync()) } /** - * Set automatic compaction every interval ms - * @param {Number} interval in milliseconds, with an enforced minimum of 5 seconds + * Set automatic compaction every `interval` ms + * @param {Number} interval in milliseconds, with an enforced minimum of 5000 milliseconds */ setAutocompactionInterval (interval) { const minInterval = 5000 @@ -134,7 +139,7 @@ class Persistence { } /** - * Stop autocompaction (do nothing if autocompaction was not running) + * Stop autocompaction (do nothing if automatic compaction was not running) */ stopAutocompaction () { if (this.autocompactionIntervalId) clearInterval(this.autocompactionIntervalId) @@ -143,18 +148,24 @@ class Persistence { /** * Persist new state for the given newDocs (can be insertion, update or removal) * Use an append-only format + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {string[]} newDocs Can be empty if no doc was updated/removed - * @param {NoParamCallback} [callback = () => {}] Optional, signature: err + * @param {NoParamCallback} [callback = () => {}] + * @protected */ persistNewState (newDocs, callback = () => {}) { callbackify(this.persistNewStateAsync.bind(this))(newDocs, err => callback(err)) } /** - * Persist new state for the given newDocs (can be insertion, update or removal) - * Use an append-only format + * Async version of {@link Persistence#persistNewState} + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {document[]} newDocs Can be empty if no doc was updated/removed * @return {Promise} + * @protected + * @see Persistence#persistNewState */ async persistNewStateAsync (newDocs) { let toPersist = '' @@ -179,9 +190,12 @@ class Persistence { */ /** - * From a database's raw data, return the corresponding machine understandable collection + * From a database's raw data, return the corresponding machine understandable collection. + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {string} rawData database file * @return {{data: document[], indexes: Object.}} + * @protected */ treatRawData (rawData) { const data = rawData.split('\n') @@ -218,13 +232,23 @@ class Persistence { /** * @callback Persistence~treatRawStreamCallback * @param {?Error} err - * @param {{data: document[], indexes: Object.}?} data + * @param {?object} data + * @param {document[]} data.data + * @param {Object.} data.indexes */ /** * From a database's raw data stream, return the corresponding machine understandable collection + * Is only used by a {@link Datastore} instance. + * + * Is only used in the Node.js version, since [React-Native]{@link module:storageReactNative} & + * [browser]{@link module:storageBrowser} storage modules don't provide an equivalent of + * {@link module:storage.readFileStream}. + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {Readable} rawStream * @param {Persistence~treatRawStreamCallback} cb + * @protected */ treatRawStream (rawStream, cb) { const dataById = {} @@ -270,10 +294,14 @@ class Persistence { } /** - * From a database's raw data stream, return the corresponding machine understandable collection + * Async version of {@link Persistence#treatRawStream}. + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {Readable} rawStream * @return {Promise<{data: document[], indexes: Object.}>} * @async + * @protected + * @see Persistence#treatRawStream */ treatRawStreamAsync (rawStream) { return promisify(this.treatRawStream.bind(this))(rawStream) @@ -284,24 +312,23 @@ class Persistence { * 1) Create all indexes * 2) Insert all data * 3) Compact the database + * * This means pulling data out of the data file or creating it if it doesn't exist * Also, all data is persisted right away, which has the effect of compacting the database file * This operation is very quick at startup for a big collection (60ms for ~10k docs) - * @param {NoParamCallback} callback Optional callback, signature: err + * + * Do not use directly as it does not use the [Executor]{@link Datastore.executor}, use {@link Datastore#loadDatabase} instead. + * @param {NoParamCallback} callback + * @protected */ loadDatabase (callback = () => {}) { callbackify(this.loadDatabaseAsync.bind(this))(err => callback(err)) } /** - * Load the database - * 1) Create all indexes - * 2) Insert all data - * 3) Compact the database - * This means pulling data out of the data file or creating it if it doesn't exist - * Also, all data is persisted right away, which has the effect of compacting the database file - * This operation is very quick at startup for a big collection (60ms for ~10k docs) + * Async version of {@link Persistence#loadDatabase} * @return {Promise} + * @see Persistence#loadDatabase */ async loadDatabaseAsync () { this.db.resetIndexes() @@ -339,18 +366,19 @@ class Persistence { } /** - * Check if a directory stat and create it on the fly if it is not the case + * Check if a directory stat and create it on the fly if it is not the case. * @param {string} dir - * @param {NoParamCallback} [callback = () => {}] optional callback, signature: err + * @param {NoParamCallback} [callback = () => {}] */ static ensureDirectoryExists (dir, callback = () => {}) { storage.mkdir(dir, { recursive: true }, err => { callback(err) }) } /** - * Check if a directory stat and create it on the fly if it is not the case + * Async version of {@link Persistence.ensureDirectoryExists}. * @param {string} dir * @return {Promise} + * @see Persistence.ensureDirectoryExists */ static async ensureDirectoryExistsAsync (dir) { await storage.mkdirAsync(dir, { recursive: true }) diff --git a/lib/storage.js b/lib/storage.js index 5022279..4cbcd26 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -1,11 +1,10 @@ /** - * Way data is stored for this database - * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) - * For a react-native database, we use @react-native-async-storage/async-storage + * Way data is stored for this database. + * This version is the Node.js/Node Webkit version. + * It's essentially fs, mkdirp and crash safe write and read functions. * - * This version is the Node.js/Node Webkit version - * It's essentially fs, mkdirp and crash safe write and read functions + * @see module:storageBrowser + * @see module:storageReactNative * @module storage */ const fs = require('fs') @@ -20,7 +19,7 @@ const { Readable } = require('stream') */ /** - * Callback returns true if file exists + * Callback returns true if file exists. * @param {string} file * @param {module:storage~existsCallback} cb * @alias module:storage.exists @@ -29,16 +28,17 @@ const { Readable } = require('stream') const exists = (file, cb) => fs.access(file, fs.constants.F_OK, (err) => { cb(!err) }) /** - * Returns Promise if file exists + * Async version of {@link module:storage.exists}. * @param {string} file * @return {Promise} * @async * @alias module:storage.existsAsync + * @see module:storage.exists */ const existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() => true, () => false) /** - * Node.js' fs.rename + * Node.js' [fs.rename]{@link https://nodejs.org/api/fs.html#fsrenameoldpath-newpath-callback}. * @function * @param {string} oldPath * @param {string} newPath @@ -49,18 +49,19 @@ const existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() = const rename = fs.rename /** - * Node.js' fs.promises.rename + * Async version of {@link module:storage.rename}. * @function * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storage.renameAsync * @async + * @see module:storage.rename */ const renameAsync = fsPromises.rename /** - * Node.js' fs.writeFile + * Node.js' [fs.writeFile]{@link https://nodejs.org/api/fs.html#fswritefilefile-data-options-callback}. * @function * @param {string} path * @param {string} data @@ -71,7 +72,7 @@ const renameAsync = fsPromises.rename const writeFile = fs.writeFile /** - * Node.js' fs.promises.writeFile + * Async version of {@link module:storage.writeFile}. * @function * @param {string} path * @param {string} data @@ -79,11 +80,12 @@ const writeFile = fs.writeFile * @return {Promise} * @alias module:storage.writeFileAsync * @async + * @see module:storage.writeFile */ const writeFileAsync = fsPromises.writeFile /** - * Node.js' fs.createWriteStream + * Node.js' [fs.createWriteStream]{@link https://nodejs.org/api/fs.html#fscreatewritestreampath-options}. * @function * @param {string} path * @param {Object} [options] @@ -93,7 +95,7 @@ const writeFileAsync = fsPromises.writeFile const writeFileStream = fs.createWriteStream /** - * Node.js' fs.unlink + * Node.js' [fs.unlink]{@link https://nodejs.org/api/fs.html#fsunlinkpath-callback}. * @function * @param {string} path * @param {function} callback @@ -102,17 +104,18 @@ const writeFileStream = fs.createWriteStream const unlink = fs.unlink /** - * Node.js' fs.promises.unlink + * Async version of {@link module:storage.unlink}. * @function * @param {string} path * @return {Promise} * @async * @alias module:storage.unlinkAsync + * @see module:storage.unlink */ const unlinkAsync = fsPromises.unlink /** - * Node.js' fs.appendFile + * Node.js' [fs.appendFile]{@link https://nodejs.org/api/fs.html#fsappendfilepath-data-options-callback}. * @function * @param {string} path * @param {string} data @@ -123,7 +126,7 @@ const unlinkAsync = fsPromises.unlink const appendFile = fs.appendFile /** - * Node.js' fs.promises.appendFile + * Async version of {@link module:storage.appendFile}. * @function * @param {string} path * @param {string} data @@ -131,10 +134,12 @@ const appendFile = fs.appendFile * @return {Promise} * @alias module:storage.appendFileAsync * @async + * @see module:storage.appendFile */ const appendFileAsync = fsPromises.appendFile + /** - * Node.js' fs.readFile + * Node.js' [fs.readFile]{@link https://nodejs.org/api/fs.html#fsreadfilepath-options-callback} * @function * @param {string} path * @param {object} options @@ -142,18 +147,21 @@ const appendFileAsync = fsPromises.appendFile * @alias module:storage.readFile */ const readFile = fs.readFile + /** - * Node.js' fs.promises.readFile + * Async version of {@link module:storage.readFile}. * @function * @param {string} path * @param {object} [options] * @return {Promise} * @alias module:storage.readFileAsync * @async + * @see module:storage.readFile */ const readFileAsync = fsPromises.readFile + /** - * Node.js' fs.createReadStream + * Node.js' [fs.createReadStream]{@link https://nodejs.org/api/fs.html#fscreatereadstreampath-options}. * @function * @param {string} path * @param {Object} [options] @@ -161,8 +169,9 @@ const readFileAsync = fsPromises.readFile * @alias module:storage.readFileStream */ const readFileStream = fs.createReadStream + /** - * Node.js' fs.mkdir + * Node.js' [fs.mkdir]{@link https://nodejs.org/api/fs.html#fsmkdirpath-options-callback}. * @function * @param {string} path * @param {object} options @@ -170,28 +179,33 @@ const readFileStream = fs.createReadStream * @alias module:storage.mkdir */ const mkdir = fs.mkdir + /** - * Node.js' fs.promises.mkdir + * Async version of {@link module:storage.mkdir}. * @function * @param {string} path * @param {object} options * @return {Promise} * @alias module:storage.mkdirAsync * @async + * @see module:storage.mkdir */ const mkdirAsync = fsPromises.mkdir /** + * Async version of {@link module:storage.ensureFileDoesntExist} * @param {string} file * @return {Promise} * @alias module:storage.ensureFileDoesntExistAsync * @async + * @see module:storage.ensureFileDoesntExist */ const ensureFileDoesntExistAsync = async file => { if (await existsAsync(file)) await unlinkAsync(file) } /** + * Removes file if it exists. * @param {string} file * @param {NoParamCallback} callback * @alias module:storage.ensureFileDoesntExist @@ -199,7 +213,7 @@ const ensureFileDoesntExistAsync = async file => { const ensureFileDoesntExist = (file, callback) => callbackify(ensureFileDoesntExistAsync)(file, err => callback(err)) /** - * Flush data in OS buffer to storage if corresponding option is set + * Flush data in OS buffer to storage if corresponding option is set. * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested * @param {string} [options.filename] * @param {boolean} [options.isDir = false] Optional, defaults to false @@ -209,13 +223,14 @@ const ensureFileDoesntExist = (file, callback) => callbackify(ensureFileDoesntEx const flushToStorage = (options, callback) => callbackify(flushToStorageAsync)(options, callback) /** - * Flush data in OS buffer to storage if corresponding option is set - * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested + * Async version of {@link module:storage.flushToStorage}. + * @param {object|string} options * @param {string} [options.filename] - * @param {boolean} [options.isDir = false] Optional, defaults to false + * @param {boolean} [options.isDir = false] * @return {Promise} * @alias module:storage.flushToStorageAsync * @async + * @see module:storage.flushToStorage */ const flushToStorageAsync = async (options) => { let filename @@ -266,10 +281,10 @@ const flushToStorageAsync = async (options) => { } /** - * Fully write or rewrite the datafile + * Fully write or rewrite the datafile. * @param {string} filename * @param {string[]} lines - * @param {NoParamCallback} callback + * @param {NoParamCallback} [callback = () => {}] * @alias module:storage.writeFileLines */ const writeFileLines = (filename, lines, callback = () => {}) => { @@ -293,17 +308,18 @@ const writeFileLines = (filename, lines, callback = () => {}) => { } } /** - * Fully write or rewrite the datafile + * Async version of {@link module:storage.writeFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storage.writeFileLinesAsync * @async + * @see module:storage.writeFileLines */ const writeFileLinesAsync = (filename, lines) => promisify(writeFileLines)(filename, lines) /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost). * @param {string} filename * @param {string[]} lines * @param {NoParamCallback} [callback] Optional callback, signature: err @@ -313,11 +329,12 @@ const crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { callbackify(crashSafeWriteFileLinesAsync)(filename, lines, callback) } /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Async version of {@link module:storage.crashSafeWriteFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storage.crashSafeWriteFileLinesAsync + * @see module:storage.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { const tempFilename = filename + '~' @@ -337,7 +354,7 @@ const crashSafeWriteFileLinesAsync = async (filename, lines) => { } /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Ensure the datafile contains all the data, even if there was a crash during a full file write. * @param {string} filename * @param {NoParamCallback} callback signature: err * @alias module:storage.ensureDatafileIntegrity @@ -345,10 +362,11 @@ const crashSafeWriteFileLinesAsync = async (filename, lines) => { const ensureDatafileIntegrity = (filename, callback) => callbackify(ensureDatafileIntegrityAsync)(filename, callback) /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Async version of {@link module:storage.ensureDatafileIntegrity}. * @param {string} filename * @return {Promise} * @alias module:storage.ensureDatafileIntegrityAsync + * @see module:storage.ensureDatafileIntegrity */ const ensureDatafileIntegrityAsync = async filename => { const tempFilename = filename + '~' diff --git a/lib/utils.js b/lib/utils.js index 1700790..ac64bf6 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -9,7 +9,8 @@ * Produces a duplicate-free version of the array, using === to test object equality. In particular only the first * occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee * function. - * Heavily inspired by https://underscorejs.org/#uniq + * + * Heavily inspired by {@link https://underscorejs.org/#uniq}. * @param {Array} array * @param {function} [iteratee] transformation applied to every element before checking for duplicates. This will not * transform the items in the result. @@ -23,7 +24,8 @@ const uniq = (array, iteratee) => { /** * Returns true if arg is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings * and numbers are not. - * Heavily inspired by https://underscorejs.org/#isObject + * + * Heavily inspired by {@link https://underscorejs.org/#isObject}. * @param {*} arg * @return {boolean} */ @@ -31,7 +33,8 @@ const isObject = arg => typeof arg === 'object' && arg !== null /** * Returns true if d is a Date. - * Heavily inspired by https://underscorejs.org/#isDate + * + * Heavily inspired by {@link https://underscorejs.org/#isDate}. * @param {*} d * @return {boolean} * @alias module:utils.isDate @@ -40,7 +43,8 @@ const isDate = d => isObject(d) && Object.prototype.toString.call(d) === '[objec /** * Returns true if re is a RegExp. - * Heavily inspired by https://underscorejs.org/#isRegExp + * + * Heavily inspired by {@link https://underscorejs.org/#isRegExp}. * @param {*} re * @return {boolean} * @alias module:utils.isRegExp diff --git a/lib/waterfall.js b/lib/waterfall.js index b35e3cd..fab25b4 100644 --- a/lib/waterfall.js +++ b/lib/waterfall.js @@ -13,7 +13,7 @@ class Waterfall { * * Use {@link Waterfall#guardian} instead which retrievethe latest version of the guardian. * @type {Promise} - * @protected + * @private */ this._guardian = Promise.resolve() } diff --git a/package.json b/package.json index c5590d2..4b38f34 100755 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "test:typings": "ts-node ./typings-tests.ts", "prepublishOnly": "npm run build:browser", "generateDocs:markdown": "node jsdoc2md.js", - "generateDocs:html": "jsdoc -c jsdoc.conf.js -d docs-html --readme README.md lib/*.js browser-version/lib/*.js" + "generateDocs:html": "jsdoc -c jsdoc.conf.js -d docs-html --readme README.md" }, "main": "index.js", "browser": { From 5d8b23a69d842fd410053b4e0ba9eb6086e18bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 7 Jan 2022 05:20:26 +0100 Subject: [PATCH 41/65] cleanup JSDOC & generate md + html, md is pushed in the repo --- docs/Cursor.md | 122 +++++----- docs/Datastore.md | 454 +++++++++++++++++++++++++------------ docs/Executor.md | 61 ++--- docs/Index.md | 61 +++-- docs/Persistence.md | 165 +++++++------- docs/Waterfall.md | 22 +- docs/customUtilsBrowser.md | 10 +- docs/customUtilsNode.md | 10 +- docs/globals.md | 155 +++++++++++++ docs/model.md | 73 +++--- docs/storage.md | 289 ++++++++++++----------- docs/storageBrowser.md | 190 ++++++++-------- docs/storageReactNative.md | 188 +++++++-------- docs/utils.md | 39 ++-- jsdoc2md.js | 31 ++- lib/cursor.js | 77 +++++-- lib/datastore.js | 218 +++++++++--------- lib/persistence.js | 1 - 18 files changed, 1237 insertions(+), 929 deletions(-) create mode 100644 docs/globals.md diff --git a/docs/Cursor.md b/docs/Cursor.md index d3303f5..cf07df1 100644 --- a/docs/Cursor.md +++ b/docs/Cursor.md @@ -2,14 +2,17 @@ ## Cursor ⇐ Promise

Manage access to data, be it to find, update or remove it.

-

It extends Promise so that its methods are chainable & awaitable.

+

It extends Promise so that its methods (which return this) are chainable & awaitable.

**Kind**: global class **Extends**: Promise * [Cursor](#Cursor) ⇐ Promise - * [new Cursor(db, query, [execFn], [async])](#new_Cursor_new) + * [new Cursor(db, query, [execFn], [hasCallback])](#new_Cursor_new) * _instance_ + * [.db](#Cursor+db) : [Datastore](#Datastore) + * [.query](#Cursor+query) : [query](#query) + * [.hasCallback](#Cursor+hasCallback) : boolean * [.limit(limit)](#Cursor+limit) ⇒ [Cursor](#Cursor) * [.skip(skip)](#Cursor+skip) ⇒ [Cursor](#Cursor) * [.sort(sortQuery)](#Cursor+sort) ⇒ [Cursor](#Cursor) @@ -20,33 +23,48 @@ * [.exec(_callback)](#Cursor+exec) * [.execAsync()](#Cursor+execAsync) ⇒ Promise.<(Array.<document>\|\*)> * _inner_ - * [~execFn](#Cursor..execFn) : function - * [~execFnAsync](#Cursor..execFnAsync) ⇒ Promise + * [~execFnWithCallback](#Cursor..execFnWithCallback) : function + * [~execFnWithoutCallback](#Cursor..execFnWithoutCallback) ⇒ Promise \| \* * [~execCallback](#Cursor..execCallback) : function -### new Cursor(db, query, [execFn], [async]) +### new Cursor(db, query, [execFn], [hasCallback])

Create a new cursor for this collection

+**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| db | [Datastore](#Datastore) | |

The datastore this cursor is bound to

| -| query | [query](#query) | |

The query this cursor will operate on

| -| [execFn] | [execFn](#Cursor..execFn) \| [execFnAsync](#Cursor..execFnAsync) | |

Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove

| -| [async] | boolean | false |

If true, specifies that the execFn is of type [execFnAsync](#Cursor..execFnAsync) rather than [execFn](#Cursor..execFn).

| +- db [Datastore](#Datastore) -

The datastore this cursor is bound to

+- query [query](#query) -

The query this cursor will operate on

+- [execFn] [execFnWithoutCallback](#Cursor..execFnWithoutCallback) | [execFnWithCallback](#Cursor..execFnWithCallback) -

Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove

+- [hasCallback] boolean = true -

If false, specifies that the execFn is of type [execFnWithoutCallback](#Cursor..execFnWithoutCallback) rather than [execFnWithCallback](#Cursor..execFnWithCallback).

+ + +### cursor.db : [Datastore](#Datastore) +**Kind**: instance property of [Cursor](#Cursor) +**Access**: protected + + +### cursor.query : [query](#query) +**Kind**: instance property of [Cursor](#Cursor) +**Access**: protected + + +### cursor.hasCallback : boolean +

Determines if the [Cursor#execFn](Cursor#execFn) is an [execFnWithoutCallback](#Cursor..execFnWithoutCallback) or not.

+ +**Kind**: instance property of [Cursor](#Cursor) +**Access**: protected ### cursor.limit(limit) ⇒ [Cursor](#Cursor)

Set a limit to the number of results

**Kind**: instance method of [Cursor](#Cursor) +**Params** -| Param | Type | -| --- | --- | -| limit | Number | +- limit Number @@ -54,10 +72,9 @@

Skip a number of results

**Kind**: instance method of [Cursor](#Cursor) +**Params** -| Param | Type | -| --- | --- | -| skip | Number | +- skip Number @@ -65,10 +82,9 @@

Sort results of the query

**Kind**: instance method of [Cursor](#Cursor) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| sortQuery | Object.<string, number> |

sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending

| +- sortQuery Object.<string, number> -

sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending

@@ -76,21 +92,22 @@

Add the use of a projection

**Kind**: instance method of [Cursor](#Cursor) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| projection | Object.<string, number> |

MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 { key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits.

| +- projection Object.<string, number> -

MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 +{ key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits.

### cursor.project(candidates) ⇒ [Array.<document>](#document) -

Apply the projection

+

Apply the projection.

+

This is an internal function. You should use [execAsync](#Cursor+execAsync) or [exec](#Cursor+exec).

**Kind**: instance method of [Cursor](#Cursor) +**Access**: protected +**Params** -| Param | Type | -| --- | --- | -| candidates | [Array.<document>](#document) | +- candidates [Array.<document>](#document) @@ -104,14 +121,15 @@ This is an internal function, use execAsync which uses the executor

### cursor.\_exec(_callback)

Get all matching elements -Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne -This is an internal function, use exec which uses the executor

+Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

+

This is an internal function, use [exec](#Cursor+exec) which uses the [executor](#Datastore+executor).

**Kind**: instance method of [Cursor](#Cursor) +**Access**: protected +**See**: Cursor#exec +**Params** -| Param | Type | -| --- | --- | -| _callback | [execCallback](#Cursor..execCallback) | +- _callback [execCallback](#Cursor..execCallback) @@ -120,44 +138,44 @@ This is an internal function, use exec which uses the executor

Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

**Kind**: instance method of [Cursor](#Cursor) +**Params** -| Param | Type | -| --- | --- | -| _callback | [execCallback](#Cursor..execCallback) | +- _callback [execCallback](#Cursor..execCallback) ### cursor.execAsync() ⇒ Promise.<(Array.<document>\|\*)> -

Get all matching elements -Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

+

Async version of [exec](#Cursor+exec).

**Kind**: instance method of [Cursor](#Cursor) - +**See**: Cursor#exec + + +### Cursor~execFnWithCallback : function +

Has a callback

-### Cursor~execFn : function **Kind**: inner typedef of [Cursor](#Cursor) +**Params** + +- err Error +- res [?Array.<document>](#document) | [document](#document) -| Param | Type | -| --- | --- | -| err | Error | -| res | [?Array.<document>](#document) \| [document](#document) | + - +### Cursor~execFnWithoutCallback ⇒ Promise \| \* +

Does not have a callback, may return a Promise.

-### Cursor~execFnAsync ⇒ Promise **Kind**: inner typedef of [Cursor](#Cursor) +**Params** -| Param | Type | -| --- | --- | -| res | [?Array.<document>](#document) \| [document](#document) | +- res [?Array.<document>](#document) | [document](#document) ### Cursor~execCallback : function **Kind**: inner typedef of [Cursor](#Cursor) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| err | Error | | -| res | [Array.<document>](#document) \| \* |

If an execFn was given to the Cursor, then the type of this parameter is the one returned by the execFn.

| +- err Error +- res [Array.<document>](#document) | \* -

If an execFn was given to the Cursor, then the type of this parameter is the one returned by the execFn.

diff --git a/docs/Datastore.md b/docs/Datastore.md index 83ca95b..25aef46 100644 --- a/docs/Datastore.md +++ b/docs/Datastore.md @@ -5,37 +5,46 @@ **Kind**: global class **Extends**: EventEmitter -**Emits**: Datastore.event:"compaction.done" +**Emits**: Datastore#event:"compaction.done" * [Datastore](#Datastore) ⇐ EventEmitter * [new Datastore(options)](#new_Datastore_new) * _instance_ + * [.inMemoryOnly](#Datastore+inMemoryOnly) : boolean + * [.autoload](#Datastore+autoload) : boolean + * [.timestampData](#Datastore+timestampData) : boolean + * [.filename](#Datastore+filename) : string * [.persistence](#Datastore+persistence) : [Persistence](#Persistence) * [.executor](#Datastore+executor) : [Executor](#Executor) + * [.indexes](#Datastore+indexes) : Object.<string, Index> + * [.ttlIndexes](#Datastore+ttlIndexes) : Object.<string, number> * [.autoloadPromise](#Datastore+autoloadPromise) : Promise + * [.compareStrings()](#Datastore+compareStrings) : [compareStrings](#compareStrings) * [.loadDatabase(callback)](#Datastore+loadDatabase) * [.loadDatabaseAsync()](#Datastore+loadDatabaseAsync) ⇒ Promise * [.getAllData()](#Datastore+getAllData) ⇒ [Array.<document>](#document) - * [.resetIndexes()](#Datastore+resetIndexes) + * [.resetIndexes(newData)](#Datastore+resetIndexes) * [.ensureIndex(options, callback)](#Datastore+ensureIndex) * [.ensureIndexAsync(options)](#Datastore+ensureIndexAsync) ⇒ Promise.<void> * [.removeIndex(fieldName, callback)](#Datastore+removeIndex) * [.removeIndexAsync(fieldName)](#Datastore+removeIndexAsync) ⇒ Promise.<void> + * [.addToIndexes(doc)](#Datastore+addToIndexes) * [.removeFromIndexes(doc)](#Datastore+removeFromIndexes) * [.updateIndexes(oldDoc, [newDoc])](#Datastore+updateIndexes) + * [.getCandidates(query, [dontExpireStaleDocs], callback)](#Datastore+getCandidates) + * [.getCandidatesAsync(query, [dontExpireStaleDocs])](#Datastore+getCandidatesAsync) ⇒ Promise.<Array.<document>> * [.insertAsync(newDoc)](#Datastore+insertAsync) ⇒ [Promise.<document>](#document) * [.count(query, [callback])](#Datastore+count) ⇒ Cursor.<number> \| undefined * [.countAsync(query)](#Datastore+countAsync) ⇒ Cursor.<number> * [.find(query, [projection], [callback])](#Datastore+find) ⇒ Cursor.<Array.<document>> \| undefined * [.findAsync(query, [projection])](#Datastore+findAsync) ⇒ Cursor.<Array.<document>> - * [.findOne(query, projection, callback)](#Datastore+findOne) ⇒ [Cursor.<document>](#document) \| undefined + * [.findOne(query, [projection], [callback])](#Datastore+findOne) ⇒ [Cursor.<document>](#document) \| undefined * [.findOneAsync(query, projection)](#Datastore+findOneAsync) ⇒ [Cursor.<document>](#document) - * [.update(query, update, [options], [cb])](#Datastore+update) + * [.update(query, update, [options|], [cb])](#Datastore+update) * [.updateAsync(query, update, [options])](#Datastore+updateAsync) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> * [.remove(query, [options], [cb])](#Datastore+remove) * [.removeAsync(query, [options])](#Datastore+removeAsync) ⇒ Promise.<number> - * _static_ - * ["event:compaction.done"](#Datastore.event_compaction.done) + * ["event:compaction.done"](#Datastore+event_compaction.done) * _inner_ * [~countCallback](#Datastore..countCallback) : function * [~findOneCallback](#Datastore..findOneCallback) : function @@ -51,21 +60,76 @@ function fetches the data from datafile and prepares the database. Don't datastore, no command (insert, find, update, remove) will be executed before loadDatabase is called, so make sure to call it yourself or use the autoload option.

+**Params** + +- options object | string -

Can be an object or a string. If options is a string, the behavior is the same as in +v0.6: it will be interpreted as options.filename. Giving a string is deprecated, and will be removed in the +next major version.

+ - [.filename] string = null -

Path to the file where the data is persisted. If left blank, the datastore is +automatically considered in-memory only. It cannot end with a ~ which is used in the temporary files NeDB uses to +perform crash-safe writes.

+ - [.inMemoryOnly] boolean = false -

If set to true, no data will be written in storage.

+ - [.timestampData] boolean = false -

If set to true, createdAt and updatedAt will be created and +populated automatically (if not specified by user)

+ - [.autoload] boolean = false -

If used, the database will automatically be loaded from the datafile +upon creation (you don't need to call loadDatabase). Any command issued before load is finished is buffered and +will be executed when load is done. When autoloading is done, you can either use the onload callback, or you can +use this.autoloadPromise which resolves (or rejects) when autloading is done.

+ - [.onload] function -

If you use autoloading, this is the handler called after the loadDatabase. It +takes one error argument. If you use autoloading without specifying this handler, and an error happens during +load, an error will be thrown.

+ - [.beforeDeserialization] function -

Hook you can use to transform data after it was serialized and +before it is written to disk. Can be used for example to encrypt data before writing database to disk. This +function takes a string as parameter (one line of an NeDB data file) and outputs the transformed string, which +must absolutely not contain a \n character (or data will be lost).

+ - [.afterSerialization] function -

Inverse of afterSerialization. Make sure to include both and not +just one, or you risk data loss. For the same reason, make sure both functions are inverses of one another. Some +failsafe mechanisms are in place to prevent data loss if you misuse the serialization hooks: NeDB checks that never +one is declared without the other, and checks that they are reverse of one another by testing on random strings of +various lengths. In addition, if too much data is detected as corrupt, NeDB will refuse to start as it could mean +you're not using the deserialization hook corresponding to the serialization hook used before.

+ - [.corruptAlertThreshold] number = 0.1 -

Between 0 and 1, defaults to 10%. NeDB will refuse to start +if more than this percentage of the datafile is corrupt. 0 means you don't tolerate any corruption, 1 means you +don't care.

+ - [.compareStrings] [compareStrings](#compareStrings) -

If specified, it overrides default string comparison which is not +well adapted to non-US characters in particular accented letters. Native localCompare will most of the time be +the right choice.

+ - [.nodeWebkitAppName] string -

Deprecated: if you are using NeDB from whithin a Node Webkit app, +specify its name (the same one you use in the package.json) in this field and the filename will be relative to +the directory Node Webkit uses to store the rest of the application's data (local storage etc.). It works on Linux, +OS X and Windows. Now that you can use require('nw.gui').App.dataPath in Node Webkit to get the path to the data +directory for your application, you should not use this option anymore and it will be removed.

+ + + +### datastore.inMemoryOnly : boolean +

Determines if the Datastore keeps data in-memory, or if it saves it in storage. Is not read after +instanciation.

-| Param | Type | Default | Description | -| --- | --- | --- | --- | -| options | object \| string | |

Can be an object or a string. If options is a string, the behavior is the same as in v0.6: it will be interpreted as options.filename. Giving a string is deprecated, and will be removed in the next major version.

| -| [options.filename] | string | null |

Path to the file where the data is persisted. If left blank, the datastore is automatically considered in-memory only. It cannot end with a ~ which is used in the temporary files NeDB uses to perform crash-safe writes.

| -| [options.inMemoryOnly] | boolean | false |

If set to true, no data will be written in storage.

| -| [options.timestampData] | boolean | false |

If set to true, createdAt and updatedAt will be created and populated automatically (if not specified by user)

| -| [options.autoload] | boolean | false |

If used, the database will automatically be loaded from the datafile upon creation (you don't need to call loadDatabase). Any command issued before load is finished is buffered and will be executed when load is done. When autoloading is done, you can either use the onload callback, or you can use this.autoloadPromise which resolves (or rejects) when autloading is done.

| -| [options.onload] | function | |

If you use autoloading, this is the handler called after the loadDatabase. It takes one error argument. If you use autoloading without specifying this handler, and an error happens during load, an error will be thrown.

| -| [options.beforeDeserialization] | function | |

Hook you can use to transform data after it was serialized and before it is written to disk. Can be used for example to encrypt data before writing database to disk. This function takes a string as parameter (one line of an NeDB data file) and outputs the transformed string, which must absolutely not contain a \n character (or data will be lost).

| -| [options.afterSerialization] | function | |

Inverse of afterSerialization. Make sure to include both and not just one, or you risk data loss. For the same reason, make sure both functions are inverses of one another. Some failsafe mechanisms are in place to prevent data loss if you misuse the serialization hooks: NeDB checks that never one is declared without the other, and checks that they are reverse of one another by testing on random strings of various lengths. In addition, if too much data is detected as corrupt, NeDB will refuse to start as it could mean you're not using the deserialization hook corresponding to the serialization hook used before.

| -| [options.corruptAlertThreshold] | number | 0.1 |

Between 0 and 1, defaults to 10%. NeDB will refuse to start if more than this percentage of the datafile is corrupt. 0 means you don't tolerate any corruption, 1 means you don't care.

| -| [options.compareStrings] | [compareStrings](#compareStrings) | |

If specified, it overrides default string comparison which is not well adapted to non-US characters in particular accented letters. Native localCompare will most of the time be the right choice.

| -| [options.nodeWebkitAppName] | string | |

Deprecated: if you are using NeDB from whithin a Node Webkit app, specify its name (the same one you use in the package.json) in this field and the filename will be relative to the directory Node Webkit uses to store the rest of the application's data (local storage etc.). It works on Linux, OS X and Windows. Now that you can use require('nw.gui').App.dataPath in Node Webkit to get the path to the data directory for your application, you should not use this option anymore and it will be removed.

| +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### datastore.autoload : boolean +

Determines if the Datastore should autoload the database upon instantiation. Is not read after instanciation.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### datastore.timestampData : boolean +

Determines if the Datastore should add createdAt and updatedAt fields automatically if not set by the user.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + +### datastore.filename : string +

If null, it means inMemoryOnly is true. The filename is the name given to the storage module. Is not read +after instanciation.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected ### datastore.persistence : [Persistence](#Persistence) @@ -80,6 +144,23 @@ produced by the Datastore and by this.persistence.compactData to ensure operations are performed sequentially in the database.

**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### datastore.indexes : Object.<string, Index> +

Indexed by field name, dot notation can be used. +_id is always indexed and since _ids are generated randomly the underlying binary search tree is always well-balanced

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### datastore.ttlIndexes : Object.<string, number> +

Stores the time to live (TTL) of the indexes created. The key represents the field name, the value the number of +seconds after which data with this index field should be removed.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected ### datastore.autoloadPromise : Promise @@ -87,35 +168,47 @@ to ensure operations are performed sequentially in the database.

The onload callback is not awaited by this Promise, it is started immediately after that.

**Kind**: instance property of [Datastore](#Datastore) + + +### datastore.compareStrings() : [compareStrings](#compareStrings) +

Overrides default string comparison which is not well adapted to non-US characters in particular accented +letters. Native localCompare will most of the time be the right choice

+ +**Kind**: instance method of [Datastore](#Datastore) +**Access**: protected ### datastore.loadDatabase(callback)

Load the database from the datafile, and trigger the execution of buffered commands if any.

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | -| --- | --- | -| callback | function | +- callback function ### datastore.loadDatabaseAsync() ⇒ Promise -

Load the database from the datafile, and trigger the execution of buffered commands if any.

+

Async version of [loadDatabase](#Datastore+loadDatabase).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#loadDatabase ### datastore.getAllData() ⇒ [Array.<document>](#document) -

Get an array of all the data in the database

+

Get an array of all the data in the database.

**Kind**: instance method of [Datastore](#Datastore) -### datastore.resetIndexes() -

Reset all currently defined indexes

+### datastore.resetIndexes(newData) +

Reset all currently defined indexes.

**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- newData [document](#document) | [?Array.<document>](#document) + ### datastore.ensureIndex(options, callback) @@ -125,33 +218,29 @@ executor. Previous versions said explicitly the callback was optional, it is now recommended setting one.

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| options | object | | | -| options.fieldName | string | |

Name of the field to index. Use the dot notation to index a field in a nested document.

| -| [options.unique] | boolean | false |

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

| -| [options.sparse] | boolean | false |

don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

| -| [options.expireAfterSeconds] | number | |

if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

| -| callback | [NoParamCallback](#NoParamCallback) | |

Callback, signature: err

| +- options object + - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

+ - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

+ - [.sparse] boolean = false -

don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

+ - [.expireAfterSeconds] number -

if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

+- callback [NoParamCallback](#NoParamCallback) -

Callback, signature: err

### datastore.ensureIndexAsync(options) ⇒ Promise.<void> -

Ensure an index is kept for this field. Same parameters as lib/indexes -This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the -executor. -Previous versions said explicitly the callback was optional, it is now recommended setting one.

+

Async version of [ensureIndex](#Datastore+ensureIndex).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#ensureIndex +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| options | object | | | -| options.fieldName | string | |

Name of the field to index. Use the dot notation to index a field in a nested document.

| -| [options.unique] | boolean | false |

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

| -| [options.sparse] | boolean | false |

Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

| -| [options.expireAfterSeconds] | number | |

If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

| +- options object + - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

+ - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

+ - [.sparse] boolean = false -

Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

+ - [.expireAfterSeconds] number -

If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

@@ -160,84 +249,131 @@ Previous versions said explicitly the callback was optional, it is now recommend Previous versions said explicitly the callback was optional, it is now recommended setting one.

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| fieldName | string |

Field name of the index to remove. Use the dot notation to remove an index referring to a field in a nested document.

| -| callback | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| +- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a +field in a nested document.

+- callback [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

### datastore.removeIndexAsync(fieldName) ⇒ Promise.<void> -

Remove an index -Previous versions said explicitly the callback was optional, it is now recommended setting one.

+

Async version of [removeIndex](#Datastore+removeIndex).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#removeIndex +**Params** + +- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a +field in a nested document.

+ + + +### datastore.addToIndexes(doc) +

Add one or several document(s) to all indexes.

+

This is an internal function.

**Kind**: instance method of [Datastore](#Datastore) +**Access**: protected +**Params** -| Param | Type | Description | -| --- | --- | --- | -| fieldName | string |

Field name of the index to remove. Use the dot notation to remove an index referring to a field in a nested document.

| +- doc [document](#document) ### datastore.removeFromIndexes(doc) -

Remove one or several document(s) from all indexes

+

Remove one or several document(s) from all indexes.

+

This is an internal function.

**Kind**: instance method of [Datastore](#Datastore) +**Access**: protected +**Params** -| Param | Type | -| --- | --- | -| doc | [document](#document) | +- doc [document](#document) ### datastore.updateIndexes(oldDoc, [newDoc]) -

Update one or several documents in all indexes -To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs -If one update violates a constraint, all changes are rolled back

+

Update one or several documents in all indexes.

+

To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs.

+

If one update violates a constraint, all changes are rolled back.

+

This is an internal function.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- oldDoc [document](#document) | Array.<{oldDoc: document, newDoc: document}> -

Document to update, or an Array of +{oldDoc, newDoc} pairs.

+- [newDoc] [document](#document) -

Document to replace the oldDoc with. If the first argument is an Array of +{oldDoc, newDoc} pairs, this second argument is ignored.

+ + + +### datastore.getCandidates(query, [dontExpireStaleDocs], callback) +

Return the list of candidates for a given query +Crude implementation for now, we return the candidates given by the first usable index if any +We try the following query types, in this order: basic match, $in match, comparison match +One way to make it better would be to enable the use of multiple indexes if the first usable index +returns too much data. I may do it in the future.

+

Returned candidates will be scanned to find and remove all expired documents

+

This is an internal function.

**Kind**: instance method of [Datastore](#Datastore) +**Access**: protected +**Params** -| Param | Type | Description | -| --- | --- | --- | -| oldDoc | [document](#document) \| Array.<{oldDoc: document, newDoc: document}> |

Document to update, or an Array of {oldDoc, newDoc} pairs.

| -| [newDoc] | [document](#document) |

Document to replace the oldDoc with. If the first argument is an Array of {oldDoc, newDoc} pairs, this second argument is ignored.

| +- query [query](#query) +- [dontExpireStaleDocs] boolean | function = false -

If true don't remove stale docs. Useful for the remove +function which shouldn't be impacted by expirations. If argument is not given, it is used as the callback.

+- callback [MultipleDocumentsCallback](#MultipleDocumentsCallback) -

Signature err, candidates

+ + + +### datastore.getCandidatesAsync(query, [dontExpireStaleDocs]) ⇒ Promise.<Array.<document>> +

Async version of [getCandidates](#Datastore+getCandidates).

+

This is an internal function.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Returns**: Promise.<Array.<document>> -

candidates

+**Access**: protected +**See**: Datastore#getCandidates +**Params** + +- query [query](#query) +- [dontExpireStaleDocs] boolean = false -

If true don't remove stale docs. Useful for the remove function +which shouldn't be impacted by expirations.

### datastore.insertAsync(newDoc) ⇒ [Promise.<document>](#document) -

Insert a new document -Private Use Datastore.insertAsync which has the same signature

+

Async version of [Datastore#insert](Datastore#insert).

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | -| --- | --- | -| newDoc | [document](#document) \| [Array.<document>](#document) | +- newDoc [document](#document) | [Array.<document>](#document) ### datastore.count(query, [callback]) ⇒ Cursor.<number> \| undefined -

Count all documents matching the query

+

Count all documents matching the query.

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| query | [query](#query) |

MongoDB-style query

| -| [callback] | [countCallback](#Datastore..countCallback) |

If given, the function will return undefined, otherwise it will return the Cursor.

| +- query [query](#query) -

MongoDB-style query

+- [callback] [countCallback](#Datastore..countCallback) -

If given, the function will return undefined, otherwise it will return the Cursor.

### datastore.countAsync(query) ⇒ Cursor.<number> -

Count all documents matching the query

+

Async version of [count](#Datastore+count).

**Kind**: instance method of [Datastore](#Datastore) **Returns**: Cursor.<number> -

count

+**Params** -| Param | Type | Description | -| --- | --- | --- | -| query | [query](#query) |

MongoDB-style query

| +- query [query](#query) -

MongoDB-style query

@@ -246,83 +382,105 @@ Private Use Datastore.insertAsync which has the same signature

If no callback is passed, we return the cursor so that user can limit, skip and finally exec

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| query | [query](#query) | |

MongoDB-style query

| -| [projection] | [projection](#projection) \| [MultipleDocumentsCallback](#MultipleDocumentsCallback) | {} |

MongoDB-style projection. If not given, will be interpreted as the callback.

| -| [callback] | [MultipleDocumentsCallback](#MultipleDocumentsCallback) | |

Optional callback, signature: err, docs

| +- query [query](#query) -

MongoDB-style query

+- [projection] [projection](#projection) | [MultipleDocumentsCallback](#MultipleDocumentsCallback) = {} -

MongoDB-style projection. If not given, will be +interpreted as the callback.

+- [callback] [MultipleDocumentsCallback](#MultipleDocumentsCallback) -

Optional callback, signature: err, docs

### datastore.findAsync(query, [projection]) ⇒ Cursor.<Array.<document>> -

Find all documents matching the query -If no callback is passed, we return the cursor so that user can limit, skip and finally exec

+

Async version of [find](#Datastore+find).

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| query | [query](#query) | |

MongoDB-style query

| -| [projection] | [projection](#projection) | {} |

MongoDB-style projection

| +- query [query](#query) -

MongoDB-style query

+- [projection] [projection](#projection) = {} -

MongoDB-style projection

-### datastore.findOne(query, projection, callback) ⇒ [Cursor.<document>](#document) \| undefined -

Find one document matching the query

+### datastore.findOne(query, [projection], [callback]) ⇒ [Cursor.<document>](#document) \| undefined +

Find one document matching the query.

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| query | [query](#query) |

MongoDB-style query

| -| projection | [projection](#projection) |

MongoDB-style projection

| -| callback | [SingleDocumentCallback](#SingleDocumentCallback) |

Optional callback, signature: err, doc

| +- query [query](#query) -

MongoDB-style query

+- [projection] [projection](#projection) | [SingleDocumentCallback](#SingleDocumentCallback) = {} -

MongoDB-style projection

+- [callback] [SingleDocumentCallback](#SingleDocumentCallback) -

Optional callback, signature: err, doc

### datastore.findOneAsync(query, projection) ⇒ [Cursor.<document>](#document) -

Find one document matching the query

+

Async version of [findOne](#Datastore+findOne).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#findOne +**Params** -| Param | Type | Description | -| --- | --- | --- | -| query | [query](#query) |

MongoDB-style query

| -| projection | [projection](#projection) |

MongoDB-style projection

| +- query [query](#query) -

MongoDB-style query

+- projection [projection](#projection) -

MongoDB-style projection

-### datastore.update(query, update, [options], [cb]) +### datastore.update(query, update, [options|], [cb])

Update all docs matching query.

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| query | [query](#query) | |

is the same kind of finding query you use with find and findOne

| -| update | [document](#document) \| update | |

specifies how the documents should be modified. It is either a new document or a set of modifiers (you cannot use both together, it doesn't make sense!):

  • A new document will replace the matched docs
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a field's value and $min/$max to change field's value, only if provided value is less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
| -| [options] | Object | |

Optional options

| -| [options.multi] | boolean | false |

If true, can update multiple documents

| -| [options.upsert] | boolean | false |

If true, can insert a new document corresponding to the update rules if your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted document. In the other case, the query is stripped from all operator recursively, and the update is applied to it.

| -| [options.returnUpdatedDocs] | boolean | false |

(not Mongo-DB compatible) If true and update is not an upsert, will return the array of documents matched by the find query and updated. Updated documents will be returned even if the update did not actually modify them.

| -| [cb] | [updateCallback](#Datastore..updateCallback) | () => {} |

Optional callback

| +- query [query](#query) -

is the same kind of finding query you use with find and findOne

+- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a +set of modifiers (you cannot use both together, it doesn't make sense!):

+
    +
  • A new document will replace the matched docs
  • +
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. +Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a +field's value and $min/$max to change field's value, only if provided value is less/greater than current +value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
  • +
+- [options|] Object | [updateCallback](#Datastore..updateCallback) -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

+ - [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if +your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted +document. In the other case, the query is stripped from all operator recursively, and the update is applied to +it.

+ - [.returnUpdatedDocs] boolean = false -

(not Mongo-DB compatible) If true and update is not an upsert, +will return the array of documents matched by the find query and updated. Updated documents will be returned even +if the update did not actually modify them.

+- [cb] [updateCallback](#Datastore..updateCallback) = () => {} -

Optional callback

### datastore.updateAsync(query, update, [options]) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> -

Update all docs matching query.

+

Async version of [update](#Datastore+update).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#update +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| query | [query](#query) | |

is the same kind of finding query you use with find and findOne

| -| update | [document](#document) \| update | |

specifies how the documents should be modified. It is either a new document or a set of modifiers (you cannot use both together, it doesn't make sense!):

  • A new document will replace the matched docs
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a field's value and $min/$max to change field's value, only if provided value is less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
| -| [options] | Object | |

Optional options

| -| [options.multi] | boolean | false |

If true, can update multiple documents

| -| [options.upsert] | boolean | false |

If true, can insert a new document corresponding to the update rules if your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted document. In the other case, the query is stripped from all operator recursively, and the update is applied to it.

| -| [options.returnUpdatedDocs] | boolean | false |

(not Mongo-DB compatible) If true and update is not an upsert, will return the array of documents matched by the find query and updated. Updated documents will be returned even if the update did not actually modify them.

| +- query [query](#query) -

is the same kind of finding query you use with find and findOne

+- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a +set of modifiers (you cannot use both together, it doesn't make sense!):

+
    +
  • A new document will replace the matched docs
  • +
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. +Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a +field's value and $min/$max to change field's value, only if provided value is less/greater than current +value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
  • +
+- [options] Object = {} -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

+ - [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if +your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted +document. In the other case, the query is stripped from all operator recursively, and the update is applied to +it.

+ - [.returnUpdatedDocs] boolean = false -

(not Mongo-DB compatible) If true and update is not an upsert, +will return the array of documents matched by the find query and updated. Updated documents will be returned even +if the update did not actually modify them.

@@ -330,13 +488,12 @@ If no callback is passed, we return the cursor so that user can limit, skip and

Remove all docs matching the query.

**Kind**: instance method of [Datastore](#Datastore) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| query | [query](#query) | | | -| [options] | object | |

Optional options

| -| [options.multi] | boolean | false |

If true, can update multiple documents

| -| [cb] | [removeCallback](#Datastore..removeCallback) | () => {} |

Optional callback, signature: err, numRemoved

| +- query [query](#query) +- [options] object | [removeCallback](#Datastore..removeCallback) = {} -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

+- [cb] [removeCallback](#Datastore..removeCallback) = () => {} -

Optional callback

@@ -346,14 +503,13 @@ Use Datastore.removeAsync which has the same signature

**Kind**: instance method of [Datastore](#Datastore) **Returns**: Promise.<number> -

How many documents were removed

+**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| query | [query](#query) | | | -| [options] | object | |

Optional options

| -| [options.multi] | boolean | false |

If true, can update multiple documents

| +- query [query](#query) +- [options] object = {} -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

- + ### "event:compaction.done"

Compaction event. Happens when the Datastore's Persistence has been compacted. @@ -365,21 +521,19 @@ It happens when calling datastore.persistence.compactDatafile, whic ### Datastore~countCallback : function **Kind**: inner typedef of [Datastore](#Datastore) +**Params** -| Param | Type | -| --- | --- | -| err | Error | -| count | number | +- err Error +- count number ### Datastore~findOneCallback : function **Kind**: inner typedef of [Datastore](#Datastore) +**Params** -| Param | Type | -| --- | --- | -| err | Error | -| doc | [document](#document) | +- err Error +- doc [document](#document) @@ -400,21 +554,19 @@ or running another find query on the whole dataset to check its size. Both optio was necessary.

**Kind**: inner typedef of [Datastore](#Datastore) +**Params** -| Param | Type | -| --- | --- | -| err | Error | -| numAffected | number | -| affectedDocuments | [?Array.<document>](#document) \| [document](#document) | -| upsert | boolean | +- err Error +- numAffected number +- affectedDocuments [?Array.<document>](#document) | [document](#document) +- upsert boolean ### Datastore~removeCallback : function **Kind**: inner typedef of [Datastore](#Datastore) +**Params** -| Param | Type | -| --- | --- | -| err | Error | -| numRemoved | number | +- err Error +- numRemoved number diff --git a/docs/Executor.md b/docs/Executor.md index 47ca3f7..1d24696 100644 --- a/docs/Executor.md +++ b/docs/Executor.md @@ -8,10 +8,6 @@ Has an option for a buffer that can be triggered afterwards.

* [Executor](#Executor) * [new Executor()](#new_Executor_new) - * [.ready](#Executor+ready) : boolean - * [.queue](#Executor+queue) : [Waterfall](#Waterfall) - * [.buffer](#Executor+buffer) : [Waterfall](#Waterfall) - * [._triggerBuffer()](#Executor+_triggerBuffer) * [.push(task, [forceQueuing])](#Executor+push) * [.pushAsync(task, [forceQueuing])](#Executor+pushAsync) ⇒ Promise.<\*> * [.processBuffer()](#Executor+processBuffer) @@ -21,35 +17,6 @@ Has an option for a buffer that can be triggered afterwards.

### new Executor()

Instantiates a new Executor.

- - -### executor.ready : boolean -

If this.ready is false, then every task pushed will be buffered until this.processBuffer is called.

- -**Kind**: instance property of [Executor](#Executor) -**Access**: protected - - -### executor.queue : [Waterfall](#Waterfall) -

The main queue

- -**Kind**: instance property of [Executor](#Executor) -**Access**: protected - - -### executor.buffer : [Waterfall](#Waterfall) -

The buffer queue

- -**Kind**: instance property of [Executor](#Executor) -**Access**: protected - - -### executor.\_triggerBuffer() -

Method to trigger the buffer processing.

-

Do not be use directly, use this.processBuffer instead.

- -**Kind**: instance method of [Executor](#Executor) -**Access**: protected ### executor.push(task, [forceQueuing]) @@ -57,27 +24,29 @@ Has an option for a buffer that can be triggered afterwards.

If not, buffer task for later processing

**Kind**: instance method of [Executor](#Executor) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| task | Object | | | -| task.this | Object | |

Object to use as this

| -| task.fn | function | |

Function to execute

| -| task.arguments | Array | |

Array of arguments, IMPORTANT: only the last argument may be a function (the callback) and the last argument cannot be false/undefined/null

| -| [forceQueuing] | Boolean | false |

Optional (defaults to false) force executor to queue task even if it is not ready

| +- task Object + - .this Object -

Object to use as this

+ - .fn function -

Function to execute

+ - .arguments Array -

Array of arguments, IMPORTANT: only the last argument may be a function +(the callback) and the last argument cannot be false/undefined/null

+- [forceQueuing] Boolean = false -

Optional (defaults to false) force executor to queue task even if it is not ready

### executor.pushAsync(task, [forceQueuing]) ⇒ Promise.<\*> -

If executor is ready, queue task (and process it immediately if executor was idle) -If not, buffer task for later processing

+

Async version of [push](#Executor+push). +This version is way simpler than its callbackEquivalent: you give it an async function task, it is executed when +all the previous tasks are done, and then resolves or rejects and when it is finished with its original result or +error.

**Kind**: instance method of [Executor](#Executor) +**See**: Executor#push +**Params** -| Param | Type | Default | -| --- | --- | --- | -| task | function | | -| [forceQueuing] | boolean | false | +- task [AsyncFunction](#AsyncFunction) +- [forceQueuing] boolean = false diff --git a/docs/Index.md b/docs/Index.md index 202cea0..fd1716d 100644 --- a/docs/Index.md +++ b/docs/Index.md @@ -29,13 +29,12 @@ fields to be undefined

All methods on an index guarantee that either the whole operation was successful and the index changed or the operation was unsuccessful and an error is thrown while the index is unchanged

+**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| options | object | | | -| options.fieldName | string | |

On which field should the index apply (can use dot notation to index on sub fields)

| -| [options.unique] | boolean | false |

Enforces a unique constraint

| -| [options.sparse] | boolean | false |

Allows a sparse index (we can have documents for which fieldName is undefined)

| +- options object + - .fieldName string -

On which field should the index apply (can use dot notation to index on sub fields)

+ - [.unique] boolean = false -

Enforces a unique constraint

+ - [.sparse] boolean = false -

Allows a sparse index (we can have documents for which fieldName is undefined)

@@ -73,10 +72,10 @@ or the operation was unsuccessful and an error is thrown while the index is unch

Reset an index

**Kind**: instance method of [Index](#Index) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| [newData] | [document](#document) \| [?Array.<document>](#document) |

Data to initialize the index with. If an error is thrown during insertion, the index is not modified.

| +- [newData] [document](#document) | [?Array.<document>](#document) -

Data to initialize the index with. If an error is thrown during +insertion, the index is not modified.

@@ -86,10 +85,9 @@ If an array is passed, we insert all its elements (if one insertion fails the in O(log(n))

**Kind**: instance method of [Index](#Index) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| doc | [document](#document) \| [Array.<document>](#document) |

The document, or array of documents, to insert.

| +- doc [document](#document) | [Array.<document>](#document) -

The document, or array of documents, to insert.

@@ -100,10 +98,9 @@ The remove operation is safe with regards to the 'unique' constraint O(log(n))

**Kind**: instance method of [Index](#Index) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| doc | [Array.<document>](#document) \| [document](#document) |

The document, or Array of documents, to remove.

| +- doc [Array.<document>](#document) | [document](#document) -

The document, or Array of documents, to remove.

@@ -113,11 +110,12 @@ If a constraint is violated, changes are rolled back and an error thrown Naive implementation, still in O(log(n))

**Kind**: instance method of [Index](#Index) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| oldDoc | [document](#document) \| Array.<{oldDoc: document, newDoc: document}> |

Document to update, or an Array of {oldDoc, newDoc} pairs.

| -| [newDoc] | [document](#document) |

Document to replace the oldDoc with. If the first argument is an Array of {oldDoc, newDoc} pairs, this second argument is ignored.

| +- oldDoc [document](#document) | Array.<{oldDoc: document, newDoc: document}> -

Document to update, or an Array of +{oldDoc, newDoc} pairs.

+- [newDoc] [document](#document) -

Document to replace the oldDoc with. If the first argument is an Array of +{oldDoc, newDoc} pairs, this second argument is ignored.

@@ -125,11 +123,10 @@ Naive implementation, still in O(log(n))

Revert an update

**Kind**: instance method of [Index](#Index) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| oldDoc | [document](#document) \| Array.<{oldDoc: document, newDoc: document}> |

Document to revert to, or an Array of {oldDoc, newDoc} pairs.

| -| [newDoc] | [document](#document) |

Document to revert from. If the first argument is an Array of {oldDoc, newDoc}, this second argument is ignored.

| +- oldDoc [document](#document) | Array.<{oldDoc: document, newDoc: document}> -

Document to revert to, or an Array of {oldDoc, newDoc} pairs.

+- [newDoc] [document](#document) -

Document to revert from. If the first argument is an Array of {oldDoc, newDoc}, this second argument is ignored.

@@ -137,10 +134,9 @@ Naive implementation, still in O(log(n))

Get all documents in index whose key match value (if it is a Thing) or one of the elements of value (if it is an array of Things)

**Kind**: instance method of [Index](#Index) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| value | Array.<\*> \| \* |

Value to match the key against

| +- value Array.<\*> | \* -

Value to match the key against

@@ -149,14 +145,13 @@ Naive implementation, still in O(log(n))

Documents are sorted by key

**Kind**: instance method of [Index](#Index) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| query | object |

An object with at least one matcher among $gt, $gte, $lt, $lte.

| -| [query.$gt] | \* |

Greater than matcher.

| -| [query.$gte] | \* |

Greater than or equal matcher.

| -| [query.$lt] | \* |

Lower than matcher.

| -| [query.$lte] | \* |

Lower than or equal matcher.

| +- query object -

An object with at least one matcher among $gt, $gte, $lt, $lte.

+ - [.$gt] \* -

Greater than matcher.

+ - [.$gte] \* -

Greater than or equal matcher.

+ - [.$lt] \* -

Lower than matcher.

+ - [.$lte] \* -

Lower than or equal matcher.

diff --git a/docs/Persistence.md b/docs/Persistence.md index d660e09..1b4c51c 100644 --- a/docs/Persistence.md +++ b/docs/Persistence.md @@ -8,7 +8,7 @@ * [Persistence](#Persistence) * [new Persistence()](#new_Persistence_new) * _instance_ - * [.persistCachedDatabase(callback)](#Persistence+persistCachedDatabase) + * [.persistCachedDatabase([callback])](#Persistence+persistCachedDatabase) * [.persistCachedDatabaseAsync()](#Persistence+persistCachedDatabaseAsync) ⇒ Promise.<void> * [.compactDatafile([callback])](#Persistence+compactDatafile) * [.compactDatafileAsync()](#Persistence+compactDatafileAsync) @@ -33,70 +33,69 @@ ### new Persistence()

Create a new Persistence object for database options.db

+**Params** -| Param | Type | Description | -| --- | --- | --- | -| options.db | [Datastore](#Datastore) | | -| [options.corruptAlertThreshold] | Number |

Optional, threshold after which an alert is thrown if too much data is corrupt

| -| [options.nodeWebkitAppName] | string |

Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion)

| -| [options.beforeDeserialization] | function |

Hook you can use to transform data after it was serialized and before it is written to disk.

| -| [options.afterSerialization] | function |

Inverse of afterSerialization.

| + - .db [Datastore](#Datastore) + - [.corruptAlertThreshold] Number -

Optional, threshold after which an alert is thrown if too much data is corrupt

+ - [.nodeWebkitAppName] string -

Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion)

+ - [.beforeDeserialization] [serializationHook](#serializationHook) -

Hook you can use to transform data after it was serialized and before it is written to disk.

+ - [.afterSerialization] [serializationHook](#serializationHook) -

Inverse of afterSerialization.

-### persistence.persistCachedDatabase(callback) +### persistence.persistCachedDatabase([callback])

Persist cached database This serves as a compaction function since the cache always contains only the number of documents in the collection -while the data file is append-only so it may grow larger -This is an internal function, use compactDataFile which uses the executor

+while the data file is append-only so it may grow larger

+

This is an internal function, use [compactDatafile](#Persistence+compactDatafile) which uses the [executor](#Datastore+executor).

**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** -| Param | Type | Description | -| --- | --- | --- | -| callback | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| +- [callback] [NoParamCallback](#NoParamCallback) = () => {} ### persistence.persistCachedDatabaseAsync() ⇒ Promise.<void> -

Persist cached database -This serves as a compaction function since the cache always contains only the number of documents in the collection -while the data file is append-only so it may grow larger -This is an internal function, use compactDataFileAsync which uses the executor

+

Async version of [persistCachedDatabase](#Persistence+persistCachedDatabase).

+

This is an internal function, use [compactDatafileAsync](#Persistence+compactDatafileAsync) which uses the [executor](#Datastore+executor).

**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**See**: Persistence#persistCachedDatabase ### persistence.compactDatafile([callback])

Queue a rewrite of the datafile

**Kind**: instance method of [Persistence](#Persistence) +**See**: Persistence#persistCachedDatabase +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| [callback] | [NoParamCallback](#NoParamCallback) | () => {} |

Optional callback, signature: err

| +- [callback] [NoParamCallback](#NoParamCallback) = () => {} ### persistence.compactDatafileAsync() -

Queue a rewrite of the datafile

+

Async version of [compactDatafile](#Persistence+compactDatafile).

**Kind**: instance method of [Persistence](#Persistence) +**See**: Persistence#compactDatafile ### persistence.setAutocompactionInterval(interval) -

Set automatic compaction every interval ms

+

Set automatic compaction every interval ms

**Kind**: instance method of [Persistence](#Persistence) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| interval | Number |

in milliseconds, with an enforced minimum of 5 seconds

| +- interval Number -

in milliseconds, with an enforced minimum of 5000 milliseconds

### persistence.stopAutocompaction() -

Stop autocompaction (do nothing if autocompaction was not running)

+

Stop autocompaction (do nothing if automatic compaction was not running)

**Kind**: instance method of [Persistence](#Persistence) @@ -104,59 +103,68 @@ This is an internal function, use compactDataFileAsync which uses the executorPersist new state for the given newDocs (can be insertion, update or removal) Use an append-only format

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| newDocs | Array.<string> | |

Can be empty if no doc was updated/removed

| -| [callback] | [NoParamCallback](#NoParamCallback) | () => {} |

Optional, signature: err

| +- newDocs Array.<string> -

Can be empty if no doc was updated/removed

+- [callback] [NoParamCallback](#NoParamCallback) = () => {} ### persistence.persistNewStateAsync(newDocs) ⇒ Promise -

Persist new state for the given newDocs (can be insertion, update or removal) -Use an append-only format

+

Async version of [persistNewState](#Persistence+persistNewState)

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

**Kind**: instance method of [Persistence](#Persistence) +**See**: Persistence#persistNewState +**Params** -| Param | Type | Description | -| --- | --- | --- | -| newDocs | [Array.<document>](#document) |

Can be empty if no doc was updated/removed

| +- newDocs [Array.<document>](#document) -

Can be empty if no doc was updated/removed

### persistence.treatRawData(rawData) ⇒ Object -

From a database's raw data, return the corresponding machine understandable collection

+

From a database's raw data, return the corresponding machine understandable collection.

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** -| Param | Type | Description | -| --- | --- | --- | -| rawData | string |

database file

| +- rawData string -

database file

### persistence.treatRawStream(rawStream, cb) -

From a database's raw data stream, return the corresponding machine understandable collection

+

From a database's raw data stream, return the corresponding machine understandable collection +Is only used by a [Datastore](#Datastore) instance.

+

Is only used in the Node.js version, since [React-Native](#module_storageReactNative) & +[browser](#module_storageBrowser) storage modules don't provide an equivalent of +[readFileStream](#module_storage.readFileStream).

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** -| Param | Type | -| --- | --- | -| rawStream | Readable | -| cb | [treatRawStreamCallback](#Persistence..treatRawStreamCallback) | +- rawStream Readable +- cb [treatRawStreamCallback](#Persistence..treatRawStreamCallback) ### persistence.treatRawStreamAsync(rawStream) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> -

From a database's raw data stream, return the corresponding machine understandable collection

+

Async version of [treatRawStream](#Persistence+treatRawStream).

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**See**: Persistence#treatRawStream +**Params** -| Param | Type | -| --- | --- | -| rawStream | Readable | +- rawStream Readable @@ -165,54 +173,47 @@ Use an append-only format

  1. Create all indexes
  2. Insert all data
  3. -
  4. Compact the database -This means pulling data out of the data file or creating it if it doesn't exist -Also, all data is persisted right away, which has the effect of compacting the database file -This operation is very quick at startup for a big collection (60ms for ~10k docs)
  5. +
  6. Compact the database
+

This means pulling data out of the data file or creating it if it doesn't exist +Also, all data is persisted right away, which has the effect of compacting the database file +This operation is very quick at startup for a big collection (60ms for ~10k docs)

+

Do not use directly as it does not use the [Executor](Datastore.executor), use [loadDatabase](#Datastore+loadDatabase) instead.

**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** -| Param | Type | Description | -| --- | --- | --- | -| callback | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| +- callback [NoParamCallback](#NoParamCallback) ### persistence.loadDatabaseAsync() ⇒ Promise.<void> -

Load the database

-
    -
  1. Create all indexes
  2. -
  3. Insert all data
  4. -
  5. Compact the database -This means pulling data out of the data file or creating it if it doesn't exist -Also, all data is persisted right away, which has the effect of compacting the database file -This operation is very quick at startup for a big collection (60ms for ~10k docs)
  6. -
+

Async version of [loadDatabase](#Persistence+loadDatabase)

**Kind**: instance method of [Persistence](#Persistence) +**See**: Persistence#loadDatabase ### Persistence.ensureDirectoryExists(dir, [callback]) -

Check if a directory stat and create it on the fly if it is not the case

+

Check if a directory stat and create it on the fly if it is not the case.

**Kind**: static method of [Persistence](#Persistence) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| dir | string | | | -| [callback] | [NoParamCallback](#NoParamCallback) | () => {} |

optional callback, signature: err

| +- dir string +- [callback] [NoParamCallback](#NoParamCallback) = () => {} ### Persistence.ensureDirectoryExistsAsync(dir) ⇒ Promise.<void> -

Check if a directory stat and create it on the fly if it is not the case

+

Async version of [ensureDirectoryExists](#Persistence.ensureDirectoryExists).

**Kind**: static method of [Persistence](#Persistence) +**See**: Persistence.ensureDirectoryExists +**Params** -| Param | Type | -| --- | --- | -| dir | string | +- dir string @@ -223,19 +224,19 @@ This operation is very quick at startup for a big collection (60ms for ~10k docs data for this application. Probably the best place to store data

**Kind**: static method of [Persistence](#Persistence) +**Params** -| Param | Type | -| --- | --- | -| appName | string | -| relativeFilename | string | +- appName string +- relativeFilename string ### Persistence~treatRawStreamCallback : function **Kind**: inner typedef of [Persistence](#Persistence) +**Params** -| Param | Type | -| --- | --- | -| err | Error | -| data | Object | +- err Error +- data object + - .data [Array.<document>](#document) + - .indexes Object.<string, rawIndex> diff --git a/docs/Waterfall.md b/docs/Waterfall.md index 4091ea2..b253438 100644 --- a/docs/Waterfall.md +++ b/docs/Waterfall.md @@ -1,11 +1,12 @@ ## Waterfall +

Responsible for sequentially executing actions on the database

+ **Kind**: global class * [Waterfall](#Waterfall) * [new Waterfall()](#new_Waterfall_new) - * [._guardian](#Waterfall+_guardian) : Promise * [.guardian](#Waterfall+guardian) ⇒ Promise * [.waterfall(func)](#Waterfall+waterfall) ⇒ [AsyncFunction](#AsyncFunction) * [.chain(promise)](#Waterfall+chain) ⇒ Promise @@ -15,15 +16,6 @@ ### new Waterfall()

Instantiate a new Waterfall.

- - -### waterfall.\_guardian : Promise -

This is the internal Promise object which resolves when all the tasks of the Waterfall are done.

-

It will change any time this.waterfall is called.

-

Use [guardian](#Waterfall+guardian) instead which retrievethe latest version of the guardian.

- -**Kind**: instance property of [Waterfall](#Waterfall) -**Access**: protected ### waterfall.guardian ⇒ Promise @@ -35,10 +27,9 @@ ### waterfall.waterfall(func) ⇒ [AsyncFunction](#AsyncFunction) **Kind**: instance method of [Waterfall](#Waterfall) +**Params** -| Param | Type | -| --- | --- | -| func | [AsyncFunction](#AsyncFunction) | +- func [AsyncFunction](#AsyncFunction) @@ -46,8 +37,7 @@

Shorthand for chaining a promise to the Waterfall

**Kind**: instance method of [Waterfall](#Waterfall) +**Params** -| Param | Type | -| --- | --- | -| promise | Promise | +- promise Promise diff --git a/docs/customUtilsBrowser.md b/docs/customUtilsBrowser.md index b0f6f31..3a931d0 100644 --- a/docs/customUtilsBrowser.md +++ b/docs/customUtilsBrowser.md @@ -17,10 +17,9 @@ https://github.com/dominictarr/crypto-browserify NOTE: Math.random() does not guarantee "cryptographic quality" but we actually don't need it

**Kind**: inner method of [customUtilsBrowser](#module_customUtilsBrowser) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| size | number |

in bytes

| +- size number -

in bytes

@@ -29,8 +28,7 @@ NOTE: Math.random() does not guarantee "cryptographic quality" but we https://github.com/beatgammit/base64-js/

**Kind**: inner method of [customUtilsBrowser](#module_customUtilsBrowser) +**Params** -| Param | Type | -| --- | --- | -| uint8 | array | +- uint8 array diff --git a/docs/customUtilsNode.md b/docs/customUtilsNode.md index 5c86017..ec23df5 100644 --- a/docs/customUtilsNode.md +++ b/docs/customUtilsNode.md @@ -20,10 +20,9 @@ The probability of a collision is extremely small (need 3*10^12 documents to hav See http://en.wikipedia.org/wiki/Birthday_problem

**Kind**: static method of [customUtilsNode](#module_customUtilsNode) +**Params** -| Param | Type | -| --- | --- | -| len | number | +- len number @@ -36,8 +35,7 @@ The probability of a collision is extremely small (need 3*10^12 documents to hav See http://en.wikipedia.org/wiki/Birthday_problem

**Kind**: static method of [customUtilsNode](#module_customUtilsNode) +**Params** -| Param | Type | -| --- | --- | -| len | number | +- len number diff --git a/docs/globals.md b/docs/globals.md new file mode 100644 index 0000000..b1a8a76 --- /dev/null +++ b/docs/globals.md @@ -0,0 +1,155 @@ + + +## NoParamCallback : function +

Callback with no parameter

+ +**Kind**: global typedef +**Params** + +- err Error + + + + +## compareStrings ⇒ number +

String comparison function.

+
  if (a < b) return -1
+  if (a > b) return 1
+  return 0
+
+ +**Kind**: global typedef +**Params** + +- a string +- b string + + + + +## MultipleDocumentsCallback : function +

Callback that returns an Array of documents

+ +**Kind**: global typedef +**Params** + +- err Error +- docs [Array.<document>](#document) + + + + +## SingleDocumentCallback : function +

Callback that returns a single document

+ +**Kind**: global typedef +**Params** + +- err Error +- docs [document](#document) + + + + +## AsyncFunction ⇒ Promise.<\*> +

Generic async function

+ +**Kind**: global typedef +**Params** + +- ...args \* + + + + +## document : Object.<string, \*> +

Generic document in NeDB. +It consists of an Object with anything you want inside.

+ +**Kind**: global typedef +**Properties** + +| Name | Type | Description | +| --- | --- | --- | +| [_id] | string |

Internal _id of the document, which can be null or undefined at some points (when not inserted yet for example).

| + + + + +## query : Object.<string, \*> +

Nedb query.

+

Each key of a query references a field name, which can use the dot-notation to reference subfields inside nested +documents, arrays, arrays of subdocuments and to match a specific element of an array.

+

Each value of a query can be one of the following:

+
    +
  • string: matches all documents which have this string as value for the referenced field name
  • +
  • number: matches all documents which have this number as value for the referenced field name
  • +
  • Regexp: matches all documents which have a value that matches the given Regexp for the referenced field name
  • +
  • object: matches all documents which have this object as deep-value for the referenced field name
  • +
  • Comparison operators: the syntax is { field: { $op: value } } where $op is any comparison operator: +
      +
    • $lt, $lte: less than, less than or equal
    • +
    • $gt, $gte: greater than, greater than or equal
    • +
    • $in: member of. value must be an array of values
    • +
    • $ne, $nin: not equal, not a member of
    • +
    • $stat: checks whether the document posses the property field. value should be true or false
    • +
    • $regex: checks whether a string is matched by the regular expression. Contrary to MongoDB, the use of +$options with $regex is not supported, because it doesn't give you more power than regex flags. Basic +queries are more readable so only use the $regex operator when you need to use another operator with it
    • +
    • $size: if the referenced filed is an Array, matches on the size of the array
    • +
    • $elemMatch: matches if at least one array element matches the sub-query entirely
    • +
    +
  • +
  • Logical operators: You can combine queries using logical operators: +
      +
    • For $or and $and, the syntax is { $op: [query1, query2, ...] }.
    • +
    • For $not, the syntax is { $not: query }
    • +
    • For $where, the syntax is:
    • +
    +
    { $where: function () {
    +  // object is 'this'
    +  // return a boolean
    +} }
    +
    +
  • +
+ +**Kind**: global typedef + + + +## projection : Object.<string, (0\|1)> +

Nedb projection.

+

You can give find and findOne an optional second argument, projections. +The syntax is the same as MongoDB: { a: 1, b: 1 } to return only the a +and b fields, { a: 0, b: 0 } to omit these two fields. You cannot use both +modes at the time, except for _id which is by default always returned and +which you can choose to omit. You can project on nested documents.

+

To reference subfields, you can use the dot-notation.

+ +**Kind**: global typedef + + + +## serializationHook ⇒ string +

The beforeDeserializationand afterDeserialization callbacks should

+ +**Kind**: global typedef +**Params** + +- x string + + + + +## rawIndex +**Kind**: global typedef +**Properties** + +| Name | Type | +| --- | --- | +| fieldName | string | +| [unique] | boolean | +| [sparse] | boolean | + + diff --git a/docs/model.md b/docs/model.md index 3acaa33..5bd8153 100644 --- a/docs/model.md +++ b/docs/model.md @@ -32,10 +32,9 @@ Querying, update

Works by applying the above checkKey function to all fields recursively

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | -| --- | --- | -| obj | [document](#document) \| [Array.<document>](#document) | +- obj [document](#document) | [Array.<document>](#document) @@ -48,10 +47,9 @@ Accepted primitive types: Number, String, Boolean, Date, null Accepted secondary types: Objects, Arrays

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | -| --- | --- | -| obj | [document](#document) | +- obj [document](#document) @@ -60,10 +58,9 @@ Accepted secondary types: Objects, Arrays

Return the object itself

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | -| --- | --- | -| rawData | string | +- rawData string @@ -76,12 +73,11 @@ If two objects dont have the same type, the (arbitrary) type hierarchy is: undef Return -1 if a < b, 1 if a > b and 0 if a = b (note that equality here is NOT the same as defined in areThingsEqual!)

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| a | \* | | -| b | \* | | -| [_compareStrings] | [compareStrings](#compareStrings) |

String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters)

| +- a \* +- b \* +- [_compareStrings] [compareStrings](#compareStrings) -

String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters)

@@ -89,11 +85,10 @@ Return -1 if a < b, 1 if a > b and 0 if a = b (note that equality here is

Modify a DB object according to an update query

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | -| --- | --- | -| obj | [document](#document) | -| updateQuery | [query](#query) | +- obj [document](#document) +- updateQuery [query](#query) @@ -101,11 +96,10 @@ Return -1 if a < b, 1 if a > b and 0 if a = b (note that equality here is

Get a value from object with dot notation

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | -| --- | --- | -| obj | object | -| field | string | +- obj object +- field string @@ -116,11 +110,10 @@ In the case of object, we check deep equality Returns true if they are, false otherwise

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | -| --- | --- | -| a | \* | -| a | \* | +- a \* +- a \* @@ -128,11 +121,10 @@ Returns true if they are, false otherwise

Tell if a given document matches a query

**Kind**: static method of [model](#module_model) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| obj | [document](#document) |

Document to check

| -| query | [query](#query) | | +- obj [document](#document) -

Document to check

+- query [query](#query) @@ -189,29 +181,26 @@ Returns true if they are, false otherwise

### model~modifierFunction : function **Kind**: inner typedef of [model](#module_model) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| obj | Object |

The model to modify

| -| field | String |

Can contain dots, in that case that means we will set a subfield recursively

| -| value | [document](#document) | | +- obj Object -

The model to modify

+- field String -

Can contain dots, in that case that means we will set a subfield recursively

+- value [document](#document) ### model~comparisonOperator ⇒ boolean **Kind**: inner typedef of [model](#module_model) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| a | \* |

Value in the object

| -| b | \* |

Value in the query

| +- a \* -

Value in the object

+- b \* -

Value in the query

### model~whereCallback ⇒ boolean **Kind**: inner typedef of [model](#module_model) +**Params** -| Param | Type | -| --- | --- | -| obj | [document](#document) | +- obj [document](#document) diff --git a/docs/storage.md b/docs/storage.md index dffd9d7..86d9525 100644 --- a/docs/storage.md +++ b/docs/storage.md @@ -1,12 +1,14 @@ ## storage -

Way data is stored for this database -For a Node.js/Node Webkit database it's the file system -For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) -For a react-native database, we use @react-native-async-storage/async-storage

-

This version is the Node.js/Node Webkit version -It's essentially fs, mkdirp and crash safe write and read functions

+

Way data is stored for this database. +This version is the Node.js/Node Webkit version. +It's essentially fs, mkdirp and crash safe write and read functions.

+ +**See** + +- module:storageBrowser +- module:storageReactNative * [storage](#module_storage) @@ -31,7 +33,7 @@ It's essentially fs, mkdirp and crash safe write and read functions

* [.ensureFileDoesntExist(file, callback)](#module_storage.ensureFileDoesntExist) * [.flushToStorage(options, callback)](#module_storage.flushToStorage) * [.flushToStorageAsync(options)](#module_storage.flushToStorageAsync) ⇒ Promise.<void> - * [.writeFileLines(filename, lines, callback)](#module_storage.writeFileLines) + * [.writeFileLines(filename, lines, [callback])](#module_storage.writeFileLines) * [.writeFileLinesAsync(filename, lines)](#module_storage.writeFileLinesAsync) ⇒ Promise.<void> * [.crashSafeWriteFileLines(filename, lines, [callback])](#module_storage.crashSafeWriteFileLines) * [.crashSafeWriteFileLinesAsync(filename, lines)](#module_storage.crashSafeWriteFileLinesAsync) ⇒ Promise.<void> @@ -43,327 +45,316 @@ It's essentially fs, mkdirp and crash safe write and read functions

### storage.exists(file, cb) -

Callback returns true if file exists

+

Callback returns true if file exists.

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| file | string | -| cb | [existsCallback](#module_storage..existsCallback) | +- file string +- cb [existsCallback](#module_storage..existsCallback) ### storage.existsAsync(file) ⇒ Promise.<boolean> -

Returns Promise if file exists

+

Async version of [exists](#module_storage.exists).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.exists +**Params** -| Param | Type | -| --- | --- | -| file | string | +- file string ### storage.rename(oldPath, newPath, c) ⇒ void -

Node.js' fs.rename

+

Node.js' [fs.rename](https://nodejs.org/api/fs.html#fsrenameoldpath-newpath-callback).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| oldPath | string | -| newPath | string | -| c | [NoParamCallback](#NoParamCallback) | +- oldPath string +- newPath string +- c [NoParamCallback](#NoParamCallback) ### storage.renameAsync(oldPath, newPath) ⇒ Promise.<void> -

Node.js' fs.promises.rename

+

Async version of [rename](#module_storage.rename).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.rename +**Params** -| Param | Type | -| --- | --- | -| oldPath | string | -| newPath | string | +- oldPath string +- newPath string ### storage.writeFile(path, data, options, callback) -

Node.js' fs.writeFile

+

Node.js' [fs.writeFile](https://nodejs.org/api/fs.html#fswritefilefile-data-options-callback).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| data | string | -| options | object | -| callback | function | +- path string +- data string +- options object +- callback function ### storage.writeFileAsync(path, data, [options]) ⇒ Promise.<void> -

Node.js' fs.promises.writeFile

+

Async version of [writeFile](#module_storage.writeFile).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.writeFile +**Params** -| Param | Type | -| --- | --- | -| path | string | -| data | string | -| [options] | object | +- path string +- data string +- [options] object ### storage.writeFileStream(path, [options]) ⇒ fs.WriteStream -

Node.js' fs.createWriteStream

+

Node.js' [fs.createWriteStream](https://nodejs.org/api/fs.html#fscreatewritestreampath-options).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| [options] | Object | +- path string +- [options] Object ### storage.unlink(path, callback) -

Node.js' fs.unlink

+

Node.js' [fs.unlink](https://nodejs.org/api/fs.html#fsunlinkpath-callback).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| callback | function | +- path string +- callback function ### storage.unlinkAsync(path) ⇒ Promise.<void> -

Node.js' fs.promises.unlink

+

Async version of [unlink](#module_storage.unlink).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.unlink +**Params** -| Param | Type | -| --- | --- | -| path | string | +- path string ### storage.appendFile(path, data, options, callback) -

Node.js' fs.appendFile

+

Node.js' [fs.appendFile](https://nodejs.org/api/fs.html#fsappendfilepath-data-options-callback).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| data | string | -| options | object | -| callback | function | +- path string +- data string +- options object +- callback function ### storage.appendFileAsync(path, data, [options]) ⇒ Promise.<void> -

Node.js' fs.promises.appendFile

+

Async version of [appendFile](#module_storage.appendFile).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.appendFile +**Params** -| Param | Type | -| --- | --- | -| path | string | -| data | string | -| [options] | object | +- path string +- data string +- [options] object ### storage.readFile(path, options, callback) -

Node.js' fs.readFile

+

Node.js' [fs.readFile](https://nodejs.org/api/fs.html#fsreadfilepath-options-callback)

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| options | object | -| callback | function | +- path string +- options object +- callback function ### storage.readFileAsync(path, [options]) ⇒ Promise.<Buffer> -

Node.js' fs.promises.readFile

+

Async version of [readFile](#module_storage.readFile).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.readFile +**Params** -| Param | Type | -| --- | --- | -| path | string | -| [options] | object | +- path string +- [options] object ### storage.readFileStream(path, [options]) ⇒ fs.ReadStream -

Node.js' fs.createReadStream

+

Node.js' [fs.createReadStream](https://nodejs.org/api/fs.html#fscreatereadstreampath-options).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| [options] | Object | +- path string +- [options] Object ### storage.mkdir(path, options, callback) -

Node.js' fs.mkdir

+

Node.js' [fs.mkdir](https://nodejs.org/api/fs.html#fsmkdirpath-options-callback).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| options | object | -| callback | function | +- path string +- options object +- callback function ### storage.mkdirAsync(path, options) ⇒ Promise.<(void\|string)> -

Node.js' fs.promises.mkdir

+

Async version of [mkdir](#module_storage.mkdir).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.mkdir +**Params** -| Param | Type | -| --- | --- | -| path | string | -| options | object | +- path string +- options object ### storage.ensureFileDoesntExistAsync(file) ⇒ Promise.<void> +

Async version of [ensureFileDoesntExist](#module_storage.ensureFileDoesntExist)

+ **Kind**: static method of [storage](#module_storage) +**See**: module:storage.ensureFileDoesntExist +**Params** -| Param | Type | -| --- | --- | -| file | string | +- file string ### storage.ensureFileDoesntExist(file, callback) +

Removes file if it exists.

+ **Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| file | string | -| callback | [NoParamCallback](#NoParamCallback) | +- file string +- callback [NoParamCallback](#NoParamCallback) ### storage.flushToStorage(options, callback) -

Flush data in OS buffer to storage if corresponding option is set

+

Flush data in OS buffer to storage if corresponding option is set.

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| options | object \| string | |

If options is a string, it is assumed that the flush of the file (not dir) called options was requested

| -| [options.filename] | string | | | -| [options.isDir] | boolean | false |

Optional, defaults to false

| -| callback | [NoParamCallback](#NoParamCallback) | | | +- options object | string -

If options is a string, it is assumed that the flush of the file (not dir) called options was requested

+ - [.filename] string + - [.isDir] boolean = false -

Optional, defaults to false

+- callback [NoParamCallback](#NoParamCallback) ### storage.flushToStorageAsync(options) ⇒ Promise.<void> -

Flush data in OS buffer to storage if corresponding option is set

+

Async version of [flushToStorage](#module_storage.flushToStorage).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.flushToStorage +**Params** -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| options | object \| string | |

If options is a string, it is assumed that the flush of the file (not dir) called options was requested

| -| [options.filename] | string | | | -| [options.isDir] | boolean | false |

Optional, defaults to false

| +- options object | string + - [.filename] string + - [.isDir] boolean = false -### storage.writeFileLines(filename, lines, callback) -

Fully write or rewrite the datafile

+### storage.writeFileLines(filename, lines, [callback]) +

Fully write or rewrite the datafile.

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| lines | Array.<string> | -| callback | [NoParamCallback](#NoParamCallback) | +- filename string +- lines Array.<string> +- [callback] [NoParamCallback](#NoParamCallback) = () => {} ### storage.writeFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Fully write or rewrite the datafile

+

Async version of [writeFileLines](#module_storage.writeFileLines).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.writeFileLines +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| lines | Array.<string> | +- filename string +- lines Array.<string> ### storage.crashSafeWriteFileLines(filename, lines, [callback]) -

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost).

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| filename | string | | -| lines | Array.<string> | | -| [callback] | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| +- filename string +- lines Array.<string> +- [callback] [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

### storage.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+

Async version of [crashSafeWriteFileLines](#module_storage.crashSafeWriteFileLines).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.crashSafeWriteFileLines +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| lines | Array.<string> | +- filename string +- lines Array.<string> ### storage.ensureDatafileIntegrity(filename, callback) -

Ensure the datafile contains all the data, even if there was a crash during a full file write

+

Ensure the datafile contains all the data, even if there was a crash during a full file write.

**Kind**: static method of [storage](#module_storage) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| filename | string | | -| callback | [NoParamCallback](#NoParamCallback) |

signature: err

| +- filename string +- callback [NoParamCallback](#NoParamCallback) -

signature: err

### storage.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> -

Ensure the datafile contains all the data, even if there was a crash during a full file write

+

Async version of [ensureDatafileIntegrity](#module_storage.ensureDatafileIntegrity).

**Kind**: static method of [storage](#module_storage) +**See**: module:storage.ensureDatafileIntegrity +**Params** -| Param | Type | -| --- | --- | -| filename | string | +- filename string ### storage~existsCallback : function **Kind**: inner typedef of [storage](#module_storage) +**Params** -| Param | Type | -| --- | --- | -| exists | boolean | +- exists boolean diff --git a/docs/storageBrowser.md b/docs/storageBrowser.md index e7d620c..343cdfe 100644 --- a/docs/storageBrowser.md +++ b/docs/storageBrowser.md @@ -1,10 +1,13 @@ ## storageBrowser -

Way data is stored for this database -For a Node.js/Node Webkit database it's the file system -For a browser-side database it's localforage which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage)

-

This version is the browser version

+

Way data is stored for this database

+

This version is the browser version and uses [localforage](https://github.com/localForage/localForage) which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage).

+ +**See** + +- module:storage +- module:storageReactNative * [storageBrowser](#module_storageBrowser) @@ -33,37 +36,37 @@ For a browser-side database it's localforage which chooses the best option depen ### storageBrowser.existsAsync(file) ⇒ Promise.<boolean> -

Returns Promise if file exists

+

Returns Promise if file exists.

+

Async version of [exists](#module_storageBrowser.exists).

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**See**: module:storageBrowser.exists +**Params** -| Param | Type | -| --- | --- | -| file | string | +- file string ### storageBrowser.exists(file, cb) -

Callback returns true if file exists

+

Callback returns true if file exists.

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| file | string | -| cb | [existsCallback](#module_storageBrowser..existsCallback) | +- file string +- cb [existsCallback](#module_storageBrowser..existsCallback) ### storageBrowser.renameAsync(oldPath, newPath) ⇒ Promise.<void> -

Moves the item from one path to another

+

Async version of [rename](#module_storageBrowser.rename).

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**See**: module:storageBrowser.rename +**Params** -| Param | Type | -| --- | --- | -| oldPath | string | -| newPath | string | +- oldPath string +- newPath string @@ -71,25 +74,24 @@ For a browser-side database it's localforage which chooses the best option depen

Moves the item from one path to another

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| oldPath | string | -| newPath | string | -| c | [NoParamCallback](#NoParamCallback) | +- oldPath string +- newPath string +- c [NoParamCallback](#NoParamCallback) ### storageBrowser.writeFileAsync(file, data, [options]) ⇒ Promise.<void> -

Saves the item at given path

+

Async version of [writeFile](#module_storageBrowser.writeFile).

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**See**: module:storageBrowser.writeFile +**Params** -| Param | Type | -| --- | --- | -| file | string | -| data | string | -| [options] | object | +- file string +- data string +- [options] object @@ -97,26 +99,25 @@ For a browser-side database it's localforage which chooses the best option depen

Saves the item at given path

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| data | string | -| options | object | -| callback | function | +- path string +- data string +- options object +- callback function ### storageBrowser.appendFileAsync(filename, toAppend, [options]) ⇒ Promise.<void> -

Append to the item at given path

+

Async version of [appendFile](#module_storageBrowser.appendFile).

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**See**: module:storageBrowser.appendFile +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| toAppend | string | -| [options] | object | +- filename string +- toAppend string +- [options] object @@ -124,25 +125,24 @@ For a browser-side database it's localforage which chooses the best option depen

Append to the item at given path

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| toAppend | string | -| [options] | object | -| callback | function | +- filename string +- toAppend string +- [options] object +- callback function ### storageBrowser.readFileAsync(filename, [options]) ⇒ Promise.<Buffer> -

Read data at given path

+

Async version of [readFile](#module_storageBrowser.readFile).

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**See**: module:storageBrowser.readFile +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| [options] | object | +- filename string +- [options] object @@ -150,23 +150,22 @@ For a browser-side database it's localforage which chooses the best option depen

Read data at given path

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| options | object | -| callback | function | +- filename string +- options object +- callback function ### storageBrowser.unlinkAsync(filename) ⇒ Promise.<void> -

Remove the data at given path

+

Async version of [unlink](#module_storageBrowser.unlink).

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**See**: module:storageBrowser.unlink +**Params** -| Param | Type | -| --- | --- | -| filename | string | +- filename string @@ -174,73 +173,66 @@ For a browser-side database it's localforage which chooses the best option depen

Remove the data at given path

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| callback | function | +- path string +- callback function ### storageBrowser.mkdirAsync(path, [options]) ⇒ Promise.<(void\|string)> -

Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser

+

Shim for [mkdirAsync](#module_storage.mkdirAsync), nothing to do, no directories will be used on the browser.

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| [options] | object | +- path string +- [options] object ### storageBrowser.mkdir(path, options, callback) -

Shim for storage.mkdir, nothing to do, no directories will be used on the browser

+

Shim for [mkdir](#module_storage.mkdir), nothing to do, no directories will be used on the browser.

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| options | object | -| callback | function | +- path string +- options object +- callback function ### storageBrowser.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> -

Ensure the datafile contains all the data, even if there was a crash during a full file write -Nothing to do, no data corruption possible in the browser

+

Shim for [ensureDatafileIntegrityAsync](#module_storage.ensureDatafileIntegrityAsync), nothing to do, no data corruption possible in the browser.

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| filename | string | +- filename string ### storageBrowser.ensureDatafileIntegrity(filename, callback) -

Ensure the datafile contains all the data, even if there was a crash during a full file write -Nothing to do, no data corruption possible in the browser

+

Shim for [ensureDatafileIntegrity](#module_storage.ensureDatafileIntegrity), nothing to do, no data corruption possible in the browser.

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| filename | string | | -| callback | [NoParamCallback](#NoParamCallback) |

signature: err

| +- filename string +- callback [NoParamCallback](#NoParamCallback) -

signature: err

### storageBrowser.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+

Async version of [crashSafeWriteFileLines](#module_storageBrowser.crashSafeWriteFileLines).

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**See**: module:storageBrowser.crashSafeWriteFileLines +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| lines | Array.<string> | +- filename string +- lines Array.<string> @@ -248,19 +240,17 @@ Nothing to do, no data corruption possible in the browser

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

**Kind**: static method of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| filename | string | | -| lines | Array.<string> | | -| [callback] | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| +- filename string +- lines Array.<string> +- [callback] [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

### storageBrowser~existsCallback : function **Kind**: inner typedef of [storageBrowser](#module_storageBrowser) +**Params** -| Param | Type | -| --- | --- | -| exists | boolean | +- exists boolean diff --git a/docs/storageReactNative.md b/docs/storageReactNative.md index 405e4b5..68dc403 100644 --- a/docs/storageReactNative.md +++ b/docs/storageReactNative.md @@ -1,11 +1,13 @@ ## storageReactNative -

Way data is stored for this database -For a Node.js/Node Webkit database it's the file system -For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) -For a react-native database, we use @react-native-async-storage/async-storage

-

This version is the react-native version

+

Way data is stored for this database

+

This version is the React-Native version and uses [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage).

+ +**See** + +- module:storageBrowser +- module:storageReactNative * [storageReactNative](#module_storageReactNative) @@ -34,13 +36,13 @@ For a react-native database, we use @react-native-async-storage/async-storage

### storageReactNative.existsAsync(file) ⇒ Promise.<boolean> -

Returns Promise if file exists

+

Async version of [exists](#module_storageReactNative.exists).

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**See**: module:storageReactNative.exists +**Params** -| Param | Type | -| --- | --- | -| file | string | +- file string @@ -48,23 +50,22 @@ For a react-native database, we use @react-native-async-storage/async-storage

Callback returns true if file exists

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| file | string | -| cb | [existsCallback](#module_storageReactNative..existsCallback) | +- file string +- cb [existsCallback](#module_storageReactNative..existsCallback) ### storageReactNative.renameAsync(oldPath, newPath) ⇒ Promise.<void> -

Moves the item from one path to another

+

Async version of [rename](#module_storageReactNative.rename).

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**See**: module:storageReactNative.rename +**Params** -| Param | Type | -| --- | --- | -| oldPath | string | -| newPath | string | +- oldPath string +- newPath string @@ -72,25 +73,24 @@ For a react-native database, we use @react-native-async-storage/async-storage

Moves the item from one path to another

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| oldPath | string | -| newPath | string | -| c | [NoParamCallback](#NoParamCallback) | +- oldPath string +- newPath string +- c [NoParamCallback](#NoParamCallback) ### storageReactNative.writeFileAsync(file, data, [options]) ⇒ Promise.<void> -

Saves the item at given path

+

Async version of [writeFile](#module_storageReactNative.writeFile).

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**See**: module:storageReactNative.writeFile +**Params** -| Param | Type | -| --- | --- | -| file | string | -| data | string | -| [options] | object | +- file string +- data string +- [options] object @@ -98,26 +98,25 @@ For a react-native database, we use @react-native-async-storage/async-storage

Saves the item at given path

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| data | string | -| options | object | -| callback | function | +- path string +- data string +- options object +- callback function ### storageReactNative.appendFileAsync(filename, toAppend, [options]) ⇒ Promise.<void> -

Append to the item at given path

+

Async version of [appendFile](#module_storageReactNative.appendFile).

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**See**: module:storageReactNative.appendFile +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| toAppend | string | -| [options] | object | +- filename string +- toAppend string +- [options] object @@ -125,25 +124,24 @@ For a react-native database, we use @react-native-async-storage/async-storage

Append to the item at given path

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| toAppend | string | -| [options] | object | -| callback | function | +- filename string +- toAppend string +- [options] object +- callback function ### storageReactNative.readFileAsync(filename, [options]) ⇒ Promise.<string> -

Read data at given path

+

Async version of [readFile](#module_storageReactNative.readFile).

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**See**: module:storageReactNative.readFile +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| [options] | object | +- filename string +- [options] object @@ -151,23 +149,22 @@ For a react-native database, we use @react-native-async-storage/async-storage

Read data at given path

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| options | object | -| callback | function | +- filename string +- options object +- callback function ### storageReactNative.unlinkAsync(filename) ⇒ Promise.<void> -

Remove the data at given path

+

Async version of [unlink](#module_storageReactNative.unlink).

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**See**: module:storageReactNative.unlink +**Params** -| Param | Type | -| --- | --- | -| filename | string | +- filename string @@ -175,73 +172,66 @@ For a react-native database, we use @react-native-async-storage/async-storage

Remove the data at given path

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| callback | function | +- path string +- callback function ### storageReactNative.mkdirAsync(dir, [options]) ⇒ Promise.<(void\|string)> -

Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser

+

Shim for [mkdirAsync](#module_storage.mkdirAsync), nothing to do, no directories will be used on the browser.

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| dir | string | -| [options] | object | +- dir string +- [options] object ### storageReactNative.mkdir(path, options, callback) -

Shim for storage.mkdir, nothing to do, no directories will be used on the browser

+

Shim for [mkdir](#module_storage.mkdir), nothing to do, no directories will be used on the browser.

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| path | string | -| options | object | -| callback | function | +- path string +- options object +- callback function ### storageReactNative.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> -

Ensure the datafile contains all the data, even if there was a crash during a full file write -Nothing to do, no data corruption possible in the browser

+

Shim for [ensureDatafileIntegrityAsync](#module_storage.ensureDatafileIntegrityAsync), nothing to do, no data corruption possible in the browser.

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| filename | string | +- filename string ### storageReactNative.ensureDatafileIntegrity(filename, callback) -

Ensure the datafile contains all the data, even if there was a crash during a full file write -Nothing to do, no data corruption possible in the browser

+

Shim for [ensureDatafileIntegrity](#module_storage.ensureDatafileIntegrity), nothing to do, no data corruption possible in the browser.

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| filename | string | | -| callback | [NoParamCallback](#NoParamCallback) |

signature: err

| +- filename string +- callback [NoParamCallback](#NoParamCallback) -

signature: err

### storageReactNative.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

+

Async version of [crashSafeWriteFileLines](#module_storageReactNative.crashSafeWriteFileLines).

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**See**: module:storageReactNative.crashSafeWriteFileLines +**Params** -| Param | Type | -| --- | --- | -| filename | string | -| lines | Array.<string> | +- filename string +- lines Array.<string> @@ -249,19 +239,17 @@ Nothing to do, no data corruption possible in the browser

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

**Kind**: static method of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| filename | string | | -| lines | Array.<string> | | -| [callback] | [NoParamCallback](#NoParamCallback) |

Optional callback, signature: err

| +- filename string +- lines Array.<string> +- [callback] [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

### storageReactNative~existsCallback : function **Kind**: inner typedef of [storageReactNative](#module_storageReactNative) +**Params** -| Param | Type | -| --- | --- | -| exists | boolean | +- exists boolean diff --git a/docs/utils.md b/docs/utils.md index 11cd495..c04794b 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -18,50 +18,47 @@ This replaces the underscore dependency.

### utils.uniq(array, [iteratee]) ⇒ Array

Produces a duplicate-free version of the array, using === to test object equality. In particular only the first occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee -function. -Heavily inspired by https://underscorejs.org/#uniq

+function.

+

Heavily inspired by [https://underscorejs.org/#uniq](https://underscorejs.org/#uniq).

**Kind**: static method of [utils](#module_utils) +**Params** -| Param | Type | Description | -| --- | --- | --- | -| array | Array | | -| [iteratee] | function |

transformation applied to every element before checking for duplicates. This will not transform the items in the result.

| +- array Array +- [iteratee] function -

transformation applied to every element before checking for duplicates. This will not +transform the items in the result.

### utils.isDate(d) ⇒ boolean -

Returns true if d is a Date. -Heavily inspired by https://underscorejs.org/#isDate

+

Returns true if d is a Date.

+

Heavily inspired by [https://underscorejs.org/#isDate](https://underscorejs.org/#isDate).

**Kind**: static method of [utils](#module_utils) +**Params** -| Param | Type | -| --- | --- | -| d | \* | +- d \* ### utils.isRegExp(re) ⇒ boolean -

Returns true if re is a RegExp. -Heavily inspired by https://underscorejs.org/#isRegExp

+

Returns true if re is a RegExp.

+

Heavily inspired by [https://underscorejs.org/#isRegExp](https://underscorejs.org/#isRegExp).

**Kind**: static method of [utils](#module_utils) +**Params** -| Param | Type | -| --- | --- | -| re | \* | +- re \* ### utils~isObject(arg) ⇒ boolean

Returns true if arg is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings -and numbers are not. -Heavily inspired by https://underscorejs.org/#isObject

+and numbers are not.

+

Heavily inspired by [https://underscorejs.org/#isObject](https://underscorejs.org/#isObject).

**Kind**: inner method of [utils](#module_utils) +**Params** -| Param | Type | -| --- | --- | -| arg | \* | +- arg \* diff --git a/jsdoc2md.js b/jsdoc2md.js index dea093c..a122382 100644 --- a/jsdoc2md.js +++ b/jsdoc2md.js @@ -15,6 +15,10 @@ const getJsdocDataOptions = { 'no-cache': true } +const renderOptions = { + 'param-list-format': 'list' +} + fs.rmdirSync(outputDir, { recursive: true }) // clean docs dir fs.mkdirSync(outputDir) // make docs dir @@ -22,15 +26,24 @@ fs.mkdirSync(outputDir) // make docs dir const templateData = jsdoc2md.getTemplateDataSync(getJsdocDataOptions) /* reduce templateData to an array of class names */ -const classNames = templateData.filter(({ kind }) => kind === 'class').map(({ name }) => name) +const classNames = templateData + .filter(({ kind, access }) => kind === 'class' && access !== 'private') + .map(({ name }) => name) + +const moduleNames = templateData + .filter(({ kind, access }) => kind === 'module' && access !== 'private') + .map(({ name }) => name) -const moduleNames = templateData.filter(({ kind }) => kind === 'module').map(({ name }) => name) +const rest = templateData + .filter(({ name }) => !moduleNames.includes(name) && !classNames.includes(name)) + .filter(({ scope, access }) => scope === 'global' && access !== 'private') + .map(({ id }) => id) /* create a documentation file for each class */ for (const className of classNames) { const template = `{{#class name="${className}"}}{{>docs}}{{/class}}` console.log(`rendering ${className}, template: ${template}`) - const output = jsdoc2md.renderSync({ data: templateData, template: template }) + const output = jsdoc2md.renderSync({ ...renderOptions, data: templateData, template: template }) fs.writeFileSync(path.resolve(outputDir, `${className}.md`), output) } @@ -38,6 +51,16 @@ for (const className of classNames) { for (const moduleName of moduleNames) { const template = `{{#module name="${moduleName}"}}{{>docs}}{{/module}}` console.log(`rendering ${moduleName}, template: ${template}`) - const output = jsdoc2md.renderSync({ data: templateData, template: template }) + const output = jsdoc2md.renderSync({ ...renderOptions, data: templateData, template: template }) fs.writeFileSync(path.resolve(outputDir, `${moduleName}.md`), output) } + +let template = '' +for (const id of rest) { + template += `{{#identifier name="${id}"}}{{>docs}}{{/identifier}}\n` +} +console.log(`rendering globals, template: ${template}`) +const output = jsdoc2md.renderSync({ ...renderOptions, data: templateData, template: template }) +fs.writeFileSync(path.resolve(outputDir, 'globals.md'), output) + +// TODO rewrite links between files diff --git a/lib/cursor.js b/lib/cursor.js index 4e8cfe0..e5f4f72 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -2,21 +2,23 @@ const model = require('./model.js') const { callbackify, promisify } = require('util') /** - * @callback Cursor~execFn + * Has a callback + * @callback Cursor~execFnWithCallback * @param {?Error} err * @param {?document[]|?document} res */ /** - * @callback Cursor~execFnAsync + * Does not have a callback, may return a Promise. + * @callback Cursor~execFnWithoutCallback * @param {?document[]|?document} res - * @return {Promise} + * @return {Promise|*} */ /** * Manage access to data, be it to find, update or remove it. * - * It extends Promise so that its methods are chainable & awaitable. + * It extends `Promise` so that its methods (which return `this`) are chainable & awaitable. * @extends Promise */ class Cursor { @@ -24,18 +26,55 @@ class Cursor { * Create a new cursor for this collection * @param {Datastore} db - The datastore this cursor is bound to * @param {query} query - The query this cursor will operate on - * @param {Cursor~execFn|Cursor~execFnAsync} [execFn] - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove - * @param {boolean} [async = false] If true, specifies that the `execFn` is of type {@link Cursor~execFnAsync} rather than {@link Cursor~execFn}. - * + * @param {Cursor~execFnWithoutCallback|Cursor~execFnWithCallback} [execFn] - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove + * @param {boolean} [hasCallback = true] If false, specifies that the `execFn` is of type {@link Cursor~execFnWithoutCallback} rather than {@link Cursor~execFnWithCallback}. */ - constructor (db, query, execFn, async = false) { + constructor (db, query, execFn, hasCallback = true) { + /** + * @protected + * @type {Datastore} + */ this.db = db + /** + * @protected + * @type {query} + */ this.query = query || {} + /** + * The handler to be executed after cursor has found the results. + * @type {Cursor~execFnWithoutCallback|Cursor~execFnWithCallback|undefined} + * @protected + */ if (execFn) this.execFn = execFn - if (async) this.async = true + /** + * Determines if the {@link Cursor#execFn} is an {@link Cursor~execFnWithoutCallback} or not. + * @protected + * @type {boolean} + */ + this.hasCallback = hasCallback + /** + * @see Cursor#limit + * @type {undefined|number} + * @private + */ this._limit = undefined + /** + * @see Cursor#skip + * @type {undefined|number} + * @private + */ this._skip = undefined + /** + * @see Cursor#sort + * @type {undefined|Object.} + * @private + */ this._sort = undefined + /** + * @see Cursor#projection + * @type {undefined|Object.} + * @private + */ this._projection = undefined } @@ -81,9 +120,12 @@ class Cursor { } /** - * Apply the projection + * Apply the projection. + * + * This is an internal function. You should use {@link Cursor#execAsync} or {@link Cursor#exec}. * @param {document[]} candidates * @return {document[]} + * @protected */ project (candidates) { const res = [] @@ -185,7 +227,7 @@ class Cursor { } catch (e) { error = e } - if (this.execFn && !this.async) return promisify(this.execFn)(error, res) + if (this.execFn && this.hasCallback) return promisify(this.execFn)(error, res) else if (error) throw error else if (this.execFn) return this.execFn(res) else return res @@ -200,8 +242,11 @@ class Cursor { /** * Get all matching elements * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne - * This is an internal function, use exec which uses the executor - * @param { Cursor~execCallback} _callback + * + * This is an internal function, use {@link Cursor#exec} which uses the [executor]{@link Datastore#executor}. + * @param {Cursor~execCallback} _callback + * @protected + * @see Cursor#exec */ _exec (_callback) { callbackify(this._execAsync.bind(this))(_callback) @@ -210,17 +255,17 @@ class Cursor { /** * Get all matching elements * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne - * @param { Cursor~execCallback} _callback + * @param {Cursor~execCallback} _callback */ exec (_callback) { this.db.executor.push({ this: this, fn: this._exec, arguments: [_callback] }) } /** - * Get all matching elements - * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne + * Async version of {@link Cursor#exec}. * @return {Promise} * @async + * @see Cursor#exec */ execAsync () { return this.db.executor.pushAsync(() => this._execAsync()) diff --git a/lib/datastore.js b/lib/datastore.js index 7ff6050..63e4a71 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -53,7 +53,7 @@ const { isDate } = require('./utils.js') * It happens when calling `datastore.persistence.compactDatafile`, which is called periodically if you have called * `datastore.persistence.setAutocompactionInterval`. * - * @event Datastore.event:"compaction.done" + * @event Datastore#event:"compaction.done" * @type {undefined} */ @@ -175,7 +175,7 @@ class Datastore extends EventEmitter { * OS X and Windows. Now that you can use `require('nw.gui').App.dataPath` in Node Webkit to get the path to the data * directory for your application, you should not use this option anymore and it will be removed. * - * @fires Datastore.event:"compaction.done" + * @fires Datastore#event:"compaction.done" */ constructor (options) { super() @@ -194,19 +194,19 @@ class Datastore extends EventEmitter { * Determines if the `Datastore` keeps data in-memory, or if it saves it in storage. Is not read after * instanciation. * @type {boolean} - * @private + * @protected */ this.inMemoryOnly = options.inMemoryOnly || false /** * Determines if the `Datastore` should autoload the database upon instantiation. Is not read after instanciation. * @type {boolean} - * @private + * @protected */ this.autoload = options.autoload || false /** * Determines if the `Datastore` should add `createdAt` and `updatedAt` fields automatically if not set by the user. * @type {boolean} - * @private + * @protected */ this.timestampData = options.timestampData || false } @@ -217,7 +217,7 @@ class Datastore extends EventEmitter { * If null, it means `inMemoryOnly` is `true`. The `filename` is the name given to the storage module. Is not read * after instanciation. * @type {?string} - * @private + * @protected */ this.filename = null this.inMemoryOnly = true @@ -230,7 +230,8 @@ class Datastore extends EventEmitter { * Overrides default string comparison which is not well adapted to non-US characters in particular accented * letters. Native `localCompare` will most of the time be the right choice * @type {compareStrings} - * @private + * @function + * @protected */ this.compareStrings = options.compareStrings @@ -254,6 +255,7 @@ class Datastore extends EventEmitter { * produced by the `Datastore` and by `this.persistence.compactDataFile` & `this.persistence.compactDataFileAsync` * to ensure operations are performed sequentially in the database. * @type {Executor} + * @protected */ this.executor = new Executor() if (this.inMemoryOnly) this.executor.ready = true @@ -262,7 +264,7 @@ class Datastore extends EventEmitter { * Indexed by field name, dot notation can be used. * _id is always indexed and since _ids are generated randomly the underlying binary search tree is always well-balanced * @type {Object.} - * @private + * @protected */ this.indexes = {} this.indexes._id = new Index({ fieldName: '_id', unique: true }) @@ -270,7 +272,7 @@ class Datastore extends EventEmitter { * Stores the time to live (TTL) of the indexes created. The key represents the field name, the value the number of * seconds after which data with this index field should be removed. * @type {Object.} - * @private + * @protected */ this.ttlIndexes = {} @@ -303,16 +305,17 @@ class Datastore extends EventEmitter { } /** - * Load the database from the datafile, and trigger the execution of buffered commands if any. + * Async version of {@link Datastore#loadDatabase}. * @async * @return {Promise} + * @see Datastore#loadDatabase */ loadDatabaseAsync () { return this.executor.pushAsync(() => this.persistence.loadDatabaseAsync(), true) } /** - * Get an array of all the data in the database + * Get an array of all the data in the database. * @return {document[]} */ getAllData () { @@ -320,7 +323,8 @@ class Datastore extends EventEmitter { } /** - * Reset all currently defined indexes + * Reset all currently defined indexes. + * @param {?document|?document[]} newData */ resetIndexes (newData) { for (const index of Object.values(this.indexes)) { @@ -346,16 +350,14 @@ class Datastore extends EventEmitter { } /** - * Ensure an index is kept for this field. Same parameters as lib/indexes - * This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the - * executor. - * Previous versions said explicitly the callback was optional, it is now recommended setting one. + * Async version of {@link Datastore#ensureIndex}. * @param {object} options * @param {string} options.fieldName Name of the field to index. Use the dot notation to index a field in a nested document. * @param {boolean} [options.unique = false] Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined. * @param {boolean} [options.sparse = false] Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined. * @param {number} [options.expireAfterSeconds] - If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored * @return {Promise} + * @see Datastore#ensureIndex */ // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state async ensureIndexAsync (options = {}) { @@ -393,11 +395,11 @@ class Datastore extends EventEmitter { } /** - * Remove an index - * Previous versions said explicitly the callback was optional, it is now recommended setting one. + * Async version of {@link Datastore#removeIndex}. * @param {string} fieldName Field name of the index to remove. Use the dot notation to remove an index referring to a * field in a nested document. * @return {Promise} + * @see Datastore#removeIndex */ // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state async removeIndexAsync (fieldName) { @@ -407,9 +409,11 @@ class Datastore extends EventEmitter { } /** - * Add one or several document(s) to all indexes + * Add one or several document(s) to all indexes. + * + * This is an internal function. * @param {document} doc - * @private + * @protected */ addToIndexes (doc) { let failingIndex @@ -437,8 +441,11 @@ class Datastore extends EventEmitter { } /** - * Remove one or several document(s) from all indexes + * Remove one or several document(s) from all indexes. + * + * This is an internal function. * @param {document} doc + * @protected */ removeFromIndexes (doc) { for (const index of Object.values(this.indexes)) { @@ -447,9 +454,13 @@ class Datastore extends EventEmitter { } /** - * Update one or several documents in all indexes - * To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs - * If one update violates a constraint, all changes are rolled back + * Update one or several documents in all indexes. + * + * To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs. + * + * If one update violates a constraint, all changes are rolled back. + * + * This is an internal function. * @param {document|Array.<{oldDoc: document, newDoc: document}>} oldDoc Document to update, or an `Array` of * `{oldDoc, newDoc}` pairs. * @param {document} [newDoc] Document to replace the oldDoc with. If the first argument is an `Array` of @@ -528,12 +539,13 @@ class Datastore extends EventEmitter { * * Returned candidates will be scanned to find and remove all expired documents * + * This is an internal function. * @param {query} query * @param {boolean|function} [dontExpireStaleDocs = false] If true don't remove stale docs. Useful for the remove * function which shouldn't be impacted by expirations. If argument is not given, it is used as the callback. * @param {MultipleDocumentsCallback} callback Signature err, candidates * - * @private + * @protected */ getCandidates (query, dontExpireStaleDocs, callback) { if (typeof dontExpireStaleDocs === 'function') { @@ -545,20 +557,15 @@ class Datastore extends EventEmitter { } /** - * Return the list of candidates for a given query - * Crude implementation for now, we return the candidates given by the first usable index if any - * We try the following query types, in this order: basic match, $in match, comparison match - * One way to make it better would be to enable the use of multiple indexes if the first usable index - * returns too much data. I may do it in the future. - * - * Returned candidates will be scanned to find and remove all expired documents + * Async version of {@link Datastore#getCandidates}. * + * This is an internal function. * @param {query} query * @param {boolean} [dontExpireStaleDocs = false] If true don't remove stale docs. Useful for the remove function * which shouldn't be impacted by expirations. * @return {Promise} candidates - * - * @private + * @see Datastore#getCandidates + * @protected */ async getCandidatesAsync (query, dontExpireStaleDocs = false) { const validDocs = [] @@ -583,22 +590,22 @@ class Datastore extends EventEmitter { /** * Insert a new document - * Private Use Datastore.insert which has the same signature + * This is an internal function, use {@link Datastore#insert} which has the same signature. * @param {document|document[]} newDoc - * @param {SingleDocumentCallback} [callback = () => {}] Optional callback, signature: err, insertedDoc + * @param {SingleDocumentCallback} callback * * @private */ - _insert (newDoc, callback = () => {}) { + _insert (newDoc, callback) { return callbackify(this._insertAsync.bind(this))(newDoc, callback) } /** - * Insert a new document - * Private Use Datastore.insertAsync which has the same signature + * Async version of {@link Datastore#_insert}. * @param {document|document[]} newDoc * @return {Promise} * @private + * @see Datastore#_insert */ async _insertAsync (newDoc) { const preparedDoc = this._prepareDocumentForInsertion(newDoc) @@ -685,26 +692,24 @@ class Datastore extends EventEmitter { } /** - * Insert a new document - * Private Use Datastore.insert which has the same signature + * Insert a new document. * @param {document|document[]} newDoc * @param {SingleDocumentCallback} [callback = () => {}] Optional callback, signature: err, insertedDoc * * @private */ - insert (...args) { - this.executor.push({ this: this, fn: this._insert, arguments: args }) + insert (newDoc, callback = () => {}) { + this.executor.push({ this: this, fn: this._insert, arguments: [newDoc, callback] }) } /** - * Insert a new document - * Private Use Datastore.insertAsync which has the same signature + * Async version of {@link Datastore#insert}. * @param {document|document[]} newDoc * @return {Promise} * @async */ - insertAsync (...args) { - return this.executor.pushAsync(() => this._insertAsync(...args)) + insertAsync (newDoc) { + return this.executor.pushAsync(() => this._insertAsync(newDoc)) } /** @@ -714,7 +719,7 @@ class Datastore extends EventEmitter { */ /** - * Count all documents matching the query + * Count all documents matching the query. * @param {query} query MongoDB-style query * @param {Datastore~countCallback} [callback] If given, the function will return undefined, otherwise it will return the Cursor. * @return {Cursor|undefined} @@ -727,13 +732,13 @@ class Datastore extends EventEmitter { } /** - * Count all documents matching the query + * Async version of {@link Datastore#count}. * @param {query} query MongoDB-style query * @return {Cursor} count * @async */ countAsync (query) { - return new Cursor(this, query, async docs => docs.length, true) // this is a trick, Cursor itself is a thenable, which allows to await it + return new Cursor(this, query, async docs => docs.length, false) } /** @@ -763,15 +768,14 @@ class Datastore extends EventEmitter { } /** - * Find all documents matching the query - * If no callback is passed, we return the cursor so that user can limit, skip and finally exec + * Async version of {@link Datastore#find}. * @param {query} query MongoDB-style query * @param {projection} [projection = {}] MongoDB-style projection * @return {Cursor} * @async */ findAsync (query, projection = {}) { - const cursor = new Cursor(this, query, docs => docs.map(doc => model.deepCopy(doc)), true) + const cursor = new Cursor(this, query, docs => docs.map(doc => model.deepCopy(doc)), false) cursor.projection(projection) return cursor @@ -784,10 +788,10 @@ class Datastore extends EventEmitter { */ /** - * Find one document matching the query + * Find one document matching the query. * @param {query} query MongoDB-style query - * @param {projection} projection MongoDB-style projection - * @param {SingleDocumentCallback} callback Optional callback, signature: err, doc + * @param {projection|SingleDocumentCallback} [projection = {}] MongoDB-style projection + * @param {SingleDocumentCallback} [callback] Optional callback, signature: err, doc * @return {Cursor|undefined} */ findOne (query, projection, callback) { @@ -808,13 +812,14 @@ class Datastore extends EventEmitter { } /** - * Find one document matching the query + * Async version of {@link Datastore#findOne}. * @param {query} query MongoDB-style query * @param {projection} projection MongoDB-style projection * @return {Cursor} + * @see Datastore#findOne */ findOneAsync (query, projection = {}) { - const cursor = new Cursor(this, query, docs => docs.length === 1 ? model.deepCopy(docs[0]) : null, true) + const cursor = new Cursor(this, query, docs => docs.length === 1 ? model.deepCopy(docs[0]) : null, false) cursor.projection(projection).limit(1) return cursor @@ -843,7 +848,8 @@ class Datastore extends EventEmitter { /** * Update all docs matching query. - * Use Datastore.update which has the same signature + * + * Use {@link Datastore#update} which has the same signature. * @param {query} query is the same kind of finding query you use with `find` and `findOne` * @param {document|update} update specifies how the documents should be modified. It is either a new document or a * set of modifiers (you cannot use both together, it doesn't make sense!): @@ -852,7 +858,7 @@ class Datastore extends EventEmitter { * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. - * @param {object|Datastore~updateCallback} [options] Optional options. If not given, is interpreted as the callback. + * @param {object} [options] Optional options. If not given, is interpreted as the callback. * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted @@ -861,17 +867,11 @@ class Datastore extends EventEmitter { * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, * will return the array of documents matched by the find query and updated. Updated documents will be returned even * if the update did not actually modify them. - * @param {Datastore~updateCallback} [cb = () => {}] Optional callback + * @param {Datastore~updateCallback} callback * * @private */ - _update (query, update, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } - const callback = cb || (() => {}) - + _update (query, update, options, callback) { const _callback = (err, res = {}) => { callback(err, res.numAffected, res.affectedDocuments, res.upsert) } @@ -879,8 +879,9 @@ class Datastore extends EventEmitter { } /** - * Update all docs matching query. - * Use Datastore.updateAsync which has the same signature + * Async version of {@link Datastore#_update}. + * + * Use {@link Datastore#updateAsync} which has the same signature. * @param {query} query is the same kind of finding query you use with `find` and `findOne` * @param {document|update} update specifies how the documents should be modified. It is either a new document or a * set of modifiers (you cannot use both together, it doesn't make sense!): @@ -889,7 +890,7 @@ class Datastore extends EventEmitter { * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. - * @param {Object} [options] Optional options + * @param {Object} options options * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted @@ -900,16 +901,16 @@ class Datastore extends EventEmitter { * if the update did not actually modify them. * * @return {Promise<{numAffected: number, affectedDocuments: document[]|document|null, upsert: boolean}>} - * + * @see Datastore#_update * @private */ - async _updateAsync (query, update, options = {}) { + async _updateAsync (query, update, options) { const multi = options.multi !== undefined ? options.multi : false const upsert = options.upsert !== undefined ? options.upsert : false // If upsert option is set, check whether we need to insert the doc if (upsert) { - const cursor = new Cursor(this, query, x => x, true) + const cursor = new Cursor(this, query, x => x, false) // Need to use an internal function not tied to the executor to avoid deadlock const docs = await cursor.limit(1)._execAsync() @@ -970,14 +971,14 @@ class Datastore extends EventEmitter { /** * Update all docs matching query. * @param {query} query is the same kind of finding query you use with `find` and `findOne` - * @param {document|update} update specifies how the documents should be modified. It is either a new document or a + * @param {document|*} update specifies how the documents should be modified. It is either a new document or a * set of modifiers (you cannot use both together, it doesn't make sense!): * - A new document will replace the matched docs * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. - * @param {Object} [options] Optional options + * @param {Object|Datastore~updateCallback} [options|] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted @@ -989,21 +990,26 @@ class Datastore extends EventEmitter { * @param {Datastore~updateCallback} [cb = () => {}] Optional callback * */ - update (...args) { - this.executor.push({ this: this, fn: this._update, arguments: args }) + update (query, update, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + const callback = cb || (() => {}) + this.executor.push({ this: this, fn: this._update, arguments: [query, update, options, callback] }) } /** - * Update all docs matching query. + * Async version of {@link Datastore#update}. * @param {query} query is the same kind of finding query you use with `find` and `findOne` - * @param {document|update} update specifies how the documents should be modified. It is either a new document or a + * @param {document|*} update specifies how the documents should be modified. It is either a new document or a * set of modifiers (you cannot use both together, it doesn't make sense!): * - A new document will replace the matched docs * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. - * @param {Object} [options] Optional options + * @param {Object} [options = {}] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted @@ -1014,9 +1020,10 @@ class Datastore extends EventEmitter { * if the update did not actually modify them. * @async * @return {Promise<{numAffected: number, affectedDocuments: document[]|document|null, upsert: boolean}>} + * @see Datastore#update */ - updateAsync (...args) { - return this.executor.pushAsync(() => this._updateAsync(...args)) + updateAsync (query, update, options = {}) { + return this.executor.pushAsync(() => this._updateAsync(query, update, options)) } /** @@ -1027,33 +1034,31 @@ class Datastore extends EventEmitter { /** * Remove all docs matching the query. - * Use Datastore.remove which has the same signature - * For now very naive implementation (similar to update) + * + * Use {@link Datastore#remove} which has the same signature. + * + * For now very naive implementation (similar to update). * @param {query} query - * @param {object} [options] Optional options + * @param {object} options options * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {Datastore~removeCallback} [cb = () => {}] - * + * @param {Datastore~removeCallback} callback + * @see Datastore#remove * @private */ - _remove (query, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } - const callback = cb || (() => {}) - + _remove (query, options, callback) { callbackify(this._removeAsync.bind(this))(query, options, callback) } /** - * Remove all docs matching the query. - * Use Datastore.removeAsync which has the same signature + * Async version of {@link Datastore#_remove}. + * + * Use {@link Datastore#removeAsync} which has the same signature. * @param {query} query * @param {object} [options] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents * @return {Promise} How many documents were removed * @private + * @see Datastore#_remove */ async _removeAsync (query, options = {}) { const multi = options.multi !== undefined ? options.multi : false @@ -1077,25 +1082,30 @@ class Datastore extends EventEmitter { /** * Remove all docs matching the query. * @param {query} query - * @param {object} [options] Optional options + * @param {object|Datastore~removeCallback} [options={}] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {Datastore~removeCallback} [cb = () => {}] Optional callback, signature: err, numRemoved + * @param {Datastore~removeCallback} [cb = () => {}] Optional callback */ - remove (...args) { - this.executor.push({ this: this, fn: this._remove, arguments: args }) + remove (query, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + const callback = cb || (() => {}) + this.executor.push({ this: this, fn: this._remove, arguments: [query, options, callback] }) } /** * Remove all docs matching the query. * Use Datastore.removeAsync which has the same signature * @param {query} query - * @param {object} [options] Optional options + * @param {object} [options={}] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents * @return {Promise} How many documents were removed * @async */ - removeAsync (...args) { - return this.executor.pushAsync(() => this._removeAsync(...args)) + removeAsync (query, options = {}) { + return this.executor.pushAsync(() => this._removeAsync(query, options)) } } diff --git a/lib/persistence.js b/lib/persistence.js index 414a14e..8588b9e 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -164,7 +164,6 @@ class Persistence { * Do not use directly, it should only used by a {@link Datastore} instance. * @param {document[]} newDocs Can be empty if no doc was updated/removed * @return {Promise} - * @protected * @see Persistence#persistNewState */ async persistNewStateAsync (newDocs) { From 213c639ed67ac494a7484d0a90e93eb06ef56866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 7 Jan 2022 05:26:45 +0100 Subject: [PATCH 42/65] cleanup JSDoc --- docs/Datastore.md | 28 ++++++++++++--------------- lib/datastore.js | 48 +++++++++++++++++++++++------------------------ 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/docs/Datastore.md b/docs/Datastore.md index 25aef46..bd2a3f7 100644 --- a/docs/Datastore.md +++ b/docs/Datastore.md @@ -434,14 +434,12 @@ interpreted as the callback.

- query [query](#query) -

is the same kind of finding query you use with find and findOne

- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a -set of modifiers (you cannot use both together, it doesn't make sense!):

-
    -
  • A new document will replace the matched docs
  • -
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. -Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a -field's value and $min/$max to change field's value, only if provided value is less/greater than current -value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
  • -
+set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the +matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can +apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, +$inc to increment a field's value and $min/$max to change field's value, only if provided value is +less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special +$each and $slice.

- [options|] Object | [updateCallback](#Datastore..updateCallback) -

Optional options

- [.multi] boolean = false -

If true, can update multiple documents

- [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if @@ -464,14 +462,12 @@ if the update did not actually modify them.

- query [query](#query) -

is the same kind of finding query you use with find and findOne

- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a -set of modifiers (you cannot use both together, it doesn't make sense!):

-
    -
  • A new document will replace the matched docs
  • -
  • The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. -Available field modifiers are $set to change a field's value, $unset to delete a field, $inc to increment a -field's value and $min/$max to change field's value, only if provided value is less/greater than current -value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special $each and $slice.
  • -
+set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the +matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can +apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, +$inc to increment a field's value and $min/$max to change field's value, only if provided value is +less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special +$each and $slice.

- [options] Object = {} -

Optional options

- [.multi] boolean = false -

If true, can update multiple documents

- [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if diff --git a/lib/datastore.js b/lib/datastore.js index 63e4a71..a64daef 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -852,12 +852,12 @@ class Datastore extends EventEmitter { * Use {@link Datastore#update} which has the same signature. * @param {query} query is the same kind of finding query you use with `find` and `findOne` * @param {document|update} update specifies how the documents should be modified. It is either a new document or a - * set of modifiers (you cannot use both together, it doesn't make sense!): - * - A new document will replace the matched docs - * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. - * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a - * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current - * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the + * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can + * apply them to subdocs. Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, + * `$inc` to increment a field's value and `$min`/`$max` to change field's value, only if provided value is + * less/greater than current value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special + * `$each` and `$slice`. * @param {object} [options] Optional options. If not given, is interpreted as the callback. * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if @@ -884,12 +884,12 @@ class Datastore extends EventEmitter { * Use {@link Datastore#updateAsync} which has the same signature. * @param {query} query is the same kind of finding query you use with `find` and `findOne` * @param {document|update} update specifies how the documents should be modified. It is either a new document or a - * set of modifiers (you cannot use both together, it doesn't make sense!): - * - A new document will replace the matched docs - * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. - * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a - * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current - * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the + * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can + * apply them to subdocs. Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, + * `$inc` to increment a field's value and `$min`/`$max` to change field's value, only if provided value is + * less/greater than current value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special + * `$each` and `$slice`. * @param {Object} options options * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if @@ -972,12 +972,12 @@ class Datastore extends EventEmitter { * Update all docs matching query. * @param {query} query is the same kind of finding query you use with `find` and `findOne` * @param {document|*} update specifies how the documents should be modified. It is either a new document or a - * set of modifiers (you cannot use both together, it doesn't make sense!): - * - A new document will replace the matched docs - * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. - * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a - * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current - * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the + * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can + * apply them to subdocs. Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, + * `$inc` to increment a field's value and `$min`/`$max` to change field's value, only if provided value is + * less/greater than current value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special + * `$each` and `$slice`. * @param {Object|Datastore~updateCallback} [options|] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if @@ -1003,12 +1003,12 @@ class Datastore extends EventEmitter { * Async version of {@link Datastore#update}. * @param {query} query is the same kind of finding query you use with `find` and `findOne` * @param {document|*} update specifies how the documents should be modified. It is either a new document or a - * set of modifiers (you cannot use both together, it doesn't make sense!): - * - A new document will replace the matched docs - * - The modifiers create the fields they need to modify if they don't exist, and you can apply them to subdocs. - * Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, `$inc` to increment a - * field's value and `$min`/`$max` to change field's value, only if provided value is less/greater than current - * value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` and `$slice`. + * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the + * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can + * apply them to subdocs. Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, + * `$inc` to increment a field's value and `$min`/`$max` to change field's value, only if provided value is + * less/greater than current value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special + * `$each` and `$slice`. * @param {Object} [options = {}] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if From fab5b0336b336fb3f420c98830e40e73c0cb72fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 7 Jan 2022 19:32:11 +0100 Subject: [PATCH 43/65] rewrite Readme --- CHANGELOG.md | 1 + README.md | 844 +++++++++++++++++++-------------------------- docs/byline.md | 10 + jsdoc2md.js | 1 + lib/byline.js | 9 +- lib/datastore.js | 11 +- lib/persistence.js | 35 +- test/db.test.js | 1 + 8 files changed, 419 insertions(+), 493 deletions(-) create mode 100644 docs/byline.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 013c8b2..9542b88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Added - Added an async interface for all functions - The JSDoc is now much more exhaustive +- Added markdown documentation generated from the JSDoc ### Changed - All the functions are now async at the core, and a fully retro-compatible callback-ified version is exposed. diff --git a/README.md b/README.md index 02d614a..3a8f65c 100755 --- a/README.md +++ b/README.md @@ -20,91 +20,46 @@ Module name on npm is [`@seald-io/nedb`](https://www.npmjs.com/package/@seald-io npm install @seald-io/nedb ``` -## API - -It is a subset of MongoDB's API (the most used operations). - -* [Creating/loading a database](#creatingloading-a-database) -* [Persistence](#persistence) -* [Inserting documents](#inserting-documents) -* [Finding documents](#finding-documents) - * [Basic Querying](#basic-querying) - * [Operators ($lt, $lte, $gt, $gte, $in, $nin, $ne, $stat, $regex)](#operators-lt-lte-gt-gte-in-nin-ne-stat-regex) - * [Array fields](#array-fields) - * [Logical operators $or, $and, $not, $where](#logical-operators-or-and-not-where) - * [Sorting and paginating](#sorting-and-paginating) - * [Projections](#projections) -* [Counting documents](#counting-documents) -* [Updating documents](#updating-documents) -* [Removing documents](#removing-documents) -* [Indexing](#indexing) -* [Browser version](#browser-version) +Then to import, you just have to: + +```js +const Datastore = require('@seald-io/nedb') +``` + +## Documentation +The API is a subset of MongoDB's API (the most used operations). + +### JSDoc +You can read the markdown version of the JSDoc [in the docs directory](./docs). +It is generated by running `npm run generateDocs:markdown`. Some links don't +work (when referencing items from other files), because I split manually the +documentation into several files. We should rewrite the links with a custom +configuration of [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown): PR welcome. + +You can also generate an HTML version `npm run generateDocs:html`, links from the Readme won't work though. + +### Promise-based interface vs callback-based interface +Since version 3.0.0, NeDB provides a Promise-based equivalent for each function +which is suffixed with `Async`, for example `loadDatabaseAsync`. + +The original callback-based interface is still available, fully retro-compatible +(as far as the test suites can tell) and are a shim to this Promise-based +version. + +Don't hesitate to open an issue if it breaks something in your project. + +The rest of the readme will only show the Promise-based API, the full +documentation is available in the [`docs`](./docs) directory of the repository. ### Creating/loading a database You can use NeDB as an in-memory only datastore or as a persistent datastore. One datastore is the equivalent of a MongoDB collection. The constructor is used -as follows `new Datastore(options)` where `options` is an object with the -following fields: - -* `filename` (optional): path to the file where the data is persisted. If left - blank, the datastore is automatically considered in-memory only. It cannot end - with a `~` which is used in the temporary files NeDB uses to perform - crash-safe writes. -* `inMemoryOnly` (optional, defaults to `false`): as the name implies. -* `timestampData` (optional, defaults to `false`): timestamp the insertion and - last update of all documents, with the fields `createdAt` and `updatedAt`. - User-specified values override automatic generation, usually useful for - testing. -* `autoload` (optional, defaults to `false`): if used, the database will - automatically be loaded from the datafile upon creation (you don't need to - call `loadDatabase`). Any command issued before load is finished is buffered - and will be executed when load is done. -* `onload` (optional): if you use autoloading, this is the handler called after - the `loadDatabase`. It takes one `error` argument. If you use autoloading - without specifying this handler, and an error happens during load, an error - will be thrown. -* `afterSerialization` (optional): hook you can use to transform data after it - was serialized and before it is written to disk. Can be used for example to - encrypt data before writing database to disk. This function takes a string as - parameter (one line of an NeDB data file) and outputs the transformed - string, **which must absolutely not contain a `\n` character** (or data will - be lost). -* `beforeDeserialization` (optional): inverse of `afterSerialization`. Make sure - to include both and not just one or you risk data loss. For the same reason, - make sure both functions are inverses of one another. Some failsafe mechanisms - are in place to prevent data loss if you misuse the serialization hooks: NeDB - checks that never one is declared without the other, and checks that they are - reverse of one another by testing on random strings of various lengths. In - addition, if too much data is detected as corrupt, NeDB will refuse to start - as it could mean you're not using the deserialization hook corresponding to - the serialization hook used before (see below). -* `corruptAlertThreshold` (optional): between 0 and 1, defaults to 10%. NeDB - will refuse to start if more than this percentage of the datafile is corrupt. - 0 means you don't tolerate any corruption, 1 means you don't care. -* `compareStrings` (optional): function compareStrings(a, b) compares strings a - and b and return -1, 0 or 1. If specified, it overrides default string - comparison which is not well adapted to non-US characters in particular - accented letters. Native `localCompare` will most of the time be the right - choice -* `nodeWebkitAppName` (optional, **DEPRECATED**): if you are using NeDB from - whithin a Node Webkit app, specify its name (the same one you use in - the `package.json`) in this field and the `filename` will be relative to the - directory Node Webkit uses to store the rest of the application's data (local - storage etc.). It works on Linux, OS X and Windows. Now that you can - use `require('nw.gui').App.dataPath` in Node Webkit to get the path to the - data directory for your application, you should not use this option anymore - and it will be removed. - -If you use a persistent datastore without the `autoload` option, you need to -call `loadDatabase` manually. This function fetches the data from datafile and -prepares the database. **Don't forget it!** If you use a persistent datastore, -no command (insert, find, update, remove) will be executed before `loadDatabase` -is called, so make sure to call it yourself or use the `autoload` option. - -Also, if `loadDatabase` fails, all commands registered to the executor -afterwards will not be executed. They will be registered and executed, in -sequence, only after a successful `loadDatabase`. +as follows [`new Datastore(options)` where `options` is an object](./docs/Datastore.md#new_Datastore_new). + +If the Datastore is persistent (if you give it [`options.filename`](./docs/Datastore.md#Datastore+filename), +you'll need to load the database using [Datastore#loadDatabaseAsync](./docs/Datastore.md#Datastore+loadDatabaseAsync), +or using [`options.autoload`](./docs/Datastore.md#Datastore+autoload). ```javascript // Type 1: In-memory only datastore (no need to load the database) @@ -114,68 +69,43 @@ const db = new Datastore() // Type 2: Persistent datastore with manual loading const Datastore = require('@seald-io/nedb') const db = new Datastore({ filename: 'path/to/datafile' }) -db.loadDatabase(function (err) { // Callback is optional - // Now commands will be executed -}) - +try { + await db.loadDatabaseAsync() +} catch (error) { + // loading has failed +} +// loading has succeeded + // Type 3: Persistent datastore with automatic loading const Datastore = require('@seald-io/nedb') -const db = new Datastore({ filename: 'path/to/datafile', autoload: true }); +const db = new Datastore({ filename: 'path/to/datafile', autoload: true }) // You can await db.autoloadPromise to catch a potential error when autoloading. // You can issue commands right away -// Type 4: Persistent datastore for a Node Webkit app called 'nwtest' -// For example on Linux, the datafile will be ~/.config/nwtest/nedb-data/something.db -const Datastore = require('@seald-io/nedb') -const path = require('path') -const db = new Datastore({ filename: path.join(require('nw.gui').App.dataPath, 'something.db') }); - // Of course you can create multiple datastores if you need several // collections. In this case it's usually a good idea to use autoload for all collections. -db = {}; -db.users = new Datastore('path/to/users.db'); -db.robots = new Datastore('path/to/robots.db'); +db = {} +db.users = new Datastore('path/to/users.db') +db.robots = new Datastore('path/to/robots.db') -// You need to load each database (here we do it asynchronously) -db.users.loadDatabase(); -db.robots.loadDatabase(); +// You need to load each database +await db.users.loadDatabaseAsync() +await db.robots.loadDatabaseAsync() ``` ### Persistence -Under the hood, NeDB's persistence uses an append-only format, meaning that all -updates and deletes actually result in lines added at the end of the datafile, -for performance reasons. The database is automatically compacted (i.e. put back -in the one-line-per-document format) every time you load each database within -your application. +Under the hood, NeDB's [persistence](./docs/Persistence.md) uses an append-only +format, meaning that all updates and deletes actually result in lines added at +the end of the datafile, for performance reasons. The database is automatically +compacted (i.e. put back in the one-line-per-document format) every time you +load each database within your application. You can manually call the compaction function -with `yourDatabase.persistence.compactDatafile` which takes no argument. It -queues a compaction of the datafile in the executor, to be executed sequentially -after all pending operations. The datastore will fire a `compaction.done` event -once compaction is finished. +with [`yourDatabase#persistence#compactDatafileAsync`](./docs/Persistence.md#Persistence+compactDatafileAsync). You can also set automatic compaction at regular intervals -with `yourDatabase.persistence.setAutocompactionInterval(interval)`, `interval` -in milliseconds (a minimum of 5s is enforced), and stop automatic compaction -with `yourDatabase.persistence.stopAutocompaction()`. - -Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k -records on a typical development machine) and no other operation can happen when -it does, so most projects actually don't need to use it. - -Compaction will also immediately remove any documents whose data line has become -corrupted, assuming that the total percentage of all corrupted documents in that -database still falls below the specified `corruptAlertThreshold` option's value. - -Durability works similarly to major databases: compaction forces the OS to -physically flush data to disk, while appends to the data file do not (the OS is -responsible for flushing the data). That guarantees that a server crash can -never cause complete data loss, while preserving performance. The worst that can -happen is a crash between two syncs, causing a loss of all data between the two -syncs. Usually syncs are 30 seconds appart so that's at most 30 seconds of -data. [This post by Antirez on Redis persistence](http://oldblog.antirez.com/post/redis-persistence-demystified.html) -explains this in more details, NeDB being very close to Redis AOF persistence -with `appendfsync` option set to `no`. +with [`yourDatabase#persistence#setAutocompactionInterval`](./docs/Persistence.md#Persistence+setAutocompactionInterval), +and stop automatic compaction with [`yourDatabase#persistence#stopAutocompaction`](./docs/Persistence.md#Persistence+stopAutocompaction). ### Inserting documents @@ -185,13 +115,13 @@ not be saved (this is different from MongoDB which transforms `undefined` in `null`, something I find counter-intuitive). If the document does not contain an `_id` field, NeDB will automatically -generated one for you (a 16-characters alphanumerical string). The `_id` of a +generate one for you (a 16-characters alphanumerical string). The `_id` of a document, once set, cannot be modified. Field names cannot begin by '$' or contain a '.'. ```javascript -var doc = { +const doc = { hello: 'world', n: 5, today: new Date(), @@ -202,10 +132,13 @@ var doc = { infos: { name: '@seald-io/nedb' } } -db.insert(doc, function (err, newDoc) { // Callback is optional +try { + const newDoc = await db.insertAsync(doc) // newDoc is the newly inserted document, including its _id // newDoc has no key called notToBeSaved since its value was undefined -}) +} catch (error) { + // if an error happens +} ``` You can also bulk-insert an array of documents. This operation is atomic, @@ -213,21 +146,23 @@ meaning that if one insert fails due to a unique constraint being violated, all changes are rolled back. ```javascript -db.insert([{ a: 5 }, { a: 42 }], function (err, newDocs) { - // Two documents were inserted in the database - // newDocs is an array with these documents, augmented with their _id -}) +const newDocs = await db.insertAsync([{ a: 5 }, { a: 42 }]) +// Two documents were inserted in the database +// newDocs is an array with these documents, augmented with their _id + // If there is a unique constraint on field 'a', this will fail -db.insert([{ a: 5 }, { a: 42 }, { a: 5 }], function (err) { +try { + await db.insertAsync([{ a: 5 }, { a: 42 }, { a: 5 }]) +} catch (error) { // err is a 'uniqueViolated' error // The database was not modified -}) +} ``` ### Finding documents -Use `find` to look for multiple documents matching you query, or `findOne` to +Use `findAsync` to look for multiple documents matching you query, or `findOneAsync` to look for one specific document. You can select documents based on field equality or use comparison operators (`$lt`, `$lte`, `$gt`, `$gte`, `$in`, `$nin`, `$ne`) . You can also use logical operators `$or`, `$and`, `$not` and `$where`. See @@ -257,54 +192,48 @@ to match a specific element of an array. // { _id: 'id5', completeData: { planets: [ { name: 'Earth', number: 3 }, { name: 'Mars', number: 2 }, { name: 'Pluton', number: 9 } ] } } // Finding all planets in the solar system -db.find({ system: 'solar' }, function (err, docs) { - // docs is an array containing documents Mars, Earth, Jupiter - // If no document is found, docs is equal to [] -}) +const docs = await db.findAsync({ system: 'solar' }) +// docs is an array containing documents Mars, Earth, Jupiter +// If no document is found, docs is equal to [] + // Finding all planets whose name contain the substring 'ar' using a regular expression -db.find({ planet: /ar/ }, function (err, docs) { - // docs contains Mars and Earth -}) +const docs = await db.findAsync({ planet: /ar/ }) +// docs contains Mars and Earth // Finding all inhabited planets in the solar system -db.find({ system: 'solar', inhabited: true }, function (err, docs) { - // docs is an array containing document Earth only -}) +const docs = await db.findAsync({ system: 'solar', inhabited: true }) +// docs is an array containing document Earth only // Use the dot-notation to match fields in subdocuments -db.find({ 'humans.genders': 2 }, function (err, docs) { - // docs contains Earth -}) +const docs = await db.findAsync({ 'humans.genders': 2 }) +// docs contains Earth + // Use the dot-notation to navigate arrays of subdocuments -db.find({ 'completeData.planets.name': 'Mars' }, function (err, docs) { - // docs contains document 5 -}) +const docs = await db.findAsync({ 'completeData.planets.name': 'Mars' }) +// docs contains document 5 -db.find({ 'completeData.planets.name': 'Jupiter' }, function (err, docs) { - // docs is empty -}) +const docs = await db.findAsync({ 'completeData.planets.name': 'Jupiter' }) +// docs is empty + +const docs = await db.findAsync({ 'completeData.planets.0.name': 'Earth' }) +// docs contains document 5 +// If we had tested against 'Mars' docs would be empty because we are matching against a specific array element -db.find({ 'completeData.planets.0.name': 'Earth' }, function (err, docs) { - // docs contains document 5 - // If we had tested against 'Mars' docs would be empty because we are matching against a specific array element -}) // You can also deep-compare objects. Don't confuse this with dot-notation! -db.find({ humans: { genders: 2 } }, function (err, docs) { - // docs is empty, because { genders: 2 } is not equal to { genders: 2, eyes: true } -}) +const docs = await db.findAsync({ humans: { genders: 2 } }) +// docs is empty, because { genders: 2 } is not equal to { genders: 2, eyes: true } + // Find all documents in the collection -db.find({}, function (err, docs) { -}) +const docs = await db.findAsync({}) // The same rules apply when you want to only find one document -db.findOne({ _id: 'id1' }, function (err, doc) { - // doc is the document Mars - // If no document is found, doc is null -}) +const doc = await db.findOneAsync({ _id: 'id1' }) +// doc is the document Mars +// If no document is found, doc is null ``` #### Operators ($lt, $lte, $gt, $gte, $in, $nin, $ne, $stat, $regex) @@ -326,34 +255,29 @@ operator: ```javascript // $lt, $lte, $gt and $gte work on numbers and strings -db.find({ 'humans.genders': { $gt: 5 } }, function (err, docs) { - // docs contains Omicron Persei 8, whose humans have more than 5 genders (7). -}) +const docs = await db.findAsync({ 'humans.genders': { $gt: 5 } }) +// docs contains Omicron Persei 8, whose humans have more than 5 genders (7). // When used with strings, lexicographical order is used -db.find({ planet: { $gt: 'Mercury' } }, function (err, docs) { - // docs contains Omicron Persei 8 -}) +const docs = await db.findAsync({ planet: { $gt: 'Mercury' } }) +// docs contains Omicron Persei 8 // Using $in. $nin is used in the same way -db.find({ planet: { $in: ['Earth', 'Jupiter'] } }, function (err, docs) { - // docs contains Earth and Jupiter -}) +const docs = await db.findAsync({ planet: { $in: ['Earth', 'Jupiter'] } }) +// docs contains Earth and Jupiter // Using $stat -db.find({ satellites: { $stat: true } }, function (err, docs) { - // docs contains only Mars -}) +const docs = await db.findAsync({ satellites: { $stat: true } }) +// docs contains only Mars // Using $regex with another operator -db.find({ +const docs = await db.findAsync({ planet: { $regex: /ar/, $nin: ['Jupiter', 'Earth'] } -}, function (err, docs) { - // docs only contains Mars because Earth was excluded from the match by $nin }) +// docs only contains Mars because Earth was excluded from the match by $nin ``` #### Array fields @@ -369,16 +293,15 @@ element and there is a match if at least one element matches. ```javascript // Exact match -db.find({ satellites: ['Phobos', 'Deimos'] }, function (err, docs) { - // docs contains Mars -}) -db.find({ satellites: ['Deimos', 'Phobos'] }, function (err, docs) { - // docs is empty -}) +const docs = await db.findAsync({ satellites: ['Phobos', 'Deimos'] }) +// docs contains Mars + +const docs = await db.findAsync({ satellites: ['Deimos', 'Phobos'] }) +// docs is empty // Using an array-specific comparison function // $elemMatch operator will provide match for a document, if an element from the array field satisfies all the conditions specified with the `$elemMatch` operator -db.find({ +const docs = await db.findAsync({ completeData: { planets: { $elemMatch: { @@ -387,11 +310,10 @@ db.find({ } } } -}, function (err, docs) { - // docs contains documents with id 5 (completeData) }) +// docs contains documents with id 5 (completeData) -db.find({ +const docs = await db.findAsync({ completeData: { planets: { $elemMatch: { @@ -400,12 +322,11 @@ db.find({ } } } -}, function (err, docs) { - // docs is empty }) +// docs is empty // You can use inside #elemMatch query any known document query operator -db.find({ +const docs = await db.findAsync({ completeData: { planets: { $elemMatch: { @@ -414,33 +335,27 @@ db.find({ } } } -}, function (err, docs) { - // docs contains documents with id 5 (completeData) }) +// docs contains documents with id 5 (completeData) // Note: you can't use nested comparison functions, e.g. { $size: { $lt: 5 } } will throw an error -db.find({ satellites: { $size: 2 } }, function (err, docs) { - // docs contains Mars -}) +const docs = await db.findAsync({ satellites: { $size: 2 } }) +// docs contains Mars -db.find({ satellites: { $size: 1 } }, function (err, docs) { - // docs is empty -}) +const docs = await db.findAsync({ satellites: { $size: 1 } }) +// docs is empty // If a document's field is an array, matching it means matching any element of the array -db.find({ satellites: 'Phobos' }, function (err, docs) { - // docs contains Mars. Result would have been the same if query had been { satellites: 'Deimos' } -}) +const docs = await db.findAsync({ satellites: 'Phobos' }) +// docs contains Mars. Result would have been the same if query had been { satellites: 'Deimos' } // This also works for queries that use comparison operators -db.find({ satellites: { $lt: 'Amos' } }, function (err, docs) { - // docs is empty since Phobos and Deimos are after Amos in lexicographical order -}) +const docs = await db.findAsync({ satellites: { $lt: 'Amos' } }) +// docs is empty since Phobos and Deimos are after Amos in lexicographical order // This also works with the $in and $nin operator -db.find({ satellites: { $in: ['Moon', 'Deimos'] } }, function (err, docs) { - // docs contains Mars (the Earth document is not complete!) -}) +const docs = await db.findAsync({ satellites: { $in: ['Moon', 'Deimos'] } }) +// docs contains Mars (the Earth document is not complete!) ``` #### Logical operators $or, $and, $not, $where @@ -453,33 +368,36 @@ You can combine queries using logical operators: is `{ $where: function () { /* object is 'this', return a boolean */ } }` ```javascript -db.find({ $or: [{ planet: 'Earth' }, { planet: 'Mars' }] }, function (err, docs) { - // docs contains Earth and Mars -}) +const docs = await db.findAsync({ $or: [{ planet: 'Earth' }, { planet: 'Mars' }] }) +// docs contains Earth and Mars -db.find({ $not: { planet: 'Earth' } }, function (err, docs) { - // docs contains Mars, Jupiter, Omicron Persei 8 -}) +const docs = await db.findAsync({ $not: { planet: 'Earth' } }) +// docs contains Mars, Jupiter, Omicron Persei 8 -db.find({ $where: function () { return Object.keys(this) > 6; } }, function (err, docs) { - // docs with more than 6 properties -}) +const docs = await db.findAsync({ $where: function () { return Object.keys(this) > 6 } }) +// docs with more than 6 properties // You can mix normal queries, comparison queries and logical operators -db.find({ +const docs = await db.findAsync({ $or: [{ planet: 'Earth' }, { planet: 'Mars' }], inhabited: true -}, function (err, docs) { - // docs contains Earth }) - +// docs contains Earth ``` #### Sorting and paginating -If you don't specify a callback to `find`, `findOne` or `count`, a `Cursor` -object is returned. You can modify the cursor with `sort`, `skip` and `limit`and -then execute it with `exec(callback)`. +[`Datastore#findAsync`](./docs/Datastore.md#Datastore+findAsync), +[`Datastore#findOneAsync`](./docs/Datastore.md#Datastore+findOneAsync) and +[`Datastore#countAsync`](./docs/Datastore.md#Datastore+countAsync) don't +actually return a `Promise`, but a [`Cursor`](./docs/Cursor.md) which is a +[`Thenable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#thenable_objects) +which calls [`Cursor#execAsync`](./docs/Cursor.md#Cursor+execAsync) when awaited. + +This pattern allows to chain [`Cursor#sort`](./docs/Cursor.md#Cursor+sort), +[`Cursor#skip`](./docs/Cursor.md#Cursor+skip), +[`Cursor#limit`](./docs/Cursor.md#Cursor+limit) and +[`Cursor#projection`](./docs/Cursor.md#Cursor+projection) and await the result. ```javascript // Let's say the database contains these 4 documents @@ -489,23 +407,21 @@ then execute it with `exec(callback)`. // doc4 = { _id: 'id4', planet: 'Omicron Persei 8', system: 'futurama', inhabited: true, humans: { genders: 7 } } // No query used means all results are returned (before the Cursor modifiers) -db.find({}).sort({ planet: 1 }).skip(1).limit(2).exec(function (err, docs) { - // docs is [doc3, doc1] -}) +const docs = await db.findAsync({}).sort({ planet: 1 }).skip(1).limit(2) +// docs is [doc3, doc1] // You can sort in reverse order like this -db.find({ system: 'solar' }).sort({ planet: -1 }).exec(function (err, docs) { - // docs is [doc1, doc3, doc2] -}) +const docs = await db.findAsync({ system: 'solar' }).sort({ planet: -1 }) +// docs is [doc1, doc3, doc2] // You can sort on one field, then another, and so on like this: -db.find({}).sort({ firstField: 1, secondField: -1 }) +const docs = await db.findAsync({}).sort({ firstField: 1, secondField: -1 }) // ... You understand how this works! ``` #### Projections -You can give `find` and `findOne` an optional second argument, `projections`. +You can give `findAsync` and `findOneAsync` an optional second argument, `projections`. The syntax is the same as MongoDB: `{ a: 1, b: 1 }` to return only the `a` and `b` fields, `{ a: 0, b: 0 }` to omit these two fields. You cannot use both modes at the time, except for `_id` which is by default always returned and @@ -515,110 +431,85 @@ which you can choose to omit. You can project on nested documents. // Same database as above // Keeping only the given fields -db.find({ planet: 'Mars' }, { planet: 1, system: 1 }, function (err, docs) { - // docs is [{ planet: 'Mars', system: 'solar', _id: 'id1' }] -}) +const docs = await db.findAsync({ planet: 'Mars' }, { planet: 1, system: 1 }) +// docs is [{ planet: 'Mars', system: 'solar', _id: 'id1' }] // Keeping only the given fields but removing _id -db.find({ planet: 'Mars' }, { +const docs = await db.findAsync({ planet: 'Mars' }, { planet: 1, system: 1, _id: 0 -}, function (err, docs) { - // docs is [{ planet: 'Mars', system: 'solar' }] }) +// docs is [{ planet: 'Mars', system: 'solar' }] // Omitting only the given fields and removing _id -db.find({ planet: 'Mars' }, { +const docs = await db.findAsync({ planet: 'Mars' }, { planet: 0, system: 0, _id: 0 -}, function (err, docs) { - // docs is [{ inhabited: false, satellites: ['Phobos', 'Deimos'] }] }) +// docs is [{ inhabited: false, satellites: ['Phobos', 'Deimos'] }] // Failure: using both modes at the same time -db.find({ planet: 'Mars' }, { planet: 0, system: 1 }, function (err, docs) { - // err is the error message, docs is undefined -}) +const docs = await db.findAsync({ planet: 'Mars' }, { planet: 0, system: 1 }) +// err is the error message, docs is undefined // You can also use it in a Cursor way but this syntax is not compatible with MongoDB -db.find({ planet: 'Mars' }).projection({ +const docs = await db.findAsync({ planet: 'Mars' }).projection({ planet: 1, system: 1 -}).exec(function (err, docs) { - // docs is [{ planet: 'Mars', system: 'solar', _id: 'id1' }] }) +// docs is [{ planet: 'Mars', system: 'solar', _id: 'id1' }] // Project on a nested document -db.findOne({ planet: 'Earth' }).projection({ +const doc = await db.findOneAsync({ planet: 'Earth' }).projection({ planet: 1, 'humans.genders': 1 -}).exec(function (err, doc) { - // doc is { planet: 'Earth', _id: 'id2', humans: { genders: 2 } } }) +// doc is { planet: 'Earth', _id: 'id2', humans: { genders: 2 } } ``` ### Counting documents -You can use `count` to count documents. It has the same syntax as `find`. For -example: +You can use `countAsync` to count documents. It has the same syntax as `findAsync`. +For example: ```javascript // Count all planets in the solar system -db.count({ system: 'solar' }, function (err, count) { - // count equals to 3 -}); +const count = await db.countAsync({ system: 'solar' }) +// count equals to 3 // Count all documents in the datastore -db.count({}, function (err, count) { - // count equals to 4 -}); +const count = await db.countAsync({}) +// count equals to 4 ``` ### Updating documents -`db.update(query, update, options, callback)` will update all documents -matching `query` according to the `update` rules: - -* `query` is the same kind of finding query you use with `find` and `findOne` -* `update` specifies how the documents should be modified. It is either a new - document or a set of modifiers (you cannot use both together, it doesn't make - sense!) - * A new document will replace the matched docs - * The modifiers create the fields they need to modify if they don't exist, - and you can apply them to subdocs. Available field modifiers are `$set` to - change a field's value, `$unset` to delete a field, `$inc` to increment a - field's value and `$min`/`$max` to change field's value, only if provided - value is less/greater than current value. To work on arrays, you - have `$push`, `$pop`, `$addToSet`, `$pull`, and the special `$each` - and `$slice`. See examples below for the syntax. -* `options` is an object with two possible parameters - * `multi` (defaults to `false`) which allows the modification of several - documents if set to true - * `upsert` (defaults to `false`) if you want to insert a new document - corresponding to the `update` rules if your `query` doesn't match - anything. If your `update` is a simple object with no modifiers, it is the - inserted document. In the other case, the `query` is stripped from all - operator recursively, and the `update` is applied to it. - * `returnUpdatedDocs` (defaults to `false`, not MongoDB-compatible) if set - to true and update is not an upsert, will return the array of documents - matched by the find query and updated. Updated documents will be returned - even if the update did not actually modify them. -* `callback` (optional) - signature: `(err, numAffected, affectedDocuments, upsert)`. **Warning**: the - API was changed between v1.7.4 and v1.8. Please refer to - the [previous changelog](https://github.com/louischatriot/nedb/wiki/Change-log) - to see the change. - * For an upsert, `affectedDocuments` contains the inserted document and - the `upsert` flag is set to `true`. - * For a standard update with `returnUpdatedDocs` flag set to `false` - , `affectedDocuments` is not set. - * For a standard update with `returnUpdatedDocs` flag set to `true` - and `multi` to `false`, `affectedDocuments` is the updated document. - * For a standard update with `returnUpdatedDocs` flag set to `true` - and `multi` to `true`, `affectedDocuments` is the array of updated - documents. +[`db.updateAsync(query, update, options)`](./docs/Datastore.md#Datastore+updateAsync) +will update all documents matching `query` according to the `update` rules. + +`update` specifies how the documents should be modified. It is either a new +document or a set of modifiers (you cannot use both together): +* A new document will replace the matched docs; +* Modifiers create the fields they need to modify if they don't exist, + and you can apply them to subdocs (see [the API reference]((./docs/Datastore.md#Datastore+updateAsync))) + +`options` is an object with three possible parameters: +* `multi` which allows the modification of several documents if set to true. +* `upsert` will insert a new document corresponding if it doesn't exist (either +the `update` is a simple object with no modifiers, or the `query` modified by +the modifiers in the `update`) if set to `true`. +* `returnUpdatedDocs` will return the array of documents matched by the find +query and updated (updated documents will be returned even if the update did not +actually modify them) if set to `true`. + +It resolves into an Object with the following properties: +- `numAffected`: how many documents were affected by the update; +- `upsert`: if a document was actually upserted (not always the same as `options.upsert`; +- `affectedDocuments`: + - if `upsert` is `true` the document upserted; + - if `options.returnUpdatedDocs` is `true` either the affected document or, if `options.multi` is `true` an Array of the affected documents, else `null`; **Note**: you can't change a document's _id. @@ -630,132 +521,125 @@ matching `query` according to the `update` rules: // { _id: 'id4', planet: 'Omicron Persia 8', system: 'futurama', inhabited: true } // Replace a document by another -db.update({ planet: 'Jupiter' }, { planet: 'Pluton' }, {}, function (err, numReplaced) { - // numReplaced = 1 - // The doc #3 has been replaced by { _id: 'id3', planet: 'Pluton' } - // Note that the _id is kept unchanged, and the document has been replaced - // (the 'system' and inhabited fields are not here anymore) -}); +const { numReplaced } = await db.updateAsync({ planet: 'Jupiter' }, { planet: 'Pluton' }, {}) +// numReplaced = 1 +// The doc #3 has been replaced by { _id: 'id3', planet: 'Pluton' } +// Note that the _id is kept unchanged, and the document has been replaced +// (the 'system' and inhabited fields are not here anymore) + // Set an existing field's value -db.update({ system: 'solar' }, { $set: { system: 'solar system' } }, { multi: true }, function (err, numReplaced) { - // numReplaced = 3 - // Field 'system' on Mars, Earth, Jupiter now has value 'solar system' -}); +const { numReplaced } = await db.updateAsync({ system: 'solar' }, { $set: { system: 'solar system' } }, { multi: true }) +// numReplaced = 3 +// Field 'system' on Mars, Earth, Jupiter now has value 'solar system' + // Setting the value of a non-existing field in a subdocument by using the dot-notation -db.update({ planet: 'Mars' }, { +await db.updateAsync({ planet: 'Mars' }, { $set: { 'data.satellites': 2, 'data.red': true } -}, {}, function () { - // Mars document now is { _id: 'id1', system: 'solar', inhabited: false - // , data: { satellites: 2, red: true } - // } - // Not that to set fields in subdocuments, you HAVE to use dot-notation - // Using object-notation will just replace the top-level field - db.update({ planet: 'Mars' }, { $set: { data: { satellites: 3 } } }, {}, function () { - // Mars document now is { _id: 'id1', system: 'solar', inhabited: false - // , data: { satellites: 3 } - // } - // You lost the 'data.red' field which is probably not the intended behavior - }); -}); +}, {}) +// Mars document now is { _id: 'id1', system: 'solar', inhabited: false +// , data: { satellites: 2, red: true } +// } +// Not that to set fields in subdocuments, you HAVE to use dot-notation +// Using object-notation will just replace the top-level field +await db.updateAsync({ planet: 'Mars' }, { $set: { data: { satellites: 3 } } }, {}) +// Mars document now is { _id: 'id1', system: 'solar', inhabited: false +// , data: { satellites: 3 } +// } +// You lost the 'data.red' field which is probably not the intended behavior + // Deleting a field -db.update({ planet: 'Mars' }, { $unset: { planet: true } }, {}, function () { - // Now the document for Mars doesn't contain the planet field - // You can unset nested fields with the dot notation of course -}); +await db.updateAsync({ planet: 'Mars' }, { $unset: { planet: true } }, {}) +// Now the document for Mars doesn't contain the planet field +// You can unset nested fields with the dot notation of course + // Upserting a document -db.update({ planet: 'Pluton' }, { +const { numReplaced, affectedDocuments, upsert } = await db.updateAsync({ planet: 'Pluton' }, { planet: 'Pluton', inhabited: false -}, { upsert: true }, function (err, numReplaced, upsert) { - // numReplaced = 1, upsert = { _id: 'id5', planet: 'Pluton', inhabited: false } - // A new document { _id: 'id5', planet: 'Pluton', inhabited: false } has been added to the collection -}); +}, { upsert: true }) +// numReplaced = 1, affectedDocuments = { _id: 'id5', planet: 'Pluton', inhabited: false }, upsert = true +// A new document { _id: 'id5', planet: 'Pluton', inhabited: false } has been added to the collection + // If you upsert with a modifier, the upserted doc is the query modified by the modifier // This is simpler than it sounds :) -db.update({ planet: 'Pluton' }, { $inc: { distance: 38 } }, { upsert: true }, function () { - // A new document { _id: 'id5', planet: 'Pluton', distance: 38 } has been added to the collection -}); +await db.updateAsync({ planet: 'Pluton' }, { $inc: { distance: 38 } }, { upsert: true }) +// A new document { _id: 'id5', planet: 'Pluton', distance: 38 } has been added to the collection + // If we insert a new document { _id: 'id6', fruits: ['apple', 'orange', 'pear'] } in the collection, // let's see how we can modify the array field atomically // $push inserts new elements at the end of the array -db.update({ _id: 'id6' }, { $push: { fruits: 'banana' } }, {}, function () { - // Now the fruits array is ['apple', 'orange', 'pear', 'banana'] -}); +await db.updateAsync({ _id: 'id6' }, { $push: { fruits: 'banana' } }, {}) +// Now the fruits array is ['apple', 'orange', 'pear', 'banana'] + // $pop removes an element from the end (if used with 1) or the front (if used with -1) of the array -db.update({ _id: 'id6' }, { $pop: { fruits: 1 } }, {}, function () { - // Now the fruits array is ['apple', 'orange'] - // With { $pop: { fruits: -1 } }, it would have been ['orange', 'pear'] -}); +await db.updateAsync({ _id: 'id6' }, { $pop: { fruits: 1 } }, {}) +// Now the fruits array is ['apple', 'orange'] +// With { $pop: { fruits: -1 } }, it would have been ['orange', 'pear'] + // $addToSet adds an element to an array only if it isn't already in it // Equality is deep-checked (i.e. $addToSet will not insert an object in an array already containing the same object) // Note that it doesn't check whether the array contained duplicates before or not -db.update({ _id: 'id6' }, { $addToSet: { fruits: 'apple' } }, {}, function () { - // The fruits array didn't change - // If we had used a fruit not in the array, e.g. 'banana', it would have been added to the array -}); +await db.updateAsync({ _id: 'id6' }, { $addToSet: { fruits: 'apple' } }, {}) +// The fruits array didn't change +// If we had used a fruit not in the array, e.g. 'banana', it would have been added to the array // $pull removes all values matching a value or even any NeDB query from the array -db.update({ _id: 'id6' }, { $pull: { fruits: 'apple' } }, {}, function () { - // Now the fruits array is ['orange', 'pear'] -}); -db.update({ _id: 'id6' }, { $pull: { fruits: { $in: ['apple', 'pear'] } } }, {}, function () { - // Now the fruits array is ['orange'] -}); +await db.updateAsync({ _id: 'id6' }, { $pull: { fruits: 'apple' } }, {}) +// Now the fruits array is ['orange', 'pear'] + +await db.updateAsync({ _id: 'id6' }, { $pull: { fruits: { $in: ['apple', 'pear'] } } }, {}) +// Now the fruits array is ['orange'] + // $each can be used to $push or $addToSet multiple values at once // This example works the same way with $addToSet -db.update({ _id: 'id6' }, { $push: { fruits: { $each: ['banana', 'orange'] } } }, {}, function () { - // Now the fruits array is ['apple', 'orange', 'pear', 'banana', 'orange'] -}); +await db.updateAsync({ _id: 'id6' }, { $push: { fruits: { $each: ['banana', 'orange'] } } }, {}) +// Now the fruits array is ['apple', 'orange', 'pear', 'banana', 'orange'] + // $slice can be used in cunjunction with $push and $each to limit the size of the resulting array. // A value of 0 will update the array to an empty array. A positive value n will keep only the n first elements // A negative value -n will keep only the last n elements. // If $slice is specified but not $each, $each is set to [] -db.update({ _id: 'id6' }, { +await db.updateAsync({ _id: 'id6' }, { $push: { fruits: { $each: ['banana'], $slice: 2 } } -}, {}, function () { - // Now the fruits array is ['apple', 'orange'] -}); +}) +// Now the fruits array is ['apple', 'orange'] + // $min/$max to update only if provided value is less/greater than current value // Let's say the database contains this document // doc = { _id: 'id', name: 'Name', value: 5 } -db.update({ _id: 'id1' }, { $min: { value: 2 } }, {}, function () { - // The document will be updated to { _id: 'id', name: 'Name', value: 2 } -}); +await db.updateAsync({ _id: 'id1' }, { $min: { value: 2 } }, {}) +// The document will be updated to { _id: 'id', name: 'Name', value: 2 } + -db.update({ _id: 'id1' }, { $min: { value: 8 } }, {}, function () { - // The document will not be modified -}); +await db.updateAsync({ _id: 'id1' }, { $min: { value: 8 } }, {}) +// The document will not be modified ``` ### Removing documents -`db.remove(query, options, callback)` will remove all documents matching `query` -according to `options` - -* `query` is the same as the ones used for finding and updating -* `options` only one option for now: `multi` which allows the removal of - multiple documents if set to true. Default is false -* `callback` is optional, signature: err, numRemoved +[`db.removeAsync(query, options)`](./docs/Datastore.md#Datastore#removeAsync) +will remove documents matching `query`. Can remove multiple documents if +`options.multi` is set. Returns the `Promise`. ```javascript // Let's use the same example collection as in the "finding document" part @@ -766,19 +650,18 @@ according to `options` // Remove one document from the collection // options set to {} since the default for multi is false -db.remove({ _id: 'id2' }, {}, function (err, numRemoved) { - // numRemoved = 1 -}); +const { numRemoved } = await db.removeAsync({ _id: 'id2' }, {}) +// numRemoved = 1 + // Remove multiple documents -db.remove({ system: 'solar' }, { multi: true }, function (err, numRemoved) { - // numRemoved = 3 - // All planets from the solar system were removed -}); +const { numRemoved } = await db.removeAsync({ system: 'solar' }, { multi: true }) +// numRemoved = 3 +// All planets from the solar system were removed + // Removing all documents with the 'match-all' query -db.remove({}, { multi: true }, function (err, numRemoved) { -}); +const { numRemoved } = await db.removeAsync({}, { multi: true }) ``` ### Indexing @@ -789,94 +672,83 @@ fields in nested documents using the dot notation. For now, indexes are only used to speed up basic queries and queries using `$in`, `$lt`, `$lte`, `$gt` and `$gte`. The indexed values cannot be of type array of object. -To create an index, use `datastore.ensureIndex(options, cb)`, where callback is -optional and get passed an error if any (usually a unique constraint that was -violated). `ensureIndex` can be called when you want, even after some data was -inserted, though it's best to call it at application startup. The options are: +To create an index, use [`datastore#ensureIndexAsync(options)`](./docs/Datastore.md#Datastore+ensureIndexAsync). +It resolves when the index is persisted on disk (if the database is persistent) +and may throw an Error (usually a unique constraint that was violated). It can +be called when you want, even after some data was inserted, though it's best to +call it at application startup. The options are: * **fieldName** (required): name of the field to index. Use the dot notation to index a field in a nested document. -* **unique** (optional, defaults to `false`): enforce field uniqueness. Note - that a unique index will raise an error if you try to index two documents for - which the field is not defined. +* **unique** (optional, defaults to `false`): enforce field uniqueness. * **sparse** (optional, defaults to `false`): don't index documents for which - the field is not defined. Use this option along with "unique" if you want to - accept multiple documents for which it is not defined. + the field is not defined. * **expireAfterSeconds** (number of seconds, optional): if set, the created index is a TTL (time to live) index, that will automatically remove documents - when the system date becomes larger than the date on the indexed field - plus `expireAfterSeconds`. Documents where the indexed field is not specified - or not a `Date` object are ignored - -Note: the `_id` is automatically indexed with a unique constraint, no need to -call `ensureIndex` on it. + when the indexed field value is older than `expireAfterSeconds`. -You can remove a previously created index -with `datastore.removeIndex(fieldName, cb)`. +Note: the `_id` is automatically indexed with a unique constraint. -If your datastore is persistent, the indexes you created are persisted in the -datafile, when you load the database a second time they are automatically -created for you. No need to remove any `ensureIndex` though, if it is called on -a database that already has the index, nothing happens. +You can remove a previously created index with +[`datastore#removeIndexAsync(fieldName)`](./docs/Datastore.md#Datastore+removeIndexAsync). ```javascript -db.ensureIndex({ fieldName: 'somefield' }, function (err) { - // If there was an error, err is not null -}); +try { + await db.ensureIndexAsync({ fieldName: 'somefield' }) +} catch (error) { + // If there was an error, error is not null +} // Using a unique constraint with the index -db.ensureIndex({ fieldName: 'somefield', unique: true }, function (err) { -}); +await db.ensureIndexAsync({ fieldName: 'somefield', unique: true }) // Using a sparse unique index -db.ensureIndex({ +await db.ensureIndexAsync({ fieldName: 'somefield', unique: true, sparse: true -}, function (err) { -}); - -// Format of the error message when the unique constraint is not met -db.insert({ somefield: '@seald-io/nedb' }, function (err) { - // err is null - db.insert({ somefield: '@seald-io/nedb' }, function (err) { - // err is { errorType: 'uniqueViolated' - // , key: 'name' - // , message: 'Unique constraint violated for key name' } - }); -}); +}) + +try { + // Format of the error message when the unique constraint is not met + await db.insertAsync({ somefield: '@seald-io/nedb' }) + // works + await db.insertAsync({ somefield: '@seald-io/nedb' }) + //rejects +} catch (error) { + // error is { errorType: 'uniqueViolated', + // key: 'name', + // message: 'Unique constraint violated for key name' } +} + // Remove index on field somefield -db.removeIndex('somefield', function (err) { -}); +await db.removeIndexAsync('somefield') // Example of using expireAfterSeconds to remove documents 1 hour // after their creation (db's timestampData option is true here) -db.ensureIndex({ +await db.ensureIndex({ fieldName: 'createdAt', expireAfterSeconds: 3600 -}, function (err) { -}); +}) // You can also use the option to set an expiration date like so -db.ensureIndex({ +await db.ensureIndex({ fieldName: 'expirationDate', expireAfterSeconds: 0 -}, function (err) { - // Now all documents will expire when system time reaches the date in their - // expirationDate field -}); - +}) +// Now all documents will expire when system time reaches the date in their +// expirationDate field ``` -**Note:** the `ensureIndex` function creates the index synchronously, so it's -best to use it at application startup. It's quite fast so it doesn't increase -startup time much (35 ms for a collection containing 10,000 documents). - -## Browser version +## Other environments +NeDB runs on Node.js (it is tested on Node 12, 14 and 16), the browser (it is +tested on the latest version of Chrome) and React-Native using +[@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage). -The browser version and its minified counterpart are in -the `browser-version/out` directory. You only need to require `nedb.js` +### Browser bundle +The npm package contains a bundle and its minified counterpart for the browser. +They are located in the `browser-version/out` directory. You only need to require `nedb.js` or `nedb.min.js` in your HTML file and the global object `Nedb` can be used right away, with the same API as the server version: @@ -894,18 +766,39 @@ right away, with the same API as the server version: ``` If you specify a `filename`, the database will be persistent, and automatically -select the best storage method available (IndexedDB, WebSQL or localStorage) -depending on the browser. In most cases that means a lot of data can be stored, -typically in hundreds of MB. **WARNING**: the storage system changed between +select the best storage method available using [localforage](https://github.com/localForage/localForage) +(IndexedDB, WebSQL or localStorage) depending on the browser. In most cases that +means a lot of data can be stored, typically in hundreds of MB. + +**WARNING**: the storage system changed between v1.3 and v1.4 and is NOT back-compatible! Your application needs to resync client-side when you upgrade NeDB. -NeDB is compatible with all major browsers: Chrome, Safari, Firefox, IE9+. Tests -are in the `browser-version/test` directory (files `index.html` -and `testPersistence.html`). - -If you fork and modify nedb, you can build the browser version from the sources, -the build script is `browser-version/build.js`. +NeDB uses modern Javascript features such as `async`, `Promise`, `class`, `const` +, `let`, `Set`, `Map`, ... The bundle does not polyfill these features. If you +need to target another environment, you will need to make your own bundle. + +### Using the `browser` and `react-native` fields +NeDB uses the `browser` and `react-native` fields to replace some modules by an +environment specific shim. + +The way this works is by counting on the bundler that will package NeDB to use +this fields. This is [done by default by Webpack](https://webpack.js.org/configuration/resolve/#resolvealiasfields) +for the `browser` field. And this is [done by default by Metro](https://github.com/facebook/metro/blob/c21daba415ea26511e157f794689caab9abe8236/packages/metro/src/ModuleGraph/node-haste/Package.js#L108) +for the `react-native` field. + +This is done for: +- the [storage module](./docs/storage.md) which uses Node.js `fs`. It is + [replaced in the browser](./docs/storageBrowser.md) by one that uses + [localforage](https://github.com/localForage/localForage), and + [in `react-native`](./docs/storageBrowser.md) by one that uses + [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage) +- the [customUtils module](./docs/customUtilsNode.md) which uses Node.js + `crypto` module. It is replaced by a good enough shim to generate ids that uses `Math.random()`. +- the [byline module](./docs/byline.md) which uses Node.js `stream` + (a fork of [`node-byline`](https://github.com/jahewson/node-byline) included in + the repo because it is unmaintained). It isn't used int the browser nor + react-native versions, therefore it is shimmed with an empty object. ## Performance @@ -937,16 +830,15 @@ kind of datasets (20MB for 10,000 2KB documents). ## Modernization This fork of NeDB will be incrementally updated to: -- remove deprecated features; -- use `async` functions and `Promises` instead of callbacks with `async@0.2.6`; -- expose a `Promise`-based interface; -- remove the `underscore` dependency; -- add a way to change the `Storage` module by dependency injection, which will - pave the way to a cleaner browser version, and eventually other `Storage` - backends such as `react-native` to - replace [`react-native-local-mongodb`](https://github.com/antoniopresto/react-native-local-mongodb/) - which is discontinued. - +* [ ] cleanup the benchmark and update the performance statistics; +* [ ] remove deprecated features; +* [ ] add a way to change the `Storage` module by dependency injection, which will + pave the way to cleaner browser react-native versions (cf https://github.com/seald/nedb/pull/19). +* [x] use `async` functions and `Promises` instead of callbacks with `async@0.2.6`; +* [x] expose a `Promise`-based interface; +* [x] remove the `underscore` dependency; + +## Pull requests guidelines If you submit a pull request, thanks! There are a couple rules to follow though to make it manageable: @@ -962,30 +854,8 @@ to make it manageable: pollute the code. * Don't forget tests for your new feature. Also don't forget to run the whole test suite before submitting to make sure you didn't introduce regressions. +* Update the JSDoc and regenerate [the markdown files](./docs). * Update the readme accordingly. -* Last but not least: keep in mind what NeDB's mindset is! The goal is not to be - a replacement for MongoDB, but to have a pure JS database, easy to use, cross - platform, fast and expressive enough for the target projects (small and self - contained apps on server/desktop/browser/mobile). Sometimes it's better to - shoot for simplicity than for API completeness with regards to MongoDB. - -## Bug reporting guidelines - -If you report a bug, thank you! That said for the process to be manageable -please strictly adhere to the following guidelines. I'll not be able to handle -bug reports that don't: - -* Your bug report should be a self-containing gist complete with a package.json - for any dependencies you need. I need to run through a - simple `git clone gist; npm install; node bugreport.js`, nothing more. -* It should use assertions to showcase the expected vs actual behavior and be - hysteresis-proof. It's quite simple in fact, see this - example: https://gist.github.com/louischatriot/220cf6bd29c7de06a486 -* Simplify as much as you can. Strip all your application-specific code. Most of - the time you will see that there is no bug but an error in your code :) -* 50 lines max. If you need more, read the above point and rework your bug - report. If you're **really** convinced you need more, please explain precisely - in the issue. ## License diff --git a/docs/byline.md b/docs/byline.md new file mode 100644 index 0000000..87c28a4 --- /dev/null +++ b/docs/byline.md @@ -0,0 +1,10 @@ + + +## byline + + +### byline.LineStream +

Fork from [https://github.com/jahewson/node-byline](https://github.com/jahewson/node-byline).

+ +**Kind**: static class of [byline](#module_byline) +**See**: https://github.com/jahewson/node-byline diff --git a/jsdoc2md.js b/jsdoc2md.js index a122382..08de194 100644 --- a/jsdoc2md.js +++ b/jsdoc2md.js @@ -29,6 +29,7 @@ const templateData = jsdoc2md.getTemplateDataSync(getJsdocDataOptions) const classNames = templateData .filter(({ kind, access }) => kind === 'class' && access !== 'private') .map(({ name }) => name) + .filter(name => name !== 'LineStream') // it is a module that exports a class, dirty hack to hardcode this, but it works const moduleNames = templateData .filter(({ kind, access }) => kind === 'module' && access !== 'private') diff --git a/lib/byline.js b/lib/byline.js index 21e2437..f9a752d 100644 --- a/lib/byline.js +++ b/lib/byline.js @@ -19,7 +19,9 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. - +/** + * @module byline + */ const stream = require('stream') const timers = require('timers') @@ -31,6 +33,11 @@ const createLineStream = (readStream, options) => { return ls } +/** + * Fork from {@link https://github.com/jahewson/node-byline}. + * @see https://github.com/jahewson/node-byline + * @alias module:byline.LineStream + */ class LineStream extends stream.Transform { constructor (options) { super(options) diff --git a/lib/datastore.js b/lib/datastore.js index a64daef..6107997 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -132,10 +132,13 @@ class Datastore extends EventEmitter { /** * Create a new collection, either persistent or in-memory. * - * If you use a persistent datastore without the `autoload` option, you need to call `loadDatabase` manually. This - * function fetches the data from datafile and prepares the database. **Don't forget it!** If you use a persistent - * datastore, no command (insert, find, update, remove) will be executed before `loadDatabase` is called, so make sure - * to call it yourself or use the `autoload` option. + * If you use a persistent datastore without the `autoload` option, you need to call {@link Datastore#loadDatabase} or + * {@link Datastore#loadDatabaseAsync} manually. This function fetches the data from datafile and prepares the database. + * **Don't forget it!** If you use a persistent datastore, no command (insert, find, update, remove) will be executed + * before it is called, so make sure to call it yourself or use the `autoload` option. + * + * Also, if loading fails, all commands registered to the {@link Datastore#executor} afterwards will not be executed. + * They will be registered and executed, in sequence, only after a successful loading. * * @param {object|string} options Can be an object or a string. If options is a string, the behavior is the same as in * v0.6: it will be interpreted as `options.filename`. **Giving a string is deprecated, and will be removed in the diff --git a/lib/persistence.js b/lib/persistence.js index 8588b9e..22e4bb0 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -7,7 +7,40 @@ const model = require('./model.js') const storage = require('./storage.js') /** - * Handle every persistence-related task + * Under the hood, NeDB's persistence uses an append-only format, meaning that all + * updates and deletes actually result in lines added at the end of the datafile, + * for performance reasons. The database is automatically compacted (i.e. put back + * in the one-line-per-document format) every time you load each database within + * your application. + * + * You can manually call the compaction function + * with `yourDatabase.persistence.compactDatafile` which takes no argument. It + * queues a compaction of the datafile in the executor, to be executed sequentially + * after all pending operations. The datastore will fire a `compaction.done` event + * once compaction is finished. + * + * You can also set automatic compaction at regular intervals + * with `yourDatabase.persistence.setAutocompactionInterval(interval)`, `interval` + * in milliseconds (a minimum of 5s is enforced), and stop automatic compaction + * with `yourDatabase.persistence.stopAutocompaction()`. + * + * Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k + * records on a typical development machine) and no other operation can happen when + * it does, so most projects actually don't need to use it. + * + * Compaction will also immediately remove any documents whose data line has become + * corrupted, assuming that the total percentage of all corrupted documents in that + * database still falls below the specified `corruptAlertThreshold` option's value. + * + * Durability works similarly to major databases: compaction forces the OS to + * physically flush data to disk, while appends to the data file do not (the OS is + * responsible for flushing the data). That guarantees that a server crash can + * never cause complete data loss, while preserving performance. The worst that can + * happen is a crash between two syncs, causing a loss of all data between the two + * syncs. Usually syncs are 30 seconds appart so that's at most 30 seconds of + * data. [This post by Antirez on Redis persistence](http://oldblog.antirez.com/post/redis-persistence-demystified.html) + * explains this in more details, NeDB being very close to Redis AOF persistence + * with `appendfsync` option set to `no`. */ class Persistence { /** diff --git a/test/db.test.js b/test/db.test.js index 9a2d22c..fbac065 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -2253,6 +2253,7 @@ describe('Database', function () { fs.writeFile(testDb, rawData, 'utf8', function () { d.loadDatabase(function (err) { + err.should.not.equal(null) err.errorType.should.equal('uniqueViolated') err.key.should.equal('1') d.getAllData().length.should.equal(0) From f017197797cfc2eb6b28f31389f596924f617e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 7 Jan 2022 19:34:25 +0100 Subject: [PATCH 44/65] 3.0.0-1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 34526aa..2a64e35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-0", + "version": "3.0.0-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@seald-io/nedb", - "version": "3.0.0-0", + "version": "3.0.0-1", "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", diff --git a/package.json b/package.json index 4b38f34..83d6d40 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-0", + "version": "3.0.0-1", "files": [ "lib/**/*.js", "browser-version/**/*.js", From 32cff9b921f93d62fdf22c6d2fa3c7cc74fbe8cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 14 Jan 2022 18:39:10 +0100 Subject: [PATCH 45/65] huge cleanup --- CHANGELOG.md | 7 +- README.md | 6 +- benchmarks/commonUtilities.js | 3 +- browser-version/lib/customUtils.js | 4 +- browser-version/lib/storage.browser.js | 126 +----------- browser-version/lib/storage.react-native.js | 21 +- index.d.ts | 13 -- jsdoc2md.js | 4 +- lib/byline.js | 9 +- lib/cursor.js | 132 +++++-------- lib/customUtils.js | 1 + lib/datastore.js | 200 +++++++------------ lib/executor.js | 77 +++----- lib/indexes.js | 1 + lib/model.js | 3 +- lib/persistence.js | 204 +++++++------------- lib/storage.js | 201 ++++--------------- lib/utils.js | 9 +- lib/waterfall.js | 17 +- test/browser/nedb-browser.spec.js | 6 +- test/byline.test.js | 2 +- test/cursor.async.test.js | 8 +- test/cursor.test.js | 3 +- test/db.async.test.js | 134 ++++++------- test/db.test.js | 67 ++++--- test/executor.test.js | 3 +- test/persistence.async.test.js | 27 ++- test/persistence.test.js | 68 +++---- test/utils.test.js | 1 + test_lac/openFds.test.js | 3 +- typings-tests.ts | 4 - 31 files changed, 451 insertions(+), 913 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9542b88..23e97a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,14 +13,13 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Added markdown documentation generated from the JSDoc ### Changed -- All the functions are now async at the core, and a fully retro-compatible callback-ified version is exposed. -- The executor is now much simpler and Promise-based. A retro-compatible shim is still exposed, with the exception that it no longer handles [`arguments`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/arguments) as the arguments Array. If you use the executor directly, you'll need to convert it to a proper Array beforehand. +- All the functions are now async at the core, and a fully retro-compatible callback-ified version is exposed for the exposed functions. +- The executor is now much simpler and Promise-based. A mostly retro-compatible shim is still exposed, with the exception that it no longer handles [`arguments`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/arguments) as the arguments Array. If you use the executor directly, you'll need to convert it to a proper Array beforehand. However [follicle@1.x](https://github.com/seald/follicle) is not compatible, please update to v2. - As a result, the `async` dependency has been removed completely. To avoid rewriting the tests, shims of some functions of `async` are defined in an utilities file used exclusively in the tests. - The `Datastore#update`'s callback has its signature slightly changed. The `upsert` flag is always defined either at `true` or `false` but not `null` nor `undefined`, and `affectedDocuments` is `null` when none is given rather than `undefined` (except when there is an error of course). - +- ### Deprecated - Formally deprecate giving a string as argument to the `Datastore` constructor -- Formally deprecate using `Persistence.getNWAppFilename()` and `options.nodeWebkitAppName` ## [2.2.1] - 2022-01-18 diff --git a/README.md b/README.md index 3a8f65c..dbd6331 100755 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ written by Louis Chatriot. Since the original maintainer doesn't support this package anymore, we forked it and maintain it for the needs of [Seald](https://www.seald.io). -**Embedded persistent or in memory database for Node.js, nw.js, Electron and -browsers, 100% JavaScript, no binary dependency**. API is a subset of MongoDB's -and it's [plenty fast](#speed). +**Embedded persistent or in memory database for Node.js, Electron and browsers, +100% JavaScript, no binary dependency**. API is a subset of MongoDB's and it's +[plenty fast](#speed). ## Installation diff --git a/benchmarks/commonUtilities.js b/benchmarks/commonUtilities.js index ec708ed..36bd4e0 100755 --- a/benchmarks/commonUtilities.js +++ b/benchmarks/commonUtilities.js @@ -5,6 +5,7 @@ const fs = require('fs') const path = require('path') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') +const { callbackify } = require('util') let executeAsap try { @@ -45,7 +46,7 @@ module.exports.getConfiguration = function (benchDb) { * Ensure the workspace stat and the db datafile is empty */ module.exports.prepareDb = function (filename, cb) { - Persistence.ensureDirectoryExists(path.dirname(filename), function () { + callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(filename), function () { fs.access(filename, fs.constants.FS_OK, function (err) { if (!err) { fs.unlink(filename, cb) diff --git a/browser-version/lib/customUtils.js b/browser-version/lib/customUtils.js index 61d4ae5..eb40b27 100755 --- a/browser-version/lib/customUtils.js +++ b/browser-version/lib/customUtils.js @@ -9,7 +9,7 @@ * https://github.com/dominictarr/crypto-browserify * NOTE: Math.random() does not guarantee "cryptographic quality" but we actually don't need it * @param {number} size in bytes - * @return {array} + * @return {Array} */ const randomBytes = size => { const bytes = new Array(size) @@ -25,7 +25,7 @@ const randomBytes = size => { /** * Taken from the base64-js module * https://github.com/beatgammit/base64-js/ - * @param {array} uint8 + * @param {Array} uint8 * @return {string} */ const byteArrayToBase64 = uint8 => { diff --git a/browser-version/lib/storage.browser.js b/browser-version/lib/storage.browser.js index b713a7d..a69c0b4 100755 --- a/browser-version/lib/storage.browser.js +++ b/browser-version/lib/storage.browser.js @@ -5,10 +5,10 @@ * @module storageBrowser * @see module:storage * @see module:storageReactNative + * @private */ const localforage = require('localforage') -const { callbackify } = require('util') // TODO: util is not a dependency, this would fail if util is not polyfilled // Configure localforage to display NeDB name for now. Would be a good idea to let user use his own app name const store = localforage.createInstance({ @@ -19,12 +19,10 @@ const store = localforage.createInstance({ /** * Returns Promise if file exists. * - * Async version of {@link module:storageBrowser.exists}. * @param {string} file * @return {Promise} * @async * @alias module:storageBrowser.existsAsync - * @see module:storageBrowser.exists */ const existsAsync = async file => { try { @@ -37,27 +35,12 @@ const existsAsync = async file => { } /** - * @callback module:storageBrowser~existsCallback - * @param {boolean} exists - */ - -/** - * Callback returns true if file exists. - * @function - * @param {string} file - * @param {module:storageBrowser~existsCallback} cb - * @alias module:storageBrowser.exists - */ -const exists = callbackify(existsAsync) - -/** - * Async version of {@link module:storageBrowser.rename}. + * Moves the item from one path to another. * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storageBrowser.renameAsync * @async - * @see module:storageBrowser.rename */ const renameAsync = async (oldPath, newPath) => { try { @@ -73,25 +56,13 @@ const renameAsync = async (oldPath, newPath) => { } /** - * Moves the item from one path to another - * @function - * @param {string} oldPath - * @param {string} newPath - * @param {NoParamCallback} c - * @return {void} - * @alias module:storageBrowser.rename - */ -const rename = callbackify(renameAsync) - -/** - * Async version of {@link module:storageBrowser.writeFile}. + * Saves the item at given path. * @param {string} file * @param {string} data * @param {object} [options] * @return {Promise} * @alias module:storageBrowser.writeFileAsync * @async - * @see module:storageBrowser.writeFile */ const writeFileAsync = async (file, data, options) => { // Options do not matter in browser setup @@ -103,18 +74,7 @@ const writeFileAsync = async (file, data, options) => { } /** - * Saves the item at given path - * @function - * @param {string} path - * @param {string} data - * @param {object} options - * @param {function} callback - * @alias module:storageBrowser.writeFile - */ -const writeFile = callbackify(writeFileAsync) - -/** - * Async version of {@link module:storageBrowser.appendFile}. + * Append to the item at given path. * @function * @param {string} filename * @param {string} toAppend @@ -122,7 +82,6 @@ const writeFile = callbackify(writeFileAsync) * @return {Promise} * @alias module:storageBrowser.appendFileAsync * @async - * @see module:storageBrowser.appendFile */ const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup @@ -135,25 +94,13 @@ const appendFileAsync = async (filename, toAppend, options) => { } /** - * Append to the item at given path - * @function - * @param {string} filename - * @param {string} toAppend - * @param {object} [options] - * @param {function} callback - * @alias module:storageBrowser.appendFile - */ -const appendFile = callbackify(appendFileAsync) - -/** - * Async version of {@link module:storageBrowser.readFile}. + * Read data at given path. * @function * @param {string} filename * @param {object} [options] * @return {Promise} * @alias module:storageBrowser.readFileAsync * @async - * @see module:storageBrowser.readFile */ const readFileAsync = async (filename, options) => { try { @@ -163,15 +110,6 @@ const readFileAsync = async (filename, options) => { return '' } } -/** - * Read data at given path - * @function - * @param {string} filename - * @param {object} options - * @param {function} callback - * @alias module:storageBrowser.readFile - */ -const readFile = callbackify(readFileAsync) /** * Async version of {@link module:storageBrowser.unlink}. @@ -179,8 +117,7 @@ const readFile = callbackify(readFileAsync) * @param {string} filename * @return {Promise} * @async - * @alias module:storageBrowser.unlinkAsync - * @see module:storageBrowser.unlink + * @alias module:storageBrowser */ const unlinkAsync = async filename => { try { @@ -190,15 +127,6 @@ const unlinkAsync = async filename => { } } -/** - * Remove the data at given path - * @function - * @param {string} path - * @param {function} callback - * @alias module:storageBrowser.unlink - */ -const unlink = callbackify(unlinkAsync) - /** * Shim for {@link module:storage.mkdirAsync}, nothing to do, no directories will be used on the browser. * @function @@ -209,15 +137,6 @@ const unlink = callbackify(unlinkAsync) * @async */ const mkdirAsync = (path, options) => Promise.resolve() -/** - * Shim for {@link module:storage.mkdir}, nothing to do, no directories will be used on the browser. - * @function - * @param {string} path - * @param {object} options - * @param {function} callback - * @alias module:storageBrowser.mkdir - */ -const mkdir = callbackify(mkdirAsync) /** * Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the browser. @@ -228,61 +147,32 @@ const mkdir = callbackify(mkdirAsync) const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() /** - * Shim for {@link module:storage.ensureDatafileIntegrity}, nothing to do, no data corruption possible in the browser. - * @function - * @param {string} filename - * @param {NoParamCallback} callback signature: err - * @alias module:storageBrowser.ensureDatafileIntegrity - */ -const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) - -/** - * Async version of {@link module:storageBrowser.crashSafeWriteFileLines}. - * @param {string} filename + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storageBrowser.crashSafeWriteFileLinesAsync - * @see module:storageBrowser.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line await writeFileAsync(filename, lines.join('\n')) } -/** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) - * @function - * @param {string} filename - * @param {string[]} lines - * @param {NoParamCallback} [callback] Optional callback, signature: err - * @alias module:storageBrowser.crashSafeWriteFileLines - */ -const crashSafeWriteFileLines = callbackify(crashSafeWriteFileLinesAsync) - // Interface -module.exports.exists = exists module.exports.existsAsync = existsAsync -module.exports.rename = rename module.exports.renameAsync = renameAsync -module.exports.writeFile = writeFile module.exports.writeFileAsync = writeFileAsync -module.exports.crashSafeWriteFileLines = crashSafeWriteFileLines module.exports.crashSafeWriteFileLinesAsync = crashSafeWriteFileLinesAsync -module.exports.appendFile = appendFile module.exports.appendFileAsync = appendFileAsync -module.exports.readFile = readFile module.exports.readFileAsync = readFileAsync -module.exports.unlink = unlink module.exports.unlinkAsync = unlinkAsync -module.exports.mkdir = mkdir module.exports.mkdirAsync = mkdirAsync -module.exports.ensureDatafileIntegrity = ensureDatafileIntegrity module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync diff --git a/browser-version/lib/storage.react-native.js b/browser-version/lib/storage.react-native.js index ca2c8d2..ad7de93 100755 --- a/browser-version/lib/storage.react-native.js +++ b/browser-version/lib/storage.react-native.js @@ -3,12 +3,13 @@ * * This version is the React-Native version and uses [@react-native-async-storage/async-storage]{@link https://github.com/react-native-async-storage/async-storage}. * @module storageReactNative - * @see module:storageBrowser - * @see module:storageReactNative + * @see module:storagereact-native + * @see module:storage + * @private */ const AsyncStorage = require('@react-native-async-storage/async-storage').default -const { callbackify } = require('util') // TODO: util is not a dependency, this would fail if util is not polyfilled +const { callbackify } = require('util') /** * Async version of {@link module:storageReactNative.exists}. @@ -21,7 +22,7 @@ const { callbackify } = require('util') // TODO: util is not a dependency, this const existsAsync = async file => { try { const value = await AsyncStorage.getItem(file) - if (value !== null) return true // Even if value is undefined, localforage returns null + if (value !== null) return true // Even if value is undefined, AsyncStorage returns null return false } catch (error) { return false @@ -85,7 +86,7 @@ const rename = callbackify(renameAsync) * @see module:storageReactNative.writeFile */ const writeFileAsync = async (file, data, options) => { - // Options do not matter in browser setup + // Options do not matter in react-native setup try { await AsyncStorage.setItem(file, data) } catch (error) { @@ -116,7 +117,7 @@ const writeFile = callbackify(writeFileAsync) * @see module:storageReactNative.appendFile */ const appendFileAsync = async (filename, toAppend, options) => { - // Options do not matter in browser setup + // Options do not matter in react-native setup try { const contents = (await AsyncStorage.getItem(filename)) || '' await AsyncStorage.setItem(filename, contents + toAppend) @@ -192,7 +193,7 @@ const unlinkAsync = async filename => { const unlink = callbackify(unlinkAsync) /** - * Shim for {@link module:storage.mkdirAsync}, nothing to do, no directories will be used on the browser. + * Shim for {@link module:storage.mkdirAsync}, nothing to do, no directories will be used on the react-native. * @function * @param {string} dir * @param {object} [options] @@ -203,7 +204,7 @@ const unlink = callbackify(unlinkAsync) const mkdirAsync = (dir, options) => Promise.resolve() /** - * Shim for {@link module:storage.mkdir}, nothing to do, no directories will be used on the browser. + * Shim for {@link module:storage.mkdir}, nothing to do, no directories will be used on the react-native. * @function * @param {string} path * @param {object} options @@ -213,7 +214,7 @@ const mkdirAsync = (dir, options) => Promise.resolve() const mkdir = callbackify(mkdirAsync) /** - * Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the browser. + * Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the react-native. * @param {string} filename * @return {Promise} * @alias module:storageReactNative.ensureDatafileIntegrityAsync @@ -221,7 +222,7 @@ const mkdir = callbackify(mkdirAsync) const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() /** - * Shim for {@link module:storage.ensureDatafileIntegrity}, nothing to do, no data corruption possible in the browser. + * Shim for {@link module:storage.ensureDatafileIntegrity}, nothing to do, no data corruption possible in the react-native. * @function * @param {string} filename * @param {NoParamCallback} callback signature: err diff --git a/index.d.ts b/index.d.ts index 5a65f75..ae85d47 100644 --- a/index.d.ts +++ b/index.d.ts @@ -26,8 +26,6 @@ declare class Nedb extends EventEmitter { getAllData(): T[]; - resetIndexes(newData?: any): void; - ensureIndex(options: Nedb.EnsureIndexOptions, callback?: (err: Error | null) => void): void; ensureIndexAsync(options: Nedb.EnsureIndexOptions): Promise; @@ -36,17 +34,6 @@ declare class Nedb extends EventEmitter { removeIndexAsync(fieldName: string): Promise; - addToIndexes(doc: T | T[]): void; - - removeFromIndexes(doc: T | T[]): void; - - updateIndexes(oldDoc: T, newDoc: T): void; - updateIndexes(updates: Array<{ oldDoc: T; newDoc: T }>): void; - - getCandidates(query: any, dontExpireStaleDocs: boolean, callback?: (err: Error | null, candidates: T[]) => void): void; - - getCandidatesAsync(query: any, dontExpireStaleDocs: boolean): Promise; - insert(newDoc: T, callback?: (err: Error | null, document: T) => void): void; insert(newDocs: T[], callback?: (err: Error | null, documents: T[]) => void): void; diff --git a/jsdoc2md.js b/jsdoc2md.js index 08de194..0cf2085 100644 --- a/jsdoc2md.js +++ b/jsdoc2md.js @@ -9,9 +9,9 @@ const jsdocConf = './jsdoc.conf.js' const outputDir = './docs' const getJsdocDataOptions = { - /* same inpout path as jsdoc */ + /* same input path as jsdoc */ files: require(jsdocConf).source.include, - configure: './jsdoc.conf.js', + configure: jsdocConf, 'no-cache': true } diff --git a/lib/byline.js b/lib/byline.js index f9a752d..00a3ced 100644 --- a/lib/byline.js +++ b/lib/byline.js @@ -21,6 +21,7 @@ // IN THE SOFTWARE. /** * @module byline + * @private */ const stream = require('stream') const timers = require('timers') @@ -37,6 +38,7 @@ const createLineStream = (readStream, options) => { * Fork from {@link https://github.com/jahewson/node-byline}. * @see https://github.com/jahewson/node-byline * @alias module:byline.LineStream + * @private */ class LineStream extends stream.Transform { constructor (options) { @@ -112,9 +114,4 @@ class LineStream extends stream.Transform { } } -// convenience API -module.exports = (readStream, options) => module.exports.createStream(readStream, options) - -// basic API -module.exports.createStream = (readStream, options) => readStream ? createLineStream(readStream, options) : new LineStream(options) -module.exports.LineStream = LineStream +module.exports = createLineStream diff --git a/lib/cursor.js b/lib/cursor.js index e5f4f72..87a583c 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -1,18 +1,11 @@ const model = require('./model.js') -const { callbackify, promisify } = require('util') +const { callbackify } = require('util') /** * Has a callback - * @callback Cursor~execFnWithCallback - * @param {?Error} err - * @param {?document[]|?document} res - */ - -/** - * Does not have a callback, may return a Promise. - * @callback Cursor~execFnWithoutCallback - * @param {?document[]|?document} res - * @return {Promise|*} + * @callback Cursor~mapFn + * @param {document[]} res + * @return {*|Promise<*>} */ /** @@ -26,10 +19,9 @@ class Cursor { * Create a new cursor for this collection * @param {Datastore} db - The datastore this cursor is bound to * @param {query} query - The query this cursor will operate on - * @param {Cursor~execFnWithoutCallback|Cursor~execFnWithCallback} [execFn] - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove - * @param {boolean} [hasCallback = true] If false, specifies that the `execFn` is of type {@link Cursor~execFnWithoutCallback} rather than {@link Cursor~execFnWithCallback}. + * @param {Cursor~mapFn} [mapFn] - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove */ - constructor (db, query, execFn, hasCallback = true) { + constructor (db, query, mapFn) { /** * @protected * @type {Datastore} @@ -42,16 +34,10 @@ class Cursor { this.query = query || {} /** * The handler to be executed after cursor has found the results. - * @type {Cursor~execFnWithoutCallback|Cursor~execFnWithCallback|undefined} + * @type {Cursor~mapFn} * @protected */ - if (execFn) this.execFn = execFn - /** - * Determines if the {@link Cursor#execFn} is an {@link Cursor~execFnWithoutCallback} or not. - * @protected - * @type {boolean} - */ - this.hasCallback = hasCallback + if (mapFn) this.mapFn = mapFn /** * @see Cursor#limit * @type {undefined|number} @@ -125,9 +111,9 @@ class Cursor { * This is an internal function. You should use {@link Cursor#execAsync} or {@link Cursor#exec}. * @param {document[]} candidates * @return {document[]} - * @protected + * @private */ - project (candidates) { + _project (candidates) { const res = [] let action @@ -174,91 +160,67 @@ class Cursor { * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne * This is an internal function, use execAsync which uses the executor * @return {document[]|Promise<*>} + * @private */ async _execAsync () { let res = [] let added = 0 let skipped = 0 - let error = null - - try { - const candidates = await this.db.getCandidatesAsync(this.query) - for (const candidate of candidates) { - if (model.match(candidate, this.query)) { - // If a sort is defined, wait for the results to be sorted before applying limit and skip - if (!this._sort) { - if (this._skip && this._skip > skipped) skipped += 1 - else { - res.push(candidate) - added += 1 - if (this._limit && this._limit <= added) break - } - } else res.push(candidate) - } + const candidates = await this.db._getCandidatesAsync(this.query) + + for (const candidate of candidates) { + if (model.match(candidate, this.query)) { + // If a sort is defined, wait for the results to be sorted before applying limit and skip + if (!this._sort) { + if (this._skip && this._skip > skipped) skipped += 1 + else { + res.push(candidate) + added += 1 + if (this._limit && this._limit <= added) break + } + } else res.push(candidate) } + } - // Apply all sorts - if (this._sort) { - // Sorting - const criteria = Object.entries(this._sort).map(([key, direction]) => ({ key, direction })) - res.sort((a, b) => { - for (const criterion of criteria) { - const compare = criterion.direction * model.compareThings(model.getDotValue(a, criterion.key), model.getDotValue(b, criterion.key), this.db.compareStrings) - if (compare !== 0) return compare - } - return 0 - }) + // Apply all sorts + if (this._sort) { + // Sorting + const criteria = Object.entries(this._sort).map(([key, direction]) => ({ key, direction })) + res.sort((a, b) => { + for (const criterion of criteria) { + const compare = criterion.direction * model.compareThings(model.getDotValue(a, criterion.key), model.getDotValue(b, criterion.key), this.db.compareStrings) + if (compare !== 0) return compare + } + return 0 + }) - // Applying limit and skip - const limit = this._limit || res.length - const skip = this._skip || 0 + // Applying limit and skip + const limit = this._limit || res.length + const skip = this._skip || 0 - res = res.slice(skip, skip + limit) - } - - // Apply projection - try { - res = this.project(res) - } catch (e) { - error = e - res = undefined - } - } catch (e) { - error = e + res = res.slice(skip, skip + limit) } - if (this.execFn && this.hasCallback) return promisify(this.execFn)(error, res) - else if (error) throw error - else if (this.execFn) return this.execFn(res) - else return res + + // Apply projection + res = this._project(res) + if (this.mapFn) return this.mapFn(res) + return res } /** * @callback Cursor~execCallback * @param {Error} err - * @param {document[]|*} res If an execFn was given to the Cursor, then the type of this parameter is the one returned by the execFn. + * @param {document[]|*} res If an mapFn was given to the Cursor, then the type of this parameter is the one returned by the mapFn. */ - /** - * Get all matching elements - * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne - * - * This is an internal function, use {@link Cursor#exec} which uses the [executor]{@link Datastore#executor}. - * @param {Cursor~execCallback} _callback - * @protected - * @see Cursor#exec - */ - _exec (_callback) { - callbackify(this._execAsync.bind(this))(_callback) - } - /** * Get all matching elements * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne * @param {Cursor~execCallback} _callback */ exec (_callback) { - this.db.executor.push({ this: this, fn: this._exec, arguments: [_callback] }) + callbackify(() => this.execAsync())(_callback) } /** diff --git a/lib/customUtils.js b/lib/customUtils.js index e94c741..34bfd94 100755 --- a/lib/customUtils.js +++ b/lib/customUtils.js @@ -2,6 +2,7 @@ * Utility functions that need to be reimplemented for each environment. * This is the version for Node.js * @module customUtilsNode + * @private */ const crypto = require('crypto') diff --git a/lib/datastore.js b/lib/datastore.js index 6107997..36e9f81 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -8,6 +8,12 @@ const model = require('./model.js') const Persistence = require('./persistence.js') const { isDate } = require('./utils.js') +// TODO: have one version of the documentation for each function +// TODO: remove jsdoc2md file that generates a docs/ directory, and replace it with something that generates the README +// TODO: check the classes and modules which need to be included int he documentation +// TODO: replace examples of the Readme with @example JSDoc tags +// TODO: update changelog + /** * Callback with no parameter * @callback NoParamCallback @@ -48,6 +54,13 @@ const { isDate } = require('./utils.js') * @return {Promise<*>} */ +/** + * Callback with generic parameters + * @callback GenericCallback + * @param {?Error} err + * @param {...*} args + */ + /** * Compaction event. Happens when the Datastore's Persistence has been compacted. * It happens when calling `datastore.persistence.compactDatafile`, which is called periodically if you have called @@ -118,7 +131,9 @@ const { isDate } = require('./utils.js') */ /** - * The `beforeDeserialization`and `afterDeserialization` callbacks should + * The `beforeDeserialization` and `afterDeserialization` callbacks are hooks which are executed respectively before + * parsing each document and after stringifying them. They can be used for example to encrypt the Datastore. + * The `beforeDeserialization` should revert what `afterDeserialization` has done. * @callback serializationHook * @param {string} x * @return {string} @@ -145,22 +160,23 @@ class Datastore extends EventEmitter { * next major version.** * @param {string} [options.filename = null] Path to the file where the data is persisted. If left blank, the datastore is * automatically considered in-memory only. It cannot end with a `~` which is used in the temporary files NeDB uses to - * perform crash-safe writes. - * @param {boolean} [options.inMemoryOnly = false] If set to true, no data will be written in storage. + * perform crash-safe writes. Not used if `options.inMemoryOnly` is `true`. + * @param {boolean} [options.inMemoryOnly = false] If set to true, no data will be written in storage. This option has + * priority over `options.filename`. * @param {boolean} [options.timestampData = false] If set to true, createdAt and updatedAt will be created and * populated automatically (if not specified by user) * @param {boolean} [options.autoload = false] If used, the database will automatically be loaded from the datafile * upon creation (you don't need to call `loadDatabase`). Any command issued before load is finished is buffered and * will be executed when load is done. When autoloading is done, you can either use the `onload` callback, or you can * use `this.autoloadPromise` which resolves (or rejects) when autloading is done. - * @param {function} [options.onload] If you use autoloading, this is the handler called after the `loadDatabase`. It + * @param {NoParamCallback} [options.onload] If you use autoloading, this is the handler called after the `loadDatabase`. It * takes one `error` argument. If you use autoloading without specifying this handler, and an error happens during * load, an error will be thrown. - * @param {function} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and + * @param {serializationHook} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and * before it is written to disk. Can be used for example to encrypt data before writing database to disk. This * function takes a string as parameter (one line of an NeDB data file) and outputs the transformed string, **which * must absolutely not contain a `\n` character** (or data will be lost). - * @param {function} [options.afterSerialization] Inverse of `afterSerialization`. Make sure to include both and not + * @param {serializationHook} [options.afterSerialization] Inverse of `afterSerialization`. Make sure to include both and not * just one, or you risk data loss. For the same reason, make sure both functions are inverses of one another. Some * failsafe mechanisms are in place to prevent data loss if you misuse the serialization hooks: NeDB checks that never * one is declared without the other, and checks that they are reverse of one another by testing on random strings of @@ -172,11 +188,6 @@ class Datastore extends EventEmitter { * @param {compareStrings} [options.compareStrings] If specified, it overrides default string comparison which is not * well adapted to non-US characters in particular accented letters. Native `localCompare` will most of the time be * the right choice. - * @param {string} [options.nodeWebkitAppName] **Deprecated:** if you are using NeDB from whithin a Node Webkit app, - * specify its name (the same one you use in the `package.json`) in this field and the `filename` will be relative to - * the directory Node Webkit uses to store the rest of the application's data (local storage etc.). It works on Linux, - * OS X and Windows. Now that you can use `require('nw.gui').App.dataPath` in Node Webkit to get the path to the data - * directory for your application, you should not use this option anymore and it will be removed. * * @fires Datastore#event:"compaction.done" */ @@ -189,7 +200,7 @@ class Datastore extends EventEmitter { deprecate(() => { filename = options this.inMemoryOnly = false // Default - }, 'Giving a string to the Datastore constructor is deprecated and will be removed in the next version. Please use an options object with an argument \'filename\'.')() + }, '@seald-io/nedb: Giving a string to the Datastore constructor is deprecated and will be removed in the next major version. Please use an options object with an argument \'filename\'.')() } else { options = options || {} filename = options.filename @@ -245,7 +256,6 @@ class Datastore extends EventEmitter { */ this.persistence = new Persistence({ db: this, - nodeWebkitAppName: options.nodeWebkitAppName, afterSerialization: options.afterSerialization, beforeDeserialization: options.beforeDeserialization, corruptAlertThreshold: options.corruptAlertThreshold @@ -296,15 +306,16 @@ class Datastore extends EventEmitter { if (options.onload) options.onload(err) else throw err }) - } + } else this.autoloadPromise = null } /** * Load the database from the datafile, and trigger the execution of buffered commands if any. - * @param {function} callback + * @param {NoParamCallback} callback */ loadDatabase (callback) { - this.executor.push({ this: this.persistence, fn: this.persistence.loadDatabase, arguments: [callback] }, true) + if (typeof callback !== 'function') callback = () => {} + callbackify(() => this.loadDatabaseAsync())(callback) } /** @@ -327,9 +338,10 @@ class Datastore extends EventEmitter { /** * Reset all currently defined indexes. - * @param {?document|?document[]} newData + * @param {?document|?document[]} [newData] + * @private */ - resetIndexes (newData) { + _resetIndexes (newData) { for (const index of Object.values(this.indexes)) { index.reset(newData) } @@ -347,9 +359,9 @@ class Datastore extends EventEmitter { * @param {number} [options.expireAfterSeconds] - if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored * @param {NoParamCallback} callback Callback, signature: err */ - // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state ensureIndex (options = {}, callback = () => {}) { - callbackify(this.ensureIndexAsync.bind(this))(options, callback) + const promise = this.ensureIndexAsync(options) // to make sure the synchronous part of ensureIndexAsync is executed synchronously + callbackify(() => promise)(callback) } /** @@ -362,7 +374,6 @@ class Datastore extends EventEmitter { * @return {Promise} * @see Datastore#ensureIndex */ - // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state async ensureIndexAsync (options = {}) { if (!options.fieldName) { const err = new Error('Cannot create an index without a fieldName') @@ -382,7 +393,7 @@ class Datastore extends EventEmitter { } // We may want to force all options to be persisted including defaults, not just the ones passed the index creation function - await this.persistence.persistNewStateAsync([{ $$indexCreated: options }]) + await this.executor.pushAsync(() => this.persistence.persistNewStateAsync([{ $$indexCreated: options }]), true) } /** @@ -392,9 +403,9 @@ class Datastore extends EventEmitter { * field in a nested document. * @param {NoParamCallback} callback Optional callback, signature: err */ - // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state removeIndex (fieldName, callback = () => {}) { - callbackify(this.removeIndexAsync.bind(this))(fieldName, callback) + const promise = this.removeIndexAsync(fieldName) + callbackify(() => promise)(callback) } /** @@ -404,11 +415,10 @@ class Datastore extends EventEmitter { * @return {Promise} * @see Datastore#removeIndex */ - // TODO: contrary to what is said in the JSDoc, this function should probably be called through the executor, it persists a new state async removeIndexAsync (fieldName) { delete this.indexes[fieldName] - await this.persistence.persistNewStateAsync([{ $$indexRemoved: fieldName }]) + await this.executor.pushAsync(() => this.persistence.persistNewStateAsync([{ $$indexRemoved: fieldName }]), true) } /** @@ -416,9 +426,9 @@ class Datastore extends EventEmitter { * * This is an internal function. * @param {document} doc - * @protected + * @private */ - addToIndexes (doc) { + _addToIndexes (doc) { let failingIndex let error const keys = Object.keys(this.indexes) @@ -448,9 +458,9 @@ class Datastore extends EventEmitter { * * This is an internal function. * @param {document} doc - * @protected + * @private */ - removeFromIndexes (doc) { + _removeFromIndexes (doc) { for (const index of Object.values(this.indexes)) { index.remove(doc) } @@ -468,8 +478,9 @@ class Datastore extends EventEmitter { * `{oldDoc, newDoc}` pairs. * @param {document} [newDoc] Document to replace the oldDoc with. If the first argument is an `Array` of * `{oldDoc, newDoc}` pairs, this second argument is ignored. + * @private */ - updateIndexes (oldDoc, newDoc) { + _updateIndexes (oldDoc, newDoc) { let failingIndex let error const keys = Object.keys(this.indexes) @@ -501,7 +512,7 @@ class Datastore extends EventEmitter { * * @private */ - _getCandidates (query) { + _getRawCandidates (query) { const indexNames = Object.keys(this.indexes) // STEP 1: get candidates list by checking indexes from most to least frequent usecase // For a basic match @@ -544,37 +555,16 @@ class Datastore extends EventEmitter { * * This is an internal function. * @param {query} query - * @param {boolean|function} [dontExpireStaleDocs = false] If true don't remove stale docs. Useful for the remove - * function which shouldn't be impacted by expirations. If argument is not given, it is used as the callback. - * @param {MultipleDocumentsCallback} callback Signature err, candidates - * - * @protected - */ - getCandidates (query, dontExpireStaleDocs, callback) { - if (typeof dontExpireStaleDocs === 'function') { - callback = dontExpireStaleDocs - dontExpireStaleDocs = false - } - - callbackify(this.getCandidatesAsync.bind(this))(query, dontExpireStaleDocs, callback) - } - - /** - * Async version of {@link Datastore#getCandidates}. - * - * This is an internal function. - * @param {query} query * @param {boolean} [dontExpireStaleDocs = false] If true don't remove stale docs. Useful for the remove function * which shouldn't be impacted by expirations. * @return {Promise} candidates - * @see Datastore#getCandidates - * @protected + * @private */ - async getCandidatesAsync (query, dontExpireStaleDocs = false) { + async _getCandidatesAsync (query, dontExpireStaleDocs = false) { const validDocs = [] // STEP 1: get candidates list by checking indexes from most to least frequent usecase - const docs = this._getCandidates(query) + const docs = this._getRawCandidates(query) // STEP 2: remove all expired documents if (!dontExpireStaleDocs) { const expiredDocsIds = [] @@ -593,22 +583,10 @@ class Datastore extends EventEmitter { /** * Insert a new document - * This is an internal function, use {@link Datastore#insert} which has the same signature. - * @param {document|document[]} newDoc - * @param {SingleDocumentCallback} callback - * - * @private - */ - _insert (newDoc, callback) { - return callbackify(this._insertAsync.bind(this))(newDoc, callback) - } - - /** - * Async version of {@link Datastore#_insert}. + * This is an internal function, use {@link Datastore#insertAsync} which has the same signature. * @param {document|document[]} newDoc * @return {Promise} * @private - * @see Datastore#_insert */ async _insertAsync (newDoc) { const preparedDoc = this._prepareDocumentForInsertion(newDoc) @@ -662,7 +640,7 @@ class Datastore extends EventEmitter { */ _insertInCache (preparedDoc) { if (Array.isArray(preparedDoc)) this._insertMultipleDocsInCache(preparedDoc) - else this.addToIndexes(preparedDoc) + else this._addToIndexes(preparedDoc) } /** @@ -677,7 +655,7 @@ class Datastore extends EventEmitter { for (let i = 0; i < preparedDocs.length; i += 1) { try { - this.addToIndexes(preparedDocs[i]) + this._addToIndexes(preparedDocs[i]) } catch (e) { error = e failingIndex = i @@ -687,7 +665,7 @@ class Datastore extends EventEmitter { if (error) { for (let i = 0; i < failingIndex; i += 1) { - this.removeFromIndexes(preparedDocs[i]) + this._removeFromIndexes(preparedDocs[i]) } throw error @@ -701,8 +679,9 @@ class Datastore extends EventEmitter { * * @private */ - insert (newDoc, callback = () => {}) { - this.executor.push({ this: this, fn: this._insert, arguments: [newDoc, callback] }) + insert (newDoc, callback) { + if (typeof callback !== 'function') callback = () => {} + callbackify(doc => this.insertAsync(doc))(newDoc, callback) } /** @@ -741,7 +720,7 @@ class Datastore extends EventEmitter { * @async */ countAsync (query) { - return new Cursor(this, query, async docs => docs.length, false) + return new Cursor(this, query, docs => docs.length) } /** @@ -778,7 +757,7 @@ class Datastore extends EventEmitter { * @async */ findAsync (query, projection = {}) { - const cursor = new Cursor(this, query, docs => docs.map(doc => model.deepCopy(doc)), false) + const cursor = new Cursor(this, query, docs => docs.map(doc => model.deepCopy(doc))) cursor.projection(projection) return cursor @@ -822,7 +801,7 @@ class Datastore extends EventEmitter { * @see Datastore#findOne */ findOneAsync (query, projection = {}) { - const cursor = new Cursor(this, query, docs => docs.length === 1 ? model.deepCopy(docs[0]) : null, false) + const cursor = new Cursor(this, query, docs => docs.length === 1 ? model.deepCopy(docs[0]) : null) cursor.projection(projection).limit(1) return cursor @@ -852,38 +831,6 @@ class Datastore extends EventEmitter { /** * Update all docs matching query. * - * Use {@link Datastore#update} which has the same signature. - * @param {query} query is the same kind of finding query you use with `find` and `findOne` - * @param {document|update} update specifies how the documents should be modified. It is either a new document or a - * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the - * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can - * apply them to subdocs. Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, - * `$inc` to increment a field's value and `$min`/`$max` to change field's value, only if provided value is - * less/greater than current value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special - * `$each` and `$slice`. - * @param {object} [options] Optional options. If not given, is interpreted as the callback. - * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if - * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted - * document. In the other case, the `query` is stripped from all operator recursively, and the `update` is applied to - * it. - * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, - * will return the array of documents matched by the find query and updated. Updated documents will be returned even - * if the update did not actually modify them. - * @param {Datastore~updateCallback} callback - * - * @private - */ - _update (query, update, options, callback) { - const _callback = (err, res = {}) => { - callback(err, res.numAffected, res.affectedDocuments, res.upsert) - } - callbackify(this._updateAsync.bind(this))(query, update, options, _callback) - } - - /** - * Async version of {@link Datastore#_update}. - * * Use {@link Datastore#updateAsync} which has the same signature. * @param {query} query is the same kind of finding query you use with `find` and `findOne` * @param {document|update} update specifies how the documents should be modified. It is either a new document or a @@ -904,7 +851,6 @@ class Datastore extends EventEmitter { * if the update did not actually modify them. * * @return {Promise<{numAffected: number, affectedDocuments: document[]|document|null, upsert: boolean}>} - * @see Datastore#_update * @private */ async _updateAsync (query, update, options) { @@ -913,7 +859,7 @@ class Datastore extends EventEmitter { // If upsert option is set, check whether we need to insert the doc if (upsert) { - const cursor = new Cursor(this, query, x => x, false) + const cursor = new Cursor(this, query) // Need to use an internal function not tied to the executor to avoid deadlock const docs = await cursor.limit(1)._execAsync() @@ -940,7 +886,7 @@ class Datastore extends EventEmitter { const modifications = [] let createdAt - const candidates = await this.getCandidatesAsync(query) + const candidates = await this._getCandidatesAsync(query) // Preparing update (if an error is thrown here neither the datafile nor // the in-memory indexes are affected) for (const candidate of candidates) { @@ -957,7 +903,7 @@ class Datastore extends EventEmitter { } // Change the docs in memory - this.updateIndexes(modifications) + this._updateIndexes(modifications) // Update the datafile const updatedDocs = modifications.map(x => x.newDoc) @@ -999,7 +945,10 @@ class Datastore extends EventEmitter { options = {} } const callback = cb || (() => {}) - this.executor.push({ this: this, fn: this._update, arguments: [query, update, options, callback] }) + const _callback = (err, res = {}) => { + callback(err, res.numAffected, res.affectedDocuments, res.upsert) + } + callbackify((query, update, options) => this.updateAsync(query, update, options))(query, update, options, _callback) } /** @@ -1038,23 +987,6 @@ class Datastore extends EventEmitter { /** * Remove all docs matching the query. * - * Use {@link Datastore#remove} which has the same signature. - * - * For now very naive implementation (similar to update). - * @param {query} query - * @param {object} options options - * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {Datastore~removeCallback} callback - * @see Datastore#remove - * @private - */ - _remove (query, options, callback) { - callbackify(this._removeAsync.bind(this))(query, options, callback) - } - - /** - * Async version of {@link Datastore#_remove}. - * * Use {@link Datastore#removeAsync} which has the same signature. * @param {query} query * @param {object} [options] Optional options @@ -1066,7 +998,7 @@ class Datastore extends EventEmitter { async _removeAsync (query, options = {}) { const multi = options.multi !== undefined ? options.multi : false - const candidates = await this.getCandidatesAsync(query, true) + const candidates = await this._getCandidatesAsync(query, true) const removedDocs = [] let numRemoved = 0 @@ -1074,7 +1006,7 @@ class Datastore extends EventEmitter { if (model.match(d, query) && (multi || numRemoved === 0)) { numRemoved += 1 removedDocs.push({ $$deleted: true, _id: d._id }) - this.removeFromIndexes(d) + this._removeFromIndexes(d) } }) @@ -1095,7 +1027,7 @@ class Datastore extends EventEmitter { options = {} } const callback = cb || (() => {}) - this.executor.push({ this: this, fn: this._remove, arguments: [query, options, callback] }) + callbackify((query, options) => this.removeAsync(query, options))(query, options, callback) } /** diff --git a/lib/executor.js b/lib/executor.js index 531ced7..b7767f1 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -3,6 +3,7 @@ const Waterfall = require('./waterfall') /** * Executes operations sequentially. * Has an option for a buffer that can be triggered afterwards. + * @private */ class Executor { /** @@ -26,64 +27,23 @@ class Executor { * @type {Waterfall} * @private */ - this.buffer = new Waterfall() - this.buffer.chain(new Promise(resolve => { - /** - * Method to trigger the buffer processing. - * - * Do not be use directly, use `this.processBuffer` instead. - * @function - * @private - */ - this._triggerBuffer = resolve - })) + this.buffer = null + /** + * Method to trigger the buffer processing. + * + * Do not be use directly, use `this.processBuffer` instead. + * @function + * @private + */ + this._triggerBuffer = null + this.resetBuffer() } /** * If executor is ready, queue task (and process it immediately if executor was idle) * If not, buffer task for later processing - * @param {Object} task - * @param {Object} task.this - Object to use as this - * @param {function} task.fn - Function to execute - * @param {Array} task.arguments - Array of arguments, IMPORTANT: only the last argument may be a function - * (the callback) and the last argument cannot be false/undefined/null - * @param {Boolean} [forceQueuing = false] Optional (defaults to false) force executor to queue task even if it is not ready - */ - push (task, forceQueuing) { - const func = async () => { - const lastArg = task.arguments[task.arguments.length - 1] - await new Promise(resolve => { - if (typeof lastArg === 'function') { - // We got a callback - task.arguments.pop() // remove original callback - task.fn.apply(task.this, [...task.arguments, function () { - resolve() // triggers next task after next tick - lastArg.apply(null, arguments) // call original callback - }]) - } else if (!lastArg && task.arguments.length !== 0) { - // We got a falsy callback - task.arguments.pop() // remove original callback - task.fn.apply(task.this, [...task.arguments, () => { - resolve() - }]) - } else { - // We don't have a callback - task.fn.apply(task.this, [...task.arguments, () => { - resolve() - }]) - } - }) - } - this.pushAsync(func, forceQueuing) - } - - /** - * Async version of {@link Executor#push}. - * This version is way simpler than its callbackEquivalent: you give it an async function `task`, it is executed when - * all the previous tasks are done, and then resolves or rejects and when it is finished with its original result or - * error. - * @param {AsyncFunction} task - * @param {boolean} [forceQueuing = false] + * @param {AsyncFunction} task Function to execute + * @param {boolean} [forceQueuing = false] Optional (defaults to false) force executor to queue task even if it is not ready * @return {Promise<*>} * @async * @see Executor#push @@ -102,6 +62,17 @@ class Executor { this._triggerBuffer() this.queue.waterfall(() => this.buffer.guardian) } + + /** + * Removes all tasks queued up in the buffer + */ + resetBuffer () { + this.buffer = new Waterfall() + this.buffer.chain(new Promise(resolve => { + this._triggerBuffer = resolve + })) + if (this.ready) this._triggerBuffer() + } } // Interface diff --git a/lib/indexes.js b/lib/indexes.js index df53228..fee3ccc 100755 --- a/lib/indexes.js +++ b/lib/indexes.js @@ -30,6 +30,7 @@ const projectForUnique = elt => { /** * Indexes on field names, with atomic operations and which can optionally enforce a unique constraint or allow indexed * fields to be undefined + * @private */ class Index { /** diff --git a/lib/model.js b/lib/model.js index 6d97830..b310f07 100755 --- a/lib/model.js +++ b/lib/model.js @@ -4,6 +4,7 @@ * Copying * Querying, update * @module model + * @private */ const { uniq, isDate, isRegExp } = require('./utils.js') @@ -260,7 +261,7 @@ const compareThings = (a, b, _compareStrings) => { /** * Create the complete modifier function - * @param {function} lastStepModifierFunction a lastStepModifierFunction + * @param {modifierFunction} lastStepModifierFunction a lastStepModifierFunction * @param {boolean} [unset = false] Bad looking specific fix, needs to be generalized modifiers that behave like $unset are implemented * @return {modifierFunction} * @private diff --git a/lib/persistence.js b/lib/persistence.js index 22e4bb0..b888637 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -1,5 +1,5 @@ const path = require('path') -const { callbackify, promisify, deprecate } = require('util') +const { callbackify } = require('util') const byline = require('./byline') const customUtils = require('./customUtils.js') const Index = require('./indexes.js') @@ -47,7 +47,6 @@ class Persistence { * Create a new Persistence object for database options.db * @param {Datastore} options.db * @param {Number} [options.corruptAlertThreshold] Optional, threshold after which an alert is thrown if too much data is corrupt - * @param {string} [options.nodeWebkitAppName] Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion) * @param {serializationHook} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and before it is written to disk. * @param {serializationHook} [options.afterSerialization] Inverse of `afterSerialization`. */ @@ -84,13 +83,6 @@ class Persistence { } } } - - // For NW apps, store data in the same directory where NW stores application data - if (this.filename && options.nodeWebkitAppName) { - deprecate(() => { - this.filename = Persistence.getNWAppFilename(options.nodeWebkitAppName, this.filename) - }, 'The nodeWebkitAppName option is deprecated and will be removed in the next version. To get the path to the directory where Node Webkit stores the data for your app, use the internal nw.gui module like this require(\'nw.gui\').App.dataPath See https://github.com/rogerwang/node-webkit/issues/500')() - } } /** @@ -98,21 +90,9 @@ class Persistence { * This serves as a compaction function since the cache always contains only the number of documents in the collection * while the data file is append-only so it may grow larger * - * This is an internal function, use {@link Persistence#compactDatafile} which uses the [executor]{@link Datastore#executor}. - * @param {NoParamCallback} [callback = () => {}] - * @protected - */ - persistCachedDatabase (callback = () => {}) { - return callbackify(this.persistCachedDatabaseAsync.bind(this))(callback) - } - - /** - * Async version of {@link Persistence#persistCachedDatabase}. - * * This is an internal function, use {@link Persistence#compactDatafileAsync} which uses the [executor]{@link Datastore#executor}. * @return {Promise} * @protected - * @see Persistence#persistCachedDatabase */ async persistCachedDatabaseAsync () { const lines = [] @@ -141,10 +121,11 @@ class Persistence { /** * Queue a rewrite of the datafile * @param {NoParamCallback} [callback = () => {}] - * @see Persistence#persistCachedDatabase + * @see Persistence#persistCachedDatabaseAsync */ - compactDatafile (callback = () => {}) { - this.db.executor.push({ this: this, fn: this.persistCachedDatabase, arguments: [callback] }) + compactDatafile (callback) { + if (typeof callback !== 'function') callback = () => {} + callbackify(() => this.compactDatafileAsync())(callback) } /** @@ -183,21 +164,8 @@ class Persistence { * Use an append-only format * * Do not use directly, it should only used by a {@link Datastore} instance. - * @param {string[]} newDocs Can be empty if no doc was updated/removed - * @param {NoParamCallback} [callback = () => {}] - * @protected - */ - persistNewState (newDocs, callback = () => {}) { - callbackify(this.persistNewStateAsync.bind(this))(newDocs, err => callback(err)) - } - - /** - * Async version of {@link Persistence#persistNewState} - * - * Do not use directly, it should only used by a {@link Datastore} instance. * @param {document[]} newDocs Can be empty if no doc was updated/removed * @return {Promise} - * @see Persistence#persistNewState */ async persistNewStateAsync (newDocs) { let toPersist = '' @@ -261,14 +229,6 @@ class Persistence { return { data: tdata, indexes: indexes } } - /** - * @callback Persistence~treatRawStreamCallback - * @param {?Error} err - * @param {?object} data - * @param {document[]} data.data - * @param {Object.} data.indexes - */ - /** * From a database's raw data stream, return the corresponding machine understandable collection * Is only used by a {@link Datastore} instance. @@ -279,66 +239,56 @@ class Persistence { * * Do not use directly, it should only used by a {@link Datastore} instance. * @param {Readable} rawStream - * @param {Persistence~treatRawStreamCallback} cb + * @return {Promise<{data: document[], indexes: Object.}>} + * @async * @protected */ - treatRawStream (rawStream, cb) { - const dataById = {} - const indexes = {} - - // Last line of every data file is usually blank so not really corrupt - let corruptItems = -1 - - const lineStream = byline(rawStream, { keepEmptyLines: true }) - let length = 0 - - lineStream.on('data', (line) => { - try { - const doc = model.deserialize(this.beforeDeserialization(line)) - if (doc._id) { - if (doc.$$deleted === true) delete dataById[doc._id] - else dataById[doc._id] = doc - } else if (doc.$$indexCreated && doc.$$indexCreated.fieldName != null) indexes[doc.$$indexCreated.fieldName] = doc.$$indexCreated - else if (typeof doc.$$indexRemoved === 'string') delete indexes[doc.$$indexRemoved] - } catch (e) { - corruptItems += 1 - } + treatRawStreamAsync (rawStream) { + return new Promise((resolve, reject) => { + const dataById = {} + + const indexes = {} + + // Last line of every data file is usually blank so not really corrupt + let corruptItems = -1 + + const lineStream = byline(rawStream, { keepEmptyLines: true }) + let length = 0 + + lineStream.on('data', (line) => { + try { + const doc = model.deserialize(this.beforeDeserialization(line)) + if (doc._id) { + if (doc.$$deleted === true) delete dataById[doc._id] + else dataById[doc._id] = doc + } else if (doc.$$indexCreated && doc.$$indexCreated.fieldName != null) indexes[doc.$$indexCreated.fieldName] = doc.$$indexCreated + else if (typeof doc.$$indexRemoved === 'string') delete indexes[doc.$$indexRemoved] + } catch (e) { + corruptItems += 1 + } - length++ - }) + length++ + }) - lineStream.on('end', () => { - // A bit lenient on corruption - if (length > 0 && corruptItems / length > this.corruptAlertThreshold) { - const err = new Error(`More than ${Math.floor(100 * this.corruptAlertThreshold)}% of the data file is corrupt, the wrong beforeDeserialization hook may be used. Cautiously refusing to start NeDB to prevent dataloss`) - cb(err, null) - return - } + lineStream.on('end', () => { + // A bit lenient on corruption + if (length > 0 && corruptItems / length > this.corruptAlertThreshold) { + const err = new Error(`More than ${Math.floor(100 * this.corruptAlertThreshold)}% of the data file is corrupt, the wrong beforeDeserialization hook may be used. Cautiously refusing to start NeDB to prevent dataloss`) + reject(err, null) + return + } - const data = Object.values(dataById) + const data = Object.values(dataById) - cb(null, { data, indexes: indexes }) - }) + resolve({ data, indexes: indexes }) + }) - lineStream.on('error', function (err) { - cb(err) + lineStream.on('error', function (err) { + reject(err, null) + }) }) } - /** - * Async version of {@link Persistence#treatRawStream}. - * - * Do not use directly, it should only used by a {@link Datastore} instance. - * @param {Readable} rawStream - * @return {Promise<{data: document[], indexes: Object.}>} - * @async - * @protected - * @see Persistence#treatRawStream - */ - treatRawStreamAsync (rawStream) { - return promisify(this.treatRawStream.bind(this))(rawStream) - } - /** * Load the database * 1) Create all indexes @@ -363,12 +313,12 @@ class Persistence { * @see Persistence#loadDatabase */ async loadDatabaseAsync () { - this.db.resetIndexes() + this.db._resetIndexes() // In-memory only datastore if (this.inMemoryOnly) return - await Persistence.ensureDirectoryExistsAsync(path.dirname(this.filename)) // TODO: maybe ignore error - await storage.ensureDatafileIntegrityAsync(this.filename) // TODO: maybe ignore error + await Persistence.ensureDirectoryExistsAsync(path.dirname(this.filename)) + await storage.ensureDatafileIntegrityAsync(this.filename) let treatedData if (storage.readFileStream) { @@ -387,9 +337,9 @@ class Persistence { // Fill cached database (i.e. all indexes) with data try { - this.db.resetIndexes(treatedData.data) + this.db._resetIndexes(treatedData.data) } catch (e) { - this.db.resetIndexes() // Rollback any index which didn't fail + this.db._resetIndexes() // Rollback any index which didn't fail throw e } @@ -397,54 +347,30 @@ class Persistence { this.db.executor.processBuffer() } - /** - * Check if a directory stat and create it on the fly if it is not the case. - * @param {string} dir - * @param {NoParamCallback} [callback = () => {}] - */ - static ensureDirectoryExists (dir, callback = () => {}) { - storage.mkdir(dir, { recursive: true }, err => { callback(err) }) + async dropDatabaseAsync () { + this.stopAutocompaction() // stop autocompaction + this.db.executor.ready = false // prevent queuing new tasks + this.db.executor.resetBuffer() // remove pending buffered tasks + await this.db.executor.queue.guardian // wait for the ongoing tasks to end + // remove indexes (which means remove data from memory) + this.db.indexes = {} + // add back _id index, otherwise it will fail + this.db.indexes._id = new Index({ fieldName: '_id', unique: true }) + // reset TTL on indexes + this.db.ttlIndexes = {} + + // remove datastore file + await this.db.executor(() => storage.unlinkAsync(this.filename), true) } /** - * Async version of {@link Persistence.ensureDirectoryExists}. + * Check if a directory stat and create it on the fly if it is not the case. * @param {string} dir * @return {Promise} - * @see Persistence.ensureDirectoryExists */ static async ensureDirectoryExistsAsync (dir) { await storage.mkdirAsync(dir, { recursive: true }) } - - /** - * Return the path the datafile if the given filename is relative to the directory where Node Webkit stores - * data for this application. Probably the best place to store data - * @param {string} appName - * @param {string} relativeFilename - * @return {string} - * @deprecated - */ - static getNWAppFilename (appName, relativeFilename) { - return deprecate(() => { - let home - - if (process.platform === 'win32' || process.platform === 'win64') { - home = process.env.LOCALAPPDATA || process.env.APPDATA - if (!home) throw new Error('Couldn\'t find the base application data folder') - home = path.join(home, appName) - } else if (process.platform === 'darwin') { - home = process.env.HOME - if (!home) throw new Error('Couldn\'t find the base application data directory') - home = path.join(home, 'Library', 'Application Support', appName) - } else if (process.platform === 'linux') { - home = process.env.HOME - if (!home) throw new Error('Couldn\'t find the base application data directory') - home = path.join(home, '.config', appName) - } else throw new Error(`Can't use the Node Webkit relative path for platform ${process.platform}`) - - return path.join(home, 'nedb-data', relativeFilename) - }, 'The getNWAppFilename static method is deprecated and will be removed in the next version. To get the path to the directory where Node Webkit stores the data for your app, use the internal nw.gui module like this require(\'nw.gui\').App.dataPath See https://github.com/rogerwang/node-webkit/issues/500')() - } } // Interface diff --git a/lib/storage.js b/lib/storage.js index 4cbcd26..1da3fd1 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -6,29 +6,15 @@ * @see module:storageBrowser * @see module:storageReactNative * @module storage + * @private */ const fs = require('fs') const fsPromises = fs.promises const path = require('path') -const { callbackify, promisify } = require('util') const { Readable } = require('stream') /** - * @callback module:storage~existsCallback - * @param {boolean} exists - */ - -/** - * Callback returns true if file exists. - * @param {string} file - * @param {module:storage~existsCallback} cb - * @alias module:storage.exists - */ -// eslint-disable-next-line node/no-callback-literal -const exists = (file, cb) => fs.access(file, fs.constants.F_OK, (err) => { cb(!err) }) - -/** - * Async version of {@link module:storage.exists}. + * Returns true if file exists. * @param {string} file * @return {Promise} * @async @@ -38,41 +24,18 @@ const exists = (file, cb) => fs.access(file, fs.constants.F_OK, (err) => { cb(!e const existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() => true, () => false) /** - * Node.js' [fs.rename]{@link https://nodejs.org/api/fs.html#fsrenameoldpath-newpath-callback}. - * @function - * @param {string} oldPath - * @param {string} newPath - * @param {NoParamCallback} c - * @return {void} - * @alias module:storage.rename - */ -const rename = fs.rename - -/** - * Async version of {@link module:storage.rename}. + * Node.js' [fsPromises.rename]{@link https://nodejs.org/api/fs.html#fspromisesrenameoldpath-newpath} * @function * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storage.renameAsync * @async - * @see module:storage.rename */ const renameAsync = fsPromises.rename /** - * Node.js' [fs.writeFile]{@link https://nodejs.org/api/fs.html#fswritefilefile-data-options-callback}. - * @function - * @param {string} path - * @param {string} data - * @param {object} options - * @param {function} callback - * @alias module:storage.writeFile - */ -const writeFile = fs.writeFile - -/** - * Async version of {@link module:storage.writeFile}. + * Node.js' [fsPromises.writeFile]{@link https://nodejs.org/api/fs.html#fspromiseswritefilefile-data-options}. * @function * @param {string} path * @param {string} data @@ -80,7 +43,6 @@ const writeFile = fs.writeFile * @return {Promise} * @alias module:storage.writeFileAsync * @async - * @see module:storage.writeFile */ const writeFileAsync = fsPromises.writeFile @@ -95,38 +57,17 @@ const writeFileAsync = fsPromises.writeFile const writeFileStream = fs.createWriteStream /** - * Node.js' [fs.unlink]{@link https://nodejs.org/api/fs.html#fsunlinkpath-callback}. - * @function - * @param {string} path - * @param {function} callback - * @alias module:storage.unlink - */ -const unlink = fs.unlink - -/** - * Async version of {@link module:storage.unlink}. + * Node.js' [fsPromises.unlink]{@link https://nodejs.org/api/fs.html#fspromisesunlinkpath}. * @function * @param {string} path * @return {Promise} * @async * @alias module:storage.unlinkAsync - * @see module:storage.unlink */ const unlinkAsync = fsPromises.unlink /** - * Node.js' [fs.appendFile]{@link https://nodejs.org/api/fs.html#fsappendfilepath-data-options-callback}. - * @function - * @param {string} path - * @param {string} data - * @param {object} options - * @param {function} callback - * @alias module:storage.appendFile - */ -const appendFile = fs.appendFile - -/** - * Async version of {@link module:storage.appendFile}. + * Node.js' [fsPromises.appendFile]{@link https://nodejs.org/api/fs.html#fspromisesappendfilepath-data-options}. * @function * @param {string} path * @param {string} data @@ -134,29 +75,17 @@ const appendFile = fs.appendFile * @return {Promise} * @alias module:storage.appendFileAsync * @async - * @see module:storage.appendFile */ const appendFileAsync = fsPromises.appendFile /** - * Node.js' [fs.readFile]{@link https://nodejs.org/api/fs.html#fsreadfilepath-options-callback} - * @function - * @param {string} path - * @param {object} options - * @param {function} callback - * @alias module:storage.readFile - */ -const readFile = fs.readFile - -/** - * Async version of {@link module:storage.readFile}. + * Node.js' [fsPromises.readFile]{@link https://nodejs.org/api/fs.html#fspromisesreadfilepath-options}. * @function * @param {string} path * @param {object} [options] * @return {Promise} * @alias module:storage.readFileAsync * @async - * @see module:storage.readFile */ const readFileAsync = fsPromises.readFile @@ -171,66 +100,35 @@ const readFileAsync = fsPromises.readFile const readFileStream = fs.createReadStream /** - * Node.js' [fs.mkdir]{@link https://nodejs.org/api/fs.html#fsmkdirpath-options-callback}. - * @function - * @param {string} path - * @param {object} options - * @param {function} callback - * @alias module:storage.mkdir - */ -const mkdir = fs.mkdir - -/** - * Async version of {@link module:storage.mkdir}. + * Node.js' [fsPromises.mkdir]{@link https://nodejs.org/api/fs.html#fspromisesmkdirpath-options}. * @function * @param {string} path * @param {object} options * @return {Promise} * @alias module:storage.mkdirAsync * @async - * @see module:storage.mkdir */ const mkdirAsync = fsPromises.mkdir /** - * Async version of {@link module:storage.ensureFileDoesntExist} + * Removes file if it exists. * @param {string} file * @return {Promise} * @alias module:storage.ensureFileDoesntExistAsync * @async - * @see module:storage.ensureFileDoesntExist */ const ensureFileDoesntExistAsync = async file => { if (await existsAsync(file)) await unlinkAsync(file) } -/** - * Removes file if it exists. - * @param {string} file - * @param {NoParamCallback} callback - * @alias module:storage.ensureFileDoesntExist - */ -const ensureFileDoesntExist = (file, callback) => callbackify(ensureFileDoesntExistAsync)(file, err => callback(err)) - /** * Flush data in OS buffer to storage if corresponding option is set. * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested * @param {string} [options.filename] * @param {boolean} [options.isDir = false] Optional, defaults to false - * @param {NoParamCallback} callback - * @alias module:storage.flushToStorage - */ -const flushToStorage = (options, callback) => callbackify(flushToStorageAsync)(options, callback) - -/** - * Async version of {@link module:storage.flushToStorage}. - * @param {object|string} options - * @param {string} [options.filename] - * @param {boolean} [options.isDir = false] * @return {Promise} * @alias module:storage.flushToStorageAsync * @async - * @see module:storage.flushToStorage */ const flushToStorageAsync = async (options) => { let filename @@ -255,11 +153,11 @@ const flushToStorageAsync = async (options) => { * database is loaded and a crash happens. */ - let fd, errorOnFsync, errorOnClose // TODO: sometimes it leaves some file descriptors open + let filehandle, errorOnFsync, errorOnClose try { - fd = await fsPromises.open(filename, flags) + filehandle = await fsPromises.open(filename, flags) try { - await fd.sync() + await filehandle.sync() } catch (errFS) { errorOnFsync = errFS } @@ -267,7 +165,7 @@ const flushToStorageAsync = async (options) => { if (error.code !== 'EISDIR' || !options.isDir) throw error } finally { try { - await fd.close() + await filehandle.close() } catch (errC) { errorOnClose = errC } @@ -284,10 +182,11 @@ const flushToStorageAsync = async (options) => { * Fully write or rewrite the datafile. * @param {string} filename * @param {string[]} lines - * @param {NoParamCallback} [callback = () => {}] - * @alias module:storage.writeFileLines + * @return {Promise} + * @alias module:storage.writeFileLinesAsync + * @async */ -const writeFileLines = (filename, lines, callback = () => {}) => { +const writeFileLinesAsync = (filename, lines) => new Promise((resolve, reject) => { try { const stream = writeFileStream(filename) const readable = Readable.from(lines) @@ -295,46 +194,36 @@ const writeFileLines = (filename, lines, callback = () => {}) => { try { stream.write(line + '\n') } catch (err) { - callback(err) + reject(err) } }) readable.on('end', () => { - stream.close(callback) + stream.close(err => { + if (err) reject(err) + else resolve() + }) + }) + + readable.on('error', err => { + if (err) reject(err) + else resolve() + }) + + stream.on('error', err => { + if (err) reject(err) + else resolve() }) - readable.on('error', callback) - stream.on('error', callback) } catch (err) { - callback(err) + reject(err) } -} -/** - * Async version of {@link module:storage.writeFileLines}. - * @param {string} filename - * @param {string[]} lines - * @return {Promise} - * @alias module:storage.writeFileLinesAsync - * @async - * @see module:storage.writeFileLines - */ -const writeFileLinesAsync = (filename, lines) => promisify(writeFileLines)(filename, lines) +}) /** * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost). * @param {string} filename * @param {string[]} lines - * @param {NoParamCallback} [callback] Optional callback, signature: err - * @alias module:storage.crashSafeWriteFileLines - */ -const crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { - callbackify(crashSafeWriteFileLinesAsync)(filename, lines, callback) -} -/** - * Async version of {@link module:storage.crashSafeWriteFileLines}. - * @param {string} filename - * @param {string[]} lines * @return {Promise} * @alias module:storage.crashSafeWriteFileLinesAsync - * @see module:storage.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { const tempFilename = filename + '~' @@ -356,17 +245,8 @@ const crashSafeWriteFileLinesAsync = async (filename, lines) => { /** * Ensure the datafile contains all the data, even if there was a crash during a full file write. * @param {string} filename - * @param {NoParamCallback} callback signature: err - * @alias module:storage.ensureDatafileIntegrity - */ -const ensureDatafileIntegrity = (filename, callback) => callbackify(ensureDatafileIntegrityAsync)(filename, callback) - -/** - * Async version of {@link module:storage.ensureDatafileIntegrity}. - * @param {string} filename * @return {Promise} * @alias module:storage.ensureDatafileIntegrityAsync - * @see module:storage.ensureDatafileIntegrity */ const ensureDatafileIntegrityAsync = async filename => { const tempFilename = filename + '~' @@ -383,41 +263,28 @@ const ensureDatafileIntegrityAsync = async filename => { } // Interface -module.exports.exists = exists module.exports.existsAsync = existsAsync -module.exports.rename = rename module.exports.renameAsync = renameAsync -module.exports.writeFile = writeFile module.exports.writeFileAsync = writeFileAsync -module.exports.writeFileLines = writeFileLines module.exports.writeFileLinesAsync = writeFileLinesAsync -module.exports.crashSafeWriteFileLines = crashSafeWriteFileLines module.exports.crashSafeWriteFileLinesAsync = crashSafeWriteFileLinesAsync -module.exports.appendFile = appendFile module.exports.appendFileAsync = appendFileAsync -module.exports.readFile = readFile module.exports.readFileAsync = readFileAsync -module.exports.unlink = unlink module.exports.unlinkAsync = unlinkAsync -module.exports.mkdir = mkdir module.exports.mkdirAsync = mkdirAsync -module.exports.readFileStream = writeFileStream module.exports.readFileStream = readFileStream -module.exports.flushToStorage = flushToStorage module.exports.flushToStorageAsync = flushToStorageAsync -module.exports.ensureDatafileIntegrity = ensureDatafileIntegrity module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync -module.exports.ensureFileDoesntExist = ensureFileDoesntExist module.exports.ensureFileDoesntExistAsync = ensureFileDoesntExistAsync diff --git a/lib/utils.js b/lib/utils.js index ac64bf6..951df8f 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -3,6 +3,13 @@ * This replaces the underscore dependency. * * @module utils + * @private + */ + +/** + * @callback IterateeFunction + * @param {*} arg + * @return {*} */ /** @@ -12,7 +19,7 @@ * * Heavily inspired by {@link https://underscorejs.org/#uniq}. * @param {Array} array - * @param {function} [iteratee] transformation applied to every element before checking for duplicates. This will not + * @param {IterateeFunction} [iteratee] transformation applied to every element before checking for duplicates. This will not * transform the items in the result. * @return {Array} * @alias module:utils.uniq diff --git a/lib/waterfall.js b/lib/waterfall.js index fab25b4..bf2895d 100644 --- a/lib/waterfall.js +++ b/lib/waterfall.js @@ -1,5 +1,6 @@ /** * Responsible for sequentially executing actions on the database + * @private */ class Waterfall { /** @@ -11,21 +12,9 @@ class Waterfall { * * It will change any time `this.waterfall` is called. * - * Use {@link Waterfall#guardian} instead which retrievethe latest version of the guardian. * @type {Promise} - * @private */ - this._guardian = Promise.resolve() - } - - /** - * Getter that gives a Promise which resolves when all tasks up to when this function is called are done. - * - * This Promise cannot reject. - * @return {Promise} - */ - get guardian () { - return this._guardian + this.guardian = Promise.resolve() } /** @@ -35,7 +24,7 @@ class Waterfall { */ waterfall (func) { return (...args) => { - this._guardian = this.guardian.then(() => { + this.guardian = this.guardian.then(() => { return func(...args) .then(result => ({ error: false, result }), result => ({ error: true, result })) }) diff --git a/test/browser/nedb-browser.spec.js b/test/browser/nedb-browser.spec.js index 25743d7..24917a6 100755 --- a/test/browser/nedb-browser.spec.js +++ b/test/browser/nedb-browser.spec.js @@ -1,5 +1,5 @@ /* eslint-env mocha */ -/* global chai, Nedb */ +/* global chai, Nedb, testUtils */ /** * Testing the browser version of NeDB @@ -265,7 +265,7 @@ describe('Indexing', function () { db.insert({ a: 6 }, function () { db.insert({ a: 7 }, function () { // eslint-disable-next-line node/handle-callback-err - db.getCandidates({ a: 6 }, function (err, candidates) { + testUtils.callbackify(query => db._getCandidatesAsync(query))({ a: 6 }, function (err, candidates) { assert.strictEqual(candidates.length, 3) assert.isDefined(candidates.find(function (doc) { return doc.a === 4 })) assert.isDefined(candidates.find(function (doc) { return doc.a === 6 })) @@ -274,7 +274,7 @@ describe('Indexing', function () { db.ensureIndex({ fieldName: 'a' }) // eslint-disable-next-line node/handle-callback-err - db.getCandidates({ a: 6 }, function (err, candidates) { + testUtils.callbackify(query => db._getCandidatesAsync(query))({ a: 6 }, function (err, candidates) { assert.strictEqual(candidates.length, 1) assert.isDefined(candidates.find(function (doc) { return doc.a === 6 })) diff --git a/test/byline.test.js b/test/byline.test.js index 713d80d..129d886 100644 --- a/test/byline.test.js +++ b/test/byline.test.js @@ -46,7 +46,7 @@ describe('byline', function () { it('should work with streams2 API', function (done) { let stream = fs.createReadStream(localPath('empty.txt')) - stream = byline.createStream(stream) + stream = byline(stream) stream.on('readable', function () { while (stream.read() !== null) { diff --git a/test/cursor.async.test.js b/test/cursor.async.test.js index f4c3b4c..9178255 100755 --- a/test/cursor.async.test.js +++ b/test/cursor.async.test.js @@ -120,9 +120,9 @@ describe('Cursor Async', function () { compareStrings: function (a, b) { return a.length - b.length } }) - db.insertAsync({ name: 'alpha' }) // TODO was not awaited - db.insertAsync({ name: 'charlie' }) // TODO was not awaited - db.insertAsync({ name: 'zulu' }) // TODO was not awaited + await db.insertAsync({ name: 'alpha' }) + await db.insertAsync({ name: 'charlie' }) + await db.insertAsync({ name: 'zulu' }) const docs = await db.findAsync({}).sort({ name: 1 }) assert.equal(docs.map(x => x.name)[0], 'zulu') @@ -130,7 +130,7 @@ describe('Cursor Async', function () { assert.equal(docs.map(x => x.name)[2], 'charlie') delete db.compareStrings - const docs2 = await db.find({}).sort({ name: 1 }) + const docs2 = await db.findAsync({}).sort({ name: 1 }) assert.equal(docs2.map(x => x.name)[0], 'alpha') assert.equal(docs2.map(x => x.name)[1], 'charlie') assert.equal(docs2.map(x => x.name)[2], 'zulu') diff --git a/test/cursor.test.js b/test/cursor.test.js index fbce0c4..64a837c 100755 --- a/test/cursor.test.js +++ b/test/cursor.test.js @@ -7,6 +7,7 @@ const { each, waterfall } = require('./utils.test.js') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') const Cursor = require('../lib/cursor') +const { callbackify } = require('util') const { assert } = chai chai.should() @@ -21,7 +22,7 @@ describe('Cursor', function () { waterfall([ function (cb) { - Persistence.ensureDirectoryExists(path.dirname(testDb), function () { + callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () { fs.access(testDb, fs.constants.F_OK, function (err) { if (!err) { fs.unlink(testDb, cb) diff --git a/test/db.async.test.js b/test/db.async.test.js index 0625fc9..6ae55e4 100644 --- a/test/db.async.test.js +++ b/test/db.async.test.js @@ -53,7 +53,7 @@ describe('Database async', function () { await fs.writeFile(autoDb, fileStr, 'utf8') const db = new Datastore({ filename: autoDb, autoload: true }) - const docs = await db.find({}) + const docs = await db.findAsync({}) assert.equal(docs.length, 2) }) @@ -300,7 +300,7 @@ describe('Database async', function () { await d.insertAsync({ tf: 6 }) const _doc2 = await d.insertAsync({ tf: 4, an: 'other' }) await d.insertAsync({ tf: 9 }) - const data = await d.getCandidatesAsync({ r: 6, tf: 4 }) + const data = await d._getCandidatesAsync({ r: 6, tf: 4 }) const doc1 = data.find(d => d._id === _doc1._id) const doc2 = data.find(d => d._id === _doc2._id) @@ -310,12 +310,12 @@ describe('Database async', function () { }) it('Can use an index to get docs with a $in match', async () => { - await d.ensureIndex({ fieldName: 'tf' }) + await d.ensureIndexAsync({ fieldName: 'tf' }) await d.insertAsync({ tf: 4 }) const _doc1 = await d.insertAsync({ tf: 6 }) await d.insertAsync({ tf: 4, an: 'other' }) const _doc2 = await d.insertAsync({ tf: 9 }) - const data = await d.getCandidatesAsync({ r: 6, tf: { $in: [6, 9, 5] } }) + const data = await d._getCandidatesAsync({ r: 6, tf: { $in: [6, 9, 5] } }) const doc1 = data.find(d => d._id === _doc1._id) const doc2 = data.find(d => d._id === _doc2._id) @@ -330,7 +330,7 @@ describe('Database async', function () { const _doc2 = await d.insertAsync({ tf: 6 }) const _doc3 = await d.insertAsync({ tf: 4, an: 'other' }) const _doc4 = await d.insertAsync({ tf: 9 }) - const data = await d.getCandidatesAsync({ r: 6, notf: { $in: [6, 9, 5] } }) + const data = await d._getCandidatesAsync({ r: 6, notf: { $in: [6, 9, 5] } }) const doc1 = data.find(d => d._id === _doc1._id) const doc2 = data.find(d => d._id === _doc2._id) const doc3 = data.find(d => d._id === _doc3._id) @@ -349,7 +349,7 @@ describe('Database async', function () { const _doc2 = await d.insertAsync({ tf: 6 }) await d.insertAsync({ tf: 4, an: 'other' }) const _doc4 = await d.insertAsync({ tf: 9 }) - const data = await d.getCandidatesAsync({ r: 6, tf: { $lte: 9, $gte: 6 } }) + const data = await d._getCandidatesAsync({ r: 6, tf: { $lte: 9, $gte: 6 } }) const doc2 = data.find(d => d._id === _doc2._id) const doc4 = data.find(d => d._id === _doc4._id) @@ -448,12 +448,12 @@ describe('Database async', function () { await d.insertAsync({ somedata: 'again', plus: 'additional data' }) await d.insertAsync({ somedata: 'again' }) // Test with query that will return docs - const doc = await d.findOne({ somedata: 'ok' }) + const doc = await d.findOneAsync({ somedata: 'ok' }) assert.equal(Object.keys(doc).length, 2) assert.equal(doc.somedata, 'ok') assert.notEqual(doc._id, undefined) // Test with query that doesn't match anything - const doc2 = await d.findOne({ somedata: 'nope' }) + const doc2 = await d.findOneAsync({ somedata: 'nope' }) assert.equal(doc2, null) }) @@ -462,28 +462,28 @@ describe('Database async', function () { const date2 = new Date(9999) await d.insertAsync({ now: date1, sth: { name: 'nedb' } }) - const doc1 = await d.findOne({ now: date1 }) + const doc1 = await d.findOneAsync({ now: date1 }) assert.equal(doc1.sth.name, 'nedb') - const doc2 = await d.findOne({ now: date2 }) + const doc2 = await d.findOneAsync({ now: date2 }) assert.equal(doc2, null) - const doc3 = await d.findOne({ sth: { name: 'nedb' } }) + const doc3 = await d.findOneAsync({ sth: { name: 'nedb' } }) assert.equal(doc3.sth.name, 'nedb') - const doc4 = await d.findOne({ sth: { name: 'other' } }) + const doc4 = await d.findOneAsync({ sth: { name: 'other' } }) assert.equal(doc4, null) }) it('Can use dot-notation to query subfields', async () => { await d.insertAsync({ greeting: { english: 'hello' } }) - const doc1 = await d.findOne({ 'greeting.english': 'hello' }) + const doc1 = await d.findOneAsync({ 'greeting.english': 'hello' }) assert.equal(doc1.greeting.english, 'hello') - const doc2 = await d.findOne({ 'greeting.english': 'hellooo' }) + const doc2 = await d.findOneAsync({ 'greeting.english': 'hellooo' }) assert.equal(doc2, null) - const doc3 = await d.findOne({ 'greeting.englis': 'hello' }) + const doc3 = await d.findOneAsync({ 'greeting.englis': 'hello' }) assert.equal(doc3, null) }) @@ -551,11 +551,11 @@ describe('Database async', function () { assert.equal(doc2.hello, 'home') // And a skip - const doc3 = await d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).skip(1) + const doc3 = await d.findOneAsync({ a: { $gt: 14 } }).sort({ a: 1 }).skip(1) assert.equal(doc3.hello, 'earth') // No result - const doc4 = await d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).skip(2) + const doc4 = await d.findOneAsync({ a: { $gt: 14 } }).sort({ a: 1 }).skip(2) assert.equal(doc4, null) }) @@ -795,7 +795,7 @@ describe('Database async', function () { }) it('If the update query contains modifiers, it is applied to the object resulting from removing all operators from the find query 1', async () => { - await d.update({ $or: [{ a: 4 }, { a: 5 }] }, { + await d.updateAsync({ $or: [{ a: 4 }, { a: 5 }] }, { $set: { hello: 'world' }, $inc: { bloup: 3 } // eslint-disable-next-line node/handle-callback-err @@ -809,7 +809,7 @@ describe('Database async', function () { }) it('If the update query contains modifiers, it is applied to the object resulting from removing all operators from the find query 2', async () => { - await d.update({ $or: [{ a: 4 }, { a: 5 }], cac: 'rrr' }, { + await d.updateAsync({ $or: [{ a: 4 }, { a: 5 }], cac: 'rrr' }, { $set: { hello: 'world' }, $inc: { bloup: 3 } // eslint-disable-next-line node/handle-callback-err @@ -845,7 +845,7 @@ describe('Database async', function () { }, { multi: false }) assert.equal(numAffected, 1) - const doc = await d.findOne({ _id: id }) + const doc = await d.findOneAsync({ _id: id }) assert.equal(Object.keys(doc).length, 3) assert.equal(doc._id, id) assert.equal(doc.something, 'changed') @@ -874,13 +874,13 @@ describe('Database async', function () { await d.insertAsync({ bloup: { blip: 'blap', other: true } }) // Correct methos await d.updateAsync({}, { $set: { 'bloup.blip': 'hello' } }, {}) - const doc = await d.findOne({}) + const doc = await d.findOneAsync({}) assert.equal(doc.bloup.blip, 'hello') assert.equal(doc.bloup.other, true) // Wrong await d.updateAsync({}, { $set: { bloup: { blip: 'ola' } } }, {}) - const doc2 = await d.findOne({}) + const doc2 = await d.findOneAsync({}) assert.equal(doc2.bloup.blip, 'ola') assert.equal(doc2.bloup.other, undefined) // This information was lost }) @@ -977,7 +977,7 @@ describe('Database async', function () { }) it('If a multi update fails on one document, previous updates should be rolled back', async () => { - d.ensureIndexAsync({ fieldName: 'a' }) // TODO should be awaited, but was not in original tests + await d.ensureIndexAsync({ fieldName: 'a' }) const doc1 = await d.insertAsync({ a: 4 }) const doc2 = await d.insertAsync({ a: 5 }) const doc3 = await d.insertAsync({ a: 'abc' }) @@ -1002,7 +1002,7 @@ describe('Database async', function () { }) it('If an index constraint is violated by an update, all changes should be rolled back', async () => { - d.ensureIndex({ fieldName: 'a', unique: true }) // TODO should be awaited, but was not in original tests + await d.ensureIndexAsync({ fieldName: 'a', unique: true }) const doc1 = await d.insertAsync({ a: 4 }) const doc2 = await d.insertAsync({ a: 5 }) // With this query, candidates are always returned in the order 4, 5, 'abc' so it's always the last one which fails @@ -1067,20 +1067,20 @@ describe('Database async', function () { it('createdAt property is unchanged and updatedAt correct after an update, even a complete document replacement', async () => { const d2 = new Datastore({ inMemoryOnly: true, timestampData: true }) - d2.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests + await d2.insertAsync({ a: 1 }) const doc = await d2.findOneAsync({ a: 1 }) const createdAt = doc.createdAt.getTime() // Modifying update await wait(20) - d2.updateAsync({ a: 1 }, { $set: { b: 2 } }, {}) // TODO probably should await but was not awaited in original tests + await d2.updateAsync({ a: 1 }, { $set: { b: 2 } }, {}) const doc2 = await d2.findOneAsync({ a: 1 }) assert.equal(doc2.createdAt.getTime(), createdAt) assert.ok(Date.now() - doc2.updatedAt.getTime() < 5) // Complete replacement await wait(20) - d2.update({ a: 1 }, { c: 3 }, {}) // TODO probably should await but was not awaited in original tests + await d2.updateAsync({ a: 1 }, { c: 3 }, {}) const doc3 = await d2.findOneAsync({ c: 3 }) assert.equal(doc3.createdAt.getTime(), createdAt) assert.ok(Date.now() - doc3.updatedAt.getTime() < 5) @@ -1089,8 +1089,8 @@ describe('Database async', function () { describe('Callback signature', function () { it('Regular update, multi false', async () => { - d.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests - d.insertAsync({ a: 2 }) // TODO probably should await but was not awaited in original tests + await d.insertAsync({ a: 1 }) + await d.insertAsync({ a: 2 }) // returnUpdatedDocs set to false const { numAffected, affectedDocuments, upsert } = await d.updateAsync({ a: 1 }, { $set: { b: 20 } }, {}) @@ -1111,8 +1111,8 @@ describe('Database async', function () { }) it('Regular update, multi true', async () => { - d.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests - d.insertAsync({ a: 2 }) // TODO probably should await but was not awaited in original tests + await d.insertAsync({ a: 1 }) + await d.insertAsync({ a: 2 }) // returnUpdatedDocs set to false const { @@ -1139,8 +1139,8 @@ describe('Database async', function () { }) it('Upsert', async () => { - d.insertAsync({ a: 1 }) // TODO probably should await but was not awaited in original tests - d.insertAsync({ a: 2 }) // TODO probably should await but was not awaited in original tests + await d.insertAsync({ a: 1 }) + await d.insertAsync({ a: 2 }) // Upsert flag not set const { numAffected, affectedDocuments, upsert } = await d.updateAsync({ a: 3 }, { $set: { b: 20 } }, {}) @@ -1280,7 +1280,7 @@ describe('Database async', function () { assert.deepEqual(Object.keys(d.indexes), ['_id']) - d.ensureIndexAsync({ fieldName: 'z' }) // TODO: was not async + await d.ensureIndexAsync({ fieldName: 'z' }) assert.equal(d.indexes.z.fieldName, 'z') assert.equal(d.indexes.z.unique, false) assert.equal(d.indexes.z.sparse, false) @@ -1335,7 +1335,7 @@ describe('Database async', function () { await d.updateAsync({ z: '1' }, { $set: { yes: 'yep' } }, {}) assert.deepEqual(Object.keys(d.indexes), ['_id']) - d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'z' }) assert.equal(d.indexes.z.fieldName, 'z') assert.equal(d.indexes.z.unique, false) assert.equal(d.indexes.z.sparse, false) @@ -1367,7 +1367,7 @@ describe('Database async', function () { assert.equal(d.getAllData().length, 0) - d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'z' }) assert.equal(d.indexes.z.fieldName, 'z') assert.equal(d.indexes.z.unique, false) assert.equal(d.indexes.z.sparse, false) @@ -1426,17 +1426,17 @@ describe('Database async', function () { assert.equal(d.getAllData().length, 0) - d.ensureIndexAsync({ fieldName: 'z', unique: true }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'z', unique: true }) assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) await fs.writeFile(testDb, rawData, 'utf8') await assert.rejects(() => d.loadDatabaseAsync(), err => { assert.equal(err.errorType, 'uniqueViolated') assert.equal(err.key, '1') - assert.equal(d.getAllData().length, 0) // TODO wtf ? - assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) // TODO wtf ? return true }) + assert.equal(d.getAllData().length, 0) + assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) }) it('If a unique constraint is not respected, ensureIndex will return an error and not create an index', async () => { @@ -1465,7 +1465,7 @@ describe('Database async', function () { describe('Indexing newly inserted documents', function () { it('Newly inserted documents are indexed', async () => { - d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'z' }) assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) @@ -1478,8 +1478,8 @@ describe('Database async', function () { }) it('If multiple indexes are defined, the document is inserted in all of them', async () => { - d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited - d.ensureIndexAsync({ fieldName: 'ya' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'z' }) + await d.ensureIndexAsync({ fieldName: 'ya' }) assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) const newDoc = await d.insertAsync({ a: 2, z: 'yes', ya: 'indeed' }) @@ -1496,7 +1496,7 @@ describe('Database async', function () { }) it('Can insert two docs at the same key for a non unique index', async () => { - d.ensureIndexAsync({ fieldName: 'z' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'z' }) assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) @@ -1509,7 +1509,7 @@ describe('Database async', function () { }) it('If the index has a unique constraint, an error is thrown if it is violated and the data is not modified', async () => { - d.ensureIndexAsync({ fieldName: 'z', unique: true }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'z', unique: true }) assert.equal(d.indexes.z.tree.getNumberOfKeys(), 0) const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) @@ -1533,9 +1533,9 @@ describe('Database async', function () { }) it('If an index has a unique constraint, other indexes cannot be modified when it raises an error', async () => { - d.ensureIndexAsync({ fieldName: 'nonu1' }) // TODO was not awaited - d.ensureIndexAsync({ fieldName: 'uni', unique: true }) // TODO was not awaited - d.ensureIndexAsync({ fieldName: 'nonu2' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'nonu1' }) + await d.ensureIndexAsync({ fieldName: 'uni', unique: true }) + await d.ensureIndexAsync({ fieldName: 'nonu2' }) const newDoc = await d.insertAsync({ nonu1: 'yes', nonu2: 'yes2', uni: 'willfail' }) assert.equal(d.indexes.nonu1.tree.getNumberOfKeys(), 1) @@ -1558,7 +1558,7 @@ describe('Database async', function () { }) it('Unique indexes prevent you from inserting two docs where the field is undefined except if theyre sparse', async () => { - d.ensureIndexAsync({ fieldName: 'zzz', unique: true }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'zzz', unique: true }) assert.equal(d.indexes.zzz.tree.getNumberOfKeys(), 0) const newDoc = await d.insertAsync({ a: 2, z: 'yes' }) @@ -1571,7 +1571,7 @@ describe('Database async', function () { return true }) - d.ensureIndexAsync({ fieldName: 'yyy', unique: true, sparse: true }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'yyy', unique: true, sparse: true }) await d.insertAsync({ a: 5, z: 'other', zzz: 'set' }) assert.equal(d.indexes.yyy.getAll().length, 0) // Nothing indexed @@ -1579,8 +1579,8 @@ describe('Database async', function () { }) it('Insertion still works as before with indexing', async () => { - d.ensureIndexAsync({ fieldName: 'a' }) // TODO was not awaited - d.ensureIndexAsync({ fieldName: 'b' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'a' }) + await d.ensureIndexAsync({ fieldName: 'b' }) const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) const doc2 = await d.insertAsync({ a: 2, b: 'si' }) @@ -1590,7 +1590,7 @@ describe('Database async', function () { }) it('All indexes point to the same data as the main index on _id', async () => { - d.ensureIndexAsync({ fieldName: 'a' }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'a' }) const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) const doc2 = await d.insertAsync({ a: 2, b: 'si' }) @@ -1608,7 +1608,7 @@ describe('Database async', function () { }) it('If a unique constraint is violated, no index is changed, including the main one', async () => { - d.ensureIndexAsync({ fieldName: 'a', unique: true }) // TODO was not awaited + await d.ensureIndexAsync({ fieldName: 'a', unique: true }) const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) await assert.rejects(() => d.insertAsync({ a: 1, b: 'si' })) @@ -1627,7 +1627,7 @@ describe('Database async', function () { describe('Updating indexes upon document update', function () { it('Updating docs still works as before with indexing', async () => { - d.ensureIndexAsync({ fieldName: 'a' }) // TODO: not awaited + await d.ensureIndexAsync({ fieldName: 'a' }) const _doc1 = await d.insertAsync({ a: 1, b: 'hello' }) const _doc2 = await d.insertAsync({ a: 2, b: 'si' }) @@ -1658,8 +1658,8 @@ describe('Database async', function () { }) it('Indexes get updated when a document (or multiple documents) is updated', async () => { - d.ensureIndexAsync({ fieldName: 'a' }) // TODO: not awaited - d.ensureIndexAsync({ fieldName: 'b' }) // TODO: not awaited + await d.ensureIndexAsync({ fieldName: 'a' }) + await d.ensureIndexAsync({ fieldName: 'b' }) const doc1 = await d.insertAsync({ a: 1, b: 'hello' }) const doc2 = await d.insertAsync({ a: 2, b: 'si' }) @@ -1711,9 +1711,9 @@ describe('Database async', function () { }) it('If a simple update violates a contraint, all changes are rolled back and an error is thrown', async () => { - d.ensureIndexAsync({ fieldName: 'a', unique: true }) // TODO: not awaited - d.ensureIndexAsync({ fieldName: 'b', unique: true }) // TODO: not awaited - d.ensureIndexAsync({ fieldName: 'c', unique: true }) // TODO: not awaited + await d.ensureIndexAsync({ fieldName: 'a', unique: true }) + await d.ensureIndexAsync({ fieldName: 'b', unique: true }) + await d.ensureIndexAsync({ fieldName: 'c', unique: true }) const _doc1 = await d.insertAsync({ a: 1, b: 10, c: 100 }) const _doc2 = await d.insertAsync({ a: 2, b: 20, c: 200 }) @@ -1752,9 +1752,9 @@ describe('Database async', function () { }) it('If a multi update violates a contraint, all changes are rolled back and an error is thrown', async () => { - d.ensureIndexAsync({ fieldName: 'a', unique: true }) // TODO: was not awaited - d.ensureIndexAsync({ fieldName: 'b', unique: true }) // TODO: was not awaited - d.ensureIndexAsync({ fieldName: 'c', unique: true }) // TODO: was not awaited + await d.ensureIndexAsync({ fieldName: 'a', unique: true }) + await d.ensureIndexAsync({ fieldName: 'b', unique: true }) + await d.ensureIndexAsync({ fieldName: 'c', unique: true }) const _doc1 = await d.insertAsync({ a: 1, b: 10, c: 100 }) const _doc2 = await d.insertAsync({ a: 2, b: 20, c: 200 }) @@ -1798,7 +1798,7 @@ describe('Database async', function () { describe('Updating indexes upon document remove', function () { it('Removing docs still works as before with indexing', async () => { - d.ensureIndexAsync({ fieldName: 'a' }) // TODO: was not awaited + await d.ensureIndexAsync({ fieldName: 'a' }) await d.insertAsync({ a: 1, b: 'hello' }) const _doc2 = await d.insertAsync({ a: 2, b: 'si' }) @@ -1822,8 +1822,8 @@ describe('Database async', function () { }) it('Indexes get updated when a document (or multiple documents) is removed', async () => { - d.ensureIndexAsync({ fieldName: 'a' }) // TODO: was not awaited - d.ensureIndexAsync({ fieldName: 'b' }) // TODO: was not awaited + await d.ensureIndexAsync({ fieldName: 'a' }) + await d.ensureIndexAsync({ fieldName: 'b' }) await d.insertAsync({ a: 1, b: 'hello' }) const doc2 = await d.insertAsync({ a: 2, b: 'si' }) @@ -2027,9 +2027,9 @@ describe('Database async', function () { }) // ==== End of 'Persisting indexes' ==== it('Results of getMatching should never contain duplicates', async () => { - d.ensureIndexAsync({ fieldName: 'bad' }) // TODO: was not awaited + await d.ensureIndexAsync({ fieldName: 'bad' }) await d.insertAsync({ bad: ['a', 'b'] }) - const res = await d.getCandidatesAsync({ bad: { $in: ['a', 'b'] } }) + const res = await d._getCandidatesAsync({ bad: { $in: ['a', 'b'] } }) assert.equal(res.length, 1) }) }) // ==== End of 'Using indexes' ==== // diff --git a/test/db.test.js b/test/db.test.js index fbac065..675f5d3 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -7,6 +7,7 @@ const { apply, each, waterfall } = require('./utils.test.js') const model = require('../lib/model') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') +const { callbackify } = require('util') const reloadTimeUpperBound = 60 // In ms, an upper bound for the reload time used to check createdAt and updatedAt const { assert } = chai @@ -22,7 +23,7 @@ describe('Database', function () { waterfall([ function (cb) { - Persistence.ensureDirectoryExists(path.dirname(testDb), function () { + callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () { fs.access(testDb, fs.constants.FS_OK, function (err) { if (!err) { fs.unlink(testDb, cb) @@ -472,7 +473,7 @@ describe('Database', function () { d.insert({ tf: 4, an: 'other' }, function (err, _doc2) { d.insert({ tf: 9 }, function () { // eslint-disable-next-line node/handle-callback-err - d.getCandidates({ r: 6, tf: 4 }, function (err, data) { + callbackify(query => d._getCandidatesAsync(query))({ r: 6, tf: 4 }, function (err, data) { const doc1 = data.find(function (d) { return d._id === _doc1._id }) const doc2 = data.find(function (d) { return d._id === _doc2._id }) @@ -501,7 +502,7 @@ describe('Database', function () { // eslint-disable-next-line node/handle-callback-err d.insert({ tf: 9 }, function (err, _doc2) { // eslint-disable-next-line node/handle-callback-err - d.getCandidates({ r: 6, tf: { $in: [6, 9, 5] } }, function (err, data) { + callbackify(query => d._getCandidatesAsync(query))({ r: 6, tf: { $in: [6, 9, 5] } }, function (err, data) { const doc1 = data.find(function (d) { return d._id === _doc1._id }) const doc2 = data.find(function (d) { return d._id === _doc2._id }) @@ -530,7 +531,7 @@ describe('Database', function () { // eslint-disable-next-line node/handle-callback-err d.insert({ tf: 9 }, function (err, _doc4) { // eslint-disable-next-line node/handle-callback-err - d.getCandidates({ r: 6, notf: { $in: [6, 9, 5] } }, function (err, data) { + callbackify(query => d._getCandidatesAsync(query))({ r: 6, notf: { $in: [6, 9, 5] } }, function (err, data) { const doc1 = data.find(function (d) { return d._id === _doc1._id }) const doc2 = data.find(function (d) { return d._id === _doc2._id }) const doc3 = data.find(function (d) { return d._id === _doc3._id }) @@ -563,7 +564,7 @@ describe('Database', function () { // eslint-disable-next-line node/handle-callback-err d.insert({ tf: 9 }, function (err, _doc4) { // eslint-disable-next-line node/handle-callback-err - d.getCandidates({ r: 6, tf: { $lte: 9, $gte: 6 } }, function (err, data) { + callbackify(query => d._getCandidatesAsync(query))({ r: 6, tf: { $lte: 9, $gte: 6 } }, function (err, data) { const doc2 = data.find(function (d) { return d._id === _doc2._id }) const doc4 = data.find(function (d) { return d._id === _doc4._id }) @@ -2178,26 +2179,27 @@ describe('Database', function () { d.getAllData().length.should.equal(0) - d.ensureIndex({ fieldName: 'z' }) - d.indexes.z.fieldName.should.equal('z') - d.indexes.z.unique.should.equal(false) - d.indexes.z.sparse.should.equal(false) - d.indexes.z.tree.getNumberOfKeys().should.equal(0) + d.ensureIndex({ fieldName: 'z' }, function () { + d.indexes.z.fieldName.should.equal('z') + d.indexes.z.unique.should.equal(false) + d.indexes.z.sparse.should.equal(false) + d.indexes.z.tree.getNumberOfKeys().should.equal(0) - fs.writeFile(testDb, rawData, 'utf8', function () { - d.loadDatabase(function () { - const doc1 = d.getAllData().find(function (doc) { return doc.z === '1' }) - const doc2 = d.getAllData().find(function (doc) { return doc.z === '2' }) - const doc3 = d.getAllData().find(function (doc) { return doc.z === '3' }) + fs.writeFile(testDb, rawData, 'utf8', function () { + d.loadDatabase(function () { + const doc1 = d.getAllData().find(function (doc) { return doc.z === '1' }) + const doc2 = d.getAllData().find(function (doc) { return doc.z === '2' }) + const doc3 = d.getAllData().find(function (doc) { return doc.z === '3' }) - d.getAllData().length.should.equal(3) + d.getAllData().length.should.equal(3) - d.indexes.z.tree.getNumberOfKeys().should.equal(3) - d.indexes.z.tree.search('1')[0].should.equal(doc1) - d.indexes.z.tree.search('2')[0].should.equal(doc2) - d.indexes.z.tree.search('3')[0].should.equal(doc3) + d.indexes.z.tree.getNumberOfKeys().should.equal(3) + d.indexes.z.tree.search('1')[0].should.equal(doc1) + d.indexes.z.tree.search('2')[0].should.equal(doc2) + d.indexes.z.tree.search('3')[0].should.equal(doc3) - done() + done() + }) }) }) }) @@ -2248,18 +2250,19 @@ describe('Database', function () { d.getAllData().length.should.equal(0) - d.ensureIndex({ fieldName: 'z', unique: true }) - d.indexes.z.tree.getNumberOfKeys().should.equal(0) + d.ensureIndex({ fieldName: 'z', unique: true }, function () { + d.indexes.z.tree.getNumberOfKeys().should.equal(0) - fs.writeFile(testDb, rawData, 'utf8', function () { - d.loadDatabase(function (err) { - err.should.not.equal(null) - err.errorType.should.equal('uniqueViolated') - err.key.should.equal('1') - d.getAllData().length.should.equal(0) - d.indexes.z.tree.getNumberOfKeys().should.equal(0) + fs.writeFile(testDb, rawData, 'utf8', function () { + d.loadDatabase(function (err) { + assert.isNotNull(err) + err.errorType.should.equal('uniqueViolated') + err.key.should.equal('1') + d.getAllData().length.should.equal(0) + d.indexes.z.tree.getNumberOfKeys().should.equal(0) - done() + done() + }) }) }) }) @@ -3022,7 +3025,7 @@ describe('Database', function () { d.ensureIndex({ fieldName: 'bad' }) d.insert({ bad: ['a', 'b'] }, function () { // eslint-disable-next-line node/handle-callback-err - d.getCandidates({ bad: { $in: ['a', 'b'] } }, function (err, res) { + callbackify(query => d._getCandidatesAsync(query))({ bad: { $in: ['a', 'b'] } }, function (err, res) { res.length.should.equal(1) done() }) diff --git a/test/executor.test.js b/test/executor.test.js index a9d2de9..0b537b8 100755 --- a/test/executor.test.js +++ b/test/executor.test.js @@ -6,6 +6,7 @@ const path = require('path') const { waterfall } = require('./utils.test.js') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') +const { callbackify } = require('util') const { assert } = chai chai.should() @@ -153,7 +154,7 @@ describe('Executor', function () { waterfall([ function (cb) { - Persistence.ensureDirectoryExists(path.dirname(testDb), function () { + callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () { fs.access(testDb, fs.constants.F_OK, function (err) { if (!err) { fs.unlink(testDb, cb) diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index 3ff9e0e..32e6399 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -334,6 +334,29 @@ describe('Persistence async', function () { assert.equal(doc2Reloaded, undefined) }) + it('Calling dropDatabase after the datafile was modified loads the new data', async () => { + await d.loadDatabaseAsync() + await d.insertAsync({ a: 1 }) + await d.insertAsync({ a: 2 }) + const data = d.getAllData() + const doc1 = data.find(doc => doc.a === 1) + const doc2 = data.find(doc => doc.a === 2) + assert.equal(data.length, 2) + assert.equal(doc1.a, 1) + assert.equal(doc2.a, 2) + + await fs.writeFile(testDb, '{"a":3,"_id":"aaa"}', 'utf8') + await d.loadDatabaseAsync() + const dataReloaded = d.getAllData() + const doc1Reloaded = dataReloaded.find(function (doc) { return doc.a === 1 }) + const doc2Reloaded = dataReloaded.find(function (doc) { return doc.a === 2 }) + const doc3Reloaded = dataReloaded.find(function (doc) { return doc.a === 3 }) + assert.equal(dataReloaded.length, 1) + assert.equal(doc3Reloaded.a, 3) + assert.equal(doc1Reloaded, undefined) + assert.equal(doc2Reloaded, undefined) + }) + it('When treating raw data, refuse to proceed if too much data is corrupt, to avoid data loss', async () => { const corruptTestFilename = 'workspace/corruptTest.db' const fakeData = '{"_id":"one","hello":"world"}\n' + 'Some corrupt data\n' + '{"_id":"two","hello":"earth"}\n' + '{"_id":"three","hello":"you"}\n' @@ -707,7 +730,7 @@ describe('Persistence async', function () { it('persistCachedDatabase should update the contents of the datafile and leave a clean state even if there is a temp datafile', async () => { await d.insertAsync({ hello: 'world' }) - const docs = await d.find({}) + const docs = await d.findAsync({}) assert.equal(docs.length, 1) if (await exists(testDb)) { await fs.unlink(testDb) } @@ -749,7 +772,7 @@ describe('Persistence async', function () { const theDb = new Datastore({ filename: dbFile }) await theDb.loadDatabaseAsync() - const docs = await theDb.find({}) + const docs = await theDb.findAsync({}) assert.equal(docs.length, 0) const doc1 = await theDb.insertAsync({ a: 'hello' }) diff --git a/test/persistence.test.js b/test/persistence.test.js index a19ae04..aa965b4 100755 --- a/test/persistence.test.js +++ b/test/persistence.test.js @@ -9,6 +9,7 @@ const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') const storage = require('../lib/storage') const { execFile, fork } = require('child_process') +const { callbackify } = require('util') const Readable = require('stream').Readable const { assert } = chai @@ -24,7 +25,7 @@ describe('Persistence', function () { waterfall([ function (cb) { - Persistence.ensureDirectoryExists(path.dirname(testDb), function () { + callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () { fs.access(testDb, fs.constants.FS_OK, function (err) { if (!err) { fs.unlink(testDb, cb) @@ -66,7 +67,7 @@ describe('Persistence', function () { stream.push(rawData) stream.push(null) - d.persistence.treatRawStream(stream, function (err, result) { + callbackify(rawStream => d.persistence.treatRawStreamAsync(rawStream))(stream, function (err, result) { assert.isNull(err) const treatedData = result.data treatedData.sort(function (a, b) { return a._id - b._id }) @@ -101,7 +102,7 @@ describe('Persistence', function () { stream.push(rawData) stream.push(null) - d.persistence.treatRawStream(stream, function (err, result) { + callbackify(rawStream => d.persistence.treatRawStreamAsync(rawStream))(stream, function (err, result) { assert.isNull(err) const treatedData = result.data treatedData.sort(function (a, b) { return a._id - b._id }) @@ -135,7 +136,7 @@ describe('Persistence', function () { stream.push(rawData) stream.push(null) - d.persistence.treatRawStream(stream, function (err, result) { + callbackify(rawStream => d.persistence.treatRawStreamAsync(rawStream))(stream, function (err, result) { assert.isNull(err) const treatedData = result.data treatedData.sort(function (a, b) { return a._id - b._id }) @@ -169,7 +170,7 @@ describe('Persistence', function () { stream.push(rawData) stream.push(null) - d.persistence.treatRawStream(stream, function (err, result) { + callbackify(rawStream => d.persistence.treatRawStreamAsync(rawStream))(stream, function (err, result) { assert.isNull(err) const treatedData = result.data treatedData.sort(function (a, b) { return a._id - b._id }) @@ -205,7 +206,7 @@ describe('Persistence', function () { stream.push(rawData) stream.push(null) - d.persistence.treatRawStream(stream, function (err, result) { + callbackify(rawStream => d.persistence.treatRawStreamAsync(rawStream))(stream, function (err, result) { assert.isNull(err) const treatedData = result.data treatedData.sort(function (a, b) { return a._id - b._id }) @@ -239,7 +240,7 @@ describe('Persistence', function () { stream.push(rawData) stream.push(null) - d.persistence.treatRawStream(stream, function (err, result) { + callbackify(rawStream => d.persistence.treatRawStreamAsync(rawStream))(stream, function (err, result) { assert.isNull(err) const treatedData = result.data treatedData.sort(function (a, b) { return a._id - b._id }) @@ -277,7 +278,7 @@ describe('Persistence', function () { stream.push(rawData) stream.push(null) - d.persistence.treatRawStream(stream, function (err, result) { + callbackify(rawStream => d.persistence.treatRawStreamAsync(rawStream))(stream, function (err, result) { assert.isNull(err) const treatedData = result.data const indexes = result.indexes @@ -454,7 +455,7 @@ describe('Persistence', function () { it('Declaring only one hook will throw an exception to prevent data loss', function (done) { const hookTestFilename = 'workspace/hookTest.db' - storage.ensureFileDoesntExist(hookTestFilename, function () { + callbackify(storage.ensureFileDoesntExistAsync)(hookTestFilename, function () { fs.writeFileSync(hookTestFilename, 'Some content', 'utf8'); (function () { @@ -487,7 +488,7 @@ describe('Persistence', function () { it('Declaring two hooks that are not reverse of one another will cause an exception to prevent data loss', function (done) { const hookTestFilename = 'workspace/hookTest.db' - storage.ensureFileDoesntExist(hookTestFilename, function () { + callbackify(storage.ensureFileDoesntExistAsync)(hookTestFilename, function () { fs.writeFileSync(hookTestFilename, 'Some content', 'utf8'); (function () { @@ -509,7 +510,7 @@ describe('Persistence', function () { it('A serialization hook can be used to transform data before writing new state to disk', function (done) { const hookTestFilename = 'workspace/hookTest.db' - storage.ensureFileDoesntExist(hookTestFilename, function () { + callbackify(storage.ensureFileDoesntExistAsync)(hookTestFilename, function () { const d = new Datastore({ filename: hookTestFilename, autoload: true, @@ -586,7 +587,7 @@ describe('Persistence', function () { it('Use serialization hook when persisting cached database or compacting', function (done) { const hookTestFilename = 'workspace/hookTest.db' - storage.ensureFileDoesntExist(hookTestFilename, function () { + callbackify(storage.ensureFileDoesntExistAsync)(hookTestFilename, function () { const d = new Datastore({ filename: hookTestFilename, autoload: true, @@ -619,7 +620,7 @@ describe('Persistence', function () { idx = model.deserialize(idx) assert.deepStrictEqual(idx, { $$indexCreated: { fieldName: 'idefix' } }) - d.persistence.persistCachedDatabase(function () { + callbackify(() => d.persistence.persistCachedDatabaseAsync())(function () { const _data = fs.readFileSync(hookTestFilename, 'utf8') const data = _data.split('\n') let doc0 = bd(data[0]) @@ -646,7 +647,7 @@ describe('Persistence', function () { it('Deserialization hook is correctly used when loading data', function (done) { const hookTestFilename = 'workspace/hookTest.db' - storage.ensureFileDoesntExist(hookTestFilename, function () { + callbackify(storage.ensureFileDoesntExistAsync)(hookTestFilename, function () { const d = new Datastore({ filename: hookTestFilename, autoload: true, @@ -714,7 +715,7 @@ describe('Persistence', function () { fs.existsSync('workspace/it.db').should.equal(false) fs.existsSync('workspace/it.db~').should.equal(false) - storage.ensureDatafileIntegrity(p.filename, function (err) { + callbackify(storage.ensureDatafileIntegrityAsync)(p.filename, function (err) { assert.isNull(err) fs.existsSync('workspace/it.db').should.equal(true) @@ -737,7 +738,7 @@ describe('Persistence', function () { fs.existsSync('workspace/it.db').should.equal(true) fs.existsSync('workspace/it.db~').should.equal(false) - storage.ensureDatafileIntegrity(p.filename, function (err) { + callbackify(storage.ensureDatafileIntegrityAsync)(p.filename, function (err) { assert.isNull(err) fs.existsSync('workspace/it.db').should.equal(true) @@ -760,7 +761,7 @@ describe('Persistence', function () { fs.existsSync('workspace/it.db').should.equal(false) fs.existsSync('workspace/it.db~').should.equal(true) - storage.ensureDatafileIntegrity(p.filename, function (err) { + callbackify(storage.ensureDatafileIntegrityAsync)(p.filename, function (err) { assert.isNull(err) fs.existsSync('workspace/it.db').should.equal(true) @@ -785,7 +786,7 @@ describe('Persistence', function () { fs.existsSync('workspace/it.db').should.equal(true) fs.existsSync('workspace/it.db~').should.equal(true) - storage.ensureDatafileIntegrity(theDb.persistence.filename, function (err) { + callbackify(storage.ensureDatafileIntegrityAsync)(theDb.persistence.filename, function (err) { assert.isNull(err) fs.existsSync('workspace/it.db').should.equal(true) @@ -820,7 +821,7 @@ describe('Persistence', function () { fs.writeFileSync(testDb + '~', 'something', 'utf8') fs.existsSync(testDb + '~').should.equal(true) - d.persistence.persistCachedDatabase(function (err) { + callbackify(() => d.persistence.persistCachedDatabaseAsync())(function (err) { const contents = fs.readFileSync(testDb, 'utf8') assert.isNull(err) fs.existsSync(testDb).should.equal(true) @@ -848,7 +849,7 @@ describe('Persistence', function () { fs.writeFileSync(testDb + '~', 'bloup', 'utf8') fs.existsSync(testDb + '~').should.equal(true) - d.persistence.persistCachedDatabase(function (err) { + callbackify(() => d.persistence.persistCachedDatabaseAsync())(function (err) { const contents = fs.readFileSync(testDb, 'utf8') assert.isNull(err) fs.existsSync(testDb).should.equal(true) @@ -873,7 +874,7 @@ describe('Persistence', function () { fs.existsSync(testDb).should.equal(false) fs.existsSync(testDb + '~').should.equal(true) - d.persistence.persistCachedDatabase(function (err) { + callbackify(() => d.persistence.persistCachedDatabaseAsync())(function (err) { const contents = fs.readFileSync(testDb, 'utf8') assert.isNull(err) fs.existsSync(testDb).should.equal(true) @@ -912,8 +913,8 @@ describe('Persistence', function () { let theDb, theDb2, doc1, doc2 waterfall([ - apply(storage.ensureFileDoesntExist, dbFile), - apply(storage.ensureFileDoesntExist, dbFile + '~'), + apply(callbackify(storage.ensureFileDoesntExistAsync), dbFile), + apply(callbackify(storage.ensureFileDoesntExistAsync), dbFile + '~'), function (cb) { theDb = new Datastore({ filename: dbFile }) theDb.loadDatabase(cb) @@ -1051,25 +1052,4 @@ describe('Persistence', function () { }) }) }) // ==== End of 'Prevent dataloss when persisting data' ==== - - describe('ensureFileDoesntExist', function () { - it('Doesnt do anything if file already doesnt exist', function (done) { - storage.ensureFileDoesntExist('workspace/nonexisting', function (err) { - assert.isNull(err) - fs.existsSync('workspace/nonexisting').should.equal(false) - done() - }) - }) - - it('Deletes file if it stat', function (done) { - fs.writeFileSync('workspace/existing', 'hello world', 'utf8') - fs.existsSync('workspace/existing').should.equal(true) - - storage.ensureFileDoesntExist('workspace/existing', function (err) { - assert.isNull(err) - fs.existsSync('workspace/existing').should.equal(false) - done() - }) - }) - }) // ==== End of 'ensureFileDoesntExist' ==== }) diff --git a/test/utils.test.js b/test/utils.test.js index 8b0497d..d7272ee 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -39,3 +39,4 @@ module.exports.waterfall = waterfall module.exports.each = each module.exports.wait = wait module.exports.exists = exists +module.exports.callbackify = callbackify diff --git a/test_lac/openFds.test.js b/test_lac/openFds.test.js index 4512087..da449d6 100644 --- a/test_lac/openFds.test.js +++ b/test_lac/openFds.test.js @@ -1,6 +1,7 @@ const fs = require('fs') const { waterfall, whilst } = require('../test/utils.test.js') const Nedb = require('../lib/datastore') +const { callbackify } = require('util') const db = new Nedb({ filename: './workspace/openfds.db', autoload: true }) const N = 64 let i @@ -48,7 +49,7 @@ waterfall([ i = 0 whilst(function () { return i < 2 * N + 1 } , function (cb) { - db.persistence.persistCachedDatabase(function (err) { + callbackify(() => db.persistence.persistCachedDatabaseAsync())(function (err) { if (err) { return cb(err) } i += 1 return cb() diff --git a/typings-tests.ts b/typings-tests.ts index 3144ec0..ed98aa9 100644 --- a/typings-tests.ts +++ b/typings-tests.ts @@ -20,10 +20,6 @@ db.loadDatabase() db = new Datastore({ filename: 'path/to/datafile_2', autoload: true }) // You can issue commands right away -// Type 4: Persistent datastore for a Node Webkit app called 'nwtest' -// For example on Linux, the datafile will be ~/.config/nwtest/nedb-data/something.db -db = new Datastore({ filename: 'something.db' }) - // Of course you can create multiple datastores if you need several // collections. In this case it's usually a good idea to use autoload for all collections. const dbContainer: any = {} From 2ec0101d7bc721fef3c25090f52fccaa2dc58d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Sun, 16 Jan 2022 18:06:11 +0100 Subject: [PATCH 46/65] one documentation file --- API.md | 1054 ++++++++++++++++++++++++ README.md | 40 +- browser-version/lib/customUtils.js | 1 + browser-version/lib/storage.browser.js | 2 +- docs/Cursor.md | 181 ---- docs/Datastore.md | 568 ------------- docs/Executor.md | 57 -- docs/Index.md | 161 ---- docs/Persistence.md | 242 ------ docs/Waterfall.md | 43 - docs/byline.md | 10 - docs/customUtilsBrowser.md | 34 - docs/customUtilsNode.md | 41 - docs/globals.md | 155 ---- docs/model.md | 206 ----- docs/storage.md | 360 -------- docs/storageBrowser.md | 256 ------ docs/storageReactNative.md | 255 ------ docs/utils.md | 64 -- jsdoc2md.js | 67 -- lib/cursor.js | 3 + lib/datastore.js | 16 +- package.json | 2 +- 23 files changed, 1091 insertions(+), 2727 deletions(-) create mode 100644 API.md delete mode 100644 docs/Cursor.md delete mode 100644 docs/Datastore.md delete mode 100644 docs/Executor.md delete mode 100644 docs/Index.md delete mode 100644 docs/Persistence.md delete mode 100644 docs/Waterfall.md delete mode 100644 docs/byline.md delete mode 100644 docs/customUtilsBrowser.md delete mode 100644 docs/customUtilsNode.md delete mode 100644 docs/globals.md delete mode 100644 docs/model.md delete mode 100644 docs/storage.md delete mode 100644 docs/storageBrowser.md delete mode 100644 docs/storageReactNative.md delete mode 100644 docs/utils.md delete mode 100644 jsdoc2md.js diff --git a/API.md b/API.md new file mode 100644 index 0000000..49bdc55 --- /dev/null +++ b/API.md @@ -0,0 +1,1054 @@ +## Classes + +
+
CursorPromise
+

Manage access to data, be it to find, update or remove it.

+

It extends Promise so that its methods (which return this) are chainable & awaitable.

+
DatastoreEventEmitter
+

The Datastore class is the main class of NeDB.

+
Persistence
+

Under the hood, NeDB's persistence uses an append-only format, meaning that all +updates and deletes actually result in lines added at the end of the datafile, +for performance reasons. The database is automatically compacted (i.e. put back +in the one-line-per-document format) every time you load each database within +your application.

+

You can manually call the compaction function +with yourDatabase.persistence.compactDatafile which takes no argument. It +queues a compaction of the datafile in the executor, to be executed sequentially +after all pending operations. The datastore will fire a compaction.done event +once compaction is finished.

+

You can also set automatic compaction at regular intervals +with yourDatabase.persistence.setAutocompactionInterval(interval), interval +in milliseconds (a minimum of 5s is enforced), and stop automatic compaction +with yourDatabase.persistence.stopAutocompaction().

+

Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k +records on a typical development machine) and no other operation can happen when +it does, so most projects actually don't need to use it.

+

Compaction will also immediately remove any documents whose data line has become +corrupted, assuming that the total percentage of all corrupted documents in that +database still falls below the specified corruptAlertThreshold option's value.

+

Durability works similarly to major databases: compaction forces the OS to +physically flush data to disk, while appends to the data file do not (the OS is +responsible for flushing the data). That guarantees that a server crash can +never cause complete data loss, while preserving performance. The worst that can +happen is a crash between two syncs, causing a loss of all data between the two +syncs. Usually syncs are 30 seconds appart so that's at most 30 seconds of +data. This post by Antirez on Redis persistence +explains this in more details, NeDB being very close to Redis AOF persistence +with appendfsync option set to no.

+
+ +## Typedefs + +
+
NoParamCallback : function
+

Callback with no parameter

+
compareStringsnumber
+

String comparison function.

+
  if (a < b) return -1
+  if (a > b) return 1
+  return 0
+
+
MultipleDocumentsCallback : function
+

Callback that returns an Array of documents

+
SingleDocumentCallback : function
+

Callback that returns a single document

+
AsyncFunctionPromise.<*>
+

Generic async function

+
GenericCallback : function
+

Callback with generic parameters

+
document : Object.<string, *>
+

Generic document in NeDB. +It consists of an Object with anything you want inside.

+
query : Object.<string, *>
+

Nedb query.

+

Each key of a query references a field name, which can use the dot-notation to reference subfields inside nested +documents, arrays, arrays of subdocuments and to match a specific element of an array.

+

Each value of a query can be one of the following:

+
    +
  • string: matches all documents which have this string as value for the referenced field name
  • +
  • number: matches all documents which have this number as value for the referenced field name
  • +
  • Regexp: matches all documents which have a value that matches the given Regexp for the referenced field name
  • +
  • object: matches all documents which have this object as deep-value for the referenced field name
  • +
  • Comparison operators: the syntax is { field: { $op: value } } where $op is any comparison operator: +
      +
    • $lt, $lte: less than, less than or equal
    • +
    • $gt, $gte: greater than, greater than or equal
    • +
    • $in: member of. value must be an array of values
    • +
    • $ne, $nin: not equal, not a member of
    • +
    • $stat: checks whether the document posses the property field. value should be true or false
    • +
    • $regex: checks whether a string is matched by the regular expression. Contrary to MongoDB, the use of +$options with $regex is not supported, because it doesn't give you more power than regex flags. Basic +queries are more readable so only use the $regex operator when you need to use another operator with it
    • +
    • $size: if the referenced filed is an Array, matches on the size of the array
    • +
    • $elemMatch: matches if at least one array element matches the sub-query entirely
    • +
    +
  • +
  • Logical operators: You can combine queries using logical operators: +
      +
    • For $or and $and, the syntax is { $op: [query1, query2, ...] }.
    • +
    • For $not, the syntax is { $not: query }
    • +
    • For $where, the syntax is:
    • +
    +
    { $where: function () {
    +  // object is 'this'
    +  // return a boolean
    +} }
    +
    +
  • +
+
projection : Object.<string, (0|1)>
+

Nedb projection.

+

You can give find and findOne an optional second argument, projections. +The syntax is the same as MongoDB: { a: 1, b: 1 } to return only the a +and b fields, { a: 0, b: 0 } to omit these two fields. You cannot use both +modes at the time, except for _id which is by default always returned and +which you can choose to omit. You can project on nested documents.

+

To reference subfields, you can use the dot-notation.

+
serializationHookstring
+

The beforeDeserialization and afterDeserialization callbacks are hooks which are executed respectively before +parsing each document and after stringifying them. They can be used for example to encrypt the Datastore. +The beforeDeserialization should revert what afterDeserialization has done.

+
rawIndex
+
+
+ + + +## Cursor ⇐ Promise +

Manage access to data, be it to find, update or remove it.

+

It extends Promise so that its methods (which return this) are chainable & awaitable.

+ +**Kind**: global class +**Extends**: Promise + +* [Cursor](#Cursor) ⇐ Promise + * [new Cursor(db, query, [mapFn])](#new_Cursor_new) + * _instance_ + * [.db](#Cursor+db) : [Datastore](#Datastore) + * [.query](#Cursor+query) : [query](#query) + * [.limit(limit)](#Cursor+limit) ⇒ [Cursor](#Cursor) + * [.skip(skip)](#Cursor+skip) ⇒ [Cursor](#Cursor) + * [.sort(sortQuery)](#Cursor+sort) ⇒ [Cursor](#Cursor) + * [.projection(projection)](#Cursor+projection) ⇒ [Cursor](#Cursor) + * [.exec(_callback)](#Cursor+exec) + * [.execAsync()](#Cursor+execAsync) ⇒ Promise.<(Array.<document>\|\*)> + * _inner_ + * [~mapFn](#Cursor..mapFn) ⇒ \* \| Promise.<\*> + * [~execCallback](#Cursor..execCallback) : function + + + +### new Cursor(db, query, [mapFn]) +

Create a new cursor for this collection

+ +**Params** + +- db [Datastore](#Datastore) -

The datastore this cursor is bound to

+- query [query](#query) -

The query this cursor will operate on

+- [mapFn] [mapFn](#Cursor..mapFn) -

Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove

+ + + +### cursor.db : [Datastore](#Datastore) +**Kind**: instance property of [Cursor](#Cursor) +**Access**: protected + + +### cursor.query : [query](#query) +**Kind**: instance property of [Cursor](#Cursor) +**Access**: protected + + +### cursor.limit(limit) ⇒ [Cursor](#Cursor) +

Set a limit to the number of results

+ +**Kind**: instance method of [Cursor](#Cursor) +**Params** + +- limit Number + + + +### cursor.skip(skip) ⇒ [Cursor](#Cursor) +

Skip a number of results

+ +**Kind**: instance method of [Cursor](#Cursor) +**Params** + +- skip Number + + + +### cursor.sort(sortQuery) ⇒ [Cursor](#Cursor) +

Sort results of the query

+ +**Kind**: instance method of [Cursor](#Cursor) +**Params** + +- sortQuery Object.<string, number> -

sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending

+ + + +### cursor.projection(projection) ⇒ [Cursor](#Cursor) +

Add the use of a projection

+ +**Kind**: instance method of [Cursor](#Cursor) +**Params** + +- projection Object.<string, number> -

MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 +{ key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits.

+ + + +### cursor.exec(_callback) +

Get all matching elements +Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

+ +**Kind**: instance method of [Cursor](#Cursor) +**Params** + +- _callback [execCallback](#Cursor..execCallback) + + + +### cursor.execAsync() ⇒ Promise.<(Array.<document>\|\*)> +

Async version of [exec](#Cursor+exec).

+ +**Kind**: instance method of [Cursor](#Cursor) +**See**: Cursor#exec + + +### Cursor~mapFn ⇒ \* \| Promise.<\*> +

Has a callback

+ +**Kind**: inner typedef of [Cursor](#Cursor) +**Params** + +- res [Array.<document>](#document) + + + +### Cursor~execCallback : function +**Kind**: inner typedef of [Cursor](#Cursor) +**Params** + +- err Error +- res [Array.<document>](#document) | \* -

If an mapFn was given to the Cursor, then the type of this parameter is the one returned by the mapFn.

+ + + +## Datastore ⇐ [EventEmitter](http://nodejs.org/api/events.html) +

The Datastore class is the main class of NeDB.

+ +**Kind**: global class +**Extends**: [EventEmitter](http://nodejs.org/api/events.html) +**Emits**: Datastore#event:"compaction.done" + +* [Datastore](#Datastore) ⇐ [EventEmitter](http://nodejs.org/api/events.html) + * [new Datastore(options)](#new_Datastore_new) + * _instance_ + * [.inMemoryOnly](#Datastore+inMemoryOnly) : boolean + * [.autoload](#Datastore+autoload) : boolean + * [.timestampData](#Datastore+timestampData) : boolean + * [.filename](#Datastore+filename) : string + * [.persistence](#Datastore+persistence) : [Persistence](#Persistence) + * [.executor](#Datastore+executor) : [Executor](#new_Executor_new) + * [.indexes](#Datastore+indexes) : Object.<string, Index> + * [.ttlIndexes](#Datastore+ttlIndexes) : Object.<string, number> + * [.autoloadPromise](#Datastore+autoloadPromise) : Promise + * [.compareStrings()](#Datastore+compareStrings) : [compareStrings](#compareStrings) + * [.loadDatabase(callback)](#Datastore+loadDatabase) + * [.loadDatabaseAsync()](#Datastore+loadDatabaseAsync) ⇒ Promise + * [.getAllData()](#Datastore+getAllData) ⇒ [Array.<document>](#document) + * [.ensureIndex(options, callback)](#Datastore+ensureIndex) + * [.ensureIndexAsync(options)](#Datastore+ensureIndexAsync) ⇒ Promise.<void> + * [.removeIndex(fieldName, callback)](#Datastore+removeIndex) + * [.removeIndexAsync(fieldName)](#Datastore+removeIndexAsync) ⇒ Promise.<void> + * [.insertAsync(newDoc)](#Datastore+insertAsync) ⇒ [Promise.<document>](#document) + * [.count(query, [callback])](#Datastore+count) ⇒ Cursor.<number> \| undefined + * [.countAsync(query)](#Datastore+countAsync) ⇒ Cursor.<number> + * [.find(query, [projection], [callback])](#Datastore+find) ⇒ Cursor.<Array.<document>> \| undefined + * [.findAsync(query, [projection])](#Datastore+findAsync) ⇒ Cursor.<Array.<document>> + * [.findOne(query, [projection], [callback])](#Datastore+findOne) ⇒ [Cursor.<document>](#document) \| undefined + * [.findOneAsync(query, projection)](#Datastore+findOneAsync) ⇒ [Cursor.<document>](#document) + * [.update(query, update, [options|], [cb])](#Datastore+update) + * [.updateAsync(query, update, [options])](#Datastore+updateAsync) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> + * [.remove(query, [options], [cb])](#Datastore+remove) + * [.removeAsync(query, [options])](#Datastore+removeAsync) ⇒ Promise.<number> + * ["event:compaction.done"](#Datastore+event_compaction.done) + * _inner_ + * [~countCallback](#Datastore..countCallback) : function + * [~findOneCallback](#Datastore..findOneCallback) : function + * [~updateCallback](#Datastore..updateCallback) : function + * [~removeCallback](#Datastore..removeCallback) : function + + + +### new Datastore(options) +

Create a new collection, either persistent or in-memory.

+

If you use a persistent datastore without the autoload option, you need to call [loadDatabase](#Datastore+loadDatabase) or +[loadDatabaseAsync](#Datastore+loadDatabaseAsync) manually. This function fetches the data from datafile and prepares the database. +Don't forget it! If you use a persistent datastore, no command (insert, find, update, remove) will be executed +before it is called, so make sure to call it yourself or use the autoload option.

+

Also, if loading fails, all commands registered to the [executor](#Datastore+executor) afterwards will not be executed. +They will be registered and executed, in sequence, only after a successful loading.

+ +**Params** + +- options object | string -

Can be an object or a string. If options is a string, the behavior is the same as in +v0.6: it will be interpreted as options.filename. Giving a string is deprecated, and will be removed in the +next major version.

+ - [.filename] string = null -

Path to the file where the data is persisted. If left blank, the datastore is +automatically considered in-memory only. It cannot end with a ~ which is used in the temporary files NeDB uses to +perform crash-safe writes. Not used if options.inMemoryOnly is true.

+ - [.inMemoryOnly] boolean = false -

If set to true, no data will be written in storage. This option has +priority over options.filename.

+ - [.timestampData] boolean = false -

If set to true, createdAt and updatedAt will be created and +populated automatically (if not specified by user)

+ - [.autoload] boolean = false -

If used, the database will automatically be loaded from the datafile +upon creation (you don't need to call loadDatabase). Any command issued before load is finished is buffered and +will be executed when load is done. When autoloading is done, you can either use the onload callback, or you can +use this.autoloadPromise which resolves (or rejects) when autloading is done.

+ - [.onload] [NoParamCallback](#NoParamCallback) -

If you use autoloading, this is the handler called after the loadDatabase. It +takes one error argument. If you use autoloading without specifying this handler, and an error happens during +load, an error will be thrown.

+ - [.beforeDeserialization] [serializationHook](#serializationHook) -

Hook you can use to transform data after it was serialized and +before it is written to disk. Can be used for example to encrypt data before writing database to disk. This +function takes a string as parameter (one line of an NeDB data file) and outputs the transformed string, which +must absolutely not contain a \n character (or data will be lost).

+ - [.afterSerialization] [serializationHook](#serializationHook) -

Inverse of afterSerialization. Make sure to include both and not +just one, or you risk data loss. For the same reason, make sure both functions are inverses of one another. Some +failsafe mechanisms are in place to prevent data loss if you misuse the serialization hooks: NeDB checks that never +one is declared without the other, and checks that they are reverse of one another by testing on random strings of +various lengths. In addition, if too much data is detected as corrupt, NeDB will refuse to start as it could mean +you're not using the deserialization hook corresponding to the serialization hook used before.

+ - [.corruptAlertThreshold] number = 0.1 -

Between 0 and 1, defaults to 10%. NeDB will refuse to start +if more than this percentage of the datafile is corrupt. 0 means you don't tolerate any corruption, 1 means you +don't care.

+ - [.compareStrings] [compareStrings](#compareStrings) -

If specified, it overrides default string comparison which is not +well adapted to non-US characters in particular accented letters. Native localCompare will most of the time be +the right choice.

+ + + +### neDB.inMemoryOnly : boolean +

Determines if the Datastore keeps data in-memory, or if it saves it in storage. Is not read after +instanciation.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### neDB.autoload : boolean +

Determines if the Datastore should autoload the database upon instantiation. Is not read after instanciation.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### neDB.timestampData : boolean +

Determines if the Datastore should add createdAt and updatedAt fields automatically if not set by the user.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### neDB.filename : string +

If null, it means inMemoryOnly is true. The filename is the name given to the storage module. Is not read +after instanciation.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### neDB.persistence : [Persistence](#Persistence) +

The Persistence instance for this Datastore.

+ +**Kind**: instance property of [Datastore](#Datastore) + + +### neDB.executor : [Executor](#new_Executor_new) +

The Executor instance for this Datastore. It is used in all methods exposed by the Datastore, any Cursor +produced by the Datastore and by this.persistence.compactDataFile & this.persistence.compactDataFileAsync +to ensure operations are performed sequentially in the database.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### neDB.indexes : Object.<string, Index> +

Indexed by field name, dot notation can be used. +_id is always indexed and since _ids are generated randomly the underlying binary search tree is always well-balanced

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### neDB.ttlIndexes : Object.<string, number> +

Stores the time to live (TTL) of the indexes created. The key represents the field name, the value the number of +seconds after which data with this index field should be removed.

+ +**Kind**: instance property of [Datastore](#Datastore) +**Access**: protected + + +### neDB.autoloadPromise : Promise +

A Promise that resolves when the autoload has finished.

+

The onload callback is not awaited by this Promise, it is started immediately after that.

+ +**Kind**: instance property of [Datastore](#Datastore) + + +### neDB.compareStrings() : [compareStrings](#compareStrings) +

Overrides default string comparison which is not well adapted to non-US characters in particular accented +letters. Native localCompare will most of the time be the right choice

+ +**Kind**: instance method of [Datastore](#Datastore) +**Access**: protected + + +### neDB.loadDatabase(callback) +

Load the database from the datafile, and trigger the execution of buffered commands if any.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- callback [NoParamCallback](#NoParamCallback) + + + +### neDB.loadDatabaseAsync() ⇒ Promise +

Async version of [loadDatabase](#Datastore+loadDatabase).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#loadDatabase + + +### neDB.getAllData() ⇒ [Array.<document>](#document) +

Get an array of all the data in the database.

+ +**Kind**: instance method of [Datastore](#Datastore) + + +### neDB.ensureIndex(options, callback) +

Ensure an index is kept for this field. Same parameters as lib/indexes +This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the +executor. +Previous versions said explicitly the callback was optional, it is now recommended setting one.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- options object + - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

+ - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

+ - [.sparse] boolean = false -

don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

+ - [.expireAfterSeconds] number -

if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

+- callback [NoParamCallback](#NoParamCallback) -

Callback, signature: err

+ + + +### neDB.ensureIndexAsync(options) ⇒ Promise.<void> +

Async version of [ensureIndex](#Datastore+ensureIndex).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#ensureIndex +**Params** + +- options object + - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

+ - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

+ - [.sparse] boolean = false -

Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

+ - [.expireAfterSeconds] number -

If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

+ + + +### neDB.removeIndex(fieldName, callback) +

Remove an index +Previous versions said explicitly the callback was optional, it is now recommended setting one.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a +field in a nested document.

+- callback [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

+ + + +### neDB.removeIndexAsync(fieldName) ⇒ Promise.<void> +

Async version of [removeIndex](#Datastore+removeIndex).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#removeIndex +**Params** + +- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a +field in a nested document.

+ + + +### neDB.insertAsync(newDoc) ⇒ [Promise.<document>](#document) +

Async version of [Datastore#insert](Datastore#insert).

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- newDoc [document](#document) | [Array.<document>](#document) + + + +### neDB.count(query, [callback]) ⇒ Cursor.<number> \| undefined +

Count all documents matching the query.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- query [query](#query) -

MongoDB-style query

+- [callback] [countCallback](#Datastore..countCallback) -

If given, the function will return undefined, otherwise it will return the Cursor.

+ + + +### neDB.countAsync(query) ⇒ Cursor.<number> +

Async version of [count](#Datastore+count).

+ +**Kind**: instance method of [Datastore](#Datastore) +**Returns**: Cursor.<number> -

count

+**Params** + +- query [query](#query) -

MongoDB-style query

+ + + +### neDB.find(query, [projection], [callback]) ⇒ Cursor.<Array.<document>> \| undefined +

Find all documents matching the query +If no callback is passed, we return the cursor so that user can limit, skip and finally exec

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- query [query](#query) -

MongoDB-style query

+- [projection] [projection](#projection) | [MultipleDocumentsCallback](#MultipleDocumentsCallback) = {} -

MongoDB-style projection. If not given, will be +interpreted as the callback.

+- [callback] [MultipleDocumentsCallback](#MultipleDocumentsCallback) -

Optional callback, signature: err, docs

+ + + +### neDB.findAsync(query, [projection]) ⇒ Cursor.<Array.<document>> +

Async version of [find](#Datastore+find).

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- query [query](#query) -

MongoDB-style query

+- [projection] [projection](#projection) = {} -

MongoDB-style projection

+ + + +### neDB.findOne(query, [projection], [callback]) ⇒ [Cursor.<document>](#document) \| undefined +

Find one document matching the query.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- query [query](#query) -

MongoDB-style query

+- [projection] [projection](#projection) | [SingleDocumentCallback](#SingleDocumentCallback) = {} -

MongoDB-style projection

+- [callback] [SingleDocumentCallback](#SingleDocumentCallback) -

Optional callback, signature: err, doc

+ + + +### neDB.findOneAsync(query, projection) ⇒ [Cursor.<document>](#document) +

Async version of [findOne](#Datastore+findOne).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#findOne +**Params** + +- query [query](#query) -

MongoDB-style query

+- projection [projection](#projection) -

MongoDB-style projection

+ + + +### neDB.update(query, update, [options|], [cb]) +

Update all docs matching query.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- query [query](#query) -

is the same kind of finding query you use with find and findOne

+- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a +set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the +matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can +apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, +$inc to increment a field's value and $min/$max to change field's value, only if provided value is +less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special +$each and $slice.

+- [options|] Object | [updateCallback](#Datastore..updateCallback) -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

+ - [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if +your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted +document. In the other case, the query is stripped from all operator recursively, and the update is applied to +it.

+ - [.returnUpdatedDocs] boolean = false -

(not Mongo-DB compatible) If true and update is not an upsert, +will return the array of documents matched by the find query and updated. Updated documents will be returned even +if the update did not actually modify them.

+- [cb] [updateCallback](#Datastore..updateCallback) = () => {} -

Optional callback

+ + + +### neDB.updateAsync(query, update, [options]) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> +

Async version of [update](#Datastore+update).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#update +**Params** + +- query [query](#query) -

is the same kind of finding query you use with find and findOne

+- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a +set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the +matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can +apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, +$inc to increment a field's value and $min/$max to change field's value, only if provided value is +less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special +$each and $slice.

+- [options] Object = {} -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

+ - [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if +your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted +document. In the other case, the query is stripped from all operator recursively, and the update is applied to +it.

+ - [.returnUpdatedDocs] boolean = false -

(not Mongo-DB compatible) If true and update is not an upsert, +will return the array of documents matched by the find query and updated. Updated documents will be returned even +if the update did not actually modify them.

+ + + +### neDB.remove(query, [options], [cb]) +

Remove all docs matching the query.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- query [query](#query) +- [options] object | [removeCallback](#Datastore..removeCallback) = {} -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

+- [cb] [removeCallback](#Datastore..removeCallback) = () => {} -

Optional callback

+ + + +### neDB.removeAsync(query, [options]) ⇒ Promise.<number> +

Remove all docs matching the query. +Use Datastore.removeAsync which has the same signature

+ +**Kind**: instance method of [Datastore](#Datastore) +**Returns**: Promise.<number> -

How many documents were removed

+**Params** + +- query [query](#query) +- [options] object = {} -

Optional options

+ - [.multi] boolean = false -

If true, can update multiple documents

+ + + +### "event:compaction.done" +

Compaction event. Happens when the Datastore's Persistence has been compacted. +It happens when calling datastore.persistence.compactDatafile, which is called periodically if you have called +datastore.persistence.setAutocompactionInterval.

+ +**Kind**: event emitted by [Datastore](#Datastore) + + +### Datastore~countCallback : function +**Kind**: inner typedef of [Datastore](#Datastore) +**Params** + +- err Error +- count number + + + +### Datastore~findOneCallback : function +**Kind**: inner typedef of [Datastore](#Datastore) +**Params** + +- err Error +- doc [document](#document) + + + +### Datastore~updateCallback : function +

If update was an upsert, upsert flag is set to true, affectedDocuments can be one of the following:

+
    +
  • For an upsert, the upserted document
  • +
  • For an update with returnUpdatedDocs option false, null
  • +
  • For an update with returnUpdatedDocs true and multi false, the updated document
  • +
  • For an update with returnUpdatedDocs true and multi true, the array of updated documents
  • +
+

WARNING: The API was changed between v1.7.4 and v1.8, for consistency and readability reasons. Prior and +including to v1.7.4, the callback signature was (err, numAffected, updated) where updated was the updated document +in case of an upsert or the array of updated documents for an update if the returnUpdatedDocs option was true. That +meant that the type of affectedDocuments in a non multi update depended on whether there was an upsert or not, +leaving only two ways for the user to check whether an upsert had occured: checking the type of affectedDocuments +or running another find query on the whole dataset to check its size. Both options being ugly, the breaking change +was necessary.

+ +**Kind**: inner typedef of [Datastore](#Datastore) +**Params** + +- err Error +- numAffected number +- affectedDocuments [?Array.<document>](#document) | [document](#document) +- upsert boolean + + + +### Datastore~removeCallback : function +**Kind**: inner typedef of [Datastore](#Datastore) +**Params** + +- err Error +- numRemoved number + + + +## Persistence +

Under the hood, NeDB's persistence uses an append-only format, meaning that all +updates and deletes actually result in lines added at the end of the datafile, +for performance reasons. The database is automatically compacted (i.e. put back +in the one-line-per-document format) every time you load each database within +your application.

+

You can manually call the compaction function +with yourDatabase.persistence.compactDatafile which takes no argument. It +queues a compaction of the datafile in the executor, to be executed sequentially +after all pending operations. The datastore will fire a compaction.done event +once compaction is finished.

+

You can also set automatic compaction at regular intervals +with yourDatabase.persistence.setAutocompactionInterval(interval), interval +in milliseconds (a minimum of 5s is enforced), and stop automatic compaction +with yourDatabase.persistence.stopAutocompaction().

+

Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k +records on a typical development machine) and no other operation can happen when +it does, so most projects actually don't need to use it.

+

Compaction will also immediately remove any documents whose data line has become +corrupted, assuming that the total percentage of all corrupted documents in that +database still falls below the specified corruptAlertThreshold option's value.

+

Durability works similarly to major databases: compaction forces the OS to +physically flush data to disk, while appends to the data file do not (the OS is +responsible for flushing the data). That guarantees that a server crash can +never cause complete data loss, while preserving performance. The worst that can +happen is a crash between two syncs, causing a loss of all data between the two +syncs. Usually syncs are 30 seconds appart so that's at most 30 seconds of +data. This post by Antirez on Redis persistence +explains this in more details, NeDB being very close to Redis AOF persistence +with appendfsync option set to no.

+ +**Kind**: global class + +* [Persistence](#Persistence) + * [new Persistence()](#new_Persistence_new) + * _instance_ + * [.persistCachedDatabaseAsync()](#Persistence+persistCachedDatabaseAsync) ⇒ Promise.<void> + * [.compactDatafile([callback])](#Persistence+compactDatafile) + * [.compactDatafileAsync()](#Persistence+compactDatafileAsync) + * [.setAutocompactionInterval(interval)](#Persistence+setAutocompactionInterval) + * [.stopAutocompaction()](#Persistence+stopAutocompaction) + * [.persistNewStateAsync(newDocs)](#Persistence+persistNewStateAsync) ⇒ Promise + * [.treatRawData(rawData)](#Persistence+treatRawData) ⇒ Object + * [.treatRawStreamAsync(rawStream)](#Persistence+treatRawStreamAsync) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> + * [.loadDatabase(callback)](#Persistence+loadDatabase) + * [.loadDatabaseAsync()](#Persistence+loadDatabaseAsync) ⇒ Promise.<void> + * _static_ + * [.ensureDirectoryExistsAsync(dir)](#Persistence.ensureDirectoryExistsAsync) ⇒ Promise.<void> + + + +### new Persistence() +

Create a new Persistence object for database options.db

+ +**Params** + + - .db [Datastore](#Datastore) + - [.corruptAlertThreshold] Number -

Optional, threshold after which an alert is thrown if too much data is corrupt

+ - [.beforeDeserialization] [serializationHook](#serializationHook) -

Hook you can use to transform data after it was serialized and before it is written to disk.

+ - [.afterSerialization] [serializationHook](#serializationHook) -

Inverse of afterSerialization.

+ + + +### persistence.persistCachedDatabaseAsync() ⇒ Promise.<void> +

Persist cached database +This serves as a compaction function since the cache always contains only the number of documents in the collection +while the data file is append-only so it may grow larger

+

This is an internal function, use [compactDatafileAsync](#Persistence+compactDatafileAsync) which uses the [executor](#Datastore+executor).

+ +**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected + + +### persistence.compactDatafile([callback]) +

Queue a rewrite of the datafile

+ +**Kind**: instance method of [Persistence](#Persistence) +**See**: Persistence#persistCachedDatabaseAsync +**Params** + +- [callback] [NoParamCallback](#NoParamCallback) = () => {} + + + +### persistence.compactDatafileAsync() +

Async version of [compactDatafile](#Persistence+compactDatafile).

+ +**Kind**: instance method of [Persistence](#Persistence) +**See**: Persistence#compactDatafile + + +### persistence.setAutocompactionInterval(interval) +

Set automatic compaction every interval ms

+ +**Kind**: instance method of [Persistence](#Persistence) +**Params** + +- interval Number -

in milliseconds, with an enforced minimum of 5000 milliseconds

+ + + +### persistence.stopAutocompaction() +

Stop autocompaction (do nothing if automatic compaction was not running)

+ +**Kind**: instance method of [Persistence](#Persistence) + + +### persistence.persistNewStateAsync(newDocs) ⇒ Promise +

Persist new state for the given newDocs (can be insertion, update or removal) +Use an append-only format

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

+ +**Kind**: instance method of [Persistence](#Persistence) +**Params** + +- newDocs [Array.<document>](#document) -

Can be empty if no doc was updated/removed

+ + + +### persistence.treatRawData(rawData) ⇒ Object +

From a database's raw data, return the corresponding machine understandable collection.

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

+ +**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** + +- rawData string -

database file

+ + + +### persistence.treatRawStreamAsync(rawStream) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> +

From a database's raw data stream, return the corresponding machine understandable collection +Is only used by a [Datastore](#Datastore) instance.

+

Is only used in the Node.js version, since [React-Native](module:storageReactNative) & +[browser](module:storageBrowser) storage modules don't provide an equivalent of +[readFileStream](#module_storage.readFileStream).

+

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

+ +**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** + +- rawStream Readable + + + +### persistence.loadDatabase(callback) +

Load the database

+
    +
  1. Create all indexes
  2. +
  3. Insert all data
  4. +
  5. Compact the database
  6. +
+

This means pulling data out of the data file or creating it if it doesn't exist +Also, all data is persisted right away, which has the effect of compacting the database file +This operation is very quick at startup for a big collection (60ms for ~10k docs)

+

Do not use directly as it does not use the [Executor](Datastore.executor), use [loadDatabase](#Datastore+loadDatabase) instead.

+ +**Kind**: instance method of [Persistence](#Persistence) +**Access**: protected +**Params** + +- callback [NoParamCallback](#NoParamCallback) + + + +### persistence.loadDatabaseAsync() ⇒ Promise.<void> +

Async version of [loadDatabase](#Persistence+loadDatabase)

+ +**Kind**: instance method of [Persistence](#Persistence) +**See**: Persistence#loadDatabase + + +### Persistence.ensureDirectoryExistsAsync(dir) ⇒ Promise.<void> +

Check if a directory stat and create it on the fly if it is not the case.

+ +**Kind**: static method of [Persistence](#Persistence) +**Params** + +- dir string + + + +## NoParamCallback : function +

Callback with no parameter

+ +**Kind**: global typedef +**Params** + +- err Error + + + +## compareStrings ⇒ number +

String comparison function.

+
  if (a < b) return -1
+  if (a > b) return 1
+  return 0
+
+ +**Kind**: global typedef +**Params** + +- a string +- b string + + + +## MultipleDocumentsCallback : function +

Callback that returns an Array of documents

+ +**Kind**: global typedef +**Params** + +- err Error +- docs [Array.<document>](#document) + + + +## SingleDocumentCallback : function +

Callback that returns a single document

+ +**Kind**: global typedef +**Params** + +- err Error +- docs [document](#document) + + + +## AsyncFunction ⇒ Promise.<\*> +

Generic async function

+ +**Kind**: global typedef +**Params** + +- ...args \* + + + +## GenericCallback : function +

Callback with generic parameters

+ +**Kind**: global typedef +**Params** + +- err Error +- ...args \* + + + +## document : Object.<string, \*> +

Generic document in NeDB. +It consists of an Object with anything you want inside.

+ +**Kind**: global typedef +**Properties** + +| Name | Type | Description | +| --- | --- | --- | +| [_id] | string |

Internal _id of the document, which can be null or undefined at some points (when not inserted yet for example).

| + + + +## query : Object.<string, \*> +

Nedb query.

+

Each key of a query references a field name, which can use the dot-notation to reference subfields inside nested +documents, arrays, arrays of subdocuments and to match a specific element of an array.

+

Each value of a query can be one of the following:

+
    +
  • string: matches all documents which have this string as value for the referenced field name
  • +
  • number: matches all documents which have this number as value for the referenced field name
  • +
  • Regexp: matches all documents which have a value that matches the given Regexp for the referenced field name
  • +
  • object: matches all documents which have this object as deep-value for the referenced field name
  • +
  • Comparison operators: the syntax is { field: { $op: value } } where $op is any comparison operator: +
      +
    • $lt, $lte: less than, less than or equal
    • +
    • $gt, $gte: greater than, greater than or equal
    • +
    • $in: member of. value must be an array of values
    • +
    • $ne, $nin: not equal, not a member of
    • +
    • $stat: checks whether the document posses the property field. value should be true or false
    • +
    • $regex: checks whether a string is matched by the regular expression. Contrary to MongoDB, the use of +$options with $regex is not supported, because it doesn't give you more power than regex flags. Basic +queries are more readable so only use the $regex operator when you need to use another operator with it
    • +
    • $size: if the referenced filed is an Array, matches on the size of the array
    • +
    • $elemMatch: matches if at least one array element matches the sub-query entirely
    • +
    +
  • +
  • Logical operators: You can combine queries using logical operators: +
      +
    • For $or and $and, the syntax is { $op: [query1, query2, ...] }.
    • +
    • For $not, the syntax is { $not: query }
    • +
    • For $where, the syntax is:
    • +
    +
    { $where: function () {
    +  // object is 'this'
    +  // return a boolean
    +} }
    +
    +
  • +
+ +**Kind**: global typedef + + +## projection : Object.<string, (0\|1)> +

Nedb projection.

+

You can give find and findOne an optional second argument, projections. +The syntax is the same as MongoDB: { a: 1, b: 1 } to return only the a +and b fields, { a: 0, b: 0 } to omit these two fields. You cannot use both +modes at the time, except for _id which is by default always returned and +which you can choose to omit. You can project on nested documents.

+

To reference subfields, you can use the dot-notation.

+ +**Kind**: global typedef + + +## serializationHook ⇒ string +

The beforeDeserialization and afterDeserialization callbacks are hooks which are executed respectively before +parsing each document and after stringifying them. They can be used for example to encrypt the Datastore. +The beforeDeserialization should revert what afterDeserialization has done.

+ +**Kind**: global typedef +**Params** + +- x string + + + +## rawIndex +**Kind**: global typedef +**Properties** + +| Name | Type | +| --- | --- | +| fieldName | string | +| [unique] | boolean | +| [sparse] | boolean | + diff --git a/README.md b/README.md index dbd6331..0465e8a 100755 --- a/README.md +++ b/README.md @@ -55,11 +55,11 @@ documentation is available in the [`docs`](./docs) directory of the repository. You can use NeDB as an in-memory only datastore or as a persistent datastore. One datastore is the equivalent of a MongoDB collection. The constructor is used -as follows [`new Datastore(options)` where `options` is an object](./docs/Datastore.md#new_Datastore_new). +as follows [`new Datastore(options)` where `options` is an object](./API.md#new_Datastore_new). -If the Datastore is persistent (if you give it [`options.filename`](./docs/Datastore.md#Datastore+filename), -you'll need to load the database using [Datastore#loadDatabaseAsync](./docs/Datastore.md#Datastore+loadDatabaseAsync), -or using [`options.autoload`](./docs/Datastore.md#Datastore+autoload). +If the Datastore is persistent (if you give it [`options.filename`](./API.md#Datastore+filename), +you'll need to load the database using [Datastore#loadDatabaseAsync](./API.md#Datastore+loadDatabaseAsync), +or using [`options.autoload`](./API.md#Datastore+autoload). ```javascript // Type 1: In-memory only datastore (no need to load the database) @@ -101,11 +101,11 @@ compacted (i.e. put back in the one-line-per-document format) every time you load each database within your application. You can manually call the compaction function -with [`yourDatabase#persistence#compactDatafileAsync`](./docs/Persistence.md#Persistence+compactDatafileAsync). +with [`yourDatabase#persistence#compactDatafileAsync`](./API.md#Persistence+compactDatafileAsync). You can also set automatic compaction at regular intervals -with [`yourDatabase#persistence#setAutocompactionInterval`](./docs/Persistence.md#Persistence+setAutocompactionInterval), -and stop automatic compaction with [`yourDatabase#persistence#stopAutocompaction`](./docs/Persistence.md#Persistence+stopAutocompaction). +with [`yourDatabase#persistence#setAutocompactionInterval`](./API.md#Persistence+setAutocompactionInterval), +and stop automatic compaction with [`yourDatabase#persistence#stopAutocompaction`](./API.md#Persistence+stopAutocompaction). ### Inserting documents @@ -387,17 +387,17 @@ const docs = await db.findAsync({ #### Sorting and paginating -[`Datastore#findAsync`](./docs/Datastore.md#Datastore+findAsync), -[`Datastore#findOneAsync`](./docs/Datastore.md#Datastore+findOneAsync) and -[`Datastore#countAsync`](./docs/Datastore.md#Datastore+countAsync) don't +[`Datastore#findAsync`](./API.md#Datastore+findAsync), +[`Datastore#findOneAsync`](./API.md#Datastore+findOneAsync) and +[`Datastore#countAsync`](./API.md#Datastore+countAsync) don't actually return a `Promise`, but a [`Cursor`](./docs/Cursor.md) which is a [`Thenable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#thenable_objects) -which calls [`Cursor#execAsync`](./docs/Cursor.md#Cursor+execAsync) when awaited. +which calls [`Cursor#execAsync`](./API.md#Cursor+execAsync) when awaited. -This pattern allows to chain [`Cursor#sort`](./docs/Cursor.md#Cursor+sort), -[`Cursor#skip`](./docs/Cursor.md#Cursor+skip), -[`Cursor#limit`](./docs/Cursor.md#Cursor+limit) and -[`Cursor#projection`](./docs/Cursor.md#Cursor+projection) and await the result. +This pattern allows to chain [`Cursor#sort`](./API.md#Cursor+sort), +[`Cursor#skip`](./API.md#Cursor+skip), +[`Cursor#limit`](./API.md#Cursor+limit) and +[`Cursor#projection`](./API.md#Cursor+projection) and await the result. ```javascript // Let's say the database contains these 4 documents @@ -486,14 +486,14 @@ const count = await db.countAsync({}) ### Updating documents -[`db.updateAsync(query, update, options)`](./docs/Datastore.md#Datastore+updateAsync) +[`db.updateAsync(query, update, options)`](./API.md#Datastore+updateAsync) will update all documents matching `query` according to the `update` rules. `update` specifies how the documents should be modified. It is either a new document or a set of modifiers (you cannot use both together): * A new document will replace the matched docs; * Modifiers create the fields they need to modify if they don't exist, - and you can apply them to subdocs (see [the API reference]((./docs/Datastore.md#Datastore+updateAsync))) + and you can apply them to subdocs (see [the API reference]((./API.md#Datastore+updateAsync))) `options` is an object with three possible parameters: * `multi` which allows the modification of several documents if set to true. @@ -637,7 +637,7 @@ await db.updateAsync({ _id: 'id1' }, { $min: { value: 8 } }, {}) ### Removing documents -[`db.removeAsync(query, options)`](./docs/Datastore.md#Datastore#removeAsync) +[`db.removeAsync(query, options)`](./API.md#Datastore#removeAsync) will remove documents matching `query`. Can remove multiple documents if `options.multi` is set. Returns the `Promise`. @@ -672,7 +672,7 @@ fields in nested documents using the dot notation. For now, indexes are only used to speed up basic queries and queries using `$in`, `$lt`, `$lte`, `$gt` and `$gte`. The indexed values cannot be of type array of object. -To create an index, use [`datastore#ensureIndexAsync(options)`](./docs/Datastore.md#Datastore+ensureIndexAsync). +To create an index, use [`datastore#ensureIndexAsync(options)`](./API.md#Datastore+ensureIndexAsync). It resolves when the index is persisted on disk (if the database is persistent) and may throw an Error (usually a unique constraint that was violated). It can be called when you want, even after some data was inserted, though it's best to @@ -690,7 +690,7 @@ call it at application startup. The options are: Note: the `_id` is automatically indexed with a unique constraint. You can remove a previously created index with -[`datastore#removeIndexAsync(fieldName)`](./docs/Datastore.md#Datastore+removeIndexAsync). +[`datastore#removeIndexAsync(fieldName)`](./API.md#Datastore+removeIndexAsync). ```javascript try { diff --git a/browser-version/lib/customUtils.js b/browser-version/lib/customUtils.js index eb40b27..cc05357 100755 --- a/browser-version/lib/customUtils.js +++ b/browser-version/lib/customUtils.js @@ -2,6 +2,7 @@ * Utility functions that need to be reimplemented for each environment. * This is the version for the browser & React-Native * @module customUtilsBrowser + * @private */ /** diff --git a/browser-version/lib/storage.browser.js b/browser-version/lib/storage.browser.js index a69c0b4..1548a07 100755 --- a/browser-version/lib/storage.browser.js +++ b/browser-version/lib/storage.browser.js @@ -117,7 +117,7 @@ const readFileAsync = async (filename, options) => { * @param {string} filename * @return {Promise} * @async - * @alias module:storageBrowser + * @alias module:storageBrowser.unlink */ const unlinkAsync = async filename => { try { diff --git a/docs/Cursor.md b/docs/Cursor.md deleted file mode 100644 index cf07df1..0000000 --- a/docs/Cursor.md +++ /dev/null @@ -1,181 +0,0 @@ - - -## Cursor ⇐ Promise -

Manage access to data, be it to find, update or remove it.

-

It extends Promise so that its methods (which return this) are chainable & awaitable.

- -**Kind**: global class -**Extends**: Promise - -* [Cursor](#Cursor) ⇐ Promise - * [new Cursor(db, query, [execFn], [hasCallback])](#new_Cursor_new) - * _instance_ - * [.db](#Cursor+db) : [Datastore](#Datastore) - * [.query](#Cursor+query) : [query](#query) - * [.hasCallback](#Cursor+hasCallback) : boolean - * [.limit(limit)](#Cursor+limit) ⇒ [Cursor](#Cursor) - * [.skip(skip)](#Cursor+skip) ⇒ [Cursor](#Cursor) - * [.sort(sortQuery)](#Cursor+sort) ⇒ [Cursor](#Cursor) - * [.projection(projection)](#Cursor+projection) ⇒ [Cursor](#Cursor) - * [.project(candidates)](#Cursor+project) ⇒ [Array.<document>](#document) - * [._execAsync()](#Cursor+_execAsync) ⇒ [Array.<document>](#document) \| Promise.<\*> - * [._exec(_callback)](#Cursor+_exec) - * [.exec(_callback)](#Cursor+exec) - * [.execAsync()](#Cursor+execAsync) ⇒ Promise.<(Array.<document>\|\*)> - * _inner_ - * [~execFnWithCallback](#Cursor..execFnWithCallback) : function - * [~execFnWithoutCallback](#Cursor..execFnWithoutCallback) ⇒ Promise \| \* - * [~execCallback](#Cursor..execCallback) : function - - - -### new Cursor(db, query, [execFn], [hasCallback]) -

Create a new cursor for this collection

- -**Params** - -- db [Datastore](#Datastore) -

The datastore this cursor is bound to

-- query [query](#query) -

The query this cursor will operate on

-- [execFn] [execFnWithoutCallback](#Cursor..execFnWithoutCallback) | [execFnWithCallback](#Cursor..execFnWithCallback) -

Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove

-- [hasCallback] boolean = true -

If false, specifies that the execFn is of type [execFnWithoutCallback](#Cursor..execFnWithoutCallback) rather than [execFnWithCallback](#Cursor..execFnWithCallback).

- - - -### cursor.db : [Datastore](#Datastore) -**Kind**: instance property of [Cursor](#Cursor) -**Access**: protected - - -### cursor.query : [query](#query) -**Kind**: instance property of [Cursor](#Cursor) -**Access**: protected - - -### cursor.hasCallback : boolean -

Determines if the [Cursor#execFn](Cursor#execFn) is an [execFnWithoutCallback](#Cursor..execFnWithoutCallback) or not.

- -**Kind**: instance property of [Cursor](#Cursor) -**Access**: protected - - -### cursor.limit(limit) ⇒ [Cursor](#Cursor) -

Set a limit to the number of results

- -**Kind**: instance method of [Cursor](#Cursor) -**Params** - -- limit Number - - - -### cursor.skip(skip) ⇒ [Cursor](#Cursor) -

Skip a number of results

- -**Kind**: instance method of [Cursor](#Cursor) -**Params** - -- skip Number - - - -### cursor.sort(sortQuery) ⇒ [Cursor](#Cursor) -

Sort results of the query

- -**Kind**: instance method of [Cursor](#Cursor) -**Params** - -- sortQuery Object.<string, number> -

sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending

- - - -### cursor.projection(projection) ⇒ [Cursor](#Cursor) -

Add the use of a projection

- -**Kind**: instance method of [Cursor](#Cursor) -**Params** - -- projection Object.<string, number> -

MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 -{ key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits.

- - - -### cursor.project(candidates) ⇒ [Array.<document>](#document) -

Apply the projection.

-

This is an internal function. You should use [execAsync](#Cursor+execAsync) or [exec](#Cursor+exec).

- -**Kind**: instance method of [Cursor](#Cursor) -**Access**: protected -**Params** - -- candidates [Array.<document>](#document) - - - -### cursor.\_execAsync() ⇒ [Array.<document>](#document) \| Promise.<\*> -

Get all matching elements -Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne -This is an internal function, use execAsync which uses the executor

- -**Kind**: instance method of [Cursor](#Cursor) - - -### cursor.\_exec(_callback) -

Get all matching elements -Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

-

This is an internal function, use [exec](#Cursor+exec) which uses the [executor](#Datastore+executor).

- -**Kind**: instance method of [Cursor](#Cursor) -**Access**: protected -**See**: Cursor#exec -**Params** - -- _callback [execCallback](#Cursor..execCallback) - - - -### cursor.exec(_callback) -

Get all matching elements -Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

- -**Kind**: instance method of [Cursor](#Cursor) -**Params** - -- _callback [execCallback](#Cursor..execCallback) - - - -### cursor.execAsync() ⇒ Promise.<(Array.<document>\|\*)> -

Async version of [exec](#Cursor+exec).

- -**Kind**: instance method of [Cursor](#Cursor) -**See**: Cursor#exec - - -### Cursor~execFnWithCallback : function -

Has a callback

- -**Kind**: inner typedef of [Cursor](#Cursor) -**Params** - -- err Error -- res [?Array.<document>](#document) | [document](#document) - - - -### Cursor~execFnWithoutCallback ⇒ Promise \| \* -

Does not have a callback, may return a Promise.

- -**Kind**: inner typedef of [Cursor](#Cursor) -**Params** - -- res [?Array.<document>](#document) | [document](#document) - - - -### Cursor~execCallback : function -**Kind**: inner typedef of [Cursor](#Cursor) -**Params** - -- err Error -- res [Array.<document>](#document) | \* -

If an execFn was given to the Cursor, then the type of this parameter is the one returned by the execFn.

- diff --git a/docs/Datastore.md b/docs/Datastore.md deleted file mode 100644 index bd2a3f7..0000000 --- a/docs/Datastore.md +++ /dev/null @@ -1,568 +0,0 @@ - - -## Datastore ⇐ EventEmitter -

The Datastore class is the main class of NeDB.

- -**Kind**: global class -**Extends**: EventEmitter -**Emits**: Datastore#event:"compaction.done" - -* [Datastore](#Datastore) ⇐ EventEmitter - * [new Datastore(options)](#new_Datastore_new) - * _instance_ - * [.inMemoryOnly](#Datastore+inMemoryOnly) : boolean - * [.autoload](#Datastore+autoload) : boolean - * [.timestampData](#Datastore+timestampData) : boolean - * [.filename](#Datastore+filename) : string - * [.persistence](#Datastore+persistence) : [Persistence](#Persistence) - * [.executor](#Datastore+executor) : [Executor](#Executor) - * [.indexes](#Datastore+indexes) : Object.<string, Index> - * [.ttlIndexes](#Datastore+ttlIndexes) : Object.<string, number> - * [.autoloadPromise](#Datastore+autoloadPromise) : Promise - * [.compareStrings()](#Datastore+compareStrings) : [compareStrings](#compareStrings) - * [.loadDatabase(callback)](#Datastore+loadDatabase) - * [.loadDatabaseAsync()](#Datastore+loadDatabaseAsync) ⇒ Promise - * [.getAllData()](#Datastore+getAllData) ⇒ [Array.<document>](#document) - * [.resetIndexes(newData)](#Datastore+resetIndexes) - * [.ensureIndex(options, callback)](#Datastore+ensureIndex) - * [.ensureIndexAsync(options)](#Datastore+ensureIndexAsync) ⇒ Promise.<void> - * [.removeIndex(fieldName, callback)](#Datastore+removeIndex) - * [.removeIndexAsync(fieldName)](#Datastore+removeIndexAsync) ⇒ Promise.<void> - * [.addToIndexes(doc)](#Datastore+addToIndexes) - * [.removeFromIndexes(doc)](#Datastore+removeFromIndexes) - * [.updateIndexes(oldDoc, [newDoc])](#Datastore+updateIndexes) - * [.getCandidates(query, [dontExpireStaleDocs], callback)](#Datastore+getCandidates) - * [.getCandidatesAsync(query, [dontExpireStaleDocs])](#Datastore+getCandidatesAsync) ⇒ Promise.<Array.<document>> - * [.insertAsync(newDoc)](#Datastore+insertAsync) ⇒ [Promise.<document>](#document) - * [.count(query, [callback])](#Datastore+count) ⇒ Cursor.<number> \| undefined - * [.countAsync(query)](#Datastore+countAsync) ⇒ Cursor.<number> - * [.find(query, [projection], [callback])](#Datastore+find) ⇒ Cursor.<Array.<document>> \| undefined - * [.findAsync(query, [projection])](#Datastore+findAsync) ⇒ Cursor.<Array.<document>> - * [.findOne(query, [projection], [callback])](#Datastore+findOne) ⇒ [Cursor.<document>](#document) \| undefined - * [.findOneAsync(query, projection)](#Datastore+findOneAsync) ⇒ [Cursor.<document>](#document) - * [.update(query, update, [options|], [cb])](#Datastore+update) - * [.updateAsync(query, update, [options])](#Datastore+updateAsync) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> - * [.remove(query, [options], [cb])](#Datastore+remove) - * [.removeAsync(query, [options])](#Datastore+removeAsync) ⇒ Promise.<number> - * ["event:compaction.done"](#Datastore+event_compaction.done) - * _inner_ - * [~countCallback](#Datastore..countCallback) : function - * [~findOneCallback](#Datastore..findOneCallback) : function - * [~updateCallback](#Datastore..updateCallback) : function - * [~removeCallback](#Datastore..removeCallback) : function - - - -### new Datastore(options) -

Create a new collection, either persistent or in-memory.

-

If you use a persistent datastore without the autoload option, you need to call loadDatabase manually. This -function fetches the data from datafile and prepares the database. Don't forget it! If you use a persistent -datastore, no command (insert, find, update, remove) will be executed before loadDatabase is called, so make sure -to call it yourself or use the autoload option.

- -**Params** - -- options object | string -

Can be an object or a string. If options is a string, the behavior is the same as in -v0.6: it will be interpreted as options.filename. Giving a string is deprecated, and will be removed in the -next major version.

- - [.filename] string = null -

Path to the file where the data is persisted. If left blank, the datastore is -automatically considered in-memory only. It cannot end with a ~ which is used in the temporary files NeDB uses to -perform crash-safe writes.

- - [.inMemoryOnly] boolean = false -

If set to true, no data will be written in storage.

- - [.timestampData] boolean = false -

If set to true, createdAt and updatedAt will be created and -populated automatically (if not specified by user)

- - [.autoload] boolean = false -

If used, the database will automatically be loaded from the datafile -upon creation (you don't need to call loadDatabase). Any command issued before load is finished is buffered and -will be executed when load is done. When autoloading is done, you can either use the onload callback, or you can -use this.autoloadPromise which resolves (or rejects) when autloading is done.

- - [.onload] function -

If you use autoloading, this is the handler called after the loadDatabase. It -takes one error argument. If you use autoloading without specifying this handler, and an error happens during -load, an error will be thrown.

- - [.beforeDeserialization] function -

Hook you can use to transform data after it was serialized and -before it is written to disk. Can be used for example to encrypt data before writing database to disk. This -function takes a string as parameter (one line of an NeDB data file) and outputs the transformed string, which -must absolutely not contain a \n character (or data will be lost).

- - [.afterSerialization] function -

Inverse of afterSerialization. Make sure to include both and not -just one, or you risk data loss. For the same reason, make sure both functions are inverses of one another. Some -failsafe mechanisms are in place to prevent data loss if you misuse the serialization hooks: NeDB checks that never -one is declared without the other, and checks that they are reverse of one another by testing on random strings of -various lengths. In addition, if too much data is detected as corrupt, NeDB will refuse to start as it could mean -you're not using the deserialization hook corresponding to the serialization hook used before.

- - [.corruptAlertThreshold] number = 0.1 -

Between 0 and 1, defaults to 10%. NeDB will refuse to start -if more than this percentage of the datafile is corrupt. 0 means you don't tolerate any corruption, 1 means you -don't care.

- - [.compareStrings] [compareStrings](#compareStrings) -

If specified, it overrides default string comparison which is not -well adapted to non-US characters in particular accented letters. Native localCompare will most of the time be -the right choice.

- - [.nodeWebkitAppName] string -

Deprecated: if you are using NeDB from whithin a Node Webkit app, -specify its name (the same one you use in the package.json) in this field and the filename will be relative to -the directory Node Webkit uses to store the rest of the application's data (local storage etc.). It works on Linux, -OS X and Windows. Now that you can use require('nw.gui').App.dataPath in Node Webkit to get the path to the data -directory for your application, you should not use this option anymore and it will be removed.

- - - -### datastore.inMemoryOnly : boolean -

Determines if the Datastore keeps data in-memory, or if it saves it in storage. Is not read after -instanciation.

- -**Kind**: instance property of [Datastore](#Datastore) -**Access**: protected - - -### datastore.autoload : boolean -

Determines if the Datastore should autoload the database upon instantiation. Is not read after instanciation.

- -**Kind**: instance property of [Datastore](#Datastore) -**Access**: protected - - -### datastore.timestampData : boolean -

Determines if the Datastore should add createdAt and updatedAt fields automatically if not set by the user.

- -**Kind**: instance property of [Datastore](#Datastore) -**Access**: protected - - -### datastore.filename : string -

If null, it means inMemoryOnly is true. The filename is the name given to the storage module. Is not read -after instanciation.

- -**Kind**: instance property of [Datastore](#Datastore) -**Access**: protected - - -### datastore.persistence : [Persistence](#Persistence) -

The Persistence instance for this Datastore.

- -**Kind**: instance property of [Datastore](#Datastore) - - -### datastore.executor : [Executor](#Executor) -

The Executor instance for this Datastore. It is used in all methods exposed by the Datastore, any Cursor -produced by the Datastore and by this.persistence.compactDataFile & this.persistence.compactDataFileAsync -to ensure operations are performed sequentially in the database.

- -**Kind**: instance property of [Datastore](#Datastore) -**Access**: protected - - -### datastore.indexes : Object.<string, Index> -

Indexed by field name, dot notation can be used. -_id is always indexed and since _ids are generated randomly the underlying binary search tree is always well-balanced

- -**Kind**: instance property of [Datastore](#Datastore) -**Access**: protected - - -### datastore.ttlIndexes : Object.<string, number> -

Stores the time to live (TTL) of the indexes created. The key represents the field name, the value the number of -seconds after which data with this index field should be removed.

- -**Kind**: instance property of [Datastore](#Datastore) -**Access**: protected - - -### datastore.autoloadPromise : Promise -

A Promise that resolves when the autoload has finished.

-

The onload callback is not awaited by this Promise, it is started immediately after that.

- -**Kind**: instance property of [Datastore](#Datastore) - - -### datastore.compareStrings() : [compareStrings](#compareStrings) -

Overrides default string comparison which is not well adapted to non-US characters in particular accented -letters. Native localCompare will most of the time be the right choice

- -**Kind**: instance method of [Datastore](#Datastore) -**Access**: protected - - -### datastore.loadDatabase(callback) -

Load the database from the datafile, and trigger the execution of buffered commands if any.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- callback function - - - -### datastore.loadDatabaseAsync() ⇒ Promise -

Async version of [loadDatabase](#Datastore+loadDatabase).

- -**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#loadDatabase - - -### datastore.getAllData() ⇒ [Array.<document>](#document) -

Get an array of all the data in the database.

- -**Kind**: instance method of [Datastore](#Datastore) - - -### datastore.resetIndexes(newData) -

Reset all currently defined indexes.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- newData [document](#document) | [?Array.<document>](#document) - - - -### datastore.ensureIndex(options, callback) -

Ensure an index is kept for this field. Same parameters as lib/indexes -This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the -executor. -Previous versions said explicitly the callback was optional, it is now recommended setting one.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- options object - - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

- - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

- - [.sparse] boolean = false -

don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

- - [.expireAfterSeconds] number -

if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

-- callback [NoParamCallback](#NoParamCallback) -

Callback, signature: err

- - - -### datastore.ensureIndexAsync(options) ⇒ Promise.<void> -

Async version of [ensureIndex](#Datastore+ensureIndex).

- -**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#ensureIndex -**Params** - -- options object - - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

- - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

- - [.sparse] boolean = false -

Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

- - [.expireAfterSeconds] number -

If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

- - - -### datastore.removeIndex(fieldName, callback) -

Remove an index -Previous versions said explicitly the callback was optional, it is now recommended setting one.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a -field in a nested document.

-- callback [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

- - - -### datastore.removeIndexAsync(fieldName) ⇒ Promise.<void> -

Async version of [removeIndex](#Datastore+removeIndex).

- -**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#removeIndex -**Params** - -- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a -field in a nested document.

- - - -### datastore.addToIndexes(doc) -

Add one or several document(s) to all indexes.

-

This is an internal function.

- -**Kind**: instance method of [Datastore](#Datastore) -**Access**: protected -**Params** - -- doc [document](#document) - - - -### datastore.removeFromIndexes(doc) -

Remove one or several document(s) from all indexes.

-

This is an internal function.

- -**Kind**: instance method of [Datastore](#Datastore) -**Access**: protected -**Params** - -- doc [document](#document) - - - -### datastore.updateIndexes(oldDoc, [newDoc]) -

Update one or several documents in all indexes.

-

To update multiple documents, oldDoc must be an array of { oldDoc, newDoc } pairs.

-

If one update violates a constraint, all changes are rolled back.

-

This is an internal function.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- oldDoc [document](#document) | Array.<{oldDoc: document, newDoc: document}> -

Document to update, or an Array of -{oldDoc, newDoc} pairs.

-- [newDoc] [document](#document) -

Document to replace the oldDoc with. If the first argument is an Array of -{oldDoc, newDoc} pairs, this second argument is ignored.

- - - -### datastore.getCandidates(query, [dontExpireStaleDocs], callback) -

Return the list of candidates for a given query -Crude implementation for now, we return the candidates given by the first usable index if any -We try the following query types, in this order: basic match, $in match, comparison match -One way to make it better would be to enable the use of multiple indexes if the first usable index -returns too much data. I may do it in the future.

-

Returned candidates will be scanned to find and remove all expired documents

-

This is an internal function.

- -**Kind**: instance method of [Datastore](#Datastore) -**Access**: protected -**Params** - -- query [query](#query) -- [dontExpireStaleDocs] boolean | function = false -

If true don't remove stale docs. Useful for the remove -function which shouldn't be impacted by expirations. If argument is not given, it is used as the callback.

-- callback [MultipleDocumentsCallback](#MultipleDocumentsCallback) -

Signature err, candidates

- - - -### datastore.getCandidatesAsync(query, [dontExpireStaleDocs]) ⇒ Promise.<Array.<document>> -

Async version of [getCandidates](#Datastore+getCandidates).

-

This is an internal function.

- -**Kind**: instance method of [Datastore](#Datastore) -**Returns**: Promise.<Array.<document>> -

candidates

-**Access**: protected -**See**: Datastore#getCandidates -**Params** - -- query [query](#query) -- [dontExpireStaleDocs] boolean = false -

If true don't remove stale docs. Useful for the remove function -which shouldn't be impacted by expirations.

- - - -### datastore.insertAsync(newDoc) ⇒ [Promise.<document>](#document) -

Async version of [Datastore#insert](Datastore#insert).

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- newDoc [document](#document) | [Array.<document>](#document) - - - -### datastore.count(query, [callback]) ⇒ Cursor.<number> \| undefined -

Count all documents matching the query.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- query [query](#query) -

MongoDB-style query

-- [callback] [countCallback](#Datastore..countCallback) -

If given, the function will return undefined, otherwise it will return the Cursor.

- - - -### datastore.countAsync(query) ⇒ Cursor.<number> -

Async version of [count](#Datastore+count).

- -**Kind**: instance method of [Datastore](#Datastore) -**Returns**: Cursor.<number> -

count

-**Params** - -- query [query](#query) -

MongoDB-style query

- - - -### datastore.find(query, [projection], [callback]) ⇒ Cursor.<Array.<document>> \| undefined -

Find all documents matching the query -If no callback is passed, we return the cursor so that user can limit, skip and finally exec

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- query [query](#query) -

MongoDB-style query

-- [projection] [projection](#projection) | [MultipleDocumentsCallback](#MultipleDocumentsCallback) = {} -

MongoDB-style projection. If not given, will be -interpreted as the callback.

-- [callback] [MultipleDocumentsCallback](#MultipleDocumentsCallback) -

Optional callback, signature: err, docs

- - - -### datastore.findAsync(query, [projection]) ⇒ Cursor.<Array.<document>> -

Async version of [find](#Datastore+find).

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- query [query](#query) -

MongoDB-style query

-- [projection] [projection](#projection) = {} -

MongoDB-style projection

- - - -### datastore.findOne(query, [projection], [callback]) ⇒ [Cursor.<document>](#document) \| undefined -

Find one document matching the query.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- query [query](#query) -

MongoDB-style query

-- [projection] [projection](#projection) | [SingleDocumentCallback](#SingleDocumentCallback) = {} -

MongoDB-style projection

-- [callback] [SingleDocumentCallback](#SingleDocumentCallback) -

Optional callback, signature: err, doc

- - - -### datastore.findOneAsync(query, projection) ⇒ [Cursor.<document>](#document) -

Async version of [findOne](#Datastore+findOne).

- -**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#findOne -**Params** - -- query [query](#query) -

MongoDB-style query

-- projection [projection](#projection) -

MongoDB-style projection

- - - -### datastore.update(query, update, [options|], [cb]) -

Update all docs matching query.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- query [query](#query) -

is the same kind of finding query you use with find and findOne

-- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a -set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the -matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can -apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, -$inc to increment a field's value and $min/$max to change field's value, only if provided value is -less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special -$each and $slice.

-- [options|] Object | [updateCallback](#Datastore..updateCallback) -

Optional options

- - [.multi] boolean = false -

If true, can update multiple documents

- - [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if -your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted -document. In the other case, the query is stripped from all operator recursively, and the update is applied to -it.

- - [.returnUpdatedDocs] boolean = false -

(not Mongo-DB compatible) If true and update is not an upsert, -will return the array of documents matched by the find query and updated. Updated documents will be returned even -if the update did not actually modify them.

-- [cb] [updateCallback](#Datastore..updateCallback) = () => {} -

Optional callback

- - - -### datastore.updateAsync(query, update, [options]) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> -

Async version of [update](#Datastore+update).

- -**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#update -**Params** - -- query [query](#query) -

is the same kind of finding query you use with find and findOne

-- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a -set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the -matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can -apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, -$inc to increment a field's value and $min/$max to change field's value, only if provided value is -less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special -$each and $slice.

-- [options] Object = {} -

Optional options

- - [.multi] boolean = false -

If true, can update multiple documents

- - [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if -your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted -document. In the other case, the query is stripped from all operator recursively, and the update is applied to -it.

- - [.returnUpdatedDocs] boolean = false -

(not Mongo-DB compatible) If true and update is not an upsert, -will return the array of documents matched by the find query and updated. Updated documents will be returned even -if the update did not actually modify them.

- - - -### datastore.remove(query, [options], [cb]) -

Remove all docs matching the query.

- -**Kind**: instance method of [Datastore](#Datastore) -**Params** - -- query [query](#query) -- [options] object | [removeCallback](#Datastore..removeCallback) = {} -

Optional options

- - [.multi] boolean = false -

If true, can update multiple documents

-- [cb] [removeCallback](#Datastore..removeCallback) = () => {} -

Optional callback

- - - -### datastore.removeAsync(query, [options]) ⇒ Promise.<number> -

Remove all docs matching the query. -Use Datastore.removeAsync which has the same signature

- -**Kind**: instance method of [Datastore](#Datastore) -**Returns**: Promise.<number> -

How many documents were removed

-**Params** - -- query [query](#query) -- [options] object = {} -

Optional options

- - [.multi] boolean = false -

If true, can update multiple documents

- - - -### "event:compaction.done" -

Compaction event. Happens when the Datastore's Persistence has been compacted. -It happens when calling datastore.persistence.compactDatafile, which is called periodically if you have called -datastore.persistence.setAutocompactionInterval.

- -**Kind**: event emitted by [Datastore](#Datastore) - - -### Datastore~countCallback : function -**Kind**: inner typedef of [Datastore](#Datastore) -**Params** - -- err Error -- count number - - - -### Datastore~findOneCallback : function -**Kind**: inner typedef of [Datastore](#Datastore) -**Params** - -- err Error -- doc [document](#document) - - - -### Datastore~updateCallback : function -

If update was an upsert, upsert flag is set to true, affectedDocuments can be one of the following:

-
    -
  • For an upsert, the upserted document
  • -
  • For an update with returnUpdatedDocs option false, null
  • -
  • For an update with returnUpdatedDocs true and multi false, the updated document
  • -
  • For an update with returnUpdatedDocs true and multi true, the array of updated documents
  • -
-

WARNING: The API was changed between v1.7.4 and v1.8, for consistency and readability reasons. Prior and -including to v1.7.4, the callback signature was (err, numAffected, updated) where updated was the updated document -in case of an upsert or the array of updated documents for an update if the returnUpdatedDocs option was true. That -meant that the type of affectedDocuments in a non multi update depended on whether there was an upsert or not, -leaving only two ways for the user to check whether an upsert had occured: checking the type of affectedDocuments -or running another find query on the whole dataset to check its size. Both options being ugly, the breaking change -was necessary.

- -**Kind**: inner typedef of [Datastore](#Datastore) -**Params** - -- err Error -- numAffected number -- affectedDocuments [?Array.<document>](#document) | [document](#document) -- upsert boolean - - - -### Datastore~removeCallback : function -**Kind**: inner typedef of [Datastore](#Datastore) -**Params** - -- err Error -- numRemoved number - diff --git a/docs/Executor.md b/docs/Executor.md deleted file mode 100644 index 1d24696..0000000 --- a/docs/Executor.md +++ /dev/null @@ -1,57 +0,0 @@ - - -## Executor -

Executes operations sequentially. -Has an option for a buffer that can be triggered afterwards.

- -**Kind**: global class - -* [Executor](#Executor) - * [new Executor()](#new_Executor_new) - * [.push(task, [forceQueuing])](#Executor+push) - * [.pushAsync(task, [forceQueuing])](#Executor+pushAsync) ⇒ Promise.<\*> - * [.processBuffer()](#Executor+processBuffer) - - - -### new Executor() -

Instantiates a new Executor.

- - - -### executor.push(task, [forceQueuing]) -

If executor is ready, queue task (and process it immediately if executor was idle) -If not, buffer task for later processing

- -**Kind**: instance method of [Executor](#Executor) -**Params** - -- task Object - - .this Object -

Object to use as this

- - .fn function -

Function to execute

- - .arguments Array -

Array of arguments, IMPORTANT: only the last argument may be a function -(the callback) and the last argument cannot be false/undefined/null

-- [forceQueuing] Boolean = false -

Optional (defaults to false) force executor to queue task even if it is not ready

- - - -### executor.pushAsync(task, [forceQueuing]) ⇒ Promise.<\*> -

Async version of [push](#Executor+push). -This version is way simpler than its callbackEquivalent: you give it an async function task, it is executed when -all the previous tasks are done, and then resolves or rejects and when it is finished with its original result or -error.

- -**Kind**: instance method of [Executor](#Executor) -**See**: Executor#push -**Params** - -- task [AsyncFunction](#AsyncFunction) -- [forceQueuing] boolean = false - - - -### executor.processBuffer() -

Queue all tasks in buffer (in the same order they came in) -Automatically sets executor as ready

- -**Kind**: instance method of [Executor](#Executor) diff --git a/docs/Index.md b/docs/Index.md deleted file mode 100644 index fd1716d..0000000 --- a/docs/Index.md +++ /dev/null @@ -1,161 +0,0 @@ - - -## Index -

Indexes on field names, with atomic operations and which can optionally enforce a unique constraint or allow indexed -fields to be undefined

- -**Kind**: global class - -* [Index](#Index) - * [new Index(options)](#new_Index_new) - * [.fieldName](#Index+fieldName) : string - * [.unique](#Index+unique) : boolean - * [.sparse](#Index+sparse) : boolean - * [.treeOptions](#Index+treeOptions) : Object - * [.tree](#Index+tree) : AVLTree - * [.reset([newData])](#Index+reset) - * [.insert(doc)](#Index+insert) - * [.remove(doc)](#Index+remove) - * [.update(oldDoc, [newDoc])](#Index+update) - * [.revertUpdate(oldDoc, [newDoc])](#Index+revertUpdate) - * [.getMatching(value)](#Index+getMatching) ⇒ [Array.<document>](#document) - * [.getBetweenBounds(query)](#Index+getBetweenBounds) ⇒ [Array.<document>](#document) - * [.getAll()](#Index+getAll) ⇒ [Array.<document>](#document) - - - -### new Index(options) -

Create a new index -All methods on an index guarantee that either the whole operation was successful and the index changed -or the operation was unsuccessful and an error is thrown while the index is unchanged

- -**Params** - -- options object - - .fieldName string -

On which field should the index apply (can use dot notation to index on sub fields)

- - [.unique] boolean = false -

Enforces a unique constraint

- - [.sparse] boolean = false -

Allows a sparse index (we can have documents for which fieldName is undefined)

- - - -### index.fieldName : string -

On which field the index applies to (may use dot notation to index on sub fields).

- -**Kind**: instance property of [Index](#Index) - - -### index.unique : boolean -

Defines if the index enforces a unique constraint for this index.

- -**Kind**: instance property of [Index](#Index) - - -### index.sparse : boolean -

Defines if we can have documents for which fieldName is undefined

- -**Kind**: instance property of [Index](#Index) - - -### index.treeOptions : Object -

Options object given to the underlying BinarySearchTree.

- -**Kind**: instance property of [Index](#Index) - - -### index.tree : AVLTree -

Underlying BinarySearchTree for this index. Uses an AVLTree for optimization.

- -**Kind**: instance property of [Index](#Index) - - -### index.reset([newData]) -

Reset an index

- -**Kind**: instance method of [Index](#Index) -**Params** - -- [newData] [document](#document) | [?Array.<document>](#document) -

Data to initialize the index with. If an error is thrown during -insertion, the index is not modified.

- - - -### index.insert(doc) -

Insert a new document in the index -If an array is passed, we insert all its elements (if one insertion fails the index is not modified) -O(log(n))

- -**Kind**: instance method of [Index](#Index) -**Params** - -- doc [document](#document) | [Array.<document>](#document) -

The document, or array of documents, to insert.

- - - -### index.remove(doc) -

Removes a document from the index. -If an array is passed, we remove all its elements -The remove operation is safe with regards to the 'unique' constraint -O(log(n))

- -**Kind**: instance method of [Index](#Index) -**Params** - -- doc [Array.<document>](#document) | [document](#document) -

The document, or Array of documents, to remove.

- - - -### index.update(oldDoc, [newDoc]) -

Update a document in the index -If a constraint is violated, changes are rolled back and an error thrown -Naive implementation, still in O(log(n))

- -**Kind**: instance method of [Index](#Index) -**Params** - -- oldDoc [document](#document) | Array.<{oldDoc: document, newDoc: document}> -

Document to update, or an Array of -{oldDoc, newDoc} pairs.

-- [newDoc] [document](#document) -

Document to replace the oldDoc with. If the first argument is an Array of -{oldDoc, newDoc} pairs, this second argument is ignored.

- - - -### index.revertUpdate(oldDoc, [newDoc]) -

Revert an update

- -**Kind**: instance method of [Index](#Index) -**Params** - -- oldDoc [document](#document) | Array.<{oldDoc: document, newDoc: document}> -

Document to revert to, or an Array of {oldDoc, newDoc} pairs.

-- [newDoc] [document](#document) -

Document to revert from. If the first argument is an Array of {oldDoc, newDoc}, this second argument is ignored.

- - - -### index.getMatching(value) ⇒ [Array.<document>](#document) -

Get all documents in index whose key match value (if it is a Thing) or one of the elements of value (if it is an array of Things)

- -**Kind**: instance method of [Index](#Index) -**Params** - -- value Array.<\*> | \* -

Value to match the key against

- - - -### index.getBetweenBounds(query) ⇒ [Array.<document>](#document) -

Get all documents in index whose key is between bounds are they are defined by query -Documents are sorted by key

- -**Kind**: instance method of [Index](#Index) -**Params** - -- query object -

An object with at least one matcher among $gt, $gte, $lt, $lte.

- - [.$gt] \* -

Greater than matcher.

- - [.$gte] \* -

Greater than or equal matcher.

- - [.$lt] \* -

Lower than matcher.

- - [.$lte] \* -

Lower than or equal matcher.

- - - -### index.getAll() ⇒ [Array.<document>](#document) -

Get all elements in the index

- -**Kind**: instance method of [Index](#Index) diff --git a/docs/Persistence.md b/docs/Persistence.md deleted file mode 100644 index 1b4c51c..0000000 --- a/docs/Persistence.md +++ /dev/null @@ -1,242 +0,0 @@ - - -## Persistence -

Handle every persistence-related task

- -**Kind**: global class - -* [Persistence](#Persistence) - * [new Persistence()](#new_Persistence_new) - * _instance_ - * [.persistCachedDatabase([callback])](#Persistence+persistCachedDatabase) - * [.persistCachedDatabaseAsync()](#Persistence+persistCachedDatabaseAsync) ⇒ Promise.<void> - * [.compactDatafile([callback])](#Persistence+compactDatafile) - * [.compactDatafileAsync()](#Persistence+compactDatafileAsync) - * [.setAutocompactionInterval(interval)](#Persistence+setAutocompactionInterval) - * [.stopAutocompaction()](#Persistence+stopAutocompaction) - * [.persistNewState(newDocs, [callback])](#Persistence+persistNewState) - * [.persistNewStateAsync(newDocs)](#Persistence+persistNewStateAsync) ⇒ Promise - * [.treatRawData(rawData)](#Persistence+treatRawData) ⇒ Object - * [.treatRawStream(rawStream, cb)](#Persistence+treatRawStream) - * [.treatRawStreamAsync(rawStream)](#Persistence+treatRawStreamAsync) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> - * [.loadDatabase(callback)](#Persistence+loadDatabase) - * [.loadDatabaseAsync()](#Persistence+loadDatabaseAsync) ⇒ Promise.<void> - * _static_ - * [.ensureDirectoryExists(dir, [callback])](#Persistence.ensureDirectoryExists) - * [.ensureDirectoryExistsAsync(dir)](#Persistence.ensureDirectoryExistsAsync) ⇒ Promise.<void> - * ~~[.getNWAppFilename(appName, relativeFilename)](#Persistence.getNWAppFilename) ⇒ string~~ - * _inner_ - * [~treatRawStreamCallback](#Persistence..treatRawStreamCallback) : function - - - -### new Persistence() -

Create a new Persistence object for database options.db

- -**Params** - - - .db [Datastore](#Datastore) - - [.corruptAlertThreshold] Number -

Optional, threshold after which an alert is thrown if too much data is corrupt

- - [.nodeWebkitAppName] string -

Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion)

- - [.beforeDeserialization] [serializationHook](#serializationHook) -

Hook you can use to transform data after it was serialized and before it is written to disk.

- - [.afterSerialization] [serializationHook](#serializationHook) -

Inverse of afterSerialization.

- - - -### persistence.persistCachedDatabase([callback]) -

Persist cached database -This serves as a compaction function since the cache always contains only the number of documents in the collection -while the data file is append-only so it may grow larger

-

This is an internal function, use [compactDatafile](#Persistence+compactDatafile) which uses the [executor](#Datastore+executor).

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- [callback] [NoParamCallback](#NoParamCallback) = () => {} - - - -### persistence.persistCachedDatabaseAsync() ⇒ Promise.<void> -

Async version of [persistCachedDatabase](#Persistence+persistCachedDatabase).

-

This is an internal function, use [compactDatafileAsync](#Persistence+compactDatafileAsync) which uses the [executor](#Datastore+executor).

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**See**: Persistence#persistCachedDatabase - - -### persistence.compactDatafile([callback]) -

Queue a rewrite of the datafile

- -**Kind**: instance method of [Persistence](#Persistence) -**See**: Persistence#persistCachedDatabase -**Params** - -- [callback] [NoParamCallback](#NoParamCallback) = () => {} - - - -### persistence.compactDatafileAsync() -

Async version of [compactDatafile](#Persistence+compactDatafile).

- -**Kind**: instance method of [Persistence](#Persistence) -**See**: Persistence#compactDatafile - - -### persistence.setAutocompactionInterval(interval) -

Set automatic compaction every interval ms

- -**Kind**: instance method of [Persistence](#Persistence) -**Params** - -- interval Number -

in milliseconds, with an enforced minimum of 5000 milliseconds

- - - -### persistence.stopAutocompaction() -

Stop autocompaction (do nothing if automatic compaction was not running)

- -**Kind**: instance method of [Persistence](#Persistence) - - -### persistence.persistNewState(newDocs, [callback]) -

Persist new state for the given newDocs (can be insertion, update or removal) -Use an append-only format

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- newDocs Array.<string> -

Can be empty if no doc was updated/removed

-- [callback] [NoParamCallback](#NoParamCallback) = () => {} - - - -### persistence.persistNewStateAsync(newDocs) ⇒ Promise -

Async version of [persistNewState](#Persistence+persistNewState)

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

- -**Kind**: instance method of [Persistence](#Persistence) -**See**: Persistence#persistNewState -**Params** - -- newDocs [Array.<document>](#document) -

Can be empty if no doc was updated/removed

- - - -### persistence.treatRawData(rawData) ⇒ Object -

From a database's raw data, return the corresponding machine understandable collection.

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- rawData string -

database file

- - - -### persistence.treatRawStream(rawStream, cb) -

From a database's raw data stream, return the corresponding machine understandable collection -Is only used by a [Datastore](#Datastore) instance.

-

Is only used in the Node.js version, since [React-Native](#module_storageReactNative) & -[browser](#module_storageBrowser) storage modules don't provide an equivalent of -[readFileStream](#module_storage.readFileStream).

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- rawStream Readable -- cb [treatRawStreamCallback](#Persistence..treatRawStreamCallback) - - - -### persistence.treatRawStreamAsync(rawStream) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> -

Async version of [treatRawStream](#Persistence+treatRawStream).

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**See**: Persistence#treatRawStream -**Params** - -- rawStream Readable - - - -### persistence.loadDatabase(callback) -

Load the database

-
    -
  1. Create all indexes
  2. -
  3. Insert all data
  4. -
  5. Compact the database
  6. -
-

This means pulling data out of the data file or creating it if it doesn't exist -Also, all data is persisted right away, which has the effect of compacting the database file -This operation is very quick at startup for a big collection (60ms for ~10k docs)

-

Do not use directly as it does not use the [Executor](Datastore.executor), use [loadDatabase](#Datastore+loadDatabase) instead.

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- callback [NoParamCallback](#NoParamCallback) - - - -### persistence.loadDatabaseAsync() ⇒ Promise.<void> -

Async version of [loadDatabase](#Persistence+loadDatabase)

- -**Kind**: instance method of [Persistence](#Persistence) -**See**: Persistence#loadDatabase - - -### Persistence.ensureDirectoryExists(dir, [callback]) -

Check if a directory stat and create it on the fly if it is not the case.

- -**Kind**: static method of [Persistence](#Persistence) -**Params** - -- dir string -- [callback] [NoParamCallback](#NoParamCallback) = () => {} - - - -### Persistence.ensureDirectoryExistsAsync(dir) ⇒ Promise.<void> -

Async version of [ensureDirectoryExists](#Persistence.ensureDirectoryExists).

- -**Kind**: static method of [Persistence](#Persistence) -**See**: Persistence.ensureDirectoryExists -**Params** - -- dir string - - - -### ~~Persistence.getNWAppFilename(appName, relativeFilename) ⇒ string~~ -***Deprecated*** - -

Return the path the datafile if the given filename is relative to the directory where Node Webkit stores -data for this application. Probably the best place to store data

- -**Kind**: static method of [Persistence](#Persistence) -**Params** - -- appName string -- relativeFilename string - - - -### Persistence~treatRawStreamCallback : function -**Kind**: inner typedef of [Persistence](#Persistence) -**Params** - -- err Error -- data object - - .data [Array.<document>](#document) - - .indexes Object.<string, rawIndex> - diff --git a/docs/Waterfall.md b/docs/Waterfall.md deleted file mode 100644 index b253438..0000000 --- a/docs/Waterfall.md +++ /dev/null @@ -1,43 +0,0 @@ - - -## Waterfall -

Responsible for sequentially executing actions on the database

- -**Kind**: global class - -* [Waterfall](#Waterfall) - * [new Waterfall()](#new_Waterfall_new) - * [.guardian](#Waterfall+guardian) ⇒ Promise - * [.waterfall(func)](#Waterfall+waterfall) ⇒ [AsyncFunction](#AsyncFunction) - * [.chain(promise)](#Waterfall+chain) ⇒ Promise - - - -### new Waterfall() -

Instantiate a new Waterfall.

- - - -### waterfall.guardian ⇒ Promise -

Getter that gives a Promise which resolves when all tasks up to when this function is called are done.

-

This Promise cannot reject.

- -**Kind**: instance property of [Waterfall](#Waterfall) - - -### waterfall.waterfall(func) ⇒ [AsyncFunction](#AsyncFunction) -**Kind**: instance method of [Waterfall](#Waterfall) -**Params** - -- func [AsyncFunction](#AsyncFunction) - - - -### waterfall.chain(promise) ⇒ Promise -

Shorthand for chaining a promise to the Waterfall

- -**Kind**: instance method of [Waterfall](#Waterfall) -**Params** - -- promise Promise - diff --git a/docs/byline.md b/docs/byline.md deleted file mode 100644 index 87c28a4..0000000 --- a/docs/byline.md +++ /dev/null @@ -1,10 +0,0 @@ - - -## byline - - -### byline.LineStream -

Fork from [https://github.com/jahewson/node-byline](https://github.com/jahewson/node-byline).

- -**Kind**: static class of [byline](#module_byline) -**See**: https://github.com/jahewson/node-byline diff --git a/docs/customUtilsBrowser.md b/docs/customUtilsBrowser.md deleted file mode 100644 index 3a931d0..0000000 --- a/docs/customUtilsBrowser.md +++ /dev/null @@ -1,34 +0,0 @@ - - -## customUtilsBrowser -

Utility functions that need to be reimplemented for each environment. -This is the version for the browser & React-Native

- - -* [customUtilsBrowser](#module_customUtilsBrowser) - * [~randomBytes(size)](#module_customUtilsBrowser..randomBytes) ⇒ array.<number> - * [~byteArrayToBase64(uint8)](#module_customUtilsBrowser..byteArrayToBase64) ⇒ string - - - -### customUtilsBrowser~randomBytes(size) ⇒ array.<number> -

Taken from the crypto-browserify module -https://github.com/dominictarr/crypto-browserify -NOTE: Math.random() does not guarantee "cryptographic quality" but we actually don't need it

- -**Kind**: inner method of [customUtilsBrowser](#module_customUtilsBrowser) -**Params** - -- size number -

in bytes

- - - -### customUtilsBrowser~byteArrayToBase64(uint8) ⇒ string -

Taken from the base64-js module -https://github.com/beatgammit/base64-js/

- -**Kind**: inner method of [customUtilsBrowser](#module_customUtilsBrowser) -**Params** - -- uint8 array - diff --git a/docs/customUtilsNode.md b/docs/customUtilsNode.md deleted file mode 100644 index ec23df5..0000000 --- a/docs/customUtilsNode.md +++ /dev/null @@ -1,41 +0,0 @@ - - -## customUtilsNode -

Utility functions that need to be reimplemented for each environment. -This is the version for Node.js

- - -* [customUtilsNode](#module_customUtilsNode) - * [.uid(len)](#module_customUtilsNode.uid) ⇒ string - * [.uid(len)](#module_customUtilsNode.uid) ⇒ string - - - -### customUtilsNode.uid(len) ⇒ string -

Return a random alphanumerical string of length len -There is a very small probability (less than 1/1,000,000) for the length to be less than len -(il the base64 conversion yields too many pluses and slashes) but -that's not an issue here -The probability of a collision is extremely small (need 3*10^12 documents to have one chance in a million of a collision) -See http://en.wikipedia.org/wiki/Birthday_problem

- -**Kind**: static method of [customUtilsNode](#module_customUtilsNode) -**Params** - -- len number - - - -### customUtilsNode.uid(len) ⇒ string -

Return a random alphanumerical string of length len -There is a very small probability (less than 1/1,000,000) for the length to be less than len -(il the base64 conversion yields too many pluses and slashes) but -that's not an issue here -The probability of a collision is extremely small (need 3*10^12 documents to have one chance in a million of a collision) -See http://en.wikipedia.org/wiki/Birthday_problem

- -**Kind**: static method of [customUtilsNode](#module_customUtilsNode) -**Params** - -- len number - diff --git a/docs/globals.md b/docs/globals.md deleted file mode 100644 index b1a8a76..0000000 --- a/docs/globals.md +++ /dev/null @@ -1,155 +0,0 @@ - - -## NoParamCallback : function -

Callback with no parameter

- -**Kind**: global typedef -**Params** - -- err Error - - - - -## compareStrings ⇒ number -

String comparison function.

-
  if (a < b) return -1
-  if (a > b) return 1
-  return 0
-
- -**Kind**: global typedef -**Params** - -- a string -- b string - - - - -## MultipleDocumentsCallback : function -

Callback that returns an Array of documents

- -**Kind**: global typedef -**Params** - -- err Error -- docs [Array.<document>](#document) - - - - -## SingleDocumentCallback : function -

Callback that returns a single document

- -**Kind**: global typedef -**Params** - -- err Error -- docs [document](#document) - - - - -## AsyncFunction ⇒ Promise.<\*> -

Generic async function

- -**Kind**: global typedef -**Params** - -- ...args \* - - - - -## document : Object.<string, \*> -

Generic document in NeDB. -It consists of an Object with anything you want inside.

- -**Kind**: global typedef -**Properties** - -| Name | Type | Description | -| --- | --- | --- | -| [_id] | string |

Internal _id of the document, which can be null or undefined at some points (when not inserted yet for example).

| - - - - -## query : Object.<string, \*> -

Nedb query.

-

Each key of a query references a field name, which can use the dot-notation to reference subfields inside nested -documents, arrays, arrays of subdocuments and to match a specific element of an array.

-

Each value of a query can be one of the following:

-
    -
  • string: matches all documents which have this string as value for the referenced field name
  • -
  • number: matches all documents which have this number as value for the referenced field name
  • -
  • Regexp: matches all documents which have a value that matches the given Regexp for the referenced field name
  • -
  • object: matches all documents which have this object as deep-value for the referenced field name
  • -
  • Comparison operators: the syntax is { field: { $op: value } } where $op is any comparison operator: -
      -
    • $lt, $lte: less than, less than or equal
    • -
    • $gt, $gte: greater than, greater than or equal
    • -
    • $in: member of. value must be an array of values
    • -
    • $ne, $nin: not equal, not a member of
    • -
    • $stat: checks whether the document posses the property field. value should be true or false
    • -
    • $regex: checks whether a string is matched by the regular expression. Contrary to MongoDB, the use of -$options with $regex is not supported, because it doesn't give you more power than regex flags. Basic -queries are more readable so only use the $regex operator when you need to use another operator with it
    • -
    • $size: if the referenced filed is an Array, matches on the size of the array
    • -
    • $elemMatch: matches if at least one array element matches the sub-query entirely
    • -
    -
  • -
  • Logical operators: You can combine queries using logical operators: -
      -
    • For $or and $and, the syntax is { $op: [query1, query2, ...] }.
    • -
    • For $not, the syntax is { $not: query }
    • -
    • For $where, the syntax is:
    • -
    -
    { $where: function () {
    -  // object is 'this'
    -  // return a boolean
    -} }
    -
    -
  • -
- -**Kind**: global typedef - - - -## projection : Object.<string, (0\|1)> -

Nedb projection.

-

You can give find and findOne an optional second argument, projections. -The syntax is the same as MongoDB: { a: 1, b: 1 } to return only the a -and b fields, { a: 0, b: 0 } to omit these two fields. You cannot use both -modes at the time, except for _id which is by default always returned and -which you can choose to omit. You can project on nested documents.

-

To reference subfields, you can use the dot-notation.

- -**Kind**: global typedef - - - -## serializationHook ⇒ string -

The beforeDeserializationand afterDeserialization callbacks should

- -**Kind**: global typedef -**Params** - -- x string - - - - -## rawIndex -**Kind**: global typedef -**Properties** - -| Name | Type | -| --- | --- | -| fieldName | string | -| [unique] | boolean | -| [sparse] | boolean | - - diff --git a/docs/model.md b/docs/model.md deleted file mode 100644 index 5bd8153..0000000 --- a/docs/model.md +++ /dev/null @@ -1,206 +0,0 @@ - - -## model -

Handle models (i.e. docs) -Serialization/deserialization -Copying -Querying, update

- - -* [model](#module_model) - * _static_ - * [.checkObject(obj)](#module_model.checkObject) - * [.serialize(obj)](#module_model.serialize) ⇒ string - * [.deserialize(rawData)](#module_model.deserialize) ⇒ [document](#document) - * [.compareThings(a, b, [_compareStrings])](#module_model.compareThings) ⇒ number - * [.modify(obj, updateQuery)](#module_model.modify) ⇒ [document](#document) - * [.getDotValue(obj, field)](#module_model.getDotValue) ⇒ \* - * [.areThingsEqual(a, a)](#module_model.areThingsEqual) ⇒ boolean - * [.match(obj, query)](#module_model.match) ⇒ boolean - * _inner_ - * [~modifierFunctions](#module_model..modifierFunctions) : enum - * [~comparisonFunctions](#module_model..comparisonFunctions) : enum - * [~logicalOperators](#module_model..logicalOperators) - * [~modifierFunction](#module_model..modifierFunction) : function - * [~comparisonOperator](#module_model..comparisonOperator) ⇒ boolean - * [~whereCallback](#module_model..whereCallback) ⇒ boolean - - - -### model.checkObject(obj) -

Check a DB object and throw an error if it's not valid -Works by applying the above checkKey function to all fields recursively

- -**Kind**: static method of [model](#module_model) -**Params** - -- obj [document](#document) | [Array.<document>](#document) - - - -### model.serialize(obj) ⇒ string -

Serialize an object to be persisted to a one-line string -For serialization/deserialization, we use the native JSON parser and not eval or Function -That gives us less freedom but data entered in the database may come from users -so eval and the like are not safe -Accepted primitive types: Number, String, Boolean, Date, null -Accepted secondary types: Objects, Arrays

- -**Kind**: static method of [model](#module_model) -**Params** - -- obj [document](#document) - - - -### model.deserialize(rawData) ⇒ [document](#document) -

From a one-line representation of an object generate by the serialize function -Return the object itself

- -**Kind**: static method of [model](#module_model) -**Params** - -- rawData string - - - -### model.compareThings(a, b, [_compareStrings]) ⇒ number -

Compare { things U undefined } -Things are defined as any native types (string, number, boolean, null, date) and objects -We need to compare with undefined as it will be used in indexes -In the case of objects and arrays, we deep-compare -If two objects dont have the same type, the (arbitrary) type hierarchy is: undefined, null, number, strings, boolean, dates, arrays, objects -Return -1 if a < b, 1 if a > b and 0 if a = b (note that equality here is NOT the same as defined in areThingsEqual!)

- -**Kind**: static method of [model](#module_model) -**Params** - -- a \* -- b \* -- [_compareStrings] [compareStrings](#compareStrings) -

String comparing function, returning -1, 0 or 1, overriding default string comparison (useful for languages with accented letters)

- - - -### model.modify(obj, updateQuery) ⇒ [document](#document) -

Modify a DB object according to an update query

- -**Kind**: static method of [model](#module_model) -**Params** - -- obj [document](#document) -- updateQuery [query](#query) - - - -### model.getDotValue(obj, field) ⇒ \* -

Get a value from object with dot notation

- -**Kind**: static method of [model](#module_model) -**Params** - -- obj object -- field string - - - -### model.areThingsEqual(a, a) ⇒ boolean -

Check whether 'things' are equal -Things are defined as any native types (string, number, boolean, null, date) and objects -In the case of object, we check deep equality -Returns true if they are, false otherwise

- -**Kind**: static method of [model](#module_model) -**Params** - -- a \* -- a \* - - - -### model.match(obj, query) ⇒ boolean -

Tell if a given document matches a query

- -**Kind**: static method of [model](#module_model) -**Params** - -- obj [document](#document) -

Document to check

-- query [query](#query) - - - -### model~modifierFunctions : enum -**Kind**: inner enum of [model](#module_model) -**Properties** - -| Name | Type | Default | Description | -| --- | --- | --- | --- | -| $set | modifierFunction | |

Set a field to a new value

| -| $unset | modifierFunction | |

Unset a field

| -| $min | modifierFunction | |

Updates the value of the field, only if specified field is smaller than the current value of the field

| -| $max | modifierFunction | |

Updates the value of the field, only if specified field is greater than the current value of the field

| -| $inc | modifierFunction | |

Increment a numeric field's value

| -| $pull | modifierFunction | |

Removes all instances of a value from an existing array

| -| $pop | modifierFunction | |

Remove the first or last element of an array

| -| $addToSet | modifierFunction | |

Add an element to an array field only if it is not already in it No modification if the element is already in the array Note that it doesn't check whether the original array contains duplicates

| -| $push | modifierFunction | |

Push an element to the end of an array field Optional modifier $each instead of value to push several values Optional modifier $slice to slice the resulting array, see https://docs.mongodb.org/manual/reference/operator/update/slice/ Difference with MongoDB: if $slice is specified and not $each, we act as if value is an empty array

| - - - -### model~comparisonFunctions : enum -**Kind**: inner enum of [model](#module_model) -**Properties** - -| Name | Type | Default | Description | -| --- | --- | --- | --- | -| $lt | comparisonOperator | |

Lower than

| -| $lte | comparisonOperator | |

Lower than or equals

| -| $gt | comparisonOperator | |

Greater than

| -| $gte | comparisonOperator | |

Greater than or equals

| -| $ne | comparisonOperator | |

Does not equal

| -| $in | comparisonOperator | |

Is in Array

| -| $nin | comparisonOperator | |

Is not in Array

| -| $regex | comparisonOperator | |

Matches Regexp

| -| $exists | comparisonOperator | |

Returns true if field exists

| -| $size | comparisonOperator | |

Specific to Arrays, returns true if a length equals b

| -| $elemMatch | comparisonOperator | |

Specific to Arrays, returns true if some elements of a match the query b

| - - - -### model~logicalOperators -**Kind**: inner enum of [model](#module_model) -**Properties** - -| Name | Default | Description | -| --- | --- | --- | -| $or | |

Match any of the subqueries

| -| $and | |

Match all of the subqueries

| -| $not | |

Inverted match of the query

| -| $where | |

Use a function to match

| - - - -### model~modifierFunction : function -**Kind**: inner typedef of [model](#module_model) -**Params** - -- obj Object -

The model to modify

-- field String -

Can contain dots, in that case that means we will set a subfield recursively

-- value [document](#document) - - - -### model~comparisonOperator ⇒ boolean -**Kind**: inner typedef of [model](#module_model) -**Params** - -- a \* -

Value in the object

-- b \* -

Value in the query

- - - -### model~whereCallback ⇒ boolean -**Kind**: inner typedef of [model](#module_model) -**Params** - -- obj [document](#document) - diff --git a/docs/storage.md b/docs/storage.md deleted file mode 100644 index 86d9525..0000000 --- a/docs/storage.md +++ /dev/null @@ -1,360 +0,0 @@ - - -## storage -

Way data is stored for this database. -This version is the Node.js/Node Webkit version. -It's essentially fs, mkdirp and crash safe write and read functions.

- -**See** - -- module:storageBrowser -- module:storageReactNative - - -* [storage](#module_storage) - * _static_ - * [.exists(file, cb)](#module_storage.exists) - * [.existsAsync(file)](#module_storage.existsAsync) ⇒ Promise.<boolean> - * [.rename(oldPath, newPath, c)](#module_storage.rename) ⇒ void - * [.renameAsync(oldPath, newPath)](#module_storage.renameAsync) ⇒ Promise.<void> - * [.writeFile(path, data, options, callback)](#module_storage.writeFile) - * [.writeFileAsync(path, data, [options])](#module_storage.writeFileAsync) ⇒ Promise.<void> - * [.writeFileStream(path, [options])](#module_storage.writeFileStream) ⇒ fs.WriteStream - * [.unlink(path, callback)](#module_storage.unlink) - * [.unlinkAsync(path)](#module_storage.unlinkAsync) ⇒ Promise.<void> - * [.appendFile(path, data, options, callback)](#module_storage.appendFile) - * [.appendFileAsync(path, data, [options])](#module_storage.appendFileAsync) ⇒ Promise.<void> - * [.readFile(path, options, callback)](#module_storage.readFile) - * [.readFileAsync(path, [options])](#module_storage.readFileAsync) ⇒ Promise.<Buffer> - * [.readFileStream(path, [options])](#module_storage.readFileStream) ⇒ fs.ReadStream - * [.mkdir(path, options, callback)](#module_storage.mkdir) - * [.mkdirAsync(path, options)](#module_storage.mkdirAsync) ⇒ Promise.<(void\|string)> - * [.ensureFileDoesntExistAsync(file)](#module_storage.ensureFileDoesntExistAsync) ⇒ Promise.<void> - * [.ensureFileDoesntExist(file, callback)](#module_storage.ensureFileDoesntExist) - * [.flushToStorage(options, callback)](#module_storage.flushToStorage) - * [.flushToStorageAsync(options)](#module_storage.flushToStorageAsync) ⇒ Promise.<void> - * [.writeFileLines(filename, lines, [callback])](#module_storage.writeFileLines) - * [.writeFileLinesAsync(filename, lines)](#module_storage.writeFileLinesAsync) ⇒ Promise.<void> - * [.crashSafeWriteFileLines(filename, lines, [callback])](#module_storage.crashSafeWriteFileLines) - * [.crashSafeWriteFileLinesAsync(filename, lines)](#module_storage.crashSafeWriteFileLinesAsync) ⇒ Promise.<void> - * [.ensureDatafileIntegrity(filename, callback)](#module_storage.ensureDatafileIntegrity) - * [.ensureDatafileIntegrityAsync(filename)](#module_storage.ensureDatafileIntegrityAsync) ⇒ Promise.<void> - * _inner_ - * [~existsCallback](#module_storage..existsCallback) : function - - - -### storage.exists(file, cb) -

Callback returns true if file exists.

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- file string -- cb [existsCallback](#module_storage..existsCallback) - - - -### storage.existsAsync(file) ⇒ Promise.<boolean> -

Async version of [exists](#module_storage.exists).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.exists -**Params** - -- file string - - - -### storage.rename(oldPath, newPath, c) ⇒ void -

Node.js' [fs.rename](https://nodejs.org/api/fs.html#fsrenameoldpath-newpath-callback).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- oldPath string -- newPath string -- c [NoParamCallback](#NoParamCallback) - - - -### storage.renameAsync(oldPath, newPath) ⇒ Promise.<void> -

Async version of [rename](#module_storage.rename).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.rename -**Params** - -- oldPath string -- newPath string - - - -### storage.writeFile(path, data, options, callback) -

Node.js' [fs.writeFile](https://nodejs.org/api/fs.html#fswritefilefile-data-options-callback).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- path string -- data string -- options object -- callback function - - - -### storage.writeFileAsync(path, data, [options]) ⇒ Promise.<void> -

Async version of [writeFile](#module_storage.writeFile).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.writeFile -**Params** - -- path string -- data string -- [options] object - - - -### storage.writeFileStream(path, [options]) ⇒ fs.WriteStream -

Node.js' [fs.createWriteStream](https://nodejs.org/api/fs.html#fscreatewritestreampath-options).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- path string -- [options] Object - - - -### storage.unlink(path, callback) -

Node.js' [fs.unlink](https://nodejs.org/api/fs.html#fsunlinkpath-callback).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- path string -- callback function - - - -### storage.unlinkAsync(path) ⇒ Promise.<void> -

Async version of [unlink](#module_storage.unlink).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.unlink -**Params** - -- path string - - - -### storage.appendFile(path, data, options, callback) -

Node.js' [fs.appendFile](https://nodejs.org/api/fs.html#fsappendfilepath-data-options-callback).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- path string -- data string -- options object -- callback function - - - -### storage.appendFileAsync(path, data, [options]) ⇒ Promise.<void> -

Async version of [appendFile](#module_storage.appendFile).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.appendFile -**Params** - -- path string -- data string -- [options] object - - - -### storage.readFile(path, options, callback) -

Node.js' [fs.readFile](https://nodejs.org/api/fs.html#fsreadfilepath-options-callback)

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- path string -- options object -- callback function - - - -### storage.readFileAsync(path, [options]) ⇒ Promise.<Buffer> -

Async version of [readFile](#module_storage.readFile).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.readFile -**Params** - -- path string -- [options] object - - - -### storage.readFileStream(path, [options]) ⇒ fs.ReadStream -

Node.js' [fs.createReadStream](https://nodejs.org/api/fs.html#fscreatereadstreampath-options).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- path string -- [options] Object - - - -### storage.mkdir(path, options, callback) -

Node.js' [fs.mkdir](https://nodejs.org/api/fs.html#fsmkdirpath-options-callback).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- path string -- options object -- callback function - - - -### storage.mkdirAsync(path, options) ⇒ Promise.<(void\|string)> -

Async version of [mkdir](#module_storage.mkdir).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.mkdir -**Params** - -- path string -- options object - - - -### storage.ensureFileDoesntExistAsync(file) ⇒ Promise.<void> -

Async version of [ensureFileDoesntExist](#module_storage.ensureFileDoesntExist)

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.ensureFileDoesntExist -**Params** - -- file string - - - -### storage.ensureFileDoesntExist(file, callback) -

Removes file if it exists.

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- file string -- callback [NoParamCallback](#NoParamCallback) - - - -### storage.flushToStorage(options, callback) -

Flush data in OS buffer to storage if corresponding option is set.

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- options object | string -

If options is a string, it is assumed that the flush of the file (not dir) called options was requested

- - [.filename] string - - [.isDir] boolean = false -

Optional, defaults to false

-- callback [NoParamCallback](#NoParamCallback) - - - -### storage.flushToStorageAsync(options) ⇒ Promise.<void> -

Async version of [flushToStorage](#module_storage.flushToStorage).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.flushToStorage -**Params** - -- options object | string - - [.filename] string - - [.isDir] boolean = false - - - -### storage.writeFileLines(filename, lines, [callback]) -

Fully write or rewrite the datafile.

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- filename string -- lines Array.<string> -- [callback] [NoParamCallback](#NoParamCallback) = () => {} - - - -### storage.writeFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Async version of [writeFileLines](#module_storage.writeFileLines).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.writeFileLines -**Params** - -- filename string -- lines Array.<string> - - - -### storage.crashSafeWriteFileLines(filename, lines, [callback]) -

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost).

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- filename string -- lines Array.<string> -- [callback] [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

- - - -### storage.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Async version of [crashSafeWriteFileLines](#module_storage.crashSafeWriteFileLines).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.crashSafeWriteFileLines -**Params** - -- filename string -- lines Array.<string> - - - -### storage.ensureDatafileIntegrity(filename, callback) -

Ensure the datafile contains all the data, even if there was a crash during a full file write.

- -**Kind**: static method of [storage](#module_storage) -**Params** - -- filename string -- callback [NoParamCallback](#NoParamCallback) -

signature: err

- - - -### storage.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> -

Async version of [ensureDatafileIntegrity](#module_storage.ensureDatafileIntegrity).

- -**Kind**: static method of [storage](#module_storage) -**See**: module:storage.ensureDatafileIntegrity -**Params** - -- filename string - - - -### storage~existsCallback : function -**Kind**: inner typedef of [storage](#module_storage) -**Params** - -- exists boolean - diff --git a/docs/storageBrowser.md b/docs/storageBrowser.md deleted file mode 100644 index 343cdfe..0000000 --- a/docs/storageBrowser.md +++ /dev/null @@ -1,256 +0,0 @@ - - -## storageBrowser -

Way data is stored for this database

-

This version is the browser version and uses [localforage](https://github.com/localForage/localForage) which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage).

- -**See** - -- module:storage -- module:storageReactNative - - -* [storageBrowser](#module_storageBrowser) - * _static_ - * [.existsAsync(file)](#module_storageBrowser.existsAsync) ⇒ Promise.<boolean> - * [.exists(file, cb)](#module_storageBrowser.exists) - * [.renameAsync(oldPath, newPath)](#module_storageBrowser.renameAsync) ⇒ Promise.<void> - * [.rename(oldPath, newPath, c)](#module_storageBrowser.rename) ⇒ void - * [.writeFileAsync(file, data, [options])](#module_storageBrowser.writeFileAsync) ⇒ Promise.<void> - * [.writeFile(path, data, options, callback)](#module_storageBrowser.writeFile) - * [.appendFileAsync(filename, toAppend, [options])](#module_storageBrowser.appendFileAsync) ⇒ Promise.<void> - * [.appendFile(filename, toAppend, [options], callback)](#module_storageBrowser.appendFile) - * [.readFileAsync(filename, [options])](#module_storageBrowser.readFileAsync) ⇒ Promise.<Buffer> - * [.readFile(filename, options, callback)](#module_storageBrowser.readFile) - * [.unlinkAsync(filename)](#module_storageBrowser.unlinkAsync) ⇒ Promise.<void> - * [.unlink(path, callback)](#module_storageBrowser.unlink) - * [.mkdirAsync(path, [options])](#module_storageBrowser.mkdirAsync) ⇒ Promise.<(void\|string)> - * [.mkdir(path, options, callback)](#module_storageBrowser.mkdir) - * [.ensureDatafileIntegrityAsync(filename)](#module_storageBrowser.ensureDatafileIntegrityAsync) ⇒ Promise.<void> - * [.ensureDatafileIntegrity(filename, callback)](#module_storageBrowser.ensureDatafileIntegrity) - * [.crashSafeWriteFileLinesAsync(filename, lines)](#module_storageBrowser.crashSafeWriteFileLinesAsync) ⇒ Promise.<void> - * [.crashSafeWriteFileLines(filename, lines, [callback])](#module_storageBrowser.crashSafeWriteFileLines) - * _inner_ - * [~existsCallback](#module_storageBrowser..existsCallback) : function - - - -### storageBrowser.existsAsync(file) ⇒ Promise.<boolean> -

Returns Promise if file exists.

-

Async version of [exists](#module_storageBrowser.exists).

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**See**: module:storageBrowser.exists -**Params** - -- file string - - - -### storageBrowser.exists(file, cb) -

Callback returns true if file exists.

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- file string -- cb [existsCallback](#module_storageBrowser..existsCallback) - - - -### storageBrowser.renameAsync(oldPath, newPath) ⇒ Promise.<void> -

Async version of [rename](#module_storageBrowser.rename).

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**See**: module:storageBrowser.rename -**Params** - -- oldPath string -- newPath string - - - -### storageBrowser.rename(oldPath, newPath, c) ⇒ void -

Moves the item from one path to another

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- oldPath string -- newPath string -- c [NoParamCallback](#NoParamCallback) - - - -### storageBrowser.writeFileAsync(file, data, [options]) ⇒ Promise.<void> -

Async version of [writeFile](#module_storageBrowser.writeFile).

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**See**: module:storageBrowser.writeFile -**Params** - -- file string -- data string -- [options] object - - - -### storageBrowser.writeFile(path, data, options, callback) -

Saves the item at given path

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- path string -- data string -- options object -- callback function - - - -### storageBrowser.appendFileAsync(filename, toAppend, [options]) ⇒ Promise.<void> -

Async version of [appendFile](#module_storageBrowser.appendFile).

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**See**: module:storageBrowser.appendFile -**Params** - -- filename string -- toAppend string -- [options] object - - - -### storageBrowser.appendFile(filename, toAppend, [options], callback) -

Append to the item at given path

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- filename string -- toAppend string -- [options] object -- callback function - - - -### storageBrowser.readFileAsync(filename, [options]) ⇒ Promise.<Buffer> -

Async version of [readFile](#module_storageBrowser.readFile).

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**See**: module:storageBrowser.readFile -**Params** - -- filename string -- [options] object - - - -### storageBrowser.readFile(filename, options, callback) -

Read data at given path

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- filename string -- options object -- callback function - - - -### storageBrowser.unlinkAsync(filename) ⇒ Promise.<void> -

Async version of [unlink](#module_storageBrowser.unlink).

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**See**: module:storageBrowser.unlink -**Params** - -- filename string - - - -### storageBrowser.unlink(path, callback) -

Remove the data at given path

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- path string -- callback function - - - -### storageBrowser.mkdirAsync(path, [options]) ⇒ Promise.<(void\|string)> -

Shim for [mkdirAsync](#module_storage.mkdirAsync), nothing to do, no directories will be used on the browser.

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- path string -- [options] object - - - -### storageBrowser.mkdir(path, options, callback) -

Shim for [mkdir](#module_storage.mkdir), nothing to do, no directories will be used on the browser.

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- path string -- options object -- callback function - - - -### storageBrowser.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> -

Shim for [ensureDatafileIntegrityAsync](#module_storage.ensureDatafileIntegrityAsync), nothing to do, no data corruption possible in the browser.

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- filename string - - - -### storageBrowser.ensureDatafileIntegrity(filename, callback) -

Shim for [ensureDatafileIntegrity](#module_storage.ensureDatafileIntegrity), nothing to do, no data corruption possible in the browser.

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- filename string -- callback [NoParamCallback](#NoParamCallback) -

signature: err

- - - -### storageBrowser.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Async version of [crashSafeWriteFileLines](#module_storageBrowser.crashSafeWriteFileLines).

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**See**: module:storageBrowser.crashSafeWriteFileLines -**Params** - -- filename string -- lines Array.<string> - - - -### storageBrowser.crashSafeWriteFileLines(filename, lines, [callback]) -

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

- -**Kind**: static method of [storageBrowser](#module_storageBrowser) -**Params** - -- filename string -- lines Array.<string> -- [callback] [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

- - - -### storageBrowser~existsCallback : function -**Kind**: inner typedef of [storageBrowser](#module_storageBrowser) -**Params** - -- exists boolean - diff --git a/docs/storageReactNative.md b/docs/storageReactNative.md deleted file mode 100644 index 68dc403..0000000 --- a/docs/storageReactNative.md +++ /dev/null @@ -1,255 +0,0 @@ - - -## storageReactNative -

Way data is stored for this database

-

This version is the React-Native version and uses [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage).

- -**See** - -- module:storageBrowser -- module:storageReactNative - - -* [storageReactNative](#module_storageReactNative) - * _static_ - * [.existsAsync(file)](#module_storageReactNative.existsAsync) ⇒ Promise.<boolean> - * [.exists(file, cb)](#module_storageReactNative.exists) - * [.renameAsync(oldPath, newPath)](#module_storageReactNative.renameAsync) ⇒ Promise.<void> - * [.rename(oldPath, newPath, c)](#module_storageReactNative.rename) ⇒ void - * [.writeFileAsync(file, data, [options])](#module_storageReactNative.writeFileAsync) ⇒ Promise.<void> - * [.writeFile(path, data, options, callback)](#module_storageReactNative.writeFile) - * [.appendFileAsync(filename, toAppend, [options])](#module_storageReactNative.appendFileAsync) ⇒ Promise.<void> - * [.appendFile(filename, toAppend, [options], callback)](#module_storageReactNative.appendFile) - * [.readFileAsync(filename, [options])](#module_storageReactNative.readFileAsync) ⇒ Promise.<string> - * [.readFile(filename, options, callback)](#module_storageReactNative.readFile) - * [.unlinkAsync(filename)](#module_storageReactNative.unlinkAsync) ⇒ Promise.<void> - * [.unlink(path, callback)](#module_storageReactNative.unlink) - * [.mkdirAsync(dir, [options])](#module_storageReactNative.mkdirAsync) ⇒ Promise.<(void\|string)> - * [.mkdir(path, options, callback)](#module_storageReactNative.mkdir) - * [.ensureDatafileIntegrityAsync(filename)](#module_storageReactNative.ensureDatafileIntegrityAsync) ⇒ Promise.<void> - * [.ensureDatafileIntegrity(filename, callback)](#module_storageReactNative.ensureDatafileIntegrity) - * [.crashSafeWriteFileLinesAsync(filename, lines)](#module_storageReactNative.crashSafeWriteFileLinesAsync) ⇒ Promise.<void> - * [.crashSafeWriteFileLines(filename, lines, [callback])](#module_storageReactNative.crashSafeWriteFileLines) - * _inner_ - * [~existsCallback](#module_storageReactNative..existsCallback) : function - - - -### storageReactNative.existsAsync(file) ⇒ Promise.<boolean> -

Async version of [exists](#module_storageReactNative.exists).

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**See**: module:storageReactNative.exists -**Params** - -- file string - - - -### storageReactNative.exists(file, cb) -

Callback returns true if file exists

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- file string -- cb [existsCallback](#module_storageReactNative..existsCallback) - - - -### storageReactNative.renameAsync(oldPath, newPath) ⇒ Promise.<void> -

Async version of [rename](#module_storageReactNative.rename).

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**See**: module:storageReactNative.rename -**Params** - -- oldPath string -- newPath string - - - -### storageReactNative.rename(oldPath, newPath, c) ⇒ void -

Moves the item from one path to another

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- oldPath string -- newPath string -- c [NoParamCallback](#NoParamCallback) - - - -### storageReactNative.writeFileAsync(file, data, [options]) ⇒ Promise.<void> -

Async version of [writeFile](#module_storageReactNative.writeFile).

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**See**: module:storageReactNative.writeFile -**Params** - -- file string -- data string -- [options] object - - - -### storageReactNative.writeFile(path, data, options, callback) -

Saves the item at given path

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- path string -- data string -- options object -- callback function - - - -### storageReactNative.appendFileAsync(filename, toAppend, [options]) ⇒ Promise.<void> -

Async version of [appendFile](#module_storageReactNative.appendFile).

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**See**: module:storageReactNative.appendFile -**Params** - -- filename string -- toAppend string -- [options] object - - - -### storageReactNative.appendFile(filename, toAppend, [options], callback) -

Append to the item at given path

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- filename string -- toAppend string -- [options] object -- callback function - - - -### storageReactNative.readFileAsync(filename, [options]) ⇒ Promise.<string> -

Async version of [readFile](#module_storageReactNative.readFile).

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**See**: module:storageReactNative.readFile -**Params** - -- filename string -- [options] object - - - -### storageReactNative.readFile(filename, options, callback) -

Read data at given path

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- filename string -- options object -- callback function - - - -### storageReactNative.unlinkAsync(filename) ⇒ Promise.<void> -

Async version of [unlink](#module_storageReactNative.unlink).

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**See**: module:storageReactNative.unlink -**Params** - -- filename string - - - -### storageReactNative.unlink(path, callback) -

Remove the data at given path

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- path string -- callback function - - - -### storageReactNative.mkdirAsync(dir, [options]) ⇒ Promise.<(void\|string)> -

Shim for [mkdirAsync](#module_storage.mkdirAsync), nothing to do, no directories will be used on the browser.

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- dir string -- [options] object - - - -### storageReactNative.mkdir(path, options, callback) -

Shim for [mkdir](#module_storage.mkdir), nothing to do, no directories will be used on the browser.

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- path string -- options object -- callback function - - - -### storageReactNative.ensureDatafileIntegrityAsync(filename) ⇒ Promise.<void> -

Shim for [ensureDatafileIntegrityAsync](#module_storage.ensureDatafileIntegrityAsync), nothing to do, no data corruption possible in the browser.

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- filename string - - - -### storageReactNative.ensureDatafileIntegrity(filename, callback) -

Shim for [ensureDatafileIntegrity](#module_storage.ensureDatafileIntegrity), nothing to do, no data corruption possible in the browser.

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- filename string -- callback [NoParamCallback](#NoParamCallback) -

signature: err

- - - -### storageReactNative.crashSafeWriteFileLinesAsync(filename, lines) ⇒ Promise.<void> -

Async version of [crashSafeWriteFileLines](#module_storageReactNative.crashSafeWriteFileLines).

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**See**: module:storageReactNative.crashSafeWriteFileLines -**Params** - -- filename string -- lines Array.<string> - - - -### storageReactNative.crashSafeWriteFileLines(filename, lines, [callback]) -

Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost)

- -**Kind**: static method of [storageReactNative](#module_storageReactNative) -**Params** - -- filename string -- lines Array.<string> -- [callback] [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

- - - -### storageReactNative~existsCallback : function -**Kind**: inner typedef of [storageReactNative](#module_storageReactNative) -**Params** - -- exists boolean - diff --git a/docs/utils.md b/docs/utils.md deleted file mode 100644 index c04794b..0000000 --- a/docs/utils.md +++ /dev/null @@ -1,64 +0,0 @@ - - -## utils -

Utility functions for all environments. -This replaces the underscore dependency.

- - -* [utils](#module_utils) - * _static_ - * [.uniq(array, [iteratee])](#module_utils.uniq) ⇒ Array - * [.isDate(d)](#module_utils.isDate) ⇒ boolean - * [.isRegExp(re)](#module_utils.isRegExp) ⇒ boolean - * _inner_ - * [~isObject(arg)](#module_utils..isObject) ⇒ boolean - - - -### utils.uniq(array, [iteratee]) ⇒ Array -

Produces a duplicate-free version of the array, using === to test object equality. In particular only the first -occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee -function.

-

Heavily inspired by [https://underscorejs.org/#uniq](https://underscorejs.org/#uniq).

- -**Kind**: static method of [utils](#module_utils) -**Params** - -- array Array -- [iteratee] function -

transformation applied to every element before checking for duplicates. This will not -transform the items in the result.

- - - -### utils.isDate(d) ⇒ boolean -

Returns true if d is a Date.

-

Heavily inspired by [https://underscorejs.org/#isDate](https://underscorejs.org/#isDate).

- -**Kind**: static method of [utils](#module_utils) -**Params** - -- d \* - - - -### utils.isRegExp(re) ⇒ boolean -

Returns true if re is a RegExp.

-

Heavily inspired by [https://underscorejs.org/#isRegExp](https://underscorejs.org/#isRegExp).

- -**Kind**: static method of [utils](#module_utils) -**Params** - -- re \* - - - -### utils~isObject(arg) ⇒ boolean -

Returns true if arg is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings -and numbers are not.

-

Heavily inspired by [https://underscorejs.org/#isObject](https://underscorejs.org/#isObject).

- -**Kind**: inner method of [utils](#module_utils) -**Params** - -- arg \* - diff --git a/jsdoc2md.js b/jsdoc2md.js deleted file mode 100644 index 0cf2085..0000000 --- a/jsdoc2md.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict' -const jsdoc2md = require('jsdoc-to-markdown') -const fs = require('fs') -const path = require('path') - -const jsdocConf = './jsdoc.conf.js' - -/* output path */ -const outputDir = './docs' - -const getJsdocDataOptions = { - /* same input path as jsdoc */ - files: require(jsdocConf).source.include, - configure: jsdocConf, - 'no-cache': true -} - -const renderOptions = { - 'param-list-format': 'list' -} - -fs.rmdirSync(outputDir, { recursive: true }) // clean docs dir -fs.mkdirSync(outputDir) // make docs dir - -/* get template data */ -const templateData = jsdoc2md.getTemplateDataSync(getJsdocDataOptions) - -/* reduce templateData to an array of class names */ -const classNames = templateData - .filter(({ kind, access }) => kind === 'class' && access !== 'private') - .map(({ name }) => name) - .filter(name => name !== 'LineStream') // it is a module that exports a class, dirty hack to hardcode this, but it works - -const moduleNames = templateData - .filter(({ kind, access }) => kind === 'module' && access !== 'private') - .map(({ name }) => name) - -const rest = templateData - .filter(({ name }) => !moduleNames.includes(name) && !classNames.includes(name)) - .filter(({ scope, access }) => scope === 'global' && access !== 'private') - .map(({ id }) => id) - -/* create a documentation file for each class */ -for (const className of classNames) { - const template = `{{#class name="${className}"}}{{>docs}}{{/class}}` - console.log(`rendering ${className}, template: ${template}`) - const output = jsdoc2md.renderSync({ ...renderOptions, data: templateData, template: template }) - fs.writeFileSync(path.resolve(outputDir, `${className}.md`), output) -} - -/* create a documentation file for each module */ -for (const moduleName of moduleNames) { - const template = `{{#module name="${moduleName}"}}{{>docs}}{{/module}}` - console.log(`rendering ${moduleName}, template: ${template}`) - const output = jsdoc2md.renderSync({ ...renderOptions, data: templateData, template: template }) - fs.writeFileSync(path.resolve(outputDir, `${moduleName}.md`), output) -} - -let template = '' -for (const id of rest) { - template += `{{#identifier name="${id}"}}{{>docs}}{{/identifier}}\n` -} -console.log(`rendering globals, template: ${template}`) -const output = jsdoc2md.renderSync({ ...renderOptions, data: templateData, template: template }) -fs.writeFileSync(path.resolve(outputDir, 'globals.md'), output) - -// TODO rewrite links between files diff --git a/lib/cursor.js b/lib/cursor.js index 87a583c..dfe32f3 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -247,4 +247,7 @@ class Cursor { } // Interface +/** + * @type {Cursor} + */ module.exports = Cursor diff --git a/lib/datastore.js b/lib/datastore.js index 36e9f81..bea4c7d 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -13,7 +13,7 @@ const { isDate } = require('./utils.js') // TODO: check the classes and modules which need to be included int he documentation // TODO: replace examples of the Readme with @example JSDoc tags // TODO: update changelog - +// TODO: dropDatabase callback + tests /** * Callback with no parameter * @callback NoParamCallback @@ -140,8 +140,16 @@ const { isDate } = require('./utils.js') */ /** - * The `Datastore` class is the main class of NeDB. - * @extends EventEmitter + * @external EventEmitter + * @see http://nodejs.org/api/events.html + */ + +/** + * @class + * @classdesc The `Datastore` class is the main class of NeDB. + * @extends external:EventEmitter + * @emits Datastore#event:"compaction.done" + * @typicalname NeDB */ class Datastore extends EventEmitter { /** @@ -188,8 +196,6 @@ class Datastore extends EventEmitter { * @param {compareStrings} [options.compareStrings] If specified, it overrides default string comparison which is not * well adapted to non-US characters in particular accented letters. Native `localCompare` will most of the time be * the right choice. - * - * @fires Datastore#event:"compaction.done" */ constructor (options) { super() diff --git a/package.json b/package.json index 83d6d40..8e43458 100755 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "test:react-native": "jest test/react-native", "test:typings": "ts-node ./typings-tests.ts", "prepublishOnly": "npm run build:browser", - "generateDocs:markdown": "node jsdoc2md.js", + "generateDocs:markdown": "jsdoc2md --no-cache -c jsdoc.conf.js --param-list-format list --files . > API.md", "generateDocs:html": "jsdoc -c jsdoc.conf.js -d docs-html --readme README.md" }, "main": "index.js", From 8b776b5c45761cb84e86d69a225e7c8d0cf52011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Sun, 16 Jan 2022 18:06:41 +0100 Subject: [PATCH 47/65] remove todos --- lib/datastore.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index bea4c7d..5823f6e 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -9,9 +9,6 @@ const Persistence = require('./persistence.js') const { isDate } = require('./utils.js') // TODO: have one version of the documentation for each function -// TODO: remove jsdoc2md file that generates a docs/ directory, and replace it with something that generates the README -// TODO: check the classes and modules which need to be included int he documentation -// TODO: replace examples of the Readme with @example JSDoc tags // TODO: update changelog // TODO: dropDatabase callback + tests /** From dbcc3647d12f9bf9fc8dc7a6d5adbab219f9dcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 17 Jan 2022 15:30:37 +0100 Subject: [PATCH 48/65] repair race condition in tests + improve docs --- API.md | 109 ++++++++++++++---------- lib/cursor.js | 3 - lib/datastore.js | 104 ++++++++++++----------- lib/storage.js | 6 +- test/persistence.async.test.js | 84 ++++++++++++------- test/persistence.test.js | 2 + test_lac/loadAndCrash.test.js | 148 +++++++++------------------------ test_lac/openFds.test.js | 110 ++++++++++++------------ 8 files changed, 268 insertions(+), 298 deletions(-) diff --git a/API.md b/API.md index 49bdc55..d99c5b0 100644 --- a/API.md +++ b/API.md @@ -258,14 +258,15 @@ Will return pointers to matched elements (shallow copies), returning full copies * [.ttlIndexes](#Datastore+ttlIndexes) : Object.<string, number> * [.autoloadPromise](#Datastore+autoloadPromise) : Promise * [.compareStrings()](#Datastore+compareStrings) : [compareStrings](#compareStrings) - * [.loadDatabase(callback)](#Datastore+loadDatabase) + * [.loadDatabase([callback])](#Datastore+loadDatabase) * [.loadDatabaseAsync()](#Datastore+loadDatabaseAsync) ⇒ Promise * [.getAllData()](#Datastore+getAllData) ⇒ [Array.<document>](#document) - * [.ensureIndex(options, callback)](#Datastore+ensureIndex) + * [.ensureIndex(options, [callback])](#Datastore+ensureIndex) * [.ensureIndexAsync(options)](#Datastore+ensureIndexAsync) ⇒ Promise.<void> * [.removeIndex(fieldName, callback)](#Datastore+removeIndex) * [.removeIndexAsync(fieldName)](#Datastore+removeIndexAsync) ⇒ Promise.<void> - * [.insertAsync(newDoc)](#Datastore+insertAsync) ⇒ [Promise.<document>](#document) + * [.insert(newDoc, [callback])](#Datastore+insert) + * [.insertAsync(newDoc)](#Datastore+insertAsync) ⇒ Promise.<(document\|Array.<document>)> * [.count(query, [callback])](#Datastore+count) ⇒ Cursor.<number> \| undefined * [.countAsync(query)](#Datastore+countAsync) ⇒ Cursor.<number> * [.find(query, [projection], [callback])](#Datastore+find) ⇒ Cursor.<Array.<document>> \| undefined @@ -408,21 +409,21 @@ letters. Native localCompare will most of the time be the right cho **Access**: protected -### neDB.loadDatabase(callback) -

Load the database from the datafile, and trigger the execution of buffered commands if any.

+### neDB.loadDatabase([callback]) +

Callback version of [loadDatabaseAsync](#Datastore+loadDatabaseAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#loadDatabaseAsync **Params** -- callback [NoParamCallback](#NoParamCallback) +- [callback] [NoParamCallback](#NoParamCallback) ### neDB.loadDatabaseAsync() ⇒ Promise -

Async version of [loadDatabase](#Datastore+loadDatabase).

+

Load the database from the datafile, and trigger the execution of buffered commands if any.

**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#loadDatabase ### neDB.getAllData() ⇒ [Array.<document>](#document) @@ -431,36 +432,40 @@ letters. Native localCompare will most of the time be the right cho **Kind**: instance method of [Datastore](#Datastore) -### neDB.ensureIndex(options, callback) -

Ensure an index is kept for this field. Same parameters as lib/indexes -This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the -executor. -Previous versions said explicitly the callback was optional, it is now recommended setting one.

+### neDB.ensureIndex(options, [callback]) +

Callback version of [ensureIndex](#Datastore+ensureIndex).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#ensureIndex **Params** - options object - - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

- - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

- - [.sparse] boolean = false -

don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

- - [.expireAfterSeconds] number -

if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

-- callback [NoParamCallback](#NoParamCallback) -

Callback, signature: err

+ - .fieldName string + - [.unique] boolean = false + - [.sparse] boolean = false + - [.expireAfterSeconds] number +- [callback] [NoParamCallback](#NoParamCallback) ### neDB.ensureIndexAsync(options) ⇒ Promise.<void> -

Async version of [ensureIndex](#Datastore+ensureIndex).

+

Ensure an index is kept for this field. Same parameters as lib/indexes +This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the +executor.

**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#ensureIndex **Params** - options object - - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested document.

- - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.

- - [.sparse] boolean = false -

Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.

- - [.expireAfterSeconds] number -

If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored

+ - .fieldName string -

Name of the field to index. Use the dot notation to index a field in a nested +document.

+ - [.unique] boolean = false -

Enforce field uniqueness. Note that a unique index will raise an error +if you try to index two documents for which the field is not defined.

+ - [.sparse] boolean = false -

Don't index documents for which the field is not defined. Use this option +along with "unique" if you want to accept multiple documents for which it is not defined.

+ - [.expireAfterSeconds] number -

If set, the created index is a TTL (time to live) index, that will +automatically remove documents when the system date becomes larger than the date on the indexed field plus +expireAfterSeconds. Documents where the indexed field is not specified or not a Date object are ignored.

@@ -487,31 +492,45 @@ field in a nested document.

- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a field in a nested document.

- + -### neDB.insertAsync(newDoc) ⇒ [Promise.<document>](#document) -

Async version of [Datastore#insert](Datastore#insert).

+### neDB.insert(newDoc, [callback]) +

Callback version of [insertAsync](#Datastore+insertAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#insertAsync **Params** - newDoc [document](#document) | [Array.<document>](#document) +- [callback] [SingleDocumentCallback](#SingleDocumentCallback) | [MultipleDocumentsCallback](#MultipleDocumentsCallback) + + + +### neDB.insertAsync(newDoc) ⇒ Promise.<(document\|Array.<document>)> +

Insert a new document, or new documents.

+ +**Kind**: instance method of [Datastore](#Datastore) +**Returns**: Promise.<(document\|Array.<document>)> -

The document(s) inserted.

+**Params** + +- newDoc [document](#document) | [Array.<document>](#document) -

Document or array of documents to insert.

### neDB.count(query, [callback]) ⇒ Cursor.<number> \| undefined -

Count all documents matching the query.

+

Callback-version of [countAsync](#Datastore+countAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#countAsync **Params** -- query [query](#query) -

MongoDB-style query

-- [callback] [countCallback](#Datastore..countCallback) -

If given, the function will return undefined, otherwise it will return the Cursor.

+- query [query](#query) +- [callback] [countCallback](#Datastore..countCallback) ### neDB.countAsync(query) ⇒ Cursor.<number> -

Async version of [count](#Datastore+count).

+

Count all documents matching the query.

**Kind**: instance method of [Datastore](#Datastore) **Returns**: Cursor.<number> -

count

@@ -522,21 +541,22 @@ field in a nested document.

### neDB.find(query, [projection], [callback]) ⇒ Cursor.<Array.<document>> \| undefined -

Find all documents matching the query -If no callback is passed, we return the cursor so that user can limit, skip and finally exec

+

Callback version of [findAsync](#Datastore+findAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#findAsync **Params** -- query [query](#query) -

MongoDB-style query

-- [projection] [projection](#projection) | [MultipleDocumentsCallback](#MultipleDocumentsCallback) = {} -

MongoDB-style projection. If not given, will be -interpreted as the callback.

-- [callback] [MultipleDocumentsCallback](#MultipleDocumentsCallback) -

Optional callback, signature: err, docs

+- query [query](#query) +- [projection] [projection](#projection) | [MultipleDocumentsCallback](#MultipleDocumentsCallback) = {} +- [callback] [MultipleDocumentsCallback](#MultipleDocumentsCallback) ### neDB.findAsync(query, [projection]) ⇒ Cursor.<Array.<document>> -

Async version of [find](#Datastore+find).

+

Find all documents matching the query. +We return the [Cursor](#Cursor) that the user can either await directly or use to can [limit](#Cursor+limit) or +[skip](#Cursor+skip) before.

**Kind**: instance method of [Datastore](#Datastore) **Params** @@ -547,22 +567,23 @@ interpreted as the callback.

### neDB.findOne(query, [projection], [callback]) ⇒ [Cursor.<document>](#document) \| undefined -

Find one document matching the query.

+

Callback version of [findOneAsync](#Datastore+findOneAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#findOneAsync **Params** -- query [query](#query) -

MongoDB-style query

-- [projection] [projection](#projection) | [SingleDocumentCallback](#SingleDocumentCallback) = {} -

MongoDB-style projection

-- [callback] [SingleDocumentCallback](#SingleDocumentCallback) -

Optional callback, signature: err, doc

+- query [query](#query) +- [projection] [projection](#projection) | [SingleDocumentCallback](#SingleDocumentCallback) = {} +- [callback] [SingleDocumentCallback](#SingleDocumentCallback) ### neDB.findOneAsync(query, projection) ⇒ [Cursor.<document>](#document) -

Async version of [findOne](#Datastore+findOne).

+

Find one document matching the query. +We return the [Cursor](#Cursor) that the user can either await directly or use to can [skip](#Cursor+skip) before.

**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#findOne **Params** - query [query](#query) -

MongoDB-style query

diff --git a/lib/cursor.js b/lib/cursor.js index dfe32f3..87a583c 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -247,7 +247,4 @@ class Cursor { } // Interface -/** - * @type {Cursor} - */ module.exports = Cursor diff --git a/lib/datastore.js b/lib/datastore.js index 5823f6e..55052b5 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -313,19 +313,19 @@ class Datastore extends EventEmitter { } /** - * Load the database from the datafile, and trigger the execution of buffered commands if any. - * @param {NoParamCallback} callback + * Callback version of {@link Datastore#loadDatabaseAsync}. + * @param {NoParamCallback} [callback] + * @see Datastore#loadDatabaseAsync */ loadDatabase (callback) { - if (typeof callback !== 'function') callback = () => {} - callbackify(() => this.loadDatabaseAsync())(callback) + const promise = this.loadDatabaseAsync() + if (typeof callback === 'function') callbackify(() => promise)(callback) } /** - * Async version of {@link Datastore#loadDatabase}. + * Load the database from the datafile, and trigger the execution of buffered commands if any. * @async * @return {Promise} - * @see Datastore#loadDatabase */ loadDatabaseAsync () { return this.executor.pushAsync(() => this.persistence.loadDatabaseAsync(), true) @@ -351,31 +351,35 @@ class Datastore extends EventEmitter { } /** - * Ensure an index is kept for this field. Same parameters as lib/indexes - * This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the - * executor. - * Previous versions said explicitly the callback was optional, it is now recommended setting one. + * Callback version of {@link Datastore#ensureIndex}. * @param {object} options - * @param {string} options.fieldName Name of the field to index. Use the dot notation to index a field in a nested document. - * @param {boolean} [options.unique = false] Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined. - * @param {boolean} [options.sparse = false] don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined. - * @param {number} [options.expireAfterSeconds] - if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored - * @param {NoParamCallback} callback Callback, signature: err + * @param {string} options.fieldName + * @param {boolean} [options.unique = false] + * @param {boolean} [options.sparse = false] + * @param {number} [options.expireAfterSeconds] + * @param {NoParamCallback} [callback] + * @see Datastore#ensureIndex */ - ensureIndex (options = {}, callback = () => {}) { + ensureIndex (options = {}, callback) { const promise = this.ensureIndexAsync(options) // to make sure the synchronous part of ensureIndexAsync is executed synchronously - callbackify(() => promise)(callback) + if (typeof callback === 'function') callbackify(() => promise)(callback) } /** - * Async version of {@link Datastore#ensureIndex}. + * Ensure an index is kept for this field. Same parameters as lib/indexes + * This function acts synchronously on the indexes, however the persistence of the indexes is deferred with the + * executor. * @param {object} options - * @param {string} options.fieldName Name of the field to index. Use the dot notation to index a field in a nested document. - * @param {boolean} [options.unique = false] Enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined. - * @param {boolean} [options.sparse = false] Don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined. - * @param {number} [options.expireAfterSeconds] - If set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plus `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored + * @param {string} options.fieldName Name of the field to index. Use the dot notation to index a field in a nested + * document. + * @param {boolean} [options.unique = false] Enforce field uniqueness. Note that a unique index will raise an error + * if you try to index two documents for which the field is not defined. + * @param {boolean} [options.sparse = false] Don't index documents for which the field is not defined. Use this option + * along with "unique" if you want to accept multiple documents for which it is not defined. + * @param {number} [options.expireAfterSeconds] - If set, the created index is a TTL (time to live) index, that will + * automatically remove documents when the system date becomes larger than the date on the indexed field plus + * `expireAfterSeconds`. Documents where the indexed field is not specified or not a `Date` object are ignored. * @return {Promise} - * @see Datastore#ensureIndex */ async ensureIndexAsync (options = {}) { if (!options.fieldName) { @@ -676,21 +680,20 @@ class Datastore extends EventEmitter { } /** - * Insert a new document. + * Callback version of {@link Datastore#insertAsync}. * @param {document|document[]} newDoc - * @param {SingleDocumentCallback} [callback = () => {}] Optional callback, signature: err, insertedDoc - * - * @private + * @param {SingleDocumentCallback|MultipleDocumentsCallback} [callback] + * @see Datastore#insertAsync */ insert (newDoc, callback) { - if (typeof callback !== 'function') callback = () => {} - callbackify(doc => this.insertAsync(doc))(newDoc, callback) + const promise = this.insertAsync(newDoc) + if (typeof callback === 'function') callbackify(() => promise)(callback) } /** - * Async version of {@link Datastore#insert}. - * @param {document|document[]} newDoc - * @return {Promise} + * Insert a new document, or new documents. + * @param {document|document[]} newDoc Document or array of documents to insert. + * @return {Promise} The document(s) inserted. * @async */ insertAsync (newDoc) { @@ -704,10 +707,11 @@ class Datastore extends EventEmitter { */ /** - * Count all documents matching the query. - * @param {query} query MongoDB-style query - * @param {Datastore~countCallback} [callback] If given, the function will return undefined, otherwise it will return the Cursor. + * Callback-version of {@link Datastore#countAsync}. + * @param {query} query + * @param {Datastore~countCallback} [callback] * @return {Cursor|undefined} + * @see Datastore#countAsync */ count (query, callback) { const cursor = this.countAsync(query) @@ -717,7 +721,7 @@ class Datastore extends EventEmitter { } /** - * Async version of {@link Datastore#count}. + * Count all documents matching the query. * @param {query} query MongoDB-style query * @return {Cursor} count * @async @@ -727,13 +731,12 @@ class Datastore extends EventEmitter { } /** - * Find all documents matching the query - * If no callback is passed, we return the cursor so that user can limit, skip and finally exec - * @param {query} query MongoDB-style query - * @param {projection|MultipleDocumentsCallback} [projection = {}] MongoDB-style projection. If not given, will be - * interpreted as the callback. - * @param {MultipleDocumentsCallback} [callback] Optional callback, signature: err, docs + * Callback version of {@link Datastore#findAsync}. + * @param {query} query + * @param {projection|MultipleDocumentsCallback} [projection = {}] + * @param {MultipleDocumentsCallback} [callback] * @return {Cursor|undefined} + * @see Datastore#findAsync */ find (query, projection, callback) { if (arguments.length === 1) { @@ -753,7 +756,9 @@ class Datastore extends EventEmitter { } /** - * Async version of {@link Datastore#find}. + * Find all documents matching the query. + * We return the {@link Cursor} that the user can either `await` directly or use to can {@link Cursor#limit} or + * {@link Cursor#skip} before. * @param {query} query MongoDB-style query * @param {projection} [projection = {}] MongoDB-style projection * @return {Cursor} @@ -773,11 +778,12 @@ class Datastore extends EventEmitter { */ /** - * Find one document matching the query. - * @param {query} query MongoDB-style query - * @param {projection|SingleDocumentCallback} [projection = {}] MongoDB-style projection - * @param {SingleDocumentCallback} [callback] Optional callback, signature: err, doc + * Callback version of {@link Datastore#findOneAsync}. + * @param {query} query + * @param {projection|SingleDocumentCallback} [projection = {}] + * @param {SingleDocumentCallback} [callback] * @return {Cursor|undefined} + * @see Datastore#findOneAsync */ findOne (query, projection, callback) { if (arguments.length === 1) { @@ -797,11 +803,11 @@ class Datastore extends EventEmitter { } /** - * Async version of {@link Datastore#findOne}. + * Find one document matching the query. + * We return the {@link Cursor} that the user can either `await` directly or use to can {@link Cursor#skip} before. * @param {query} query MongoDB-style query * @param {projection} projection MongoDB-style projection * @return {Cursor} - * @see Datastore#findOne */ findOneAsync (query, projection = {}) { const cursor = new Cursor(this, query, docs => docs.length === 1 ? model.deepCopy(docs[0]) : null) diff --git a/lib/storage.js b/lib/storage.js index 1da3fd1..b6d72cc 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -205,13 +205,11 @@ const writeFileLinesAsync = (filename, lines) => new Promise((resolve, reject) = }) readable.on('error', err => { - if (err) reject(err) - else resolve() + reject(err) }) stream.on('error', err => { - if (err) reject(err) - else resolve() + reject(err) }) } catch (err) { reject(err) diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index 32e6399..1373648 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -824,39 +824,63 @@ describe('Persistence async', function () { const datafileLength = (await fs.readFile('workspace/lac.db', 'utf8')).length + assert(datafileLength > 5000) + // Loading it in a separate process that we will crash before finishing the loadDatabase - fork('test_lac/loadAndCrash.test').on('exit', async function (code) { - assert.equal(code, 1) // See test_lac/loadAndCrash.test.js - - assert.equal(await exists('workspace/lac.db'), true) - assert.equal(await exists('workspace/lac.db~'), true) - assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) - assert.equal((await fs.readFile('workspace/lac.db~', 'utf8')).length, 5000) - - // Reload database without a crash, check that no data was lost and fs state is clean (no temp file) - const db = new Datastore({ filename: 'workspace/lac.db' }) - await db.loadDatabaseAsync() - assert.equal(await exists('workspace/lac.db'), true) - assert.equal(await exists('workspace/lac.db~'), false) - assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) - - const docs = await db.findAsync({}) - assert.equal(docs.length, N) - for (i = 0; i < N; i += 1) { - docI = docs.find(d => d._id === 'anid_' + i) - assert.notEqual(docI, undefined) - assert.deepEqual({ hello: 'world', _id: 'anid_' + i }, docI) - } - }) + const child = fork('test_lac/loadAndCrash.test', [], { stdio: 'inherit' }) + + await Promise.race([ + new Promise((resolve, reject) => child.on('error', reject)), + new Promise((resolve, reject) => { + child.on('exit', async function (code) { + try { + assert.equal(code, 1) // See test_lac/loadAndCrash.test.js + + assert.equal(await exists('workspace/lac.db'), true) + assert.equal(await exists('workspace/lac.db~'), true) + assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) + assert.equal((await fs.readFile('workspace/lac.db~', 'utf8')).length, 5000) + + // Reload database without a crash, check that no data was lost and fs state is clean (no temp file) + const db = new Datastore({ filename: 'workspace/lac.db' }) + await db.loadDatabaseAsync() + assert.equal(await exists('workspace/lac.db'), true) + assert.equal(await exists('workspace/lac.db~'), false) + assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) + + const docs = await db.findAsync({}) + assert.equal(docs.length, N) + for (i = 0; i < N; i += 1) { + docI = docs.find(d => d._id === 'anid_' + i) + assert.notEqual(docI, undefined) + assert.deepEqual({ hello: 'world', _id: 'anid_' + i }, docI) + } + resolve() + } catch (error) { + reject(error) + } + }) + }) + ]) + }) - // Not run on Windows as there is no clean way to set maximum file descriptors. Not an issue as the code itself is tested. - it('Cannot cause EMFILE errors by opening too many file descriptors', async function () { - this.timeout(5000) - if (process.platform === 'win32' || process.platform === 'win64') { return } - const { stdout } = await promisify(execFile)('test_lac/openFdsLaunch.sh') + // Not run on Windows as there is no clean way to set maximum file descriptors. Not an issue as the code itself is tested. + it('Cannot cause EMFILE errors by opening too many file descriptors', async function () { + this.timeout(10000) + if (process.platform === 'win32' || process.platform === 'win64') { return } + try { + const { stdout, stderr } = await promisify(execFile)('test_lac/openFdsLaunch.sh') // The subprocess will not output anything to stdout unless part of the test fails - if (stdout.length !== 0) throw new Error(stdout) - }) + if (stderr.length !== 0) { + console.error('subprocess catch\n', stdout) + throw new Error(stderr) + } + } catch (err) { + if (Object.prototype.hasOwnProperty.call(err, 'stdout') || Object.prototype.hasOwnProperty.call(err, 'stderr')) { + console.error('subprocess catch\n', err.stdout) + throw new Error(err.stderr) + } else throw err + } }) }) // ==== End of 'Prevent dataloss when persisting data' ==== diff --git a/test/persistence.test.js b/test/persistence.test.js index aa965b4..d83fc24 100755 --- a/test/persistence.test.js +++ b/test/persistence.test.js @@ -1004,6 +1004,8 @@ describe('Persistence', function () { const datafileLength = fs.readFileSync('workspace/lac.db', 'utf8').length + assert(datafileLength > 5000) + // Loading it in a separate process that we will crash before finishing the loadDatabase fork('test_lac/loadAndCrash.test').on('exit', function (code) { code.should.equal(1) // See test_lac/loadAndCrash.test.js diff --git a/test_lac/loadAndCrash.test.js b/test_lac/loadAndCrash.test.js index ca5bd82..66ea9d1 100755 --- a/test_lac/loadAndCrash.test.js +++ b/test_lac/loadAndCrash.test.js @@ -1,133 +1,59 @@ /* eslint-env mocha */ -/* global DEBUG */ /** * Load and modify part of fs to ensure writeFile will crash after writing 5000 bytes */ const fs = require('fs') - -function rethrow () { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - const backtrace = new Error() - return function (err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length) - throw backtrace - } - } - } - - return function (err) { - if (err) { - throw err // Forgot a callback but don't know where? Use NODE_DEBUG=fs +const { Writable } = require('stream') +const { callbackify } = require('util') + +fs.promises.writeFile = async function (path, data) { + let onePassDone = false + const options = { encoding: 'utf8', mode: 0o666, flag: 'w' } // we don't care about the actual options passed + + const filehandle = await fs.promises.open(path, options.flag, options.mode) + const buffer = (data instanceof Buffer) ? data : Buffer.from('' + data, options.encoding || 'utf8') + let length = buffer.length + let offset = 0 + + try { + while (length > 0) { + if (onePassDone) { process.exit(1) } // Crash on purpose before rewrite done + const { bytesWritten } = await filehandle.write(buffer, offset, Math.min(5000, length)) // Force write by chunks of 5000 bytes to ensure data will be incomplete on crash + onePassDone = true + offset += bytesWritten + length -= bytesWritten } + } finally { + await filehandle.close() } } -function maybeCallback (cb) { - return typeof cb === 'function' ? cb : rethrow() -} - -function isFd (path) { - return (path >>> 0) === path -} - -function assertEncoding (encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding) +class FakeFsWriteStream extends Writable { + constructor (filename) { + super() + this.filename = filename + this._content = Buffer.alloc(0) } -} - -let onePassDone = false - -function writeAll (fd, isUserFd, buffer, offset, length, position, callback_) { - const callback = maybeCallback(arguments[arguments.length - 1]) - - if (onePassDone) { process.exit(1) } // Crash on purpose before rewrite done - const l = Math.min(5000, length) // Force write by chunks of 5000 bytes to ensure data will be incomplete on crash - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, l, position, function (writeErr, written) { - if (writeErr) { - if (isUserFd) { - if (callback) callback(writeErr) - } else { - fs.close(fd, function () { - if (callback) callback(writeErr) - }) - } - } else { - onePassDone = true - if (written === length) { - if (isUserFd) { - if (callback) callback(null) - } else { - fs.close(fd, callback) - } - } else { - offset += written - length -= written - if (position !== null) { - position += written - } - writeAll(fd, isUserFd, buffer, offset, length, position, callback) - } - } - }) -} - -fs.writeFile = function (path, data, options, callback_) { - const callback = maybeCallback(arguments[arguments.length - 1]) - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 438, flag: 'w' } // Mode 438 == 0o666 (compatibility with older Node releases) - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'w' } // Mode 438 == 0o666 (compatibility with older Node releases) - } else if (typeof options !== 'object') { - throw new Error(`throwOptionsError${options}`) + _write (chunk, encoding, callback) { + this._content = Buffer.concat([this._content, Buffer.from(chunk, encoding)]) + callback() } - assertEncoding(options.encoding) - - const flag = options.flag || 'w' - - if (isFd(path)) { - writeFd(path, true) - return + _end (chunk, encoding, callback) { + this._content = Buffer.concat([this._content, Buffer.from(chunk, encoding)]) + callback() } - fs.open(path, flag, options.mode, function (openErr, fd) { - if (openErr) { - if (callback) callback(openErr) - } else { - writeFd(fd, false) - } - }) - - function writeFd (fd, isUserFd) { - const buffer = (data instanceof Buffer) ? data : Buffer.from('' + data, options.encoding || 'utf8') - const position = /a/.test(flag) ? null : 0 - - writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback) + close (callback) { + callbackify(fs.promises.writeFile)(this.filename, this._content, 'utf8', callback) } } -fs.createWriteStream = function (path) { - let content = '' - return { - write (data) { - content += data - }, - close (callback) { - fs.writeFile(path, content, callback) - } - } -} +fs.createWriteStream = path => new FakeFsWriteStream(path) -// End of fs modification +// End of fs monkey patching const Nedb = require('../lib/datastore.js') const db = new Nedb({ filename: 'workspace/lac.db' }) -db.loadDatabase() +db.loadDatabaseAsync() // no need to await diff --git a/test_lac/openFds.test.js b/test_lac/openFds.test.js index da449d6..f9e72e4 100644 --- a/test_lac/openFds.test.js +++ b/test_lac/openFds.test.js @@ -1,65 +1,61 @@ const fs = require('fs') -const { waterfall, whilst } = require('../test/utils.test.js') +const fsPromises = fs.promises const Nedb = require('../lib/datastore') -const { callbackify } = require('util') -const db = new Nedb({ filename: './workspace/openfds.db', autoload: true }) const N = 64 -let i -let fds -function multipleOpen (filename, N, callback) { - whilst(function () { return i < N } - , function (cb) { - fs.open(filename, 'r', function (err, fd) { - i += 1 - if (fd) { fds.push(fd) } - return cb(err) - }) +// A console.error triggers an error of the parent test + +const test = async () => { + let filehandles = [] + try { + for (let i = 0; i < 2 * N + 1; i++) { + const filehandle = await fsPromises.open('./test_lac/openFdsTestFile', 'r') + filehandles.push(filehandle) } - , callback) -} + console.error('No error occurred while opening a file too many times') + process.exit(1) + } catch (error) { + if (error.code !== 'EMFILE') { + console.error(error) + process.exit(1) + } + } finally { + for (const filehandle of filehandles) { + await filehandle.close() + } + filehandles = [] + } + + try { + for (let i = 0; i < N; i++) { + const filehandle = await fsPromises.open('./test_lac/openFdsTestFile2', 'r') + filehandles.push(filehandle) + } + } catch (error) { + console.error(`An unexpected error occurred when opening file not too many times at i: ${i} with error: ${error}`) + process.exit(1) + } finally { + for (const filehandle of filehandles) { + await filehandle.close() + } + } -waterfall([ - // Check that ulimit has been set to the correct value - function (cb) { - i = 0 - fds = [] - multipleOpen('./test_lac/openFdsTestFile', 2 * N + 1, function (err) { - if (!err) { console.log('No error occured while opening a file too many times') } - fds.forEach(function (fd) { fs.closeSync(fd) }) - return cb() - }) - }, - function (cb) { - i = 0 - fds = [] - multipleOpen('./test_lac/openFdsTestFile2', N, function (err) { - if (err) { console.log('An unexpected error occured when opening file not too many times: ' + err) } - fds.forEach(function (fd) { fs.closeSync(fd) }) - return cb() - }) - }, - // Then actually test NeDB persistence - function () { - db.remove({}, { multi: true }, function (err) { - if (err) { console.log(err) } - db.insert({ hello: 'world' }, function (err) { - if (err) { console.log(err) } + try { + const db = new Nedb({ filename: './workspace/openfds.db' }) + await db.loadDatabaseAsync() + await db.removeAsync({}, { multi: true }) + await db.insertAsync({ hello: 'world' }) - i = 0 - whilst(function () { return i < 2 * N + 1 } - , function (cb) { - callbackify(() => db.persistence.persistCachedDatabaseAsync())(function (err) { - if (err) { return cb(err) } - i += 1 - return cb() - }) - } - , function (err) { - if (err) { console.log('Got unexpected error during one peresistence operation: ' + err) } - } - ) - }) - }) + for (let i = 0; i < 2 * N + 1; i++) { + await db.persistence.persistCachedDatabaseAsync() + } + } catch (error) { + console.error(`Got unexpected error during one persistence operation at ${i}: with error: ${error}`) } -], () => {}) +} +try { + test() +} catch (error) { + console.error(error) + process.exit(1) +} From a17662a66b7fb669fa8cc49423a8d9c7a396c3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 17 Jan 2022 21:03:54 +0100 Subject: [PATCH 49/65] update JSDoc, readme, remove jquery and jsdoc from dependencies, remove sources from jsdoc.conf.js which conflicts with --files from jsdoc2md, implement dropDatabase & tests --- API.md | 375 ++++++++++++++------------------- CHANGELOG.md | 53 ++++- README.md | 9 +- jsdoc.conf.js | 5 +- lib/cursor.js | 28 +-- lib/datastore.js | 232 ++++++++++++-------- lib/persistence.js | 93 ++++---- package-lock.json | 38 ++-- package.json | 5 +- test/db.async.test.js | 2 +- test/db.test.js | 2 +- test/persistence.async.test.js | 88 +++++++- test/persistence.test.js | 2 +- test_lac/openFds.test.js | 4 +- 14 files changed, 504 insertions(+), 432 deletions(-) diff --git a/API.md b/API.md index d99c5b0..325d046 100644 --- a/API.md +++ b/API.md @@ -12,16 +12,10 @@ updates and deletes actually result in lines added at the end of the datafile, for performance reasons. The database is automatically compacted (i.e. put back in the one-line-per-document format) every time you load each database within your application.

-

You can manually call the compaction function -with yourDatabase.persistence.compactDatafile which takes no argument. It -queues a compaction of the datafile in the executor, to be executed sequentially -after all pending operations. The datastore will fire a compaction.done event -once compaction is finished.

-

You can also set automatic compaction at regular intervals -with yourDatabase.persistence.setAutocompactionInterval(interval), interval -in milliseconds (a minimum of 5s is enforced), and stop automatic compaction -with yourDatabase.persistence.stopAutocompaction().

-

Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k +

Persistence handles the compaction exposed in the Datastore [compactDatafileAsync](#Datastore+compactDatafileAsync), +[setAutocompactionInterval](#Datastore+setAutocompactionInterval).

+

Since version 3.0.0, using [Datastore.persistence](Datastore.persistence) methods manually is deprecated.

+

Compaction takes a bit of time (not too much: 130ms for 50k records on a typical development machine) and no other operation can happen when it does, so most projects actually don't need to use it.

Compaction will also immediately remove any documents whose data line has become @@ -50,13 +44,13 @@ with appendfsync option set to no.

return 0
MultipleDocumentsCallback : function
-

Callback that returns an Array of documents

+

Callback that returns an Array of documents.

SingleDocumentCallback : function
-

Callback that returns a single document

+

Callback that returns a single document.

AsyncFunctionPromise.<*>
-

Generic async function

+

Generic async function.

GenericCallback : function
-

Callback with generic parameters

+

Callback with generic parameters.

document : Object.<string, *>

Generic document in NeDB. It consists of an Object with anything you want inside.

@@ -140,7 +134,7 @@ The beforeDeserialization should revert what afterDeserializa ### new Cursor(db, query, [mapFn]) -

Create a new cursor for this collection

+

Create a new cursor for this collection.

**Params** @@ -161,9 +155,10 @@ The beforeDeserialization should revert what afterDeserializa ### cursor.limit(limit) ⇒ [Cursor](#Cursor) -

Set a limit to the number of results

+

Set a limit to the number of results for the given Cursor.

**Kind**: instance method of [Cursor](#Cursor) +**Returns**: [Cursor](#Cursor) -

the same instance of Cursor, (useful for chaining).

**Params** - limit Number @@ -171,9 +166,10 @@ The beforeDeserialization should revert what afterDeserializa ### cursor.skip(skip) ⇒ [Cursor](#Cursor) -

Skip a number of results

+

Skip a number of results for the given Cursor.

**Kind**: instance method of [Cursor](#Cursor) +**Returns**: [Cursor](#Cursor) -

the same instance of Cursor, (useful for chaining).

**Params** - skip Number @@ -181,9 +177,10 @@ The beforeDeserialization should revert what afterDeserializa ### cursor.sort(sortQuery) ⇒ [Cursor](#Cursor) -

Sort results of the query

+

Sort results of the query for the given Cursor.

**Kind**: instance method of [Cursor](#Cursor) +**Returns**: [Cursor](#Cursor) -

the same instance of Cursor, (useful for chaining).

**Params** - sortQuery Object.<string, number> -

sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending

@@ -191,9 +188,10 @@ The beforeDeserialization should revert what afterDeserializa ### cursor.projection(projection) ⇒ [Cursor](#Cursor) -

Add the use of a projection

+

Add the use of a projection to the given Cursor.

**Kind**: instance method of [Cursor](#Cursor) +**Returns**: [Cursor](#Cursor) -

the same instance of Cursor, (useful for chaining).

**Params** - projection Object.<string, number> -

MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 @@ -202,10 +200,10 @@ The beforeDeserialization should revert what afterDeserializa ### cursor.exec(_callback) -

Get all matching elements -Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne

+

Callback version of [exec](#Cursor+exec).

**Kind**: instance method of [Cursor](#Cursor) +**See**: Cursor#execAsync **Params** - _callback [execCallback](#Cursor..execCallback) @@ -213,10 +211,10 @@ Will return pointers to matched elements (shallow copies), returning full copies ### cursor.execAsync() ⇒ Promise.<(Array.<document>\|\*)> -

Async version of [exec](#Cursor+exec).

+

Get all matching elements. +Will return pointers to matched elements (shallow copies), returning full copies is the role of [findAsync](#Datastore+findAsync) or [findOneAsync](#Datastore+findOneAsync).

**Kind**: instance method of [Cursor](#Cursor) -**See**: Cursor#exec ### Cursor~mapFn ⇒ \* \| Promise.<\*> @@ -234,7 +232,7 @@ Will return pointers to matched elements (shallow copies), returning full copies **Params** - err Error -- res [Array.<document>](#document) | \* -

If an mapFn was given to the Cursor, then the type of this parameter is the one returned by the mapFn.

+- res [Array.<document>](#document) | \* -

If a mapFn was given to the Cursor, then the type of this parameter is the one returned by the mapFn.

@@ -258,12 +256,18 @@ Will return pointers to matched elements (shallow copies), returning full copies * [.ttlIndexes](#Datastore+ttlIndexes) : Object.<string, number> * [.autoloadPromise](#Datastore+autoloadPromise) : Promise * [.compareStrings()](#Datastore+compareStrings) : [compareStrings](#compareStrings) + * [.compactDatafileAsync()](#Datastore+compactDatafileAsync) + * [.compactDatafile([callback])](#Datastore+compactDatafile) + * [.setAutocompactionInterval(interval)](#Datastore+setAutocompactionInterval) + * [.stopAutocompaction()](#Datastore+stopAutocompaction) * [.loadDatabase([callback])](#Datastore+loadDatabase) + * [.dropDatabaseAsync()](#Datastore+dropDatabaseAsync) ⇒ Promise + * [.dropDatabase([callback])](#Datastore+dropDatabase) * [.loadDatabaseAsync()](#Datastore+loadDatabaseAsync) ⇒ Promise * [.getAllData()](#Datastore+getAllData) ⇒ [Array.<document>](#document) * [.ensureIndex(options, [callback])](#Datastore+ensureIndex) * [.ensureIndexAsync(options)](#Datastore+ensureIndexAsync) ⇒ Promise.<void> - * [.removeIndex(fieldName, callback)](#Datastore+removeIndex) + * [.removeIndex(fieldName, [callback])](#Datastore+removeIndex) * [.removeIndexAsync(fieldName)](#Datastore+removeIndexAsync) ⇒ Promise.<void> * [.insert(newDoc, [callback])](#Datastore+insert) * [.insertAsync(newDoc)](#Datastore+insertAsync) ⇒ Promise.<(document\|Array.<document>)> @@ -273,7 +277,7 @@ Will return pointers to matched elements (shallow copies), returning full copies * [.findAsync(query, [projection])](#Datastore+findAsync) ⇒ Cursor.<Array.<document>> * [.findOne(query, [projection], [callback])](#Datastore+findOne) ⇒ [Cursor.<document>](#document) \| undefined * [.findOneAsync(query, projection)](#Datastore+findOneAsync) ⇒ [Cursor.<document>](#document) - * [.update(query, update, [options|], [cb])](#Datastore+update) + * [.update(query, update, [options|], [callback])](#Datastore+update) * [.updateAsync(query, update, [options])](#Datastore+updateAsync) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> * [.remove(query, [options], [cb])](#Datastore+remove) * [.removeAsync(query, [options])](#Datastore+removeAsync) ⇒ Promise.<number> @@ -370,9 +374,9 @@ after instanciation.

### neDB.executor : [Executor](#new_Executor_new) -

The Executor instance for this Datastore. It is used in all methods exposed by the Datastore, any Cursor -produced by the Datastore and by this.persistence.compactDataFile & this.persistence.compactDataFileAsync -to ensure operations are performed sequentially in the database.

+

The Executor instance for this Datastore. It is used in all methods exposed by the [Datastore](#Datastore), +any [Cursor](#Cursor) produced by the Datastore and by [compactDatafileAsync](#Datastore+compactDatafileAsync) to ensure operations +are performed sequentially in the database.

**Kind**: instance property of [Datastore](#Datastore) **Access**: protected @@ -407,6 +411,41 @@ letters. Native localCompare will most of the time be the right cho **Kind**: instance method of [Datastore](#Datastore) **Access**: protected + + +### neDB.compactDatafileAsync() +

Queue a compaction/rewrite of the datafile. +It works by rewriting the database file, and compacts it since the cache always contains only the number of +documents in the collection while the data file is append-only so it may grow larger.

+ +**Kind**: instance method of [Datastore](#Datastore) + + +### neDB.compactDatafile([callback]) +

Callback version of [compactDatafileAsync](#Datastore+compactDatafileAsync).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#compactDatafileAsync +**Params** + +- [callback] [NoParamCallback](#NoParamCallback) = () => {} + + + +### neDB.setAutocompactionInterval(interval) +

Set automatic compaction every interval ms

+ +**Kind**: instance method of [Datastore](#Datastore) +**Params** + +- interval Number -

in milliseconds, with an enforced minimum of 5000 milliseconds

+ + + +### neDB.stopAutocompaction() +

Stop autocompaction (do nothing if automatic compaction was not running)

+ +**Kind**: instance method of [Datastore](#Datastore) ### neDB.loadDatabase([callback]) @@ -418,6 +457,25 @@ letters. Native localCompare will most of the time be the right cho - [callback] [NoParamCallback](#NoParamCallback) + + +### neDB.dropDatabaseAsync() ⇒ Promise +

Stops auto-compaction, finishes all queued operations, drops the database both in memory and in storage. +WARNING: it is not recommended re-using an instance of NeDB if its database has been dropped, it is +preferable to instantiate a new one.

+ +**Kind**: instance method of [Datastore](#Datastore) + + +### neDB.dropDatabase([callback]) +

Callback version of [dropDatabaseAsync](#Datastore+dropDatabaseAsync).

+ +**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#dropDatabaseAsync +**Params** + +- [callback] [NoParamCallback](#NoParamCallback) + ### neDB.loadDatabaseAsync() ⇒ Promise @@ -469,21 +527,20 @@ automatically remove documents when the system date becomes larger than the date -### neDB.removeIndex(fieldName, callback) -

Remove an index -Previous versions said explicitly the callback was optional, it is now recommended setting one.

+### neDB.removeIndex(fieldName, [callback]) +

Callback version of [removeIndexAsync](#Datastore+removeIndexAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#removeIndexAsync **Params** -- fieldName string -

Field name of the index to remove. Use the dot notation to remove an index referring to a -field in a nested document.

-- callback [NoParamCallback](#NoParamCallback) -

Optional callback, signature: err

+- fieldName string +- [callback] [NoParamCallback](#NoParamCallback) ### neDB.removeIndexAsync(fieldName) ⇒ Promise.<void> -

Async version of [removeIndex](#Datastore+removeIndex).

+

Remove an index.

**Kind**: instance method of [Datastore](#Datastore) **See**: Datastore#removeIndex @@ -591,41 +648,46 @@ We return the [Cursor](#Cursor) that the user can either await dire -### neDB.update(query, update, [options|], [cb]) -

Update all docs matching query.

+### neDB.update(query, update, [options|], [callback]) +

Callback version of [updateAsync](#Datastore+updateAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#updateAsync **Params** -- query [query](#query) -

is the same kind of finding query you use with find and findOne

-- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a -set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the -matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can -apply them to subdocs. Available field modifiers are $set to change a field's value, $unset to delete a field, -$inc to increment a field's value and $min/$max to change field's value, only if provided value is -less/greater than current value. To work on arrays, you have $push, $pop, $addToSet, $pull, and the special -$each and $slice.

-- [options|] Object | [updateCallback](#Datastore..updateCallback) -

Optional options

- - [.multi] boolean = false -

If true, can update multiple documents

- - [.upsert] boolean = false -

If true, can insert a new document corresponding to the update rules if -your query doesn't match anything. If your update is a simple object with no modifiers, it is the inserted -document. In the other case, the query is stripped from all operator recursively, and the update is applied to -it.

- - [.returnUpdatedDocs] boolean = false -

(not Mongo-DB compatible) If true and update is not an upsert, -will return the array of documents matched by the find query and updated. Updated documents will be returned even -if the update did not actually modify them.

-- [cb] [updateCallback](#Datastore..updateCallback) = () => {} -

Optional callback

+- query [query](#query) +- update [document](#document) | \* +- [options|] Object | [updateCallback](#Datastore..updateCallback) + - [.multi] boolean = false + - [.upsert] boolean = false + - [.returnUpdatedDocs] boolean = false +- [callback] [updateCallback](#Datastore..updateCallback) ### neDB.updateAsync(query, update, [options]) ⇒ Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> -

Async version of [update](#Datastore+update).

+

Update all docs matching query.

**Kind**: instance method of [Datastore](#Datastore) -**See**: Datastore#update +**Returns**: Promise.<{numAffected: number, affectedDocuments: (Array.<document>\|document\|null), upsert: boolean}> -
    +
  • upsert is true if and only if the update did insert a document, cannot be true if options.upsert !== true.
  • +
  • numAffected is the number of documents affected by the update or insertion (if options.multi is false or options.upsert is true, cannot exceed 1);
  • +
  • affectedDocuments can be one of the following: +
      +
    • If upsert is true, the inserted document;
    • +
    • If options.returnUpdatedDocs is false, null;
    • +
    • If options.returnUpdatedDocs is true: +
        +
      • If options.multi is false, the updated document;
      • +
      • If options.multi is false, the array of updated documents.
      • +
      +
    • +
    +
  • +
**Params** -- query [query](#query) -

is the same kind of finding query you use with find and findOne

+- query [query](#query) -

is the same kind of finding query you use with find and findOne.

- update [document](#document) | \* -

specifies how the documents should be modified. It is either a new document or a set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can @@ -646,27 +708,27 @@ if the update did not actually modify them.

### neDB.remove(query, [options], [cb]) -

Remove all docs matching the query.

+

Callback version of [removeAsync](#Datastore+removeAsync).

**Kind**: instance method of [Datastore](#Datastore) +**See**: Datastore#removeAsync **Params** - query [query](#query) -- [options] object | [removeCallback](#Datastore..removeCallback) = {} -

Optional options

- - [.multi] boolean = false -

If true, can update multiple documents

-- [cb] [removeCallback](#Datastore..removeCallback) = () => {} -

Optional callback

+- [options] object | [removeCallback](#Datastore..removeCallback) = {} + - [.multi] boolean = false +- [cb] [removeCallback](#Datastore..removeCallback) = () => {} ### neDB.removeAsync(query, [options]) ⇒ Promise.<number> -

Remove all docs matching the query. -Use Datastore.removeAsync which has the same signature

+

Remove all docs matching the query.

**Kind**: instance method of [Datastore](#Datastore) **Returns**: Promise.<number> -

How many documents were removed

**Params** -- query [query](#query) +- query [query](#query) -

MongoDB-style query

- [options] object = {} -

Optional options

- [.multi] boolean = false -

If true, can update multiple documents

@@ -674,13 +736,15 @@ Use Datastore.removeAsync which has the same signature

### "event:compaction.done"

Compaction event. Happens when the Datastore's Persistence has been compacted. -It happens when calling datastore.persistence.compactDatafile, which is called periodically if you have called -datastore.persistence.setAutocompactionInterval.

+It happens when calling [compactDatafileAsync](#Datastore+compactDatafileAsync), which is called periodically if you have called +[setAutocompactionInterval](#Datastore+setAutocompactionInterval).

**Kind**: event emitted by [Datastore](#Datastore) ### Datastore~countCallback : function +

Callback for [Datastore#countCallback](Datastore#countCallback).

+ **Kind**: inner typedef of [Datastore](#Datastore) **Params** @@ -699,22 +763,15 @@ It happens when calling datastore.persistence.compactDatafile, whic ### Datastore~updateCallback : function -

If update was an upsert, upsert flag is set to true, affectedDocuments can be one of the following:

-
    -
  • For an upsert, the upserted document
  • -
  • For an update with returnUpdatedDocs option false, null
  • -
  • For an update with returnUpdatedDocs true and multi false, the updated document
  • -
  • For an update with returnUpdatedDocs true and multi true, the array of updated documents
  • -
-

WARNING: The API was changed between v1.7.4 and v1.8, for consistency and readability reasons. Prior and -including to v1.7.4, the callback signature was (err, numAffected, updated) where updated was the updated document -in case of an upsert or the array of updated documents for an update if the returnUpdatedDocs option was true. That -meant that the type of affectedDocuments in a non multi update depended on whether there was an upsert or not, -leaving only two ways for the user to check whether an upsert had occured: checking the type of affectedDocuments -or running another find query on the whole dataset to check its size. Both options being ugly, the breaking change -was necessary.

+

See [updateAsync](#Datastore+updateAsync) return type for the definition of the callback parameters.

+

WARNING: Prior to 3.0.0, upsert was either true of falsy (but not false), it is now always a boolean. +affectedDocuments could be undefined when returnUpdatedDocs was false, it is now null in these cases.

+

WARNING: Prior to 1.8.0, the upsert argument was not given, it was impossible for the developer to determine +during a { multi: false, returnUpdatedDocs: true, upsert: true } update if it inserted a document or just updated +it.

**Kind**: inner typedef of [Datastore](#Datastore) +**See**: {Datastore#updateAsync} **Params** - err Error @@ -739,16 +796,10 @@ updates and deletes actually result in lines added at the end of the datafile, for performance reasons. The database is automatically compacted (i.e. put back in the one-line-per-document format) every time you load each database within your application.

-

You can manually call the compaction function -with yourDatabase.persistence.compactDatafile which takes no argument. It -queues a compaction of the datafile in the executor, to be executed sequentially -after all pending operations. The datastore will fire a compaction.done event -once compaction is finished.

-

You can also set automatic compaction at regular intervals -with yourDatabase.persistence.setAutocompactionInterval(interval), interval -in milliseconds (a minimum of 5s is enforced), and stop automatic compaction -with yourDatabase.persistence.stopAutocompaction().

-

Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k +

Persistence handles the compaction exposed in the Datastore [compactDatafileAsync](#Datastore+compactDatafileAsync), +[setAutocompactionInterval](#Datastore+setAutocompactionInterval).

+

Since version 3.0.0, using [Datastore.persistence](Datastore.persistence) methods manually is deprecated.

+

Compaction takes a bit of time (not too much: 130ms for 50k records on a typical development machine) and no other operation can happen when it does, so most projects actually don't need to use it.

Compaction will also immediately remove any documents whose data line has become @@ -768,19 +819,9 @@ with appendfsync option set to no.

* [Persistence](#Persistence) * [new Persistence()](#new_Persistence_new) - * _instance_ - * [.persistCachedDatabaseAsync()](#Persistence+persistCachedDatabaseAsync) ⇒ Promise.<void> - * [.compactDatafile([callback])](#Persistence+compactDatafile) - * [.compactDatafileAsync()](#Persistence+compactDatafileAsync) - * [.setAutocompactionInterval(interval)](#Persistence+setAutocompactionInterval) - * [.stopAutocompaction()](#Persistence+stopAutocompaction) - * [.persistNewStateAsync(newDocs)](#Persistence+persistNewStateAsync) ⇒ Promise - * [.treatRawData(rawData)](#Persistence+treatRawData) ⇒ Object - * [.treatRawStreamAsync(rawStream)](#Persistence+treatRawStreamAsync) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> - * [.loadDatabase(callback)](#Persistence+loadDatabase) - * [.loadDatabaseAsync()](#Persistence+loadDatabaseAsync) ⇒ Promise.<void> - * _static_ - * [.ensureDirectoryExistsAsync(dir)](#Persistence.ensureDirectoryExistsAsync) ⇒ Promise.<void> + * ~~[.compactDatafile([callback])](#Persistence+compactDatafile)~~ + * ~~[.setAutocompactionInterval()](#Persistence+setAutocompactionInterval)~~ + * ~~[.stopAutocompaction()](#Persistence+stopAutocompaction)~~ @@ -794,127 +835,35 @@ with appendfsync option set to no.

- [.beforeDeserialization] [serializationHook](#serializationHook) -

Hook you can use to transform data after it was serialized and before it is written to disk.

- [.afterSerialization] [serializationHook](#serializationHook) -

Inverse of afterSerialization.

- + -### persistence.persistCachedDatabaseAsync() ⇒ Promise.<void> -

Persist cached database -This serves as a compaction function since the cache always contains only the number of documents in the collection -while the data file is append-only so it may grow larger

-

This is an internal function, use [compactDatafileAsync](#Persistence+compactDatafileAsync) which uses the [executor](#Datastore+executor).

+### ~~persistence.compactDatafile([callback])~~ +***Deprecated*** **Kind**: instance method of [Persistence](#Persistence) -**Access**: protected - +**See** -### persistence.compactDatafile([callback]) -

Queue a rewrite of the datafile

+- Datastore#compactDatafile +- Persistence#compactDatafileAsync -**Kind**: instance method of [Persistence](#Persistence) -**See**: Persistence#persistCachedDatabaseAsync **Params** - [callback] [NoParamCallback](#NoParamCallback) = () => {} - - -### persistence.compactDatafileAsync() -

Async version of [compactDatafile](#Persistence+compactDatafile).

- -**Kind**: instance method of [Persistence](#Persistence) -**See**: Persistence#compactDatafile -### persistence.setAutocompactionInterval(interval) -

Set automatic compaction every interval ms

+### ~~persistence.setAutocompactionInterval()~~ +***Deprecated*** **Kind**: instance method of [Persistence](#Persistence) -**Params** - -- interval Number -

in milliseconds, with an enforced minimum of 5000 milliseconds

- +**See**: Datastore#setAutocompactionInterval -### persistence.stopAutocompaction() -

Stop autocompaction (do nothing if automatic compaction was not running)

- -**Kind**: instance method of [Persistence](#Persistence) - - -### persistence.persistNewStateAsync(newDocs) ⇒ Promise -

Persist new state for the given newDocs (can be insertion, update or removal) -Use an append-only format

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

- -**Kind**: instance method of [Persistence](#Persistence) -**Params** - -- newDocs [Array.<document>](#document) -

Can be empty if no doc was updated/removed

- - - -### persistence.treatRawData(rawData) ⇒ Object -

From a database's raw data, return the corresponding machine understandable collection.

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

+### ~~persistence.stopAutocompaction()~~ +***Deprecated*** **Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- rawData string -

database file

- - - -### persistence.treatRawStreamAsync(rawStream) ⇒ Promise.<{data: Array.<document>, indexes: Object.<string, rawIndex>}> -

From a database's raw data stream, return the corresponding machine understandable collection -Is only used by a [Datastore](#Datastore) instance.

-

Is only used in the Node.js version, since [React-Native](module:storageReactNative) & -[browser](module:storageBrowser) storage modules don't provide an equivalent of -[readFileStream](#module_storage.readFileStream).

-

Do not use directly, it should only used by a [Datastore](#Datastore) instance.

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- rawStream Readable - - - -### persistence.loadDatabase(callback) -

Load the database

-
    -
  1. Create all indexes
  2. -
  3. Insert all data
  4. -
  5. Compact the database
  6. -
-

This means pulling data out of the data file or creating it if it doesn't exist -Also, all data is persisted right away, which has the effect of compacting the database file -This operation is very quick at startup for a big collection (60ms for ~10k docs)

-

Do not use directly as it does not use the [Executor](Datastore.executor), use [loadDatabase](#Datastore+loadDatabase) instead.

- -**Kind**: instance method of [Persistence](#Persistence) -**Access**: protected -**Params** - -- callback [NoParamCallback](#NoParamCallback) - - - -### persistence.loadDatabaseAsync() ⇒ Promise.<void> -

Async version of [loadDatabase](#Persistence+loadDatabase)

- -**Kind**: instance method of [Persistence](#Persistence) -**See**: Persistence#loadDatabase - - -### Persistence.ensureDirectoryExistsAsync(dir) ⇒ Promise.<void> -

Check if a directory stat and create it on the fly if it is not the case.

- -**Kind**: static method of [Persistence](#Persistence) -**Params** - -- dir string - +**See**: Datastore#stopAutocompaction ## NoParamCallback : function @@ -943,7 +892,7 @@ This operation is very quick at startup for a big collection (60ms for ~10k docs ## MultipleDocumentsCallback : function -

Callback that returns an Array of documents

+

Callback that returns an Array of documents.

**Kind**: global typedef **Params** @@ -954,7 +903,7 @@ This operation is very quick at startup for a big collection (60ms for ~10k docs ## SingleDocumentCallback : function -

Callback that returns a single document

+

Callback that returns a single document.

**Kind**: global typedef **Params** @@ -965,7 +914,7 @@ This operation is very quick at startup for a big collection (60ms for ~10k docs ## AsyncFunction ⇒ Promise.<\*> -

Generic async function

+

Generic async function.

**Kind**: global typedef **Params** @@ -975,7 +924,7 @@ This operation is very quick at startup for a big collection (60ms for ~10k docs ## GenericCallback : function -

Callback with generic parameters

+

Callback with generic parameters.

**Kind**: global typedef **Params** diff --git a/CHANGELOG.md b/CHANGELOG.md index 23e97a9..b62e29c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,18 +8,51 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [3.0.0] - Unreleased ### Added -- Added an async interface for all functions -- The JSDoc is now much more exhaustive -- Added markdown documentation generated from the JSDoc +- Added a `Promise`-based interface. +- The JSDoc is now much more exhaustive. +- An auto-generated JSDoc file is generated: [API.md](./API.md). +- Added `Datastore#dropDatabaseAsync` and its callback equivalent. ### Changed -- All the functions are now async at the core, and a fully retro-compatible callback-ified version is exposed for the exposed functions. -- The executor is now much simpler and Promise-based. A mostly retro-compatible shim is still exposed, with the exception that it no longer handles [`arguments`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/arguments) as the arguments Array. If you use the executor directly, you'll need to convert it to a proper Array beforehand. However [follicle@1.x](https://github.com/seald/follicle) is not compatible, please update to v2. -- As a result, the `async` dependency has been removed completely. To avoid rewriting the tests, shims of some functions of `async` are defined in an utilities file used exclusively in the tests. -- The `Datastore#update`'s callback has its signature slightly changed. The `upsert` flag is always defined either at `true` or `false` but not `null` nor `undefined`, and `affectedDocuments` is `null` when none is given rather than `undefined` (except when there is an error of course). -- -### Deprecated -- Formally deprecate giving a string as argument to the `Datastore` constructor +- The `Datastore#update`'s callback has its signature slightly changed. The +`upsert` flag is always defined either at `true` or `false` but not `null` nor +`undefined`, and `affectedDocuments` is `null` when none is given rather than +`undefined` (except when there is an error of course). +- In order to expose a `Promise`-based interface and to remove `async` from the dependencies, many internals have been either rewritten or removed: + - Datastore: + - `Datastore#getCandidates` replaced with `Datastore#_getCandidatesAsync`; + - `Datastore#resetIndexes` replaced with `Datastore#_resetIndexes`; + - `Datastore#addToIndexes` replaced with `Datastore#_addToIndexes`; + - `Datastore#removeFromIndexes` replaced with `Datastore#_removeFromIndexes`; + - `Datastore#updateIndexes` replaced with `Datastore#_updateIndexes`; + - `Datastore#_insert` replaced with `Datastore#_insertAsync`; + - `Datastore#_update` replaced with `Datastore#_updateAsync`; + - `Datastore#_remove` replaced with `Datastore#_removeAsync`; + - Persistence: + - `Persistence#loadDatabase` replaced with `Persistence#loadDatabaseAsync`; + - `Persistence#persistCachedDatabase` replaced with `Persistence#persistCachedDatabaseAsync`; + - `Persistence#persistNewState` replaced with `Persistence#persistNewStateAsync`; + - `Persistence#treatRawStream` replaced with `Persistence#treatRawStreamAsync`; + - `Persistence.ensureDirectoryExists` replaced with `Persistence#ensureDirectoryExistsAsync`; + - Cursor: + - `Cursor#_exec` replaced with `Cursor#_execAsync`; + - `Cursor#project` replaced with `Cursor#_project`; + - `Cursor#execFn` has been renamed to `Cursor#mapFn` and no longer supports a callback in its signature, it must be a synchronous function. + - Executor: it has been rewritten entirely without the `async`library. + - `Executor#buffer` & `Executor#queue` do not have the same signatures as before; + - `Executor#push` replaced with `Executor#pushAsync` which is substantially different; + - Storage modules : callback-based functions have been replaced with promise-based functions. + - Model module: it has been slightly re-written for clarity, but no changes in its interface was made. + +## Deprecated +- Using a `string` in the constructor of NeDB is now deprecated. +- Using `Datastore#persistence#compactDatafile` is now deprecated, please use `Datastore#compactDatafile` instead. +- Using `Datastore#persistence#setAutocompactionInterval` is now deprecated, please use `Datastore#setAutocompactionInterval` instead. +- Using `Datastore#persistence#stopAutocompaction` is now deprecated, please use `Datastore#stopAutocompaction` instead. + +## Removed +- The option for passing `options.nodeWebkitAppName` to the Datastore and the Persistence constructors has been removed. + - `Persistence.getNWAppFilename`; ## [2.2.1] - 2022-01-18 diff --git a/README.md b/README.md index 0465e8a..4acf51e 100755 --- a/README.md +++ b/README.md @@ -30,13 +30,8 @@ const Datastore = require('@seald-io/nedb') The API is a subset of MongoDB's API (the most used operations). ### JSDoc -You can read the markdown version of the JSDoc [in the docs directory](./docs). -It is generated by running `npm run generateDocs:markdown`. Some links don't -work (when referencing items from other files), because I split manually the -documentation into several files. We should rewrite the links with a custom -configuration of [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown): PR welcome. - -You can also generate an HTML version `npm run generateDocs:html`, links from the Readme won't work though. +You can read the markdown version of the JSDoc [in the docs directory](./API.md). +It is generated by running `npm run generateDocs:markdown`. ### Promise-based interface vs callback-based interface Since version 3.0.0, NeDB provides a Promise-based equivalent for each function diff --git a/jsdoc.conf.js b/jsdoc.conf.js index 4615043..cea646c 100644 --- a/jsdoc.conf.js +++ b/jsdoc.conf.js @@ -1,8 +1,5 @@ 'use strict' module.exports = { - plugins: ['plugins/markdown'], - source: { - include: ['./lib', './browser-version/lib'] - } + plugins: ['plugins/markdown'] } diff --git a/lib/cursor.js b/lib/cursor.js index 87a583c..f7cb083 100755 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -16,7 +16,7 @@ const { callbackify } = require('util') */ class Cursor { /** - * Create a new cursor for this collection + * Create a new cursor for this collection. * @param {Datastore} db - The datastore this cursor is bound to * @param {query} query - The query this cursor will operate on * @param {Cursor~mapFn} [mapFn] - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove @@ -65,9 +65,9 @@ class Cursor { } /** - * Set a limit to the number of results + * Set a limit to the number of results for the given Cursor. * @param {Number} limit - * @return {Cursor} + * @return {Cursor} the same instance of Cursor, (useful for chaining). */ limit (limit) { this._limit = limit @@ -75,9 +75,9 @@ class Cursor { } /** - * Skip a number of results + * Skip a number of results for the given Cursor. * @param {Number} skip - * @return {Cursor} + * @return {Cursor} the same instance of Cursor, (useful for chaining). */ skip (skip) { this._skip = skip @@ -85,9 +85,9 @@ class Cursor { } /** - * Sort results of the query + * Sort results of the query for the given Cursor. * @param {Object.} sortQuery - sortQuery is { field: order }, field can use the dot-notation, order is 1 for ascending and -1 for descending - * @return {Cursor} + * @return {Cursor} the same instance of Cursor, (useful for chaining). */ sort (sortQuery) { this._sort = sortQuery @@ -95,10 +95,10 @@ class Cursor { } /** - * Add the use of a projection + * Add the use of a projection to the given Cursor. * @param {Object.} projection - MongoDB-style projection. {} means take all fields. Then it's { key1: 1, key2: 1 } to take only key1 and key2 * { key1: 0, key2: 0 } to omit only key1 and key2. Except _id, you can't mix takes and omits. - * @return {Cursor} + * @return {Cursor} the same instance of Cursor, (useful for chaining). */ projection (projection) { this._projection = projection @@ -211,23 +211,23 @@ class Cursor { /** * @callback Cursor~execCallback * @param {Error} err - * @param {document[]|*} res If an mapFn was given to the Cursor, then the type of this parameter is the one returned by the mapFn. + * @param {document[]|*} res If a mapFn was given to the Cursor, then the type of this parameter is the one returned by the mapFn. */ /** - * Get all matching elements - * Will return pointers to matched elements (shallow copies), returning full copies is the role of find or findOne + * Callback version of {@link Cursor#exec}. * @param {Cursor~execCallback} _callback + * @see Cursor#execAsync */ exec (_callback) { callbackify(() => this.execAsync())(_callback) } /** - * Async version of {@link Cursor#exec}. + * Get all matching elements. + * Will return pointers to matched elements (shallow copies), returning full copies is the role of {@link Datastore#findAsync} or {@link Datastore#findOneAsync}. * @return {Promise} * @async - * @see Cursor#exec */ execAsync () { return this.db.executor.pushAsync(() => this._execAsync()) diff --git a/lib/datastore.js b/lib/datastore.js index 55052b5..8cdc229 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -8,9 +8,6 @@ const model = require('./model.js') const Persistence = require('./persistence.js') const { isDate } = require('./utils.js') -// TODO: have one version of the documentation for each function -// TODO: update changelog -// TODO: dropDatabase callback + tests /** * Callback with no parameter * @callback NoParamCallback @@ -31,28 +28,28 @@ const { isDate } = require('./utils.js') */ /** - * Callback that returns an Array of documents + * Callback that returns an Array of documents. * @callback MultipleDocumentsCallback * @param {?Error} err * @param {?document[]} docs */ /** - * Callback that returns a single document + * Callback that returns a single document. * @callback SingleDocumentCallback * @param {?Error} err * @param {?document} docs */ /** - * Generic async function + * Generic async function. * @callback AsyncFunction * @param {...*} args * @return {Promise<*>} */ /** - * Callback with generic parameters + * Callback with generic parameters. * @callback GenericCallback * @param {?Error} err * @param {...*} args @@ -60,8 +57,8 @@ const { isDate } = require('./utils.js') /** * Compaction event. Happens when the Datastore's Persistence has been compacted. - * It happens when calling `datastore.persistence.compactDatafile`, which is called periodically if you have called - * `datastore.persistence.setAutocompactionInterval`. + * It happens when calling {@link Datastore#compactDatafileAsync}, which is called periodically if you have called + * {@link Datastore#setAutocompactionInterval}. * * @event Datastore#event:"compaction.done" * @type {undefined} @@ -267,9 +264,9 @@ class Datastore extends EventEmitter { // This new executor is ready if we don't use persistence // If we do, it will only be ready once loadDatabase is called /** - * The `Executor` instance for this `Datastore`. It is used in all methods exposed by the `Datastore`, any `Cursor` - * produced by the `Datastore` and by `this.persistence.compactDataFile` & `this.persistence.compactDataFileAsync` - * to ensure operations are performed sequentially in the database. + * The `Executor` instance for this `Datastore`. It is used in all methods exposed by the {@link Datastore}, + * any {@link Cursor} produced by the `Datastore` and by {@link Datastore#compactDatafileAsync} to ensure operations + * are performed sequentially in the database. * @type {Executor} * @protected */ @@ -310,6 +307,58 @@ class Datastore extends EventEmitter { else throw err }) } else this.autoloadPromise = null + /** + * Interval if {@link Datastore#setAutocompactionInterval} was called. + * @private + * @type {null|number} + */ + this.autocompactionIntervalId = null + } + + /** + * Queue a compaction/rewrite of the datafile. + * It works by rewriting the database file, and compacts it since the cache always contains only the number of + * documents in the collection while the data file is append-only so it may grow larger. + * + * @async + */ + compactDatafileAsync () { + return this.executor.pushAsync(() => this.persistence.persistCachedDatabaseAsync()) + } + + /** + * Callback version of {@link Datastore#compactDatafileAsync}. + * @param {NoParamCallback} [callback = () => {}] + * @see Datastore#compactDatafileAsync + */ + compactDatafile (callback) { + const promise = this.compactDatafileAsync() + if (typeof callback === 'function') callbackify(() => promise)(callback) + } + + /** + * Set automatic compaction every `interval` ms + * @param {Number} interval in milliseconds, with an enforced minimum of 5000 milliseconds + */ + setAutocompactionInterval (interval) { + const minInterval = 5000 + const realInterval = Math.max(interval || 0, minInterval) + + this.stopAutocompaction() + + this.autocompactionIntervalId = setInterval(() => { + this.compactDatafile() + }, realInterval) + } + + /** + * Stop autocompaction (do nothing if automatic compaction was not running) + */ + stopAutocompaction () { + if (this.autocompactionIntervalId) { + clearInterval(this.autocompactionIntervalId) + this.autocompactionIntervalId = null + } } /** @@ -322,6 +371,27 @@ class Datastore extends EventEmitter { if (typeof callback === 'function') callbackify(() => promise)(callback) } + /** + * Stops auto-compaction, finishes all queued operations, drops the database both in memory and in storage. + * **WARNING**: it is not recommended re-using an instance of NeDB if its database has been dropped, it is + * preferable to instantiate a new one. + * @async + * @return {Promise} + */ + dropDatabaseAsync () { + return this.persistence.dropDatabaseAsync() // the executor is exceptionally used by Persistence + } + + /** + * Callback version of {@link Datastore#dropDatabaseAsync}. + * @param {NoParamCallback} [callback] + * @see Datastore#dropDatabaseAsync + */ + dropDatabase (callback) { + const promise = this.dropDatabaseAsync() + if (typeof callback === 'function') callbackify(() => promise)(callback) + } + /** * Load the database from the datafile, and trigger the execution of buffered commands if any. * @async @@ -404,11 +474,10 @@ class Datastore extends EventEmitter { } /** - * Remove an index - * Previous versions said explicitly the callback was optional, it is now recommended setting one. - * @param {string} fieldName Field name of the index to remove. Use the dot notation to remove an index referring to a - * field in a nested document. - * @param {NoParamCallback} callback Optional callback, signature: err + * Callback version of {@link Datastore#removeIndexAsync}. + * @param {string} fieldName + * @param {NoParamCallback} [callback] + * @see Datastore#removeIndexAsync */ removeIndex (fieldName, callback = () => {}) { const promise = this.removeIndexAsync(fieldName) @@ -416,7 +485,7 @@ class Datastore extends EventEmitter { } /** - * Async version of {@link Datastore#removeIndex}. + * Remove an index. * @param {string} fieldName Field name of the index to remove. Use the dot notation to remove an index referring to a * field in a nested document. * @return {Promise} @@ -701,6 +770,7 @@ class Datastore extends EventEmitter { } /** + * Callback for {@link Datastore#countCallback}. * @callback Datastore~countCallback * @param {?Error} err * @param {?number} count @@ -817,50 +887,35 @@ class Datastore extends EventEmitter { } /** - * If update was an upsert, `upsert` flag is set to true, `affectedDocuments` can be one of the following: - * - For an upsert, the upserted document - * - For an update with returnUpdatedDocs option false, null - * - For an update with returnUpdatedDocs true and multi false, the updated document - * - For an update with returnUpdatedDocs true and multi true, the array of updated documents + * See {@link Datastore#updateAsync} return type for the definition of the callback parameters. + * + * **WARNING:** Prior to 3.0.0, `upsert` was either `true` of falsy (but not `false`), it is now always a boolean. + * `affectedDocuments` could be `undefined` when `returnUpdatedDocs` was `false`, it is now `null` in these cases. + * + * **WARNING:** Prior to 1.8.0, the `upsert` argument was not given, it was impossible for the developer to determine + * during a `{ multi: false, returnUpdatedDocs: true, upsert: true }` update if it inserted a document or just updated + * it. * - * **WARNING:** The API was changed between v1.7.4 and v1.8, for consistency and readability reasons. Prior and - * including to v1.7.4, the callback signature was (err, numAffected, updated) where updated was the updated document - * in case of an upsert or the array of updated documents for an update if the returnUpdatedDocs option was true. That - * meant that the type of affectedDocuments in a non multi update depended on whether there was an upsert or not, - * leaving only two ways for the user to check whether an upsert had occured: checking the type of affectedDocuments - * or running another find query on the whole dataset to check its size. Both options being ugly, the breaking change - * was necessary. * @callback Datastore~updateCallback * @param {?Error} err - * @param {?number} numAffected + * @param {number} numAffected * @param {?document[]|?document} affectedDocuments - * @param {?boolean} upsert + * @param {boolean} upsert + * @see {Datastore#updateAsync} */ /** - * Update all docs matching query. - * - * Use {@link Datastore#updateAsync} which has the same signature. - * @param {query} query is the same kind of finding query you use with `find` and `findOne` - * @param {document|update} update specifies how the documents should be modified. It is either a new document or a - * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the - * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can - * apply them to subdocs. Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, - * `$inc` to increment a field's value and `$min`/`$max` to change field's value, only if provided value is - * less/greater than current value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special - * `$each` and `$slice`. - * @param {Object} options options - * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if - * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted - * document. In the other case, the `query` is stripped from all operator recursively, and the `update` is applied to - * it. - * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, - * will return the array of documents matched by the find query and updated. Updated documents will be returned even - * if the update did not actually modify them. + * Version without the using {@link Datastore~executor} of {@link Datastore#updateAsync}, use it instead. * + * @param {query} query + * @param {document|update} update + * @param {Object} options + * @param {boolean} [options.multi = false] + * @param {boolean} [options.upsert = false] + * @param {boolean} [options.returnUpdatedDocs = false] * @return {Promise<{numAffected: number, affectedDocuments: document[]|document|null, upsert: boolean}>} * @private + * @see Datastore#updateAsync */ async _updateAsync (query, update, options) { const multi = options.multi !== undefined ? options.multi : false @@ -927,42 +982,31 @@ class Datastore extends EventEmitter { } /** - * Update all docs matching query. - * @param {query} query is the same kind of finding query you use with `find` and `findOne` - * @param {document|*} update specifies how the documents should be modified. It is either a new document or a - * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the - * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can - * apply them to subdocs. Available field modifiers are `$set` to change a field's value, `$unset` to delete a field, - * `$inc` to increment a field's value and `$min`/`$max` to change field's value, only if provided value is - * less/greater than current value. To work on arrays, you have `$push`, `$pop`, `$addToSet`, `$pull`, and the special - * `$each` and `$slice`. - * @param {Object|Datastore~updateCallback} [options|] Optional options - * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {boolean} [options.upsert = false] If true, can insert a new document corresponding to the `update` rules if - * your `query` doesn't match anything. If your `update` is a simple object with no modifiers, it is the inserted - * document. In the other case, the `query` is stripped from all operator recursively, and the `update` is applied to - * it. - * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, - * will return the array of documents matched by the find query and updated. Updated documents will be returned even - * if the update did not actually modify them. - * @param {Datastore~updateCallback} [cb = () => {}] Optional callback + * Callback version of {@link Datastore#updateAsync}. + * @param {query} query + * @param {document|*} update + * @param {Object|Datastore~updateCallback} [options|] + * @param {boolean} [options.multi = false] + * @param {boolean} [options.upsert = false] + * @param {boolean} [options.returnUpdatedDocs = false] + * @param {Datastore~updateCallback} [callback] + * @see Datastore#updateAsync * */ - update (query, update, options, cb) { + update (query, update, options, callback) { if (typeof options === 'function') { - cb = options + callback = options options = {} } - const callback = cb || (() => {}) const _callback = (err, res = {}) => { - callback(err, res.numAffected, res.affectedDocuments, res.upsert) + if (callback) callback(err, res.numAffected, res.affectedDocuments, res.upsert) } callbackify((query, update, options) => this.updateAsync(query, update, options))(query, update, options, _callback) } /** - * Async version of {@link Datastore#update}. - * @param {query} query is the same kind of finding query you use with `find` and `findOne` + * Update all docs matching query. + * @param {query} query is the same kind of finding query you use with `find` and `findOne`. * @param {document|*} update specifies how the documents should be modified. It is either a new document or a * set of modifiers (you cannot use both together, it doesn't make sense!). Using a new document will replace the * matched docs. Using a set of modifiers will create the fields they need to modify if they don't exist, and you can @@ -979,9 +1023,16 @@ class Datastore extends EventEmitter { * @param {boolean} [options.returnUpdatedDocs = false] (not Mongo-DB compatible) If true and update is not an upsert, * will return the array of documents matched by the find query and updated. Updated documents will be returned even * if the update did not actually modify them. - * @async * @return {Promise<{numAffected: number, affectedDocuments: document[]|document|null, upsert: boolean}>} - * @see Datastore#update + * - `upsert` is `true` if and only if the update did insert a document, **cannot be true if `options.upsert !== true`**. + * - `numAffected` is the number of documents affected by the update or insertion (if `options.multi` is `false` or `options.upsert` is `true`, cannot exceed `1`); + * - `affectedDocuments` can be one of the following: + * - If `upsert` is `true`, the inserted document; + * - If `options.returnUpdatedDocs` is `false`, `null`; + * - If `options.returnUpdatedDocs` is `true`: + * - If `options.multi` is `false`, the updated document; + * - If `options.multi` is `false`, the array of updated documents. + * @async */ updateAsync (query, update, options = {}) { return this.executor.pushAsync(() => this._updateAsync(query, update, options)) @@ -994,15 +1045,14 @@ class Datastore extends EventEmitter { */ /** - * Remove all docs matching the query. + * Internal version without using the {@link Datastore#executor} of {@link Datastore#removeAsync}, use it instead. * - * Use {@link Datastore#removeAsync} which has the same signature. * @param {query} query - * @param {object} [options] Optional options - * @param {boolean} [options.multi = false] If true, can update multiple documents - * @return {Promise} How many documents were removed + * @param {object} [options] + * @param {boolean} [options.multi = false] + * @return {Promise} * @private - * @see Datastore#_remove + * @see Datastore#removeAsync */ async _removeAsync (query, options = {}) { const multi = options.multi !== undefined ? options.multi : false @@ -1024,11 +1074,12 @@ class Datastore extends EventEmitter { } /** - * Remove all docs matching the query. + * Callback version of {@link Datastore#removeAsync}. * @param {query} query - * @param {object|Datastore~removeCallback} [options={}] Optional options - * @param {boolean} [options.multi = false] If true, can update multiple documents - * @param {Datastore~removeCallback} [cb = () => {}] Optional callback + * @param {object|Datastore~removeCallback} [options={}] + * @param {boolean} [options.multi = false] + * @param {Datastore~removeCallback} [cb = () => {}] + * @see Datastore#removeAsync */ remove (query, options, cb) { if (typeof options === 'function') { @@ -1041,8 +1092,7 @@ class Datastore extends EventEmitter { /** * Remove all docs matching the query. - * Use Datastore.removeAsync which has the same signature - * @param {query} query + * @param {query} query MongoDB-style query * @param {object} [options={}] Optional options * @param {boolean} [options.multi = false] If true, can update multiple documents * @return {Promise} How many documents were removed diff --git a/lib/persistence.js b/lib/persistence.js index b888637..561b136 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -1,5 +1,5 @@ const path = require('path') -const { callbackify } = require('util') +const { deprecate } = require('util') const byline = require('./byline') const customUtils = require('./customUtils.js') const Index = require('./indexes.js') @@ -13,18 +13,12 @@ const storage = require('./storage.js') * in the one-line-per-document format) every time you load each database within * your application. * - * You can manually call the compaction function - * with `yourDatabase.persistence.compactDatafile` which takes no argument. It - * queues a compaction of the datafile in the executor, to be executed sequentially - * after all pending operations. The datastore will fire a `compaction.done` event - * once compaction is finished. + * Persistence handles the compaction exposed in the Datastore {@link Datastore#compactDatafileAsync}, + * {@link Datastore#setAutocompactionInterval}. * - * You can also set automatic compaction at regular intervals - * with `yourDatabase.persistence.setAutocompactionInterval(interval)`, `interval` - * in milliseconds (a minimum of 5s is enforced), and stop automatic compaction - * with `yourDatabase.persistence.stopAutocompaction()`. + * Since version 3.0.0, using {@link Datastore.persistence} methods manually is deprecated. * - * Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k + * Compaction takes a bit of time (not too much: 130ms for 50k * records on a typical development machine) and no other operation can happen when * it does, so most projects actually don't need to use it. * @@ -86,13 +80,9 @@ class Persistence { } /** - * Persist cached database - * This serves as a compaction function since the cache always contains only the number of documents in the collection - * while the data file is append-only so it may grow larger - * - * This is an internal function, use {@link Persistence#compactDatafileAsync} which uses the [executor]{@link Datastore#executor}. + * Internal version without using the {@link Datastore#executor} of {@link Datastore#compactDatafileAsync}, use it instead. * @return {Promise} - * @protected + * @private */ async persistCachedDatabaseAsync () { const lines = [] @@ -119,44 +109,29 @@ class Persistence { } /** - * Queue a rewrite of the datafile + * @see Datastore#compactDatafile + * @deprecated * @param {NoParamCallback} [callback = () => {}] - * @see Persistence#persistCachedDatabaseAsync + * @see Persistence#compactDatafileAsync */ compactDatafile (callback) { - if (typeof callback !== 'function') callback = () => {} - callbackify(() => this.compactDatafileAsync())(callback) - } - - /** - * Async version of {@link Persistence#compactDatafile}. - * @async - * @see Persistence#compactDatafile - */ - compactDatafileAsync () { - return this.db.executor.pushAsync(() => this.persistCachedDatabaseAsync()) + deprecate(callback => this.db.compactDatafile(callback), '@seald-io/nedb: calling Datastore#persistence#compactDatafile is deprecated, please use Datastore#compactDatafile, it will be removed in the next major version.')(callback) } /** - * Set automatic compaction every `interval` ms - * @param {Number} interval in milliseconds, with an enforced minimum of 5000 milliseconds + * @see Datastore#setAutocompactionInterval + * @deprecated */ setAutocompactionInterval (interval) { - const minInterval = 5000 - const realInterval = Math.max(interval || 0, minInterval) - - this.stopAutocompaction() - - this.autocompactionIntervalId = setInterval(() => { - this.compactDatafile() - }, realInterval) + deprecate(interval => this.db.setAutocompactionInterval(interval), '@seald-io/nedb: calling Datastore#persistence#setAutocompactionInterval is deprecated, please use Datastore#setAutocompactionInterval, it will be removed in the next major version.')(interval) } /** - * Stop autocompaction (do nothing if automatic compaction was not running) + * @see Datastore#stopAutocompaction + * @deprecated */ stopAutocompaction () { - if (this.autocompactionIntervalId) clearInterval(this.autocompactionIntervalId) + deprecate(() => this.db.stopAutocompaction(), '@seald-io/nedb: calling Datastore#persistence#stopAutocompaction is deprecated, please use Datastore#stopAutocompaction, it will be removed in the next major version.')() } /** @@ -166,6 +141,7 @@ class Persistence { * Do not use directly, it should only used by a {@link Datastore} instance. * @param {document[]} newDocs Can be empty if no doc was updated/removed * @return {Promise} + * @private */ async persistNewStateAsync (newDocs) { let toPersist = '' @@ -195,7 +171,7 @@ class Persistence { * Do not use directly, it should only used by a {@link Datastore} instance. * @param {string} rawData database file * @return {{data: document[], indexes: Object.}} - * @protected + * @private */ treatRawData (rawData) { const data = rawData.split('\n') @@ -241,7 +217,7 @@ class Persistence { * @param {Readable} rawStream * @return {Promise<{data: document[], indexes: Object.}>} * @async - * @protected + * @private */ treatRawStreamAsync (rawStream) { return new Promise((resolve, reject) => { @@ -299,18 +275,9 @@ class Persistence { * Also, all data is persisted right away, which has the effect of compacting the database file * This operation is very quick at startup for a big collection (60ms for ~10k docs) * - * Do not use directly as it does not use the [Executor]{@link Datastore.executor}, use {@link Datastore#loadDatabase} instead. - * @param {NoParamCallback} callback - * @protected - */ - loadDatabase (callback = () => {}) { - callbackify(this.loadDatabaseAsync.bind(this))(err => callback(err)) - } - - /** - * Async version of {@link Persistence#loadDatabase} + * Do not use directly as it does not use the [Executor]{@link Datastore.executor}, use {@link Datastore#loadDatabaseAsync} instead. * @return {Promise} - * @see Persistence#loadDatabase + * @private */ async loadDatabaseAsync () { this.db._resetIndexes() @@ -347,8 +314,15 @@ class Persistence { this.db.executor.processBuffer() } + /** + * See {@link Datastore#dropDatabaseAsync}. This function uses {@link Datastore#executor} internally. Decorating this + * function with an {@link Executor#pushAsync} will result in a deadlock. + * @return {Promise} + * @private + * @see Datastore#dropDatabaseAsync + */ async dropDatabaseAsync () { - this.stopAutocompaction() // stop autocompaction + this.db.stopAutocompaction() // stop autocompaction this.db.executor.ready = false // prevent queuing new tasks this.db.executor.resetBuffer() // remove pending buffered tasks await this.db.executor.queue.guardian // wait for the ongoing tasks to end @@ -360,13 +334,18 @@ class Persistence { this.db.ttlIndexes = {} // remove datastore file - await this.db.executor(() => storage.unlinkAsync(this.filename), true) + if (!this.db.inMemoryOnly) { + await this.db.executor.pushAsync(async () => { + if (await storage.existsAsync(this.filename)) await storage.unlinkAsync(this.filename) + }, true) + } } /** * Check if a directory stat and create it on the fly if it is not the case. * @param {string} dir * @return {Promise} + * @private */ static async ensureDirectoryExistsAsync (dir) { await storage.mkdirAsync(dir, { recursive: true }) diff --git a/package-lock.json b/package-lock.json index 2a64e35..65b8e80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,6 @@ "commander": "^7.2.0", "events": "^3.3.0", "jest": "^27.3.1", - "jquery": "^3.6.0", - "jsdoc": "^3.6.7", "jsdoc-to-markdown": "^7.1.0", "karma": "^6.3.2", "karma-chai": "^0.1.0", @@ -5877,9 +5875,9 @@ } }, "node_modules/engine.io": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz", - "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.1.tgz", + "integrity": "sha512-AyMc20q8JUUdvKd46+thc9o7yCZ6iC6MoBCChG5Z1XmFMpp+2+y/oKvwpZTUJB0KCjxScw1dV9c2h5pjiYBLuQ==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -7463,9 +7461,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", - "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", "dev": true, "funding": [ { @@ -9376,12 +9374,6 @@ "@sideway/pinpoint": "^2.0.0" } }, - "node_modules/jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", - "dev": true - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -21488,9 +21480,9 @@ } }, "engine.io": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz", - "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.1.tgz", + "integrity": "sha512-AyMc20q8JUUdvKd46+thc9o7yCZ6iC6MoBCChG5Z1XmFMpp+2+y/oKvwpZTUJB0KCjxScw1dV9c2h5pjiYBLuQ==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -22704,9 +22696,9 @@ "peer": true }, "follow-redirects": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", - "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", "dev": true }, "for-in": { @@ -24131,12 +24123,6 @@ "@sideway/pinpoint": "^2.0.0" } }, - "jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 8e43458..2ff1cfd 100755 --- a/package.json +++ b/package.json @@ -52,8 +52,6 @@ "commander": "^7.2.0", "events": "^3.3.0", "jest": "^27.3.1", - "jquery": "^3.6.0", - "jsdoc": "^3.6.7", "jsdoc-to-markdown": "^7.1.0", "karma": "^6.3.2", "karma-chai": "^0.1.0", @@ -87,8 +85,7 @@ "test:react-native": "jest test/react-native", "test:typings": "ts-node ./typings-tests.ts", "prepublishOnly": "npm run build:browser", - "generateDocs:markdown": "jsdoc2md --no-cache -c jsdoc.conf.js --param-list-format list --files . > API.md", - "generateDocs:html": "jsdoc -c jsdoc.conf.js -d docs-html --readme README.md" + "generateDocs:markdown": "jsdoc2md --no-cache -c jsdoc.conf.js --param-list-format list --files ./lib/*.js > API.md" }, "main": "index.js", "browser": { diff --git a/test/db.async.test.js b/test/db.async.test.js index 6ae55e4..3482142 100644 --- a/test/db.async.test.js +++ b/test/db.async.test.js @@ -368,7 +368,7 @@ describe('Database async', function () { await wait(101) const doc2 = await d.findOneAsync({}) assert.equal(doc2, null) - await d.persistence.compactDatafileAsync() + await d.compactDatafileAsync() // After compaction, no more mention of the document, correctly removed const datafileContents = await fs.readFile(testDb, 'utf8') assert.equal(datafileContents.split('\n').length, 2) diff --git a/test/db.test.js b/test/db.test.js index 675f5d3..11e2387 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -610,7 +610,7 @@ describe('Database', function () { }) }) - d.persistence.compactDatafile() + d.compactDatafile() }) }, 101) }) diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index 1373648..1623cd3 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -10,6 +10,7 @@ const Persistence = require('../lib/persistence') const storage = require('../lib/storage') const { execFile, fork } = require('child_process') const { promisify } = require('util') +const { ensureFileDoesntExistAsync } = require('../lib/storage') const Readable = require('stream').Readable describe('Persistence async', function () { @@ -381,7 +382,7 @@ describe('Persistence async', function () { resolve() }) }) - await d.persistence.compactDatafileAsync() + await d.compactDatafileAsync() await compacted // should already be resolved when the function returns, but still awaiting for it }) @@ -898,4 +899,89 @@ describe('Persistence async', function () { assert.equal(await exists('workspace/existing'), false) }) }) // ==== End of 'ensureFileDoesntExist' ==== + + describe('dropDatabase', function () { + it('deletes data in memory', async () => { + const inMemoryDB = new Datastore({ inMemoryOnly: true }) + await inMemoryDB.insertAsync({ hello: 'world' }) + await inMemoryDB.dropDatabaseAsync() + assert.equal(inMemoryDB.getAllData().length, 0) + }) + + it('deletes data in memory & on disk', async () => { + await d.insertAsync({ hello: 'world' }) + await d.dropDatabaseAsync() + assert.equal(d.getAllData().length, 0) + assert.equal(await exists(testDb), false) + }) + + it('check that executor is drained before drop', async () => { + for (let i = 0; i < 100; i++) { + d.insertAsync({ hello: 'world' }) // no await + } + await d.dropDatabaseAsync() // it should await the end of the inserts + assert.equal(d.getAllData().length, 0) + assert.equal(await exists(testDb), false) + }) + + it('check that autocompaction is stopped', async () => { + d.setAutocompactionInterval(5000) + await d.insertAsync({ hello: 'world' }) + await d.dropDatabaseAsync() + assert.equal(d.autocompactionIntervalId, null) + assert.equal(d.getAllData().length, 0) + assert.equal(await exists(testDb), false) + }) + + it('check that we can reload and insert afterwards', async () => { + await d.insertAsync({ hello: 'world' }) + await d.dropDatabaseAsync() + assert.equal(d.getAllData().length, 0) + assert.equal(await exists(testDb), false) + await d.loadDatabaseAsync() + await d.insertAsync({ hello: 'world' }) + assert.equal(d.getAllData().length, 1) + await d.compactDatafileAsync() + assert.equal(await exists(testDb), true) + }) + + it('check that we can dropDatatabase if the file is already deleted', async () => { + await ensureFileDoesntExistAsync(testDb) + assert.equal(await exists(testDb), false) + await d.dropDatabaseAsync() + assert.equal(await exists(testDb), false) + }) + + it('Check that TTL indexes are reset', async () => { + await d.ensureIndexAsync({ fieldName: 'expire', expireAfterSeconds: 10 }) + const date = new Date() + await d.insertAsync({ hello: 'world', expire: new Date(date.getTime() - 1000 * 20) }) // expired by 10 seconds + assert.equal((await d.findAsync({})).length, 0) // the TTL makes it so that the document is not returned + await d.dropDatabaseAsync() + assert.equal(d.getAllData().length, 0) + assert.equal(await exists(testDb), false) + await d.loadDatabaseAsync() + await d.insertAsync({ hello: 'world', expire: new Date(date.getTime() - 1000 * 20) }) + assert.equal((await d.findAsync({})).length, 1) // the TTL index should have been removed + await d.compactDatafileAsync() + assert.equal(await exists(testDb), true) + }) + + it('Check that the buffer is reset', async () => { + await d.dropDatabaseAsync() + // these 3 will hang until load + d.insertAsync({ hello: 'world' }) + d.insertAsync({ hello: 'world' }) + d.insertAsync({ hello: 'world' }) + + assert.equal(d.getAllData().length, 0) + + await d.dropDatabaseAsync() + d.insertAsync({ hi: 'world' }) + await d.loadDatabaseAsync() // will trigger the buffer execution + + assert.equal(d.getAllData().length, 1) + assert.equal(d.getAllData()[0].hi, 'world') + }) + }) // ==== End of 'dropDatabase' ==== }) diff --git a/test/persistence.test.js b/test/persistence.test.js index d83fc24..d0f11fb 100755 --- a/test/persistence.test.js +++ b/test/persistence.test.js @@ -446,7 +446,7 @@ describe('Persistence', function () { done() }) - d.persistence.compactDatafile() + d.compactDatafile() }) describe('Serialization hooks', function () { diff --git a/test_lac/openFds.test.js b/test_lac/openFds.test.js index f9e72e4..fe3d2e7 100644 --- a/test_lac/openFds.test.js +++ b/test_lac/openFds.test.js @@ -32,7 +32,7 @@ const test = async () => { filehandles.push(filehandle) } } catch (error) { - console.error(`An unexpected error occurred when opening file not too many times at i: ${i} with error: ${error}`) + console.error(`An unexpected error occurred when opening file not too many times with error: ${error}`) process.exit(1) } finally { for (const filehandle of filehandles) { @@ -50,7 +50,7 @@ const test = async () => { await db.persistence.persistCachedDatabaseAsync() } } catch (error) { - console.error(`Got unexpected error during one persistence operation at ${i}: with error: ${error}`) + console.error(`Got unexpected error during one persistence operation with error: ${error}`) } } try { From 2c2af5084122013f87db4a44a4b79cc65d1a66a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 17 Jan 2022 21:41:00 +0100 Subject: [PATCH 50/65] update readme, persistence tests and typings --- README.md | 44 +++++++---- index.d.ts | 18 ++++- test/persistence.test.js | 160 +++++++++++++++++++++++++++++++++++++++ test/utils.test.js | 4 + 4 files changed, 211 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 4acf51e..be5b576 100755 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ version. Don't hesitate to open an issue if it breaks something in your project. The rest of the readme will only show the Promise-based API, the full -documentation is available in the [`docs`](./docs) directory of the repository. +documentation is available in the [`docs`](./API.md) directory of the repository. ### Creating/loading a database @@ -87,20 +87,38 @@ await db.users.loadDatabaseAsync() await db.robots.loadDatabaseAsync() ``` +### Dropping a database + +Since v3.0.0, you can drop the database by using [`Datastore#dropDatabaseAsync`](./API.md#Datastore+dropDatabaseAsync): +```js +const Datastore = require('@seald-io/nedb') +const db = new Datastore() +await d.insertAsync({ hello: 'world' }) +await d.dropDatabaseAsync() +assert.equal(d.getAllData().length, 0) +assert.equal(await exists(testDb), false) +``` + +It is not recommended to keep using an instance of Datastore when its database +has been dropped as it may have some unintended side effects. + ### Persistence -Under the hood, NeDB's [persistence](./docs/Persistence.md) uses an append-only +Under the hood, NeDB's [persistence](./API.md#Persistence) uses an append-only format, meaning that all updates and deletes actually result in lines added at the end of the datafile, for performance reasons. The database is automatically compacted (i.e. put back in the one-line-per-document format) every time you load each database within your application. +**Breaking change**: since v3.0.0, calling methods of `yourDatabase.persistence` +is deprecated. The same functions exists directly on the `Datastore`. + You can manually call the compaction function -with [`yourDatabase#persistence#compactDatafileAsync`](./API.md#Persistence+compactDatafileAsync). +with [`yourDatabase#compactDatafileAsync`](./API.md#Datastore+compactDatafileAsync). You can also set automatic compaction at regular intervals -with [`yourDatabase#persistence#setAutocompactionInterval`](./API.md#Persistence+setAutocompactionInterval), -and stop automatic compaction with [`yourDatabase#persistence#stopAutocompaction`](./API.md#Persistence+stopAutocompaction). +with [`yourDatabase#setAutocompactionInterval`](./API.md#Datastore+setAutocompactionInterval), +and stop automatic compaction with [`yourDatabase#stopAutocompaction`](./API.md#Datastore+stopAutocompaction). ### Inserting documents @@ -385,7 +403,7 @@ const docs = await db.findAsync({ [`Datastore#findAsync`](./API.md#Datastore+findAsync), [`Datastore#findOneAsync`](./API.md#Datastore+findOneAsync) and [`Datastore#countAsync`](./API.md#Datastore+countAsync) don't -actually return a `Promise`, but a [`Cursor`](./docs/Cursor.md) which is a +actually return a `Promise`, but a [`Cursor`](./API.md#Cursor) which is a [`Thenable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#thenable_objects) which calls [`Cursor#execAsync`](./API.md#Cursor+execAsync) when awaited. @@ -783,16 +801,16 @@ for the `browser` field. And this is [done by default by Metro](https://github.c for the `react-native` field. This is done for: -- the [storage module](./docs/storage.md) which uses Node.js `fs`. It is - [replaced in the browser](./docs/storageBrowser.md) by one that uses +- the [storage module](./lib/storage.js) which uses Node.js `fs`. It is + [replaced in the browser](./browser-version/lib/storage.browser.js) by one that uses [localforage](https://github.com/localForage/localForage), and - [in `react-native`](./docs/storageBrowser.md) by one that uses + [in `react-native`](./browser-version/lib/storage.react-native.js) by one that uses [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage) -- the [customUtils module](./docs/customUtilsNode.md) which uses Node.js +- the [customUtils module](./browser-version/lib/customUtils.js) which uses Node.js `crypto` module. It is replaced by a good enough shim to generate ids that uses `Math.random()`. -- the [byline module](./docs/byline.md) which uses Node.js `stream` +- the [byline module](./browser-version/lib/byline.js) which uses Node.js `stream` (a fork of [`node-byline`](https://github.com/jahewson/node-byline) included in - the repo because it is unmaintained). It isn't used int the browser nor + the repo because it is unmaintained). It isn't used in the browser nor react-native versions, therefore it is shimmed with an empty object. ## Performance @@ -849,7 +867,7 @@ to make it manageable: pollute the code. * Don't forget tests for your new feature. Also don't forget to run the whole test suite before submitting to make sure you didn't introduce regressions. -* Update the JSDoc and regenerate [the markdown files](./docs). +* Update the JSDoc and regenerate [the markdown docs](./API.md). * Update the readme accordingly. ## License diff --git a/index.d.ts b/index.d.ts index ae85d47..7cba2bb 100644 --- a/index.d.ts +++ b/index.d.ts @@ -24,6 +24,18 @@ declare class Nedb extends EventEmitter { loadDatabaseAsync(): Promise; + dropDatabase(callback?: (err: Error |null) => void): void; + + dropDatabaseAsync(): Promise; + + compactDatafile(callback?: (err: Error |null) => void): void; + + compactDatafileAsync(): Promise; + + setAutocompactionInterval(interval: number): void; + + stopAutocompaction(): void; + getAllData(): T[]; ensureIndex(options: Nedb.EnsureIndexOptions, callback?: (err: Error | null) => void): void; @@ -101,8 +113,6 @@ declare namespace Nedb { afterSerialization?(line: string): string; corruptAlertThreshold?: number; compareStrings?(a: string, b: string): number; - /** @deprecated */ - nodeWebkitAppName?: string; } interface UpdateOptions { @@ -123,9 +133,13 @@ declare namespace Nedb { } interface Persistence { + /** @deprecated */ compactDatafile(): void; + /** @deprecated */ compactDatafileAsync(): Promise; + /** @deprecated */ setAutocompactionInterval(interval: number): void; + /** @deprecated */ stopAutocompaction(): void; } } diff --git a/test/persistence.test.js b/test/persistence.test.js index d0f11fb..774af46 100755 --- a/test/persistence.test.js +++ b/test/persistence.test.js @@ -10,6 +10,8 @@ const Persistence = require('../lib/persistence') const storage = require('../lib/storage') const { execFile, fork } = require('child_process') const { callbackify } = require('util') +const { existsCallback } = require('./utils.test') +const { ensureFileDoesntExistAsync } = require('../lib/storage') const Readable = require('stream').Readable const { assert } = chai @@ -1054,4 +1056,162 @@ describe('Persistence', function () { }) }) }) // ==== End of 'Prevent dataloss when persisting data' ==== + + describe('dropDatabase', function () { + it('deletes data in memory', done => { + const inMemoryDB = new Datastore({ inMemoryOnly: true }) + inMemoryDB.insert({ hello: 'world' }, err => { + assert.equal(err, null) + inMemoryDB.dropDatabase(err => { + assert.equal(err, null) + assert.equal(inMemoryDB.getAllData().length, 0) + return done() + }) + }) + }) + + it('deletes data in memory & on disk', done => { + d.insert({ hello: 'world' }, err => { + if (err) return done(err) + d.dropDatabase(err => { + if (err) return done(err) + assert.equal(d.getAllData().length, 0) + existsCallback(testDb, bool => { + assert.equal(bool, false) + done() + }) + }) + }) + }) + + it('check that executor is drained before drop', done => { + for (let i = 0; i < 100; i++) { + d.insert({ hello: 'world' }) // no await + } + d.dropDatabase(err => { // it should await the end of the inserts + if (err) return done(err) + assert.equal(d.getAllData().length, 0) + existsCallback(testDb, bool => { + assert.equal(bool, false) + done() + }) + }) + }) + + it('check that autocompaction is stopped', done => { + d.setAutocompactionInterval(5000) + d.insert({ hello: 'world' }, err => { + if (err) return done(err) + d.dropDatabase(err => { + if (err) return done(err) + assert.equal(d.autocompactionIntervalId, null) + assert.equal(d.getAllData().length, 0) + existsCallback(testDb, bool => { + assert.equal(bool, false) + done() + }) + }) + }) + }) + + it('check that we can reload and insert afterwards', done => { + d.insert({ hello: 'world' }, err => { + if (err) return done(err) + d.dropDatabase(err => { + if (err) return done(err) + assert.equal(d.getAllData().length, 0) + existsCallback(testDb, bool => { + assert.equal(bool, false) + d.loadDatabase(err => { + if (err) return done(err) + d.insert({ hello: 'world' }, err => { + if (err) return done(err) + assert.equal(d.getAllData().length, 1) + d.compactDatafile(err => { + if (err) return done(err) + existsCallback(testDb, bool => { + assert.equal(bool, true) + done() + }) + }) + }) + }) + }) + }) + }) + }) + + it('check that we can dropDatatabase if the file is already deleted', done => { + callbackify(ensureFileDoesntExistAsync)(testDb, err => { + if (err) return done(err) + existsCallback(testDb, bool => { + assert.equal(bool, false) + d.dropDatabase(err => { + if (err) return done(err) + existsCallback(testDb, bool => { + assert.equal(bool, false) + done() + }) + }) + }) + }) + }) + + it('Check that TTL indexes are reset', done => { + d.ensureIndex({ fieldName: 'expire', expireAfterSeconds: 10 }) + const date = new Date() + d.insert({ hello: 'world', expire: new Date(date.getTime() - 1000 * 20) }, err => { // expired by 10 seconds + if (err) return done(err) + d.find({}, (err, docs) => { + if (err) return done(err) + assert.equal(docs.length, 0) // the TTL makes it so that the document is not returned + d.dropDatabase(err => { + if (err) return done(err) + assert.equal(d.getAllData().length, 0) + existsCallback(testDb, bool => { + assert.equal(bool, false) + d.loadDatabase(err => { + if (err) return done(err) + d.insert({ hello: 'world', expire: new Date(date.getTime() - 1000 * 20) }, err => { + if (err) return done(err) + d.find({}, (err, docs) => { + if (err) return done(err) + assert.equal(docs.length, 1) // the TTL makes it so that the document is not returned + d.compactDatafile(err => { + if (err) return done(err) + existsCallback(testDb, bool => { + assert.equal(bool, true) + done() + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + + it('Check that the buffer is reset', done => { + d.dropDatabase(err => { + if (err) return done(err) + // these 3 will hang until load + d.insert({ hello: 'world' }) + d.insert({ hello: 'world' }) + d.insert({ hello: 'world' }) + assert.equal(d.getAllData().length, 0) + d.dropDatabase(err => { + if (err) return done(err) + d.insert({ hi: 'world' }) + d.loadDatabase(err => { + if (err) return done(err) + assert.equal(d.getAllData().length, 1) + assert.equal(d.getAllData()[0].hi, 'world') + done() + }) + }) + }) + }) + }) // ==== End of 'dropDatabase' ==== }) diff --git a/test/utils.test.js b/test/utils.test.js index d7272ee..214c31f 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -33,10 +33,14 @@ const wait = delay => new Promise(resolve => { }) const exists = path => fs.access(path, fsConstants.FS_OK).then(() => true, () => false) +// eslint-disable-next-line node/no-callback-literal +const existsCallback = (path, callback) => fs.access(path, fsConstants.FS_OK).then(() => callback(true), () => callback(false)) + module.exports.whilst = whilst module.exports.apply = apply module.exports.waterfall = waterfall module.exports.each = each module.exports.wait = wait module.exports.exists = exists +module.exports.existsCallback = existsCallback module.exports.callbackify = callbackify From da532719af06f15a56527c00f65a93fb97acf7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Mon, 17 Jan 2022 21:52:56 +0100 Subject: [PATCH 51/65] update changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b62e29c..85eda5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,8 +51,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Using `Datastore#persistence#stopAutocompaction` is now deprecated, please use `Datastore#stopAutocompaction` instead. ## Removed -- The option for passing `options.nodeWebkitAppName` to the Datastore and the Persistence constructors has been removed. - - `Persistence.getNWAppFilename`; +- The option for passing `options.nodeWebkitAppName` to the Datastore and the Persistence constructors has been removed, subsequently, the static method `Persistence.getNWAppFilename` has been removed as well; +- Compatibility with node < 10.1.0 (we use `fs.promises`). ## [2.2.1] - 2022-01-18 From 9694697da4070f7bc27130dbdef54b63fabcdbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 18 Jan 2022 09:16:22 +0100 Subject: [PATCH 52/65] update changelog and readme --- CHANGELOG.md | 3 +++ README.md | 29 +++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85eda5b..9908e36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `Executor#push` replaced with `Executor#pushAsync` which is substantially different; - Storage modules : callback-based functions have been replaced with promise-based functions. - Model module: it has been slightly re-written for clarity, but no changes in its interface was made. +- Typings were updated accordingly. ## Deprecated - Using a `string` in the constructor of NeDB is now deprecated. @@ -62,6 +63,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [2.2.0] - 2021-10-29 ### Added - Include a `"react-native"` version (heavily inspired from [react-native-local-mongdb](https://github.com/antoniopresto/react-native-local-mongodb)). +### Changed +- The browser version uses `browser-version/lib/storage.browser.js` instead of `browser-version/lib/storage.js` in the `"browser"` field of the package.json. ## [2.1.0] - 2021-10-21 Thanks to [@eliot-akira](https://github.com/eliot-akira) for the amazing work on file streaming. diff --git a/README.md b/README.md index be5b576..ebe2903 100755 --- a/README.md +++ b/README.md @@ -29,12 +29,7 @@ const Datastore = require('@seald-io/nedb') ## Documentation The API is a subset of MongoDB's API (the most used operations). -### JSDoc -You can read the markdown version of the JSDoc [in the docs directory](./API.md). -It is generated by running `npm run generateDocs:markdown`. - -### Promise-based interface vs callback-based interface -Since version 3.0.0, NeDB provides a Promise-based equivalent for each function +Since version [3.0.0](./CHANGELOG.md#300---unreleased), NeDB provides a Promise-based equivalent for each function which is suffixed with `Async`, for example `loadDatabaseAsync`. The original callback-based interface is still available, fully retro-compatible @@ -44,7 +39,25 @@ version. Don't hesitate to open an issue if it breaks something in your project. The rest of the readme will only show the Promise-based API, the full -documentation is available in the [`docs`](./API.md) directory of the repository. +documentation is available in the [`API.md`](./API.md) file at the root of the +repository. It is generated by running `npm run generateDocs:markdown`. + +* [Creating/loading a database](#creatingloading-a-database) +* [Dropping a database](#dropping-a-database) +* [Persistence](#persistence) +* [Inserting documents](#inserting-documents) +* [Finding documents](#finding-documents) + * [Basic Querying](#basic-querying) + * [Operators ($lt, $lte, $gt, $gte, $in, $nin, $ne, $stat, $regex)](#operators-lt-lte-gt-gte-in-nin-ne-stat-regex) + * [Array fields](#array-fields) + * [Logical operators $or, $and, $not, $where](#logical-operators-or-and-not-where) + * [Sorting and paginating](#sorting-and-paginating) + * [Projections](#projections) +* [Counting documents](#counting-documents) +* [Updating documents](#updating-documents) +* [Removing documents](#removing-documents) +* [Indexing](#indexing) +* [Other environments](#other-environments) ### Creating/loading a database @@ -110,7 +123,7 @@ the end of the datafile, for performance reasons. The database is automatically compacted (i.e. put back in the one-line-per-document format) every time you load each database within your application. -**Breaking change**: since v3.0.0, calling methods of `yourDatabase.persistence` +**Breaking change**: [since v3.0.0](./CHANGELOG.md#300---unreleased), calling methods of `yourDatabase.persistence` is deprecated. The same functions exists directly on the `Datastore`. You can manually call the compaction function From df358b91a64509f4ac5f331b80a51db3d3e57a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 18 Jan 2022 09:20:51 +0100 Subject: [PATCH 53/65] update readme to include mention of nedb-promises & bump reloadTimeUpperBound to avoid tests failing randomly --- README.md | 1 + test/db.async.test.js | 2 +- test/db.test.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ebe2903..7ca048c 100755 --- a/README.md +++ b/README.md @@ -852,6 +852,7 @@ kind of datasets (20MB for 10,000 2KB documents). ## Use in other services * An ODM for NeDB: [follicle](https://github.com/seald/follicle) +* A layer to add a promise-only interface: [nedb-promises](https://www.npmjs.com/package/nedb-promises) ## Modernization diff --git a/test/db.async.test.js b/test/db.async.test.js index 3482142..3da4b26 100644 --- a/test/db.async.test.js +++ b/test/db.async.test.js @@ -8,7 +8,7 @@ const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') const { wait } = require('./utils.test') const { exists } = require('./utils.test.js') -const reloadTimeUpperBound = 60 // In ms, an upper bound for the reload time used to check createdAt and updatedAt +const reloadTimeUpperBound = 200 // In ms, an upper bound for the reload time used to check createdAt and updatedAt describe('Database async', function () { let d diff --git a/test/db.test.js b/test/db.test.js index 11e2387..70c9561 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -8,7 +8,7 @@ const model = require('../lib/model') const Datastore = require('../lib/datastore') const Persistence = require('../lib/persistence') const { callbackify } = require('util') -const reloadTimeUpperBound = 60 // In ms, an upper bound for the reload time used to check createdAt and updatedAt +const reloadTimeUpperBound = 200 // In ms, an upper bound for the reload time used to check createdAt and updatedAt const { assert } = chai chai.should() From cb58b78781f631835fa4be11fba090d409a4b7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 18 Jan 2022 09:35:33 +0100 Subject: [PATCH 54/65] remove useless gitignore entry --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 81b6ed6..e7cc9b2 100755 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,3 @@ browser-version/node_modules browser-version/out test-results -docs-html From b7651d1ae32225f7a3dc380beea34744a6bfaf0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 18 Jan 2022 11:30:53 +0100 Subject: [PATCH 55/65] 3.0.0-2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65b8e80..af33e53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-1", + "version": "3.0.0-2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@seald-io/nedb", - "version": "3.0.0-1", + "version": "3.0.0-2", "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", diff --git a/package.json b/package.json index 2ff1cfd..03c351b 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-1", + "version": "3.0.0-2", "files": [ "lib/**/*.js", "browser-version/**/*.js", From 24000a9d3f9434a2a8fe5be170157fa618ab6cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Tue, 18 Jan 2022 14:49:46 +0100 Subject: [PATCH 56/65] 3.0.0-3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index af33e53..04f6cf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-2", + "version": "3.0.0-3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@seald-io/nedb", - "version": "3.0.0-2", + "version": "3.0.0-3", "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", diff --git a/package.json b/package.json index 03c351b..45d9f87 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-2", + "version": "3.0.0-3", "files": [ "lib/**/*.js", "browser-version/**/*.js", From fa0918477c0d1133dc7d2f82ee2915300c2f69a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 20 Jan 2022 18:24:37 +0100 Subject: [PATCH 57/65] add util in deps --- package-lock.json | 5806 ++++++++++++++++++--------------------------- package.json | 5 +- 2 files changed, 2343 insertions(+), 3468 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04f6cf4..c0601c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", - "localforage": "^1.9.0" + "localforage": "^1.9.0", + "util": "^0.12.4" }, "devDependencies": { "@react-native-async-storage/async-storage": "^1.15.9", @@ -31,6 +32,7 @@ "mocha-junit-reporter": "^2.0.0", "path-browserify": "^1.0.1", "process": "^0.11.10", + "react-native": "^0.66.0", "semver": "^7.3.5", "source-map-loader": "^2.0.2", "standard": "^16.0.3", @@ -39,48 +41,47 @@ "ts-jest": "^27.0.7", "ts-node": "^10.3.0", "typescript": "^4.4.4", - "util": "^0.12.4", "webpack": "^5.37.0", "webpack-cli": "^4.7.0", "xvfb-maybe": "^0.2.1" } }, "node_modules/@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.0" + "@babel/highlight": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", + "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", - "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helpers": "^7.16.5", - "@babel/parser": "^7.16.5", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz", + "integrity": "sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -115,12 +116,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", - "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", + "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0", + "@babel/types": "^7.16.8", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -138,40 +139,38 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", + "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", "dev": true, - "peer": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", - "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", + "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" }, @@ -192,19 +191,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", - "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz", + "integrity": "sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -214,13 +212,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", - "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz", + "integrity": "sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-annotate-as-pure": "^7.16.7", "regexpu-core": "^4.7.1" }, "engines": { @@ -231,11 +228,10 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", - "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.13.0", "@babel/helper-module-imports": "^7.12.13", @@ -255,179 +251,173 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", - "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", - "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", + "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", - "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", + "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", "dev": true, - "peer": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", - "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", + "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", "dev": true, - "peer": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", - "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", - "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", + "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-wrap-function": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", - "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", + "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -438,7 +428,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.16.0" }, @@ -447,72 +436,71 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", - "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", + "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-function-name": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", - "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", "dev": true, "dependencies": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", + "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -592,9 +580,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.16.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", - "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.8.tgz", + "integrity": "sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -604,13 +592,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", - "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", + "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -620,15 +608,15 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", - "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", + "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0" + "@babel/plugin-proposal-optional-chaining": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -638,14 +626,14 @@ } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", - "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", + "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -656,14 +644,13 @@ } }, "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", - "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", + "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -673,14 +660,14 @@ } }, "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", - "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz", + "integrity": "sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -691,13 +678,13 @@ } }, "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", - "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", + "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -708,14 +695,13 @@ } }, "node_modules/@babel/plugin-proposal-export-default-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.5.tgz", - "integrity": "sha512-pU4aCS+AzGjDD/6LnwSmeelmtqfMSjzQxs7+/AS673bYsshK1XZm9eth6OkgivVscQM8XdkVYhrb6tPFVTBVHA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.7.tgz", + "integrity": "sha512-+cENpW1rgIjExn+o5c8Jw/4BuH4eGKKYvkMB8/0ZxFQ9mC0t4z09VsPIwNg6waF69QYC81zxGeAsREGuqQoKeg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-export-default-from": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-export-default-from": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -725,13 +711,13 @@ } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", - "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", + "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -742,13 +728,13 @@ } }, "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", - "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", + "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -759,13 +745,13 @@ } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", - "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", + "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -776,13 +762,12 @@ } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", - "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", + "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -793,13 +778,13 @@ } }, "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", - "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", + "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -810,17 +795,16 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", - "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz", + "integrity": "sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==", "dev": true, - "peer": true, "dependencies": { "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.5" + "@babel/plugin-transform-parameters": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -830,13 +814,12 @@ } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", - "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", + "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -847,13 +830,12 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", - "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", + "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -865,14 +847,14 @@ } }, "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", - "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.7.tgz", + "integrity": "sha512-7twV3pzhrRxSwHeIvFE6coPgvo+exNDOiGUMg39o2LiLo1Y+4aKpfkcLGcg1UHonzorCt7SNXnoMyCnnIOA8Sw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -882,15 +864,15 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", - "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", + "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -901,14 +883,14 @@ } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", - "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", + "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=4" @@ -974,7 +956,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -983,13 +964,12 @@ } }, "node_modules/@babel/plugin-syntax-export-default-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.5.tgz", - "integrity": "sha512-tvY55nhq4mSG9WbM7IZcLIhdc5jzIZu0PQKJHtZ16+dF7oBxKbqV/Z0e9ta2zaLMvUjH+3rJv1hbZ0+lpXzuFQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.7.tgz", + "integrity": "sha512-4C3E4NsrLOgftKaTYTULhHsuQrGv3FHrBzOMDiS7UYKIpgGBkAdawg4h+EI8zPeK9M0fiIIh72hIwsI24K7MbA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1012,13 +992,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.5.tgz", - "integrity": "sha512-Nrx+7EAJx1BieBQseZa2pavVH2Rp7hADK2xn7coYqVbWRu9C2OFizYcsKo6TrrqJkJl+qF/+Qqzrk/+XDu4GnA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz", + "integrity": "sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1052,13 +1031,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz", - "integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", + "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1171,12 +1149,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", - "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1186,13 +1164,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", - "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", + "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1202,15 +1179,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", - "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", + "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5" + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8" }, "engines": { "node": ">=6.9.0" @@ -1220,13 +1196,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", - "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", + "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1236,13 +1211,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", - "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", + "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1252,19 +1226,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", - "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", - "dev": true, - "peer": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", + "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" }, "engines": { @@ -1275,13 +1248,12 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", - "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", + "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1291,13 +1263,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", - "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz", + "integrity": "sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1307,14 +1278,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", - "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", + "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1324,13 +1295,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", - "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", + "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1340,14 +1311,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", - "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", + "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1357,14 +1327,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.5.tgz", - "integrity": "sha512-skE02E/MptkZdBS4HwoRhjWXqeKQj0BWKEAPfPC+8R4/f6bjQqQ9Nftv/+HkxWwnVxh/E2NV9TNfzLN5H/oiBw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz", + "integrity": "sha512-mzmCq3cNsDpZZu9FADYYyfZJIOrSONmHcop2XEKPdBNMa4PDC4eEvcOvzZaCNcjKu72v0XQlA5y1g58aLRXdYg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-flow": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-flow": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1374,13 +1343,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", - "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", + "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1390,14 +1358,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", - "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", + "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1407,13 +1375,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", - "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", + "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1423,13 +1390,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", - "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", + "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1439,14 +1405,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", - "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", + "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1457,15 +1423,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", - "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", + "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1476,16 +1441,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", - "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz", + "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1496,14 +1461,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", - "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", + "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1513,13 +1478,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", - "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", + "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0" + "@babel/helper-create-regexp-features-plugin": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1529,13 +1494,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", - "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", + "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1545,13 +1510,12 @@ } }, "node_modules/@babel/plugin-transform-object-assign": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.5.tgz", - "integrity": "sha512-KVuJ7sWf6bcXawKVH6ZDQFYcOulObt1IOvl/gvNrkNXzmFf1IdgKOy4thmVomReleXqffMbptmXXMl3zPI7zHw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.7.tgz", + "integrity": "sha512-R8mawvm3x0COTJtveuoqZIjNypn2FjfvXZr4pSQ8VhEFBuQGBz4XhHasZtHXjgXU4XptZ4HtGof3NoYc93ZH9Q==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1561,14 +1525,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", - "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", + "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1578,13 +1541,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", - "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", + "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1594,13 +1556,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", - "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", + "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1610,13 +1571,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.5.tgz", - "integrity": "sha512-dHYCOnzSsXFz8UcdNQIHGvg94qPL/teF7CCiCEMRxmA1G2p5Mq4JnKVowCDxYfiQ9D7RstaAp9kwaSI+sXbnhw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz", + "integrity": "sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1626,17 +1586,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.5.tgz", - "integrity": "sha512-+arLIz1d7kmwX0fKxTxbnoeG85ONSnLpvdODa4P3pc1sS7CV1hfmtYWufkW/oYsPnkDrEeQFxhUWcFnrXW7jQQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz", + "integrity": "sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-jsx": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1646,13 +1605,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.5.tgz", - "integrity": "sha512-fvwq+jir1Vn4f5oBS0H/J/gD5CneTD53MHs+NMjlHcha4Sq35fwxI5RtmJGEBXO+M93f/eeD9cAhRPhmLyJiVw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.7.tgz", + "integrity": "sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1662,13 +1620,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.5.tgz", - "integrity": "sha512-/eP+nZywJntGLjSPjksAnM9/ELIs3RbiEuTu2/zAOzwwBcfiu+m/iptEq1lERUUtSXubYSHVnVHMr13GR+TwPw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.7.tgz", + "integrity": "sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1678,11 +1635,10 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", - "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", + "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", "dev": true, - "peer": true, "dependencies": { "regenerator-transform": "^0.14.2" }, @@ -1694,13 +1650,13 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", - "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", + "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1710,16 +1666,15 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz", - "integrity": "sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.8.tgz", + "integrity": "sha512-6Kg2XHPFnIarNweZxmzbgYnnWsXxkx9WQUVk2sksBRL80lBC1RAQV3wQagWxdCHiYHqPN+oenwNIuttlYgIbQQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", "semver": "^6.3.0" }, @@ -1735,19 +1690,17 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", - "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", + "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1757,13 +1710,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", - "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", + "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" }, "engines": { @@ -1774,13 +1726,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", - "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", + "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1790,13 +1741,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", - "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", + "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1806,13 +1756,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", - "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", + "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1822,15 +1772,14 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", - "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", + "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.16.0" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-typescript": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1840,13 +1789,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", - "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", + "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1856,14 +1805,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", - "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", + "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -1873,33 +1821,33 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", - "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", - "dev": true, - "peer": true, - "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-async-generator-functions": "^7.16.5", - "@babel/plugin-proposal-class-properties": "^7.16.5", - "@babel/plugin-proposal-class-static-block": "^7.16.5", - "@babel/plugin-proposal-dynamic-import": "^7.16.5", - "@babel/plugin-proposal-export-namespace-from": "^7.16.5", - "@babel/plugin-proposal-json-strings": "^7.16.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", - "@babel/plugin-proposal-numeric-separator": "^7.16.5", - "@babel/plugin-proposal-object-rest-spread": "^7.16.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", - "@babel/plugin-proposal-optional-chaining": "^7.16.5", - "@babel/plugin-proposal-private-methods": "^7.16.5", - "@babel/plugin-proposal-private-property-in-object": "^7.16.5", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.8.tgz", + "integrity": "sha512-9rNKgVCdwHb3z1IlbMyft6yIXIeP3xz6vWvGaLHrJThuEIqWfHb0DNBH9VuTgnDfdbUDhkmkvMZS/YMCtP7Elg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-async-generator-functions": "^7.16.8", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-proposal-dynamic-import": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.16.7", + "@babel/plugin-proposal-json-strings": "^7.16.7", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-numeric-separator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-private-methods": "^7.16.7", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", @@ -1914,44 +1862,44 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.5", - "@babel/plugin-transform-async-to-generator": "^7.16.5", - "@babel/plugin-transform-block-scoped-functions": "^7.16.5", - "@babel/plugin-transform-block-scoping": "^7.16.5", - "@babel/plugin-transform-classes": "^7.16.5", - "@babel/plugin-transform-computed-properties": "^7.16.5", - "@babel/plugin-transform-destructuring": "^7.16.5", - "@babel/plugin-transform-dotall-regex": "^7.16.5", - "@babel/plugin-transform-duplicate-keys": "^7.16.5", - "@babel/plugin-transform-exponentiation-operator": "^7.16.5", - "@babel/plugin-transform-for-of": "^7.16.5", - "@babel/plugin-transform-function-name": "^7.16.5", - "@babel/plugin-transform-literals": "^7.16.5", - "@babel/plugin-transform-member-expression-literals": "^7.16.5", - "@babel/plugin-transform-modules-amd": "^7.16.5", - "@babel/plugin-transform-modules-commonjs": "^7.16.5", - "@babel/plugin-transform-modules-systemjs": "^7.16.5", - "@babel/plugin-transform-modules-umd": "^7.16.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", - "@babel/plugin-transform-new-target": "^7.16.5", - "@babel/plugin-transform-object-super": "^7.16.5", - "@babel/plugin-transform-parameters": "^7.16.5", - "@babel/plugin-transform-property-literals": "^7.16.5", - "@babel/plugin-transform-regenerator": "^7.16.5", - "@babel/plugin-transform-reserved-words": "^7.16.5", - "@babel/plugin-transform-shorthand-properties": "^7.16.5", - "@babel/plugin-transform-spread": "^7.16.5", - "@babel/plugin-transform-sticky-regex": "^7.16.5", - "@babel/plugin-transform-template-literals": "^7.16.5", - "@babel/plugin-transform-typeof-symbol": "^7.16.5", - "@babel/plugin-transform-unicode-escapes": "^7.16.5", - "@babel/plugin-transform-unicode-regex": "^7.16.5", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-block-scoped-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-classes": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-dotall-regex": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-function-name": "^7.16.7", + "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-member-expression-literals": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.16.8", + "@babel/plugin-transform-modules-systemjs": "^7.16.7", + "@babel/plugin-transform-modules-umd": "^7.16.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", + "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-object-super": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-property-literals": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.16.7", + "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-shorthand-properties": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-sticky-regex": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.16.7", + "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-unicode-escapes": "^7.16.7", + "@babel/plugin-transform-unicode-regex": "^7.16.7", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.0", + "@babel/types": "^7.16.8", "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.19.1", + "core-js-compat": "^3.20.2", "semver": "^6.3.0" }, "engines": { @@ -1972,15 +1920,14 @@ } }, "node_modules/@babel/preset-flow": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.16.5.tgz", - "integrity": "sha512-rmC6Nznp4V55N4Zfec87jwd14TdREqwKVJFM/6Z2wTwoeZQr56czjaPRCezqzqc8TsHF7aLP1oczjadIQ058gw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.16.7.tgz", + "integrity": "sha512-6ceP7IyZdUYQ3wUVqyRSQXztd1YmFHWI4Xv11MIqAlE4WqxBSd/FZ61V9k+TS5Gd4mkHOtQtPp9ymRpxH4y1Ug==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-flow-strip-types": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-transform-flow-strip-types": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -2007,15 +1954,14 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", - "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", + "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.16.1" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-transform-typescript": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -2025,11 +1971,10 @@ } }, "node_modules/@babel/register": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.5.tgz", - "integrity": "sha512-NpluD+cToBiZiDsG3y9rtIcqDyivsahpaM9csfyfiq1qQWduSmihUZ+ruIqqSDGjZKZMJfgAElo9x2YWlOQuRw==", + "version": "7.16.9", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.9.tgz", + "integrity": "sha512-jJ72wcghdRIlENfvALcyODhNoGE5j75cYHdC+aQMh6cU/P86tiiXTp9XYZct1UxUMo/4+BgQRyNZEGx0KWGS+g==", "dev": true, - "peer": true, "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -2049,7 +1994,6 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "peer": true, "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -2063,7 +2007,6 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -2073,17 +2016,15 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver" } }, "node_modules/@babel/runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", - "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", + "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", "dev": true, - "peer": true, "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -2092,33 +2033,33 @@ } }, "node_modules/@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", - "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.5", - "@babel/types": "^7.16.0", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.8.tgz", + "integrity": "sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.8", + "@babel/types": "^7.16.8", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2127,12 +2068,12 @@ } }, "node_modules/@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2150,7 +2091,6 @@ "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, - "peer": true, "dependencies": { "exec-sh": "^0.3.2", "minimist": "^1.2.0" @@ -2266,15 +2206,13 @@ "version": "9.2.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", "integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@hapi/topo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dev": true, - "peer": true, "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -2305,15 +2243,15 @@ } }, "node_modules/@jest/console": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", - "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.4.2", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "slash": "^3.0.0" }, @@ -2322,15 +2260,15 @@ } }, "node_modules/@jest/core": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", - "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", - "@jest/reporters": "^27.4.5", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -2339,18 +2277,18 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.5", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-resolve-dependencies": "^27.4.5", - "jest-runner": "^27.4.5", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", - "jest-watcher": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", @@ -2373,7 +2311,6 @@ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.4.2.tgz", "integrity": "sha512-aSSCAJwUNX4R1hJQoyimsND5l+2EsFgzlepS8NuOJJHjXij/UdxYFngac44tmv9IYdI+kglAyORg0plt4/aFMQ==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^27.4.2" }, @@ -2382,31 +2319,31 @@ } }, "node_modules/@jest/environment": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", - "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.4.2", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2" + "jest-mock": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", - "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" }, "engines": { @@ -2414,29 +2351,29 @@ } }, "node_modules/@jest/globals": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", - "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/types": "^27.4.2", - "expect": "^27.4.2" + "expect": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", - "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.2", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -2445,14 +2382,14 @@ "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.4.5", - "jest-resolve": "^27.4.5", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -2486,12 +2423,12 @@ } }, "node_modules/@jest/test-result": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", - "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", + "@jest/console": "^27.4.6", "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" @@ -2501,38 +2438,38 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", - "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", "dev": true, "dependencies": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-runtime": "^27.4.5" + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-regex-util": "^27.4.0", "jest-util": "^27.4.2", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -2558,15 +2495,15 @@ } }, "node_modules/@react-native-async-storage/async-storage": { - "version": "1.15.14", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.14.tgz", - "integrity": "sha512-eJF2horabXazwszCyyXDe4w7sBSWlB0WPA8akKXuN2n7WXKHYeQJPN41lS9OahrhSZuZwqftNFE9VWgPXA8wyA==", + "version": "1.15.15", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.15.tgz", + "integrity": "sha512-Ss2FqWP9HC5AhCyP6ydRERSwWb8QMTLknETB8cp2+tbEUhu7Q/S5+e0QIrF0D2Z/YZTUvQ2MP7uXzt9FLG9OYQ==", "dev": true, "dependencies": { "merge-options": "^3.0.4" }, "peerDependencies": { - "react-native": "^0.0.0-0 || ^0.60.6 || ^0.61.5 || ^0.62.2 || ^0.63.2 || ^0.64.0 || ^0.65.0 || ^0.66.0 || 1000.0.0" + "react-native": "^0.0.0-0 || 0.60 - 0.66 || 1000.0.0" } }, "node_modules/@react-native-community/cli": { @@ -2574,7 +2511,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-6.3.1.tgz", "integrity": "sha512-UQ77AkGvPzdwJt6qhYXUyDMP1v2rdCcIlrhU48FOcAhGX+N/LCL9Cp/Ic6CkiiSHJdktbgiEEJ2srprXH8nzVg==", "dev": true, - "peer": true, "dependencies": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", "@react-native-community/cli-hermes": "^6.3.0", @@ -2623,7 +2559,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-6.0.0-rc.0.tgz", "integrity": "sha512-achYcPPoWa9D02C5tn6TBzjeY443wQTyx37urptc75JpZ7gR5YHsDyIEEWa3DDYp1va9zx/iGg+uZ/hWw07GAw==", "dev": true, - "peer": true, "dependencies": { "serve-static": "^1.13.1" } @@ -2633,7 +2568,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-6.3.0.tgz", "integrity": "sha512-Uhbm9bubyZLZ12vFCIfWbE/Qi3SBTbYIN/TC08EudTLhv/KbPomCQnmFsnJ7AXQFuOZJs73mBxoEAYSbRbwyVA==", "dev": true, - "peer": true, "dependencies": { "@react-native-community/cli-platform-android": "^6.3.0", "@react-native-community/cli-tools": "^6.2.0", @@ -2647,7 +2581,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.0.tgz", "integrity": "sha512-d5ufyYcvrZoHznYm5bjBXaiHIJv552t5gYtQpnUsxBhHSQ8QlaNmlLUyeSPRDfOw4ND9b0tPHqs4ufwx6vp/fQ==", "dev": true, - "peer": true, "dependencies": { "@react-native-community/cli-tools": "^6.2.0", "chalk": "^4.1.2", @@ -2666,7 +2599,6 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "peer": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -2683,7 +2615,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, - "peer": true, "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -2702,7 +2633,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, - "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -2715,7 +2645,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2725,7 +2654,6 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, - "peer": true, "dependencies": { "path-key": "^2.0.0" }, @@ -2738,7 +2666,6 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -2748,7 +2675,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver" } @@ -2758,7 +2684,6 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "peer": true, "dependencies": { "shebang-regex": "^1.0.0" }, @@ -2771,7 +2696,6 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2781,7 +2705,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2794,7 +2717,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.2.0.tgz", "integrity": "sha512-k15MhExxLiLDDZOeuPgvTxbp0CsoLQQpk2Du0HjZDePqqWcKJylQqMZru1o8HuQHPcEr+b71HIs5V+lKyFYpfg==", "dev": true, - "peer": true, "dependencies": { "@react-native-community/cli-tools": "^6.2.0", "chalk": "^4.1.2", @@ -2811,7 +2733,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-6.2.0.tgz", "integrity": "sha512-JfmzuFNzOr+dFTUQJo1rV0t87XAqgHRTMYXNleQVt8otOVCk1FSCgKlgqMdvQc/FCx2ZjoMWEEV/g0LrPI8Etw==", "dev": true, - "peer": true, "dependencies": { "@react-native-community/cli-server-api": "^6.2.0", "@react-native-community/cli-tools": "^6.2.0", @@ -2830,7 +2751,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-6.2.0.tgz", "integrity": "sha512-OnbnYclhoDpjge33QO5Slhfn0DsmLzzAgyrSCnb24HhSqwq7ObjMHaLpoEhpajzLG71wq5oKh0APEQjiL4Mknw==", "dev": true, - "peer": true, "dependencies": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", "@react-native-community/cli-tools": "^6.2.0", @@ -2848,7 +2768,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -2865,7 +2784,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/yargs-parser": "*" } @@ -2875,7 +2793,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -2891,7 +2808,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dev": true, - "peer": true, "dependencies": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -2902,7 +2818,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz", "integrity": "sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA==", "dev": true, - "peer": true, "dependencies": { "appdirsjs": "^1.2.4", "chalk": "^4.1.2", @@ -2919,7 +2834,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -2929,7 +2843,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-6.0.0.tgz", "integrity": "sha512-K493Fk2DMJC0ZM8s8gnfseKxGasIhuDaCUDeLZcoCSFlrjKEuEs1BKKEJiev0CARhKEXKOyyp/uqYM9nWhisNw==", "dev": true, - "peer": true, "dependencies": { "ora": "^3.4.0" } @@ -2939,7 +2852,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -2956,7 +2868,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/yargs-parser": "*" } @@ -2965,15 +2876,13 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@react-native-community/cli/node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "peer": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -2990,7 +2899,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver" } @@ -3000,7 +2908,6 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3010,7 +2917,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, - "peer": true, "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -3029,7 +2935,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, - "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -3042,7 +2947,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3052,7 +2956,6 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, - "peer": true, "dependencies": { "path-key": "^2.0.0" }, @@ -3065,7 +2968,6 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -3075,7 +2977,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -3091,7 +2992,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -3101,7 +3001,6 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "peer": true, "dependencies": { "shebang-regex": "^1.0.0" }, @@ -3114,7 +3013,6 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3124,7 +3022,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "peer": true, "dependencies": { "ansi-regex": "^4.1.0" }, @@ -3137,7 +3034,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -3147,7 +3043,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -3159,22 +3054,19 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", "integrity": "sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@react-native/normalize-color": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-1.0.0.tgz", "integrity": "sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@react-native/polyfills": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-2.0.0.tgz", "integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@seald-io/binary-search-tree": { "version": "1.0.2", @@ -3186,7 +3078,6 @@ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", "dev": true, - "peer": true, "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -3195,15 +3086,13 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@sinonjs/commons": { "version": "1.8.3", @@ -3223,6 +3112,15 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@socket.io/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -3257,9 +3155,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -3270,9 +3168,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -3316,9 +3214,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", - "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.2.tgz", + "integrity": "sha512-nQxgB8/Sg+QKhnV8e0WzPpxjIGT3tuJDDzybkDi8ItE/IgTlHo07U0shaIjzhcvQxlq9SDRE42lsJ23uvEgJ2A==", "dev": true, "dependencies": { "@types/estree": "*", @@ -3326,9 +3224,9 @@ } }, "node_modules/@types/eslint-scope": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.2.tgz", - "integrity": "sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", "dev": true, "dependencies": { "@types/eslint": "*", @@ -3351,9 +3249,9 @@ } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "node_modules/@types/istanbul-lib-report": { @@ -3375,9 +3273,9 @@ } }, "node_modules/@types/jest": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", - "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", "dev": true, "dependencies": { "jest-diff": "^27.0.0", @@ -3397,15 +3295,15 @@ "dev": true }, "node_modules/@types/node": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.1.tgz", - "integrity": "sha512-NXKvBVUzIbs6ylBwmOwHFkZS2EXCcjnqr8ZCRNaXBkHAf+3mn/rPcJxwrzuc6movh8fxQAsUUfYklJ/EG+hZqQ==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz", + "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==", "dev": true }, "node_modules/@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", "dev": true }, "node_modules/@types/stack-utils": { @@ -3640,7 +3538,6 @@ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "dev": true, - "peer": true, "dependencies": { "event-target-shim": "^5.0.0" }, @@ -3652,8 +3549,7 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=", - "dev": true, - "peer": true + "dev": true }, "node_modules/accepts": { "version": "1.3.7", @@ -3669,9 +3565,9 @@ } }, "node_modules/acorn": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", - "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3770,8 +3666,7 @@ "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ansi-colors": { "version": "4.1.1", @@ -3823,7 +3718,6 @@ "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==", "dev": true, - "peer": true, "dependencies": { "colorette": "^1.0.7", "slice-ansi": "^2.0.0", @@ -3835,7 +3729,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -3845,7 +3738,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "peer": true, "dependencies": { "ansi-regex": "^4.1.0" }, @@ -3894,8 +3786,7 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.6.tgz", "integrity": "sha512-D8wJNkqMCeQs3kLasatELsddox/Xqkhp+J07iXGyL54fVN7oc+nmNfYzGuCs1IEP6uBw+TfpuO3JKwc+lECy4w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/arg": { "version": "4.1.3", @@ -3917,7 +3808,6 @@ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3927,7 +3817,6 @@ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3937,15 +3826,14 @@ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/array-back": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.0.tgz", - "integrity": "sha512-mixVv03GOOn/ubHE4STQ+uevX42ETdk0JoMVEjNkSOCT7WgERh7C8/+NyhWYNpE3BN69pxFyJIBcF7CxWz/+4A==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true, "engines": { "node": ">=12.17" @@ -3955,8 +3843,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true, - "peer": true + "dev": true }, "node_modules/array-includes": { "version": "3.1.4", @@ -3981,22 +3868,19 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true, - "peer": true + "dev": true }, "node_modules/array-reduce": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true, - "peer": true + "dev": true }, "node_modules/array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4039,8 +3923,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true, - "peer": true + "dev": true }, "node_modules/assertion-error": { "version": "1.1.0", @@ -4056,7 +3939,6 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4066,7 +3948,6 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", "dev": true, - "peer": true, "dependencies": { "tslib": "^2.0.1" }, @@ -4079,7 +3960,6 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -4089,7 +3969,6 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "dev": true, - "peer": true, "dependencies": { "lodash": "^4.17.14" } @@ -4098,8 +3977,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/asynckit": { "version": "0.4.0", @@ -4112,7 +3990,6 @@ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true, - "peer": true, "bin": { "atob": "bin/atob.js" }, @@ -4124,7 +4001,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -4137,21 +4013,20 @@ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", "dev": true, - "peer": true, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", "dev": true, "dependencies": { - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -4169,7 +4044,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "dev": true, - "peer": true, "dependencies": { "object.assign": "^4.1.0" } @@ -4190,31 +4064,6 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-jest-hoist": { "version": "27.4.0", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", @@ -4231,14 +4080,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", - "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", + "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", "dev": true, - "peer": true, "dependencies": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.0", + "@babel/helper-define-polyfill-provider": "^0.3.1", "semver": "^6.1.1" }, "peerDependencies": { @@ -4250,33 +4098,30 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", - "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz", + "integrity": "sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.0", - "core-js-compat": "^3.18.0" + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.20.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", - "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", "dev": true, - "peer": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.0" + "@babel/helper-define-polyfill-provider": "^0.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -4286,8 +4131,7 @@ "version": "7.0.0-beta.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", @@ -4317,7 +4161,6 @@ "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", "dev": true, - "peer": true, "dependencies": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", @@ -4378,7 +4221,6 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, - "peer": true, "dependencies": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -4397,7 +4239,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^1.0.0" }, @@ -4405,15 +4246,6 @@ "node": ">=0.10.0" } }, - "node_modules/base64-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", - "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -4432,8 +4264,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/base64id": { "version": "2.0.0", @@ -4449,7 +4280,6 @@ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", "dev": true, - "peer": true, "engines": { "node": ">=0.6" } @@ -4510,7 +4340,6 @@ "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", "dev": true, - "peer": true, "dependencies": { "stream-buffers": "2.2.x" } @@ -4520,7 +4349,6 @@ "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.0.tgz", "integrity": "sha512-zgmaRvT6AN1JpPPV+S0a1/FAtoxSreYDccZGIqEMSvZl9DMe70mJ7MFzpxa1X+gHVdkToE2haRUHHMiW1OdejA==", "dev": true, - "peer": true, "dependencies": { "big-integer": "1.6.x" }, @@ -4635,7 +4463,6 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, - "peer": true, "dependencies": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -4678,7 +4505,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -4692,7 +4518,6 @@ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, - "peer": true, "dependencies": { "callsites": "^2.0.0" }, @@ -4705,7 +4530,6 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -4715,7 +4539,6 @@ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, - "peer": true, "dependencies": { "caller-callsite": "^2.0.0" }, @@ -4742,9 +4565,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001291", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001291.tgz", - "integrity": "sha512-roMV5V0HNGgJ88s42eE70sstqGW/gwFndosYrikHthw98N5tLnOTxFqMLQjZVRxTWFlJ4rn+MsgXrR7MDPY4jA==", + "version": "1.0.30001300", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz", + "integrity": "sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA==", "dev": true, "funding": { "type": "opencollective", @@ -4756,7 +4579,6 @@ "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", "dev": true, - "peer": true, "dependencies": { "rsvp": "^4.8.4" }, @@ -4837,10 +4659,16 @@ } }, "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4883,7 +4711,6 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, - "peer": true, "dependencies": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -4899,7 +4726,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^0.1.0" }, @@ -4912,7 +4738,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -4925,7 +4750,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -4938,7 +4762,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -4951,7 +4774,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -4964,7 +4786,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -4979,7 +4800,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4989,7 +4809,6 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, - "peer": true, "dependencies": { "restore-cursor": "^2.0.0" }, @@ -5002,7 +4821,6 @@ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", "dev": true, - "peer": true, "engines": { "node": ">=6" }, @@ -5026,7 +4844,6 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true, - "peer": true, "engines": { "node": ">=0.8" } @@ -5079,7 +4896,6 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, - "peer": true, "dependencies": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -5110,8 +4926,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/colors": { "version": "1.4.0", @@ -5138,8 +4953,7 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/command-line-args": { "version": "5.2.0", @@ -5251,8 +5065,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true, - "peer": true + "dev": true }, "node_modules/component-emitter": { "version": "1.3.0", @@ -5265,7 +5078,6 @@ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, - "peer": true, "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -5278,7 +5090,6 @@ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, - "peer": true, "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -5297,7 +5108,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -5307,7 +5117,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -5316,8 +5125,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "node_modules/concat-map": { "version": "0.0.1", @@ -5405,17 +5213,15 @@ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/core-js-compat": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.0.tgz", - "integrity": "sha512-relrah5h+sslXssTTOkvqcC/6RURifB0W5yhYBdBkaPYa5/2KBMiog3XiD+s3TwEHWxInWVv4Jx2/Lw0vng+IQ==", + "version": "3.20.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz", + "integrity": "sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw==", "dev": true, - "peer": true, "dependencies": { "browserslist": "^4.19.1", "semver": "7.0.0" @@ -5430,7 +5236,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -5439,8 +5244,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cors": { "version": "2.8.5", @@ -5460,7 +5264,6 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, - "peer": true, "dependencies": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", @@ -5557,8 +5360,7 @@ "version": "1.10.7", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", - "dev": true, - "peer": true + "dev": true }, "node_modules/debug": { "version": "4.3.3", @@ -5600,7 +5402,6 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true, - "peer": true, "engines": { "node": ">=0.10" } @@ -5652,7 +5453,6 @@ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, - "peer": true, "dependencies": { "clone": "^1.0.2" } @@ -5661,7 +5461,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "dependencies": { "object-keys": "^1.0.12" }, @@ -5674,7 +5473,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -5696,8 +5494,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true, - "peer": true + "dev": true }, "node_modules/depd": { "version": "1.1.2", @@ -5712,8 +5509,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true, - "peer": true + "dev": true }, "node_modules/detect-newline": { "version": "3.1.0", @@ -5832,9 +5628,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.24", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.24.tgz", - "integrity": "sha512-erwx5r69B/WFfFuF2jcNN0817BfDBdC4765kQ6WltOMuwsimlQo3JTEq0Cle+wpHralwdeX3OfAtw/mHxPK0Wg==", + "version": "1.4.48", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.48.tgz", + "integrity": "sha512-RT3SEmpv7XUA+tKXrZGudAWLDpa7f8qmhjcLaM6OD/ERxjQ/zAojT8/Vvo0BSzbArkElFZ1WyZ9FuwAYbkdBNA==", "dev": true }, "node_modules/emittery": { @@ -5869,15 +5665,14 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "peer": true, "dependencies": { "once": "^1.4.0" } }, "node_modules/engine.io": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.1.tgz", - "integrity": "sha512-AyMc20q8JUUdvKd46+thc9o7yCZ6iC6MoBCChG5Z1XmFMpp+2+y/oKvwpZTUJB0KCjxScw1dV9c2h5pjiYBLuQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.2.tgz", + "integrity": "sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -5896,12 +5691,12 @@ } }, "node_modules/engine.io-parser": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz", - "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", + "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", "dev": true, "dependencies": { - "base64-arraybuffer": "~1.0.1" + "@socket.io/base64-arraybuffer": "~1.0.2" }, "engines": { "node": ">=10.0.0" @@ -5991,7 +5786,6 @@ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", "dev": true, - "peer": true, "dependencies": { "stackframe": "^1.1.1" } @@ -6001,7 +5795,6 @@ "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", "dev": true, - "peer": true, "dependencies": { "accepts": "~1.3.7", "escape-html": "~1.0.3" @@ -6014,7 +5807,6 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", @@ -6054,7 +5846,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -6083,15 +5874,12 @@ "dev": true }, "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/escodegen": { @@ -6240,14 +6028,13 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", "dev": true, "dependencies": { "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "engines": { "node": ">=4" @@ -6329,18 +6116,6 @@ "node": ">=4" } }, - "node_modules/eslint-module-utils/node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-plugin-es": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", @@ -6835,7 +6610,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -6845,7 +6619,6 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -6869,8 +6642,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/execa": { "version": "5.1.1", @@ -6909,7 +6681,6 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, - "peer": true, "dependencies": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -6928,7 +6699,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -6938,7 +6708,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^0.1.0" }, @@ -6951,7 +6720,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -6964,7 +6732,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -6977,7 +6744,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -6990,7 +6756,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -7003,7 +6768,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -7016,7 +6780,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -7031,7 +6794,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7041,7 +6803,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7050,38 +6811,23 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "node_modules/expect": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", - "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", - "ansi-styles": "^5.0.0", "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-regex-util": "^27.4.0" + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -7093,7 +6839,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, - "peer": true, "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -7107,7 +6852,6 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, - "peer": true, "dependencies": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -7127,7 +6871,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^1.0.0" }, @@ -7140,7 +6883,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -7153,7 +6895,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7275,7 +7016,6 @@ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, - "peer": true, "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -7290,7 +7030,6 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, - "peer": true, "dependencies": { "locate-path": "^3.0.0" }, @@ -7303,7 +7042,6 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, - "peer": true, "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -7317,7 +7055,6 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "peer": true, "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -7331,7 +7068,6 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, - "peer": true, "dependencies": { "p-limit": "^2.0.0" }, @@ -7344,7 +7080,6 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -7354,7 +7089,6 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -7364,7 +7098,6 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, - "peer": true, "dependencies": { "find-up": "^3.0.0" }, @@ -7377,7 +7110,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver" } @@ -7455,7 +7187,6 @@ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==", "dev": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -7485,7 +7216,6 @@ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7493,8 +7223,7 @@ "node_modules/foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, "node_modules/form-data": { "version": "3.0.1", @@ -7515,7 +7244,6 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, - "peer": true, "dependencies": { "map-cache": "^0.2.2" }, @@ -7528,7 +7256,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -7579,8 +7306,7 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -7619,7 +7345,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -7666,7 +7391,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -7683,7 +7407,6 @@ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7736,9 +7459,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "node_modules/growl": { @@ -7775,7 +7498,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -7787,7 +7509,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7805,7 +7526,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -7817,7 +7537,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -7833,7 +7552,6 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, - "peer": true, "dependencies": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -7848,7 +7566,6 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, - "peer": true, "dependencies": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -7862,7 +7579,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -7875,7 +7591,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -7888,7 +7603,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -7909,22 +7623,19 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/hermes-engine/-/hermes-engine-0.9.0.tgz", "integrity": "sha512-r7U+Y4P2Qg/igFVZN+DpT7JFfXUn1MM4dFne8aW+cCrF6RRymof+VqrUHs1kl07j8h8V2CNesU19RKgWbr3qPw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/hermes-parser": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.4.7.tgz", "integrity": "sha512-jc+zCtXbtwTiXoMAoXOHepxAaGVFIp89wwE9qcdwnMd/uGVEtPoY8FaFSsx0ThPvyKirdR2EsIIDVrpbSXz1Ag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/hermes-profile-transformer": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz", "integrity": "sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==", "dev": true, - "peer": true, "dependencies": { "source-map": "^0.7.3" }, @@ -7937,7 +7648,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true, - "peer": true, "engines": { "node": ">= 8" } @@ -8058,7 +7768,6 @@ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", "dev": true, - "peer": true, "bin": { "image-size": "bin/image-size.js" }, @@ -8076,7 +7785,6 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, - "peer": true, "dependencies": { "caller-path": "^2.0.0", "resolve-from": "^3.0.0" @@ -8090,15 +7798,14 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true, - "peer": true, "engines": { "node": ">=4" } }, "node_modules/import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { "pkg-dir": "^4.2.0", @@ -8109,6 +7816,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { @@ -8133,14 +7843,12 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, "dependencies": { "get-intrinsic": "^1.1.0", "has": "^1.0.3", @@ -8164,7 +7872,6 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, - "peer": true, "dependencies": { "loose-envify": "^1.0.0" } @@ -8173,15 +7880,13 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true, - "peer": true + "dev": true }, "node_modules/is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "peer": true, "dependencies": { "kind-of": "^6.0.0" }, @@ -8193,7 +7898,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -8215,7 +7919,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -8239,7 +7942,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -8261,7 +7963,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -8274,7 +7975,6 @@ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, - "peer": true, "dependencies": { "ci-info": "^2.0.0" }, @@ -8286,13 +7986,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -8306,7 +8005,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "peer": true, "dependencies": { "kind-of": "^6.0.0" }, @@ -8318,7 +8016,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8334,7 +8031,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "peer": true, "dependencies": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -8349,7 +8045,6 @@ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8359,7 +8054,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, - "peer": true, "dependencies": { "is-plain-object": "^2.0.4" }, @@ -8381,7 +8075,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -8399,7 +8092,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8426,7 +8118,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -8447,7 +8138,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8489,7 +8179,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -8505,7 +8194,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8526,7 +8214,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -8541,7 +8228,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -8556,7 +8242,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -8593,7 +8278,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -8606,7 +8290,6 @@ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8616,7 +8299,6 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -8625,8 +8307,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "peer": true + "dev": true }, "node_modules/isbinaryfile": { "version": "4.0.8", @@ -8665,14 +8346,15 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "engines": { @@ -8717,9 +8399,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.1.tgz", - "integrity": "sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -8730,14 +8412,14 @@ } }, "node_modules/jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", - "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", "dev": true, "dependencies": { - "@jest/core": "^27.4.5", + "@jest/core": "^27.4.7", "import-local": "^3.0.2", - "jest-cli": "^27.4.5" + "jest-cli": "^27.4.7" }, "bin": { "jest": "bin/jest.js" @@ -8769,27 +8451,27 @@ } }, "node_modules/jest-circus": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", - "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" @@ -8799,21 +8481,21 @@ } }, "node_modules/jest-cli": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", - "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", "dev": true, "dependencies": { - "@jest/core": "^27.4.5", - "@jest/test-result": "^27.4.2", + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.4.5", + "jest-config": "^27.4.7", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "prompts": "^2.0.1", "yargs": "^16.2.0" }, @@ -8833,32 +8515,32 @@ } }, "node_modules/jest-config": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", - "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.4.5", + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", "@jest/types": "^27.4.2", - "babel-jest": "^27.4.5", + "babel-jest": "^27.4.6", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.5", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.5", + "jest-jasmine2": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-runner": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0" }, "engines": { @@ -8874,15 +8556,15 @@ } }, "node_modules/jest-diff": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", - "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", "dev": true, "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^27.4.0", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -8901,32 +8583,32 @@ } }, "node_modules/jest-each": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", - "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-environment-jsdom": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", - "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2", "jsdom": "^16.6.0" }, @@ -8935,16 +8617,16 @@ } }, "node_modules/jest-environment-node": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", - "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" }, "engines": { @@ -8961,9 +8643,9 @@ } }, "node_modules/jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", @@ -8975,7 +8657,7 @@ "jest-regex-util": "^27.4.0", "jest-serializer": "^27.4.0", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "micromatch": "^4.0.4", "walker": "^1.0.7" }, @@ -8987,28 +8669,27 @@ } }, "node_modules/jest-jasmine2": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", - "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", "dev": true, "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "throat": "^6.0.1" }, "engines": { @@ -9016,37 +8697,37 @@ } }, "node_modules/jest-leak-detector": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", - "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", "dev": true, "dependencies": { "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", - "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-message-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", - "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", @@ -9055,7 +8736,7 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -9064,9 +8745,9 @@ } }, "node_modules/jest-mock": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", - "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", @@ -9103,18 +8784,18 @@ } }, "node_modules/jest-resolve": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", - "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-pnp-resolver": "^1.2.2", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" @@ -9124,29 +8805,29 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", - "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.5" + "jest-snapshot": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-runner": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", - "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -9154,15 +8835,15 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", - "jest-haste-map": "^27.4.5", - "jest-leak-detector": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", - "jest-runtime": "^27.4.5", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "source-map-support": "^0.5.6", "throat": "^6.0.1" }, @@ -9171,37 +8852,33 @@ } }, "node_modules/jest-runtime": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", - "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/globals": "^27.4.4", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", - "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" + "strip-bom": "^4.0.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -9221,34 +8898,32 @@ } }, "node_modules/jest-snapshot": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", - "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", "dev": true, "dependencies": { "@babel/core": "^7.7.2", "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.5", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "semver": "^7.3.2" }, "engines": { @@ -9273,9 +8948,9 @@ } }, "node_modules/jest-validate": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", - "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", @@ -9283,16 +8958,16 @@ "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { "node": ">=10" @@ -9302,12 +8977,12 @@ } }, "node_modules/jest-watcher": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", - "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", "dev": true, "dependencies": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -9320,9 +8995,9 @@ } }, "node_modules/jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", "dev": true, "dependencies": { "@types/node": "*", @@ -9353,7 +9028,6 @@ "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.8.tgz", "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==", "dev": true, - "peer": true, "bin": { "jetifier": "bin/jetify", "jetifier-standalone": "bin/jetifier-standalone", @@ -9365,7 +9039,6 @@ "resolved": "https://registry.npmjs.org/joi/-/joi-17.5.0.tgz", "integrity": "sha512-R7hR50COp7StzLnDi4ywOXHrBrgNXuUUfJWIR5lPY5Bm/pOD3jZaTwpluUXVLRWcoWZxkrHBBJ5hLxgnlehbdw==", "dev": true, - "peer": true, "dependencies": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", @@ -9406,15 +9079,13 @@ "version": "250230.2.1", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250230.2.1.tgz", "integrity": "sha512-KmxeBlRjwoqCnBBKGsihFtvsBHyUFlBxJPK4FzeYcIuBfdjv6jFys44JITAgSTbQD+vIdwMEfyZklsuQX0yI1Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/jscodeshift": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.11.0.tgz", "integrity": "sha512-SdRK2C7jjs4k/kT2mwtO07KJN9RnjxtKn03d9JVj6c3j9WwaLcFYsICYDnLAzY0hp+wG2nxl+Cm2jWLiNVYb8g==", "dev": true, - "peer": true, "dependencies": { "@babel/core": "^7.1.6", "@babel/parser": "^7.1.6", @@ -9448,7 +9119,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "peer": true, "dependencies": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -9470,7 +9140,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -9483,7 +9152,6 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, - "peer": true, "dependencies": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -9499,7 +9167,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -9512,7 +9179,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9522,7 +9188,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -9535,7 +9200,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -9548,7 +9212,6 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, - "peer": true, "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -9573,7 +9236,6 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, - "peer": true, "dependencies": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -9587,7 +9249,6 @@ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -9680,40 +9341,10 @@ "node": ">=12.17" } }, - "node_modules/jsdoc/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jsdoc/node_modules/klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/jsdoc/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "dependencies": { "abab": "^2.0.5", @@ -9815,7 +9446,6 @@ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -9834,15 +9464,15 @@ } }, "node_modules/karma": { - "version": "6.3.9", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.9.tgz", - "integrity": "sha512-E/MqdLM9uVIhfuyVnrhlGBu4miafBdXEAEqCmwdEMh3n17C7UWC/8Kvm3AYKr91gc7scutekZ0xv6rxRaUCtnw==", + "version": "6.3.11", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.11.tgz", + "integrity": "sha512-QGUh4yXgizzDNPLB5nWTvP+wysKexngbyLVWFOyikB661hpa2RZLf5anZQzqliWtAQuYVep0ot0D1U7UQKpsxQ==", "dev": true, "dependencies": { "body-parser": "^1.19.0", "braces": "^3.0.2", "chokidar": "^3.5.1", - "colors": "^1.4.0", + "colors": "1.4.0", "connect": "^3.7.0", "di": "^0.0.1", "dom-serialize": "^2.2.1", @@ -9945,12 +9575,11 @@ } }, "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, - "peer": true, - "optionalDependencies": { + "dependencies": { "graceful-fs": "^4.1.9" } }, @@ -10071,8 +9700,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -10102,8 +9730,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.truncate": { "version": "4.4.2", @@ -10148,7 +9775,6 @@ "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz", "integrity": "sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==", "dev": true, - "peer": true, "dependencies": { "ansi-fragments": "^0.2.1", "dayjs": "^1.8.15", @@ -10163,7 +9789,6 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -10175,7 +9800,6 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -10185,7 +9809,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10199,15 +9822,13 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/logkitty/node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "peer": true, "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -10230,7 +9851,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "peer": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -10307,7 +9927,6 @@ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -10317,7 +9936,6 @@ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, - "peer": true, "dependencies": { "object-visit": "^1.0.0" }, @@ -10411,7 +10029,6 @@ "resolved": "https://registry.npmjs.org/metro/-/metro-0.66.2.tgz", "integrity": "sha512-uNsISfcQ3iKKSHoN5Q+LAh0l3jeeg7ZcNZ/4BAHGsk02erA0OP+l2m+b5qYVoPptHz9Oc3KyG5oGJoTu41pWjg==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/core": "^7.14.0", @@ -10475,7 +10092,6 @@ "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.66.2.tgz", "integrity": "sha512-3F+vsVubUPJYKfVMeol8/7pd8CC287Rw92QYzJD8LEmI980xcgwMUEVBZ0UIAUwlLgiJG/f4Mwhuji2EeBXrPg==", "dev": true, - "peer": true, "dependencies": { "@babel/core": "^7.14.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", @@ -10492,7 +10108,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -10502,7 +10117,6 @@ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.66.2.tgz", "integrity": "sha512-aJ/7fc/Xkofw8Fqa51OTDhBzBz26mmpIWrXAZcPdQ8MSTt883EWncxeCEjasc79NJ89BRi7sOkkaWZo2sXlKvw==", "dev": true, - "peer": true, "dependencies": { "@babel/core": "^7.14.0", "hermes-parser": "0.4.7", @@ -10515,7 +10129,6 @@ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.66.2.tgz", "integrity": "sha512-5QCYJtJOHoBSbL3H4/Fpl36oA697C3oYHqsce+Hk/dh2qtODUGpS3gOBhvP1B8iB+H8jJMyR75lZq129LJEsIQ==", "dev": true, - "peer": true, "dependencies": { "metro-core": "0.66.2", "mkdirp": "^0.5.1", @@ -10526,15 +10139,25 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.66.2.tgz", "integrity": "sha512-WtkNmRt41qOpHh1MkNA4nLiQ/m7iGL90ysSKD+fcLqlUnOBKJptPQm0ZUv8Kfqk18ddWX2KmsSbq+Sf3I6XohQ==", + "dev": true + }, + "node_modules/metro-cache/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, - "peer": true + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } }, "node_modules/metro-cache/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -10547,7 +10170,6 @@ "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.66.2.tgz", "integrity": "sha512-0C+PrKKIBNNzLZUKN/8ZDJS2U5FLMOTXDWbvBHIdqb6YXz8WplXR2+xlSlaSCCi5b+GR7cWFWUNeKA4GQS1/AQ==", "dev": true, - "peer": true, "dependencies": { "cosmiconfig": "^5.0.5", "jest-validate": "^26.5.2", @@ -10562,7 +10184,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -10579,17 +10200,15 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/metro-config/node_modules/camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -10602,7 +10221,6 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, - "peer": true, "engines": { "node": ">= 10.14.2" } @@ -10612,7 +10230,6 @@ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "camelcase": "^6.0.0", @@ -10630,7 +10247,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -10646,7 +10262,6 @@ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.66.2.tgz", "integrity": "sha512-JieLZkef/516yxXYvQxWnf3OWw5rcgWRy76K8JV/wr/i8LGVGulPAXlIi445/QZzXVydzRVASKAEVqyxM5F4mA==", "dev": true, - "peer": true, "dependencies": { "jest-haste-map": "^26.5.2", "lodash.throttle": "^4.1.1", @@ -10658,7 +10273,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -10675,7 +10289,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/yargs-parser": "*" } @@ -10685,7 +10298,6 @@ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", @@ -10713,7 +10325,6 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", "dev": true, - "peer": true, "engines": { "node": ">= 10.14.2" } @@ -10723,7 +10334,6 @@ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "graceful-fs": "^4.2.4" @@ -10737,7 +10347,6 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "@types/node": "*", @@ -10755,7 +10364,6 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -10769,15 +10377,13 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.66.2.tgz", "integrity": "sha512-nCVL1g9uR6vrw5+X1wjwZruRyMkndnzGRMqjqoljf+nGEqBTD607CR7elXw4fMWn/EM+1y0Vdq5altUu9LdgCA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro-inspector-proxy": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.66.2.tgz", "integrity": "sha512-gnLc9121eznwP0iiA9tCBW8qZjwIsCgwHWMF1g1Qaki9le9tzeJv3dK4/lFNGxyfSaLO7vahQEhsEYsiRnTROg==", "dev": true, - "peer": true, "dependencies": { "connect": "^3.6.5", "debug": "^2.2.0", @@ -10793,7 +10399,6 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -10805,7 +10410,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -10815,7 +10419,6 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -10824,15 +10427,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro-inspector-proxy/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10847,7 +10448,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dev": true, - "peer": true, "dependencies": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -10857,15 +10457,13 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro-inspector-proxy/node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "peer": true, "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -10888,7 +10486,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "peer": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -10902,7 +10499,6 @@ "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.66.2.tgz", "integrity": "sha512-7TUK+L5CmB5x1PVnFbgmjzHW4CUadq9H5jgp0HfFoWT1skXAyEsx0DHkKDXwnot0khnNhBOEfl62ctQOnE110Q==", "dev": true, - "peer": true, "dependencies": { "uglify-es": "^3.1.9" } @@ -10912,7 +10508,6 @@ "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.66.2.tgz", "integrity": "sha512-H/nLBAz0MgfDloSe1FjyH4EnbokHFdncyERvLPXDACY3ROVRCeUyFNo70ywRGXW2NMbrV4H7KUyU4zkfWhC2HQ==", "dev": true, - "peer": true, "dependencies": { "@babel/core": "^7.14.0", "@babel/plugin-proposal-class-properties": "^7.0.0", @@ -10964,7 +10559,6 @@ "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.66.2.tgz", "integrity": "sha512-z1ab7ihIT0pJrwgi9q2IH+LcW/xUWMQ0hH+Mrk7wbKQB0RnJdXFoxphrfoVHBHMUu+TBPetUcEkKawkK1e7Cng==", "dev": true, - "peer": true, "dependencies": { "@babel/core": "^7.14.0", "babel-preset-fbjs": "^3.4.0", @@ -10983,7 +10577,6 @@ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.66.2.tgz", "integrity": "sha512-pXQAJR/xauRf4kWFj2/hN5a77B4jLl0Fom5I3PHp6Arw/KxSBp0cnguXpGLwNQ6zQC0nxKCoYGL9gQpzMnN7Hw==", "dev": true, - "peer": true, "dependencies": { "absolute-path": "^0.0.0" } @@ -10992,15 +10585,13 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.66.2.tgz", "integrity": "sha512-vFhKBk2ot9FS4b+2v0OTa/guCF/QDAOJubY0CNg7PzCS5+w4y3IvZIcPX4SSS1t8pYEZBLvtdtTDarlDl81xmg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro-source-map": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.66.2.tgz", "integrity": "sha512-038tFmB7vSh73VQcDWIbr5O1m+WXWyYafDaOy+1A/2K308YP0oj33gbEgDnZsLZDwcJ+xt1x6KUEBIzlX4YGeQ==", "dev": true, - "peer": true, "dependencies": { "@babel/traverse": "^7.14.0", "@babel/types": "^7.0.0", @@ -11017,7 +10608,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11027,7 +10617,6 @@ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.66.2.tgz", "integrity": "sha512-u+DeQHyAFXVD7mVP+GST/894WHJ3i/U8oEJFnT7U3P52ZuLgX8n4tMNxhqZU12RcLR6etF8143aP0Ktx1gFLEQ==", "dev": true, - "peer": true, "dependencies": { "invariant": "^2.2.4", "metro-source-map": "0.66.2", @@ -11048,7 +10637,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11058,7 +10646,6 @@ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.66.2.tgz", "integrity": "sha512-KTvqplh0ut7oDKovvDG6yzXM02R6X+9b2oVG+qYq8Zd3aCGTi51ASx4ThCNkAHyEvCuJdYg9fxXTL+j+wvhB5w==", "dev": true, - "peer": true, "dependencies": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", @@ -11072,7 +10659,6 @@ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.66.2.tgz", "integrity": "sha512-dO4PtYOMGB7Vzte8aIzX39xytODhmbJrBYPu+zYzlDjyefJZT7BkZ0LkPIThtyJi96xWcGqi9JBSo0CeRupAHw==", "dev": true, - "peer": true, "dependencies": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", @@ -11094,7 +10680,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -11111,7 +10696,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/yargs-parser": "*" } @@ -11120,15 +10704,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -11140,7 +10722,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -11150,7 +10731,6 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11160,7 +10740,6 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0", @@ -11172,7 +10751,6 @@ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", @@ -11200,7 +10778,6 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", "dev": true, - "peer": true, "engines": { "node": ">= 10.14.2" } @@ -11210,7 +10787,6 @@ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "graceful-fs": "^4.2.4" @@ -11224,7 +10800,6 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "@types/node": "*", @@ -11242,7 +10817,6 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -11257,24 +10831,42 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, - "peer": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, + "node_modules/metro/node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/metro/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/metro/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -11287,7 +10879,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11296,15 +10887,13 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -11319,7 +10908,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dev": true, - "peer": true, "dependencies": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -11329,15 +10917,13 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/metro/node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "peer": true, "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -11360,7 +10946,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "peer": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -11447,7 +11032,6 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, - "peer": true, "dependencies": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -11457,15 +11041,15 @@ } }, "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/mkdirp2": { @@ -11475,9 +11059,9 @@ "dev": true }, "node_modules/mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.4.tgz", + "integrity": "sha512-+q2aV5VlJZuLgCWoBvGI5zEwPF9eEI0kr/sAA9Jm4xMND7RfIEyF8JE7C0JIg8WXRG+P1sdIAb5ccoHPlXLzcw==", "dev": true, "dependencies": { "@ungap/promise-all-settled": "1.1.2", @@ -11542,6 +11126,18 @@ "ms": "2.0.0" } }, + "node_modules/mocha-junit-reporter/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mocha-junit-reporter/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -11554,6 +11150,27 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/mocha/node_modules/debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -11577,6 +11194,18 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mocha/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -11714,7 +11343,6 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, - "peer": true, "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -11757,15 +11385,13 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/nocache": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==", "dev": true, - "peer": true, "engines": { "node": ">=4.0.0" } @@ -11775,7 +11401,6 @@ "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", "dev": true, - "peer": true, "dependencies": { "minimatch": "^3.0.2" }, @@ -11784,38 +11409,42 @@ } }, "node_modules/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dev": true, - "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, "engines": { "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "dev": true, - "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -11838,7 +11467,6 @@ "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" }, @@ -11893,8 +11521,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/nwsapi": { "version": "2.2.0", @@ -11906,8 +11533,7 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.66.2.tgz", "integrity": "sha512-RFewnL/RjE0qQBOuM+2bbY96zmJPIge/aDtsiDbLSb+MOiK8CReAhBHDgL+zrA3F1hQk00lMWpUwYcep750plA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/object-assign": { "version": "4.1.1", @@ -11923,7 +11549,6 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, - "peer": true, "dependencies": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -11938,7 +11563,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^0.1.0" }, @@ -11951,7 +11575,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -11964,7 +11587,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -11977,7 +11599,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -11992,7 +11613,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -12002,7 +11622,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -12020,7 +11639,6 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12029,7 +11647,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -12048,7 +11665,6 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, - "peer": true, "dependencies": { "isobject": "^3.0.0" }, @@ -12060,7 +11676,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -12123,7 +11738,6 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, - "peer": true, "dependencies": { "isobject": "^3.0.1" }, @@ -12165,7 +11779,6 @@ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -12199,7 +11812,6 @@ "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", "dev": true, - "peer": true, "dependencies": { "is-wsl": "^1.1.0" }, @@ -12229,7 +11841,6 @@ "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", "dev": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -12239,7 +11850,6 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", "dev": true, - "peer": true, "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", @@ -12257,7 +11867,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -12267,7 +11876,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -12280,7 +11888,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -12295,7 +11902,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -12304,15 +11910,13 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true, - "peer": true + "dev": true }, "node_modules/ora/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -12322,7 +11926,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -12332,7 +11935,6 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, - "peer": true, "dependencies": { "chalk": "^2.0.1" }, @@ -12345,7 +11947,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "peer": true, "dependencies": { "ansi-regex": "^4.1.0" }, @@ -12358,7 +11959,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -12371,7 +11971,6 @@ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -12381,7 +11980,6 @@ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -12467,7 +12065,6 @@ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -12539,9 +12136,9 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -12766,7 +12363,6 @@ "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.4.tgz", "integrity": "sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg==", "dev": true, - "peer": true, "dependencies": { "base64-js": "^1.5.1", "xmlbuilder": "^9.0.7" @@ -12780,7 +12376,6 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -12790,7 +12385,6 @@ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -12805,12 +12399,11 @@ } }, "node_modules/pretty-format": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", - "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" @@ -12844,8 +12437,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/progress": { "version": "2.0.3", @@ -12861,7 +12453,6 @@ "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", "dev": true, - "peer": true, "dependencies": { "asap": "~2.0.6" } @@ -12880,14 +12471,14 @@ } }, "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "react-is": "^16.13.1" } }, "node_modules/prop-types/node_modules/react-is": { @@ -12907,7 +12498,6 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, - "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -12991,11 +12581,10 @@ } }, "node_modules/react-devtools-core": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.22.1.tgz", - "integrity": "sha512-pvpNDHE7p0FtcCmIWGazoY8LLVfBI9sw0Kf10kdHhPI9Tzt3OG/qEt16GrAbE0keuna5WzX3r1qPKVjqOqsuUg==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.19.1.tgz", + "integrity": "sha512-2wJiGffPWK0KggBjVwnTaAk+Z3MSxKInHmdzPTrBh1mAarexsa93Kw+WMX88+XjN+TtYgAiLe9xeTqcO5FfJTw==", "dev": true, - "peer": true, "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" @@ -13012,7 +12601,6 @@ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.66.4.tgz", "integrity": "sha512-9vx5dlSfQlKbbDtr8+xMon6qsmSu7jvjdXWZpEKh3XVKpUidbbODv7048gwVKX8YAel1egeR7hN8vzSeI6ssTw==", "dev": true, - "peer": true, "dependencies": { "@jest/create-cache-key-function": "^27.0.1", "@react-native-community/cli": "^6.0.0", @@ -13061,7 +12649,6 @@ "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.7.tgz", "integrity": "sha512-dwNgR8zJ3ALr480QnAmpTiqvFo+rDtq6V5oCggKhYFlRjzOmVSFn3YD41u8ltvKS5G2nQ8gCs2vReFFnRGLYng==", "dev": true, - "peer": true, "dependencies": { "flow-parser": "^0.121.0", "jscodeshift": "^0.11.0", @@ -13073,7 +12660,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -13090,7 +12676,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "dependencies": { "@types/yargs-parser": "*" } @@ -13100,7 +12685,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "dependencies": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -13116,7 +12700,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "dev": true, - "peer": true, "dependencies": { "async-limiter": "~1.0.0" } @@ -13126,7 +12709,6 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", "integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -13230,7 +12812,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -13257,15 +12838,13 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=", - "dev": true, - "peer": true + "dev": true }, "node_modules/recast": { "version": "0.20.5", "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", "dev": true, - "peer": true, "dependencies": { "ast-types": "0.14.2", "esprima": "~4.0.0", @@ -13384,15 +12963,13 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/regenerate-unicode-properties": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", "dev": true, - "peer": true, "dependencies": { "regenerate": "^1.4.2" }, @@ -13404,15 +12981,13 @@ "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/regenerator-transform": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", "dev": true, - "peer": true, "dependencies": { "@babel/runtime": "^7.8.4" } @@ -13422,7 +12997,6 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, - "peer": true, "dependencies": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -13432,9 +13006,9 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz", + "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", @@ -13464,7 +13038,6 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", "dev": true, - "peer": true, "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^9.0.0", @@ -13481,15 +13054,13 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/regjsparser": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", "dev": true, - "peer": true, "dependencies": { "jsesc": "~0.5.0" }, @@ -13502,7 +13073,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true, - "peer": true, "bin": { "jsesc": "bin/jsesc" } @@ -13511,15 +13081,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true, - "peer": true + "dev": true }, "node_modules/repeat-element": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -13529,7 +13097,6 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true, - "peer": true, "engines": { "node": ">=0.10" } @@ -13556,8 +13123,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/requires-port": { "version": "1.0.0", @@ -13575,13 +13141,17 @@ } }, "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", + "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==", "dev": true, "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13613,8 +13183,7 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true, - "peer": true + "dev": true }, "node_modules/resolve.exports": { "version": "1.1.0", @@ -13630,7 +13199,6 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, - "peer": true, "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -13644,7 +13212,6 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -13654,7 +13221,6 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, - "peer": true, "dependencies": { "mimic-fn": "^1.0.0" }, @@ -13667,7 +13233,6 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true, - "peer": true, "engines": { "node": ">=0.12" } @@ -13698,7 +13263,6 @@ "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true, - "peer": true, "engines": { "node": "6.* || >= 7.*" } @@ -13706,15 +13270,13 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, - "peer": true, "dependencies": { "ret": "~0.1.10" } @@ -13731,7 +13293,6 @@ "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", "dev": true, - "peer": true, "dependencies": { "@cnakazawa/watch": "^1.0.3", "anymatch": "^2.0.0", @@ -13755,7 +13316,6 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, - "peer": true, "dependencies": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -13766,7 +13326,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "peer": true, "dependencies": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -13788,7 +13347,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -13801,7 +13359,6 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "peer": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -13818,7 +13375,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, - "peer": true, "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -13837,7 +13393,6 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, - "peer": true, "dependencies": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -13853,7 +13408,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -13866,7 +13420,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, - "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -13879,7 +13432,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -13889,7 +13441,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -13902,7 +13453,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -13915,7 +13465,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -13925,7 +13474,6 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, - "peer": true, "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -13950,7 +13498,6 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, - "peer": true, "dependencies": { "remove-trailing-separator": "^1.0.1" }, @@ -13963,7 +13510,6 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, - "peer": true, "dependencies": { "path-key": "^2.0.0" }, @@ -13976,7 +13522,6 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -13986,7 +13531,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver" } @@ -13996,7 +13540,6 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "peer": true, "dependencies": { "shebang-regex": "^1.0.0" }, @@ -14009,7 +13552,6 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14019,7 +13561,6 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, - "peer": true, "dependencies": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -14033,7 +13574,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -14045,8 +13585,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/saxes": { "version": "5.0.1", @@ -14065,7 +13604,6 @@ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "dev": true, - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -14109,7 +13647,6 @@ "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dev": true, - "peer": true, "dependencies": { "debug": "2.6.9", "depd": "~1.1.2", @@ -14134,7 +13671,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -14143,15 +13679,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, - "peer": true, "bin": { "mime": "cli.js" }, @@ -14163,15 +13697,13 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/serialize-error": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14190,7 +13722,6 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dev": true, - "peer": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -14205,15 +13736,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "peer": true + "dev": true }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, - "peer": true, "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -14229,7 +13758,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -14242,7 +13770,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14297,7 +13824,6 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true, - "peer": true, "dependencies": { "array-filter": "~0.0.0", "array-map": "~0.0.0", @@ -14309,7 +13835,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -14330,7 +13855,6 @@ "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.0.tgz", "integrity": "sha512-uYWpeGFtZtVt2NhG4AHgpwx323zxD85x42heMJBan1qAiqqozIlaGrwrEt6kRjXWRWIXsuV1VLCvVmZan2B5dg==", "dev": true, - "peer": true, "dependencies": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.0", @@ -14357,7 +13881,6 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", @@ -14372,7 +13895,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -14385,7 +13907,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -14394,15 +13915,13 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true, - "peer": true + "dev": true }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, - "peer": true, "dependencies": { "base": "^0.11.1", "debug": "^2.2.0", @@ -14422,7 +13941,6 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, - "peer": true, "dependencies": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -14437,7 +13955,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^1.0.0" }, @@ -14450,7 +13967,6 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.2.0" }, @@ -14463,7 +13979,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -14476,7 +13991,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -14486,7 +14000,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^0.1.0" }, @@ -14499,7 +14012,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "dependencies": { "is-extendable": "^0.1.0" }, @@ -14512,7 +14024,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -14525,7 +14036,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -14538,7 +14048,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -14551,7 +14060,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -14564,7 +14072,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -14579,7 +14086,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14589,7 +14095,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14598,23 +14103,21 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "node_modules/snapdragon/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/socket.io": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.0.tgz", - "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz", + "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==", "dev": true, "dependencies": { "accepts": "~1.3.4", @@ -14734,8 +14237,8 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, - "peer": true, "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -14758,8 +14261,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true, - "peer": true + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true }, "node_modules/spdx-correct": { "version": "3.1.1", @@ -14798,7 +14301,6 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, - "peer": true, "dependencies": { "extend-shallow": "^3.0.0" }, @@ -14824,28 +14326,17 @@ "node": ">=10" } }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/stackframe": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.7.1" }, @@ -14858,7 +14349,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -14933,7 +14423,6 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, - "peer": true, "dependencies": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -14947,7 +14436,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "dependencies": { "is-descriptor": "^0.1.0" }, @@ -14960,7 +14448,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -14973,7 +14460,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -14986,7 +14472,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -14999,7 +14484,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -15012,7 +14496,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "dependencies": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -15027,7 +14510,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -15046,7 +14528,6 @@ "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", "dev": true, - "peer": true, "engines": { "node": ">= 0.10.0" } @@ -15112,7 +14593,6 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -15176,7 +14656,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -15189,7 +14668,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -15224,7 +14702,6 @@ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -15254,8 +14731,7 @@ "version": "9.2.1", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/supports-color": { "version": "7.2.0", @@ -15282,6 +14758,18 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -15289,9 +14777,9 @@ "dev": true }, "node_modules/table": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", - "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", "dev": true, "dependencies": { "ajv": "^8.0.1", @@ -15333,9 +14821,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", - "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", + "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -15412,7 +14900,6 @@ "engines": [ "node >=0.8.0" ], - "peer": true, "dependencies": { "os-tmpdir": "^1.0.0", "rimraf": "~2.2.6" @@ -15429,7 +14916,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", "dev": true, - "peer": true, "bin": { "rimraf": "bin.js" } @@ -15580,7 +15066,6 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, - "peer": true, "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -15630,7 +15115,6 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, - "peer": true, "dependencies": { "kind-of": "^3.0.2" }, @@ -15643,7 +15127,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "dependencies": { "is-buffer": "^1.1.5" }, @@ -15656,7 +15139,6 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, - "peer": true, "dependencies": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -15715,9 +15197,9 @@ } }, "node_modules/ts-jest": { - "version": "27.1.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.2.tgz", - "integrity": "sha512-eSOiJOWq6Hhs6Khzk5wKC5sgWIXgXqOCiIl1+3lfnearu58Hj4QpE5tUhQcA3xtZrELbcvAGCsd6HB8OsaVaTA==", + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", "dev": true, "dependencies": { "bs-logger": "0.x", @@ -15854,8 +15336,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/type-check": { "version": "0.3.2", @@ -15962,7 +15443,6 @@ "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", "deprecated": "support for ECMAScript is superseded by `uglify-js` as of v3.13.0", "dev": true, - "peer": true, "dependencies": { "commander": "~2.13.0", "source-map": "~0.6.1" @@ -15978,8 +15458,7 @@ "version": "2.13.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/uglify-js": { "version": "3.14.5", @@ -15998,14 +15477,12 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true, - "peer": true + "dev": true }, "node_modules/unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1", "has-bigints": "^1.0.1", @@ -16027,7 +15504,6 @@ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -16037,7 +15513,6 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, - "peer": true, "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -16051,7 +15526,6 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -16061,7 +15535,6 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -16071,7 +15544,6 @@ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, - "peer": true, "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -16087,7 +15559,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -16115,7 +15586,6 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, - "peer": true, "dependencies": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -16129,7 +15599,6 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, - "peer": true, "dependencies": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -16144,7 +15613,6 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, - "peer": true, "dependencies": { "isarray": "1.0.0" }, @@ -16157,7 +15625,6 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -16176,15 +15643,13 @@ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true, - "peer": true + "dev": true }, "node_modules/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -16194,7 +15659,6 @@ "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", "integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==", "dev": true, - "peer": true, "dependencies": { "object-assign": "^4.1.1" }, @@ -16206,7 +15670,6 @@ "version": "0.12.4", "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -16220,8 +15683,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "peer": true + "dev": true }, "node_modules/utils-merge": { "version": "1.0.1", @@ -16238,7 +15700,6 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, - "peer": true, "bin": { "uuid": "bin/uuid" } @@ -16250,9 +15711,9 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -16295,8 +15756,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/void-elements": { "version": "2.0.1", @@ -16364,7 +15824,6 @@ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", "dev": true, - "peer": true, "dependencies": { "defaults": "^1.0.3" } @@ -16379,9 +15838,9 @@ } }, "node_modules/webpack": { - "version": "5.65.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", - "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.66.0.tgz", + "integrity": "sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.0", @@ -16398,7 +15857,7 @@ "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "json-parse-better-errors": "^1.0.2", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -16488,9 +15947,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", - "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, "engines": { "node": ">=10.13.0" @@ -16509,8 +15968,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/whatwg-mimetype": { "version": "2.3.0", @@ -16551,7 +16009,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -16567,14 +16024,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true, - "peer": true + "dev": true }, "node_modules/which-typed-array": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -16700,7 +16155,6 @@ "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz", "integrity": "sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==", "dev": true, - "peer": true, "dependencies": { "simple-plist": "^1.0.0", "uuid": "^3.3.2" @@ -16756,7 +16210,6 @@ "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", "integrity": "sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ==", "dev": true, - "peer": true, "dependencies": { "sax": "^1.2.1" } @@ -16766,7 +16219,6 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.4" } @@ -16869,9 +16321,9 @@ } }, "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { "node": ">=10" @@ -16904,35 +16356,35 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "@babel/highlight": "^7.16.0" + "@babel/highlight": "^7.16.7" } }, "@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", + "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", "dev": true }, "@babel/core": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", - "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helpers": "^7.16.5", - "@babel/parser": "^7.16.5", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz", + "integrity": "sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -16956,12 +16408,12 @@ } }, "@babel/generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", - "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", + "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", "dev": true, "requires": { - "@babel/types": "^7.16.0", + "@babel/types": "^7.16.8", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -16975,34 +16427,32 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", + "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", "dev": true, - "peer": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", - "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", + "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" }, @@ -17016,38 +16466,35 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", - "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz", + "integrity": "sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", - "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz", + "integrity": "sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==", "dev": true, - "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-annotate-as-pure": "^7.16.7", "regexpu-core": "^4.7.1" } }, "@babel/helper-define-polyfill-provider": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", - "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", "dev": true, - "peer": true, "requires": { "@babel/helper-compilation-targets": "^7.13.0", "@babel/helper-module-imports": "^7.12.13", @@ -17063,143 +16510,137 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "peer": true + "dev": true } } }, "@babel/helper-environment-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", - "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-explode-assignable-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", - "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", + "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", "dev": true, - "peer": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", - "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", + "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", "dev": true, - "peer": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-transforms": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", - "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", + "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", "dev": true, - "peer": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-plugin-utils": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", - "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", - "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", + "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-wrap-function": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" } }, "@babel/helper-replace-supers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", - "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", + "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-skip-transparent-expression-wrappers": { @@ -17207,63 +16648,61 @@ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, - "peer": true, "requires": { "@babel/types": "^7.16.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", - "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", + "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" } }, "@babel/helpers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", - "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", "dev": true, "requires": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", + "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -17327,215 +16766,209 @@ } }, "@babel/parser": { - "version": "7.16.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", - "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.8.tgz", + "integrity": "sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw==", "dev": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", - "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", + "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", - "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", + "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0" + "@babel/plugin-proposal-optional-chaining": "^7.16.7" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", - "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", + "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", - "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", + "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", "dev": true, - "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", - "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz", + "integrity": "sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", - "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", + "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-default-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.5.tgz", - "integrity": "sha512-pU4aCS+AzGjDD/6LnwSmeelmtqfMSjzQxs7+/AS673bYsshK1XZm9eth6OkgivVscQM8XdkVYhrb6tPFVTBVHA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.7.tgz", + "integrity": "sha512-+cENpW1rgIjExn+o5c8Jw/4BuH4eGKKYvkMB8/0ZxFQ9mC0t4z09VsPIwNg6waF69QYC81zxGeAsREGuqQoKeg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-export-default-from": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-export-default-from": "^7.16.7" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", - "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", + "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", - "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", + "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", - "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", + "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", - "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", + "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", - "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", + "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", - "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz", + "integrity": "sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==", "dev": true, - "peer": true, "requires": { "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.5" + "@babel/plugin-transform-parameters": "^7.16.7" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", - "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", + "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", - "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", + "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", - "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.7.tgz", + "integrity": "sha512-7twV3pzhrRxSwHeIvFE6coPgvo+exNDOiGUMg39o2LiLo1Y+4aKpfkcLGcg1UHonzorCt7SNXnoMyCnnIOA8Sw==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", - "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", + "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", - "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", + "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-async-generators": { @@ -17580,19 +17013,17 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, - "peer": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-syntax-export-default-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.5.tgz", - "integrity": "sha512-tvY55nhq4mSG9WbM7IZcLIhdc5jzIZu0PQKJHtZ16+dF7oBxKbqV/Z0e9ta2zaLMvUjH+3rJv1hbZ0+lpXzuFQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.7.tgz", + "integrity": "sha512-4C3E4NsrLOgftKaTYTULhHsuQrGv3FHrBzOMDiS7UYKIpgGBkAdawg4h+EI8zPeK9M0fiIIh72hIwsI24K7MbA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-export-namespace-from": { @@ -17606,13 +17037,12 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.5.tgz", - "integrity": "sha512-Nrx+7EAJx1BieBQseZa2pavVH2Rp7hADK2xn7coYqVbWRu9C2OFizYcsKo6TrrqJkJl+qF/+Qqzrk/+XDu4GnA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz", + "integrity": "sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-import-meta": { @@ -17634,13 +17064,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz", - "integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", + "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -17717,363 +17146,340 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", - "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", - "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", + "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", - "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", + "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5" + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", - "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", + "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", - "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", + "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-classes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", - "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", - "dev": true, - "peer": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", + "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", - "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", + "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-destructuring": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", - "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz", + "integrity": "sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", - "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", + "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", - "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", + "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", - "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", + "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.5.tgz", - "integrity": "sha512-skE02E/MptkZdBS4HwoRhjWXqeKQj0BWKEAPfPC+8R4/f6bjQqQ9Nftv/+HkxWwnVxh/E2NV9TNfzLN5H/oiBw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz", + "integrity": "sha512-mzmCq3cNsDpZZu9FADYYyfZJIOrSONmHcop2XEKPdBNMa4PDC4eEvcOvzZaCNcjKu72v0XQlA5y1g58aLRXdYg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-flow": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-flow": "^7.16.7" } }, "@babel/plugin-transform-for-of": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", - "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", + "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-function-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", - "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", + "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", - "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", + "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", - "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", + "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", - "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", + "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", "dev": true, "peer": true, "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", - "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", + "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", - "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz", + "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==", "dev": true, "peer": true, "requires": { - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", - "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", + "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", - "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", + "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", "dev": true, "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0" + "@babel/helper-create-regexp-features-plugin": "^7.16.7" } }, "@babel/plugin-transform-new-target": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", - "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", + "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-object-assign": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.5.tgz", - "integrity": "sha512-KVuJ7sWf6bcXawKVH6ZDQFYcOulObt1IOvl/gvNrkNXzmFf1IdgKOy4thmVomReleXqffMbptmXXMl3zPI7zHw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.7.tgz", + "integrity": "sha512-R8mawvm3x0COTJtveuoqZIjNypn2FjfvXZr4pSQ8VhEFBuQGBz4XhHasZtHXjgXU4XptZ4HtGof3NoYc93ZH9Q==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-object-super": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", - "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", + "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" } }, "@babel/plugin-transform-parameters": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", - "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", + "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-property-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", - "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", + "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-react-display-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.5.tgz", - "integrity": "sha512-dHYCOnzSsXFz8UcdNQIHGvg94qPL/teF7CCiCEMRxmA1G2p5Mq4JnKVowCDxYfiQ9D7RstaAp9kwaSI+sXbnhw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz", + "integrity": "sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.5.tgz", - "integrity": "sha512-+arLIz1d7kmwX0fKxTxbnoeG85ONSnLpvdODa4P3pc1sS7CV1hfmtYWufkW/oYsPnkDrEeQFxhUWcFnrXW7jQQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz", + "integrity": "sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==", "dev": true, - "peer": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-jsx": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.5.tgz", - "integrity": "sha512-fvwq+jir1Vn4f5oBS0H/J/gD5CneTD53MHs+NMjlHcha4Sq35fwxI5RtmJGEBXO+M93f/eeD9cAhRPhmLyJiVw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.7.tgz", + "integrity": "sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.5.tgz", - "integrity": "sha512-/eP+nZywJntGLjSPjksAnM9/ELIs3RbiEuTu2/zAOzwwBcfiu+m/iptEq1lERUUtSXubYSHVnVHMr13GR+TwPw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.7.tgz", + "integrity": "sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-regenerator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", - "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", + "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", "dev": true, - "peer": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", - "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", + "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz", - "integrity": "sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.8.tgz", + "integrity": "sha512-6Kg2XHPFnIarNweZxmzbgYnnWsXxkx9WQUVk2sksBRL80lBC1RAQV3wQagWxdCHiYHqPN+oenwNIuttlYgIbQQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", "semver": "^6.3.0" }, @@ -18082,123 +17488,116 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "peer": true + "dev": true } } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", - "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", + "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", - "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", + "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", - "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", + "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-template-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", - "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", + "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", - "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", + "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-typescript": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", - "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", + "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.16.0" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-typescript": "^7.16.7" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", - "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", + "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", "dev": true, "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", - "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", + "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", "dev": true, - "peer": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/preset-env": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", - "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", - "dev": true, - "peer": true, - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-async-generator-functions": "^7.16.5", - "@babel/plugin-proposal-class-properties": "^7.16.5", - "@babel/plugin-proposal-class-static-block": "^7.16.5", - "@babel/plugin-proposal-dynamic-import": "^7.16.5", - "@babel/plugin-proposal-export-namespace-from": "^7.16.5", - "@babel/plugin-proposal-json-strings": "^7.16.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", - "@babel/plugin-proposal-numeric-separator": "^7.16.5", - "@babel/plugin-proposal-object-rest-spread": "^7.16.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", - "@babel/plugin-proposal-optional-chaining": "^7.16.5", - "@babel/plugin-proposal-private-methods": "^7.16.5", - "@babel/plugin-proposal-private-property-in-object": "^7.16.5", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.8.tgz", + "integrity": "sha512-9rNKgVCdwHb3z1IlbMyft6yIXIeP3xz6vWvGaLHrJThuEIqWfHb0DNBH9VuTgnDfdbUDhkmkvMZS/YMCtP7Elg==", + "dev": true, + "peer": true, + "requires": { + "@babel/compat-data": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-async-generator-functions": "^7.16.8", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-proposal-dynamic-import": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.16.7", + "@babel/plugin-proposal-json-strings": "^7.16.7", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-numeric-separator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-private-methods": "^7.16.7", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", @@ -18213,44 +17612,44 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.5", - "@babel/plugin-transform-async-to-generator": "^7.16.5", - "@babel/plugin-transform-block-scoped-functions": "^7.16.5", - "@babel/plugin-transform-block-scoping": "^7.16.5", - "@babel/plugin-transform-classes": "^7.16.5", - "@babel/plugin-transform-computed-properties": "^7.16.5", - "@babel/plugin-transform-destructuring": "^7.16.5", - "@babel/plugin-transform-dotall-regex": "^7.16.5", - "@babel/plugin-transform-duplicate-keys": "^7.16.5", - "@babel/plugin-transform-exponentiation-operator": "^7.16.5", - "@babel/plugin-transform-for-of": "^7.16.5", - "@babel/plugin-transform-function-name": "^7.16.5", - "@babel/plugin-transform-literals": "^7.16.5", - "@babel/plugin-transform-member-expression-literals": "^7.16.5", - "@babel/plugin-transform-modules-amd": "^7.16.5", - "@babel/plugin-transform-modules-commonjs": "^7.16.5", - "@babel/plugin-transform-modules-systemjs": "^7.16.5", - "@babel/plugin-transform-modules-umd": "^7.16.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", - "@babel/plugin-transform-new-target": "^7.16.5", - "@babel/plugin-transform-object-super": "^7.16.5", - "@babel/plugin-transform-parameters": "^7.16.5", - "@babel/plugin-transform-property-literals": "^7.16.5", - "@babel/plugin-transform-regenerator": "^7.16.5", - "@babel/plugin-transform-reserved-words": "^7.16.5", - "@babel/plugin-transform-shorthand-properties": "^7.16.5", - "@babel/plugin-transform-spread": "^7.16.5", - "@babel/plugin-transform-sticky-regex": "^7.16.5", - "@babel/plugin-transform-template-literals": "^7.16.5", - "@babel/plugin-transform-typeof-symbol": "^7.16.5", - "@babel/plugin-transform-unicode-escapes": "^7.16.5", - "@babel/plugin-transform-unicode-regex": "^7.16.5", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-block-scoped-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-classes": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-dotall-regex": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-function-name": "^7.16.7", + "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-member-expression-literals": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.16.8", + "@babel/plugin-transform-modules-systemjs": "^7.16.7", + "@babel/plugin-transform-modules-umd": "^7.16.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", + "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-object-super": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-property-literals": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.16.7", + "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-shorthand-properties": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-sticky-regex": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.16.7", + "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-unicode-escapes": "^7.16.7", + "@babel/plugin-transform-unicode-regex": "^7.16.7", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.0", + "@babel/types": "^7.16.8", "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.19.1", + "core-js-compat": "^3.20.2", "semver": "^6.3.0" }, "dependencies": { @@ -18264,15 +17663,14 @@ } }, "@babel/preset-flow": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.16.5.tgz", - "integrity": "sha512-rmC6Nznp4V55N4Zfec87jwd14TdREqwKVJFM/6Z2wTwoeZQr56czjaPRCezqzqc8TsHF7aLP1oczjadIQ058gw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.16.7.tgz", + "integrity": "sha512-6ceP7IyZdUYQ3wUVqyRSQXztd1YmFHWI4Xv11MIqAlE4WqxBSd/FZ61V9k+TS5Gd4mkHOtQtPp9ymRpxH4y1Ug==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-flow-strip-types": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-transform-flow-strip-types": "^7.16.7" } }, "@babel/preset-modules": { @@ -18290,23 +17688,21 @@ } }, "@babel/preset-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", - "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", + "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", "dev": true, - "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.16.1" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-transform-typescript": "^7.16.7" } }, "@babel/register": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.5.tgz", - "integrity": "sha512-NpluD+cToBiZiDsG3y9rtIcqDyivsahpaM9csfyfiq1qQWduSmihUZ+ruIqqSDGjZKZMJfgAElo9x2YWlOQuRw==", + "version": "7.16.9", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.9.tgz", + "integrity": "sha512-jJ72wcghdRIlENfvALcyODhNoGE5j75cYHdC+aQMh6cU/P86tiiXTp9XYZct1UxUMo/4+BgQRyNZEGx0KWGS+g==", "dev": true, - "peer": true, "requires": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -18320,7 +17716,6 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "peer": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -18330,64 +17725,61 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "peer": true + "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true + "dev": true } } }, "@babel/runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", - "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", + "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", "dev": true, - "peer": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/traverse": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", - "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.5", - "@babel/types": "^7.16.0", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.8.tgz", + "integrity": "sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.8", + "@babel/types": "^7.16.8", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } }, @@ -18402,7 +17794,6 @@ "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, - "peer": true, "requires": { "exec-sh": "^0.3.2", "minimist": "^1.2.0" @@ -18484,15 +17875,13 @@ "version": "9.2.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", "integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==", - "dev": true, - "peer": true + "dev": true }, "@hapi/topo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dev": true, - "peer": true, "requires": { "@hapi/hoek": "^9.0.0" } @@ -18517,29 +17906,29 @@ "dev": true }, "@jest/console": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", - "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", "dev": true, "requires": { "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.4.2", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "slash": "^3.0.0" } }, "@jest/core": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", - "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", "dev": true, "requires": { - "@jest/console": "^27.4.2", - "@jest/reporters": "^27.4.5", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -18548,18 +17937,18 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.5", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-resolve-dependencies": "^27.4.5", - "jest-runner": "^27.4.5", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", - "jest-watcher": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", @@ -18571,58 +17960,57 @@ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.4.2.tgz", "integrity": "sha512-aSSCAJwUNX4R1hJQoyimsND5l+2EsFgzlepS8NuOJJHjXij/UdxYFngac44tmv9IYdI+kglAyORg0plt4/aFMQ==", "dev": true, - "peer": true, "requires": { "@jest/types": "^27.4.2" } }, "@jest/environment": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", - "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", "dev": true, "requires": { - "@jest/fake-timers": "^27.4.2", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2" + "jest-mock": "^27.4.6" } }, "@jest/fake-timers": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", - "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", "dev": true, "requires": { "@jest/types": "^27.4.2", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" } }, "@jest/globals": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", - "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/types": "^27.4.2", - "expect": "^27.4.2" + "expect": "^27.4.6" } }, "@jest/reporters": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", - "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.2", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -18631,14 +18019,14 @@ "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.4.5", - "jest-resolve": "^27.4.5", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -18658,47 +18046,47 @@ } }, "@jest/test-result": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", - "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", "dev": true, "requires": { - "@jest/console": "^27.4.2", + "@jest/console": "^27.4.6", "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", - "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", "dev": true, "requires": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-runtime": "^27.4.5" + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" } }, "@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", "dev": true, "requires": { "@babel/core": "^7.1.0", "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-regex-util": "^27.4.0", "jest-util": "^27.4.2", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -18718,9 +18106,9 @@ } }, "@react-native-async-storage/async-storage": { - "version": "1.15.14", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.14.tgz", - "integrity": "sha512-eJF2horabXazwszCyyXDe4w7sBSWlB0WPA8akKXuN2n7WXKHYeQJPN41lS9OahrhSZuZwqftNFE9VWgPXA8wyA==", + "version": "1.15.15", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.15.15.tgz", + "integrity": "sha512-Ss2FqWP9HC5AhCyP6ydRERSwWb8QMTLknETB8cp2+tbEUhu7Q/S5+e0QIrF0D2Z/YZTUvQ2MP7uXzt9FLG9OYQ==", "dev": true, "requires": { "merge-options": "^3.0.4" @@ -18731,7 +18119,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-6.3.1.tgz", "integrity": "sha512-UQ77AkGvPzdwJt6qhYXUyDMP1v2rdCcIlrhU48FOcAhGX+N/LCL9Cp/Ic6CkiiSHJdktbgiEEJ2srprXH8nzVg==", "dev": true, - "peer": true, "requires": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", "@react-native-community/cli-hermes": "^6.3.0", @@ -18771,7 +18158,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -18785,7 +18171,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "requires": { "@types/yargs-parser": "*" } @@ -18794,15 +18179,13 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true + "dev": true }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "peer": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -18815,8 +18198,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true + "dev": true } } }, @@ -18824,15 +18206,13 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", - "dev": true, - "peer": true + "dev": true }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, - "peer": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -18848,7 +18228,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, - "peer": true, "requires": { "pump": "^3.0.0" } @@ -18857,15 +18236,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "peer": true + "dev": true }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, - "peer": true, "requires": { "path-key": "^2.0.0" } @@ -18874,15 +18251,13 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "peer": true + "dev": true }, "pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -18894,15 +18269,13 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "peer": true + "dev": true }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "peer": true, "requires": { "shebang-regex": "^1.0.0" } @@ -18911,15 +18284,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "peer": true + "dev": true }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "peer": true, "requires": { "ansi-regex": "^4.1.0" }, @@ -18928,8 +18299,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "peer": true + "dev": true } } }, @@ -18938,7 +18308,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "peer": true, "requires": { "isexe": "^2.0.0" } @@ -18950,7 +18319,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-6.0.0-rc.0.tgz", "integrity": "sha512-achYcPPoWa9D02C5tn6TBzjeY443wQTyx37urptc75JpZ7gR5YHsDyIEEWa3DDYp1va9zx/iGg+uZ/hWw07GAw==", "dev": true, - "peer": true, "requires": { "serve-static": "^1.13.1" } @@ -18960,7 +18328,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-6.3.0.tgz", "integrity": "sha512-Uhbm9bubyZLZ12vFCIfWbE/Qi3SBTbYIN/TC08EudTLhv/KbPomCQnmFsnJ7AXQFuOZJs73mBxoEAYSbRbwyVA==", "dev": true, - "peer": true, "requires": { "@react-native-community/cli-platform-android": "^6.3.0", "@react-native-community/cli-tools": "^6.2.0", @@ -18974,7 +18341,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.0.tgz", "integrity": "sha512-d5ufyYcvrZoHznYm5bjBXaiHIJv552t5gYtQpnUsxBhHSQ8QlaNmlLUyeSPRDfOw4ND9b0tPHqs4ufwx6vp/fQ==", "dev": true, - "peer": true, "requires": { "@react-native-community/cli-tools": "^6.2.0", "chalk": "^4.1.2", @@ -18993,7 +18359,6 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "peer": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -19007,7 +18372,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, - "peer": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -19023,7 +18387,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, - "peer": true, "requires": { "pump": "^3.0.0" } @@ -19032,15 +18395,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "peer": true + "dev": true }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, - "peer": true, "requires": { "path-key": "^2.0.0" } @@ -19049,22 +18410,19 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "peer": true + "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true + "dev": true }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "peer": true, "requires": { "shebang-regex": "^1.0.0" } @@ -19073,15 +18431,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "peer": true + "dev": true }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "peer": true, "requires": { "isexe": "^2.0.0" } @@ -19093,7 +18449,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-6.2.0.tgz", "integrity": "sha512-k15MhExxLiLDDZOeuPgvTxbp0CsoLQQpk2Du0HjZDePqqWcKJylQqMZru1o8HuQHPcEr+b71HIs5V+lKyFYpfg==", "dev": true, - "peer": true, "requires": { "@react-native-community/cli-tools": "^6.2.0", "chalk": "^4.1.2", @@ -19110,7 +18465,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-6.2.0.tgz", "integrity": "sha512-JfmzuFNzOr+dFTUQJo1rV0t87XAqgHRTMYXNleQVt8otOVCk1FSCgKlgqMdvQc/FCx2ZjoMWEEV/g0LrPI8Etw==", "dev": true, - "peer": true, "requires": { "@react-native-community/cli-server-api": "^6.2.0", "@react-native-community/cli-tools": "^6.2.0", @@ -19129,7 +18483,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-6.2.0.tgz", "integrity": "sha512-OnbnYclhoDpjge33QO5Slhfn0DsmLzzAgyrSCnb24HhSqwq7ObjMHaLpoEhpajzLG71wq5oKh0APEQjiL4Mknw==", "dev": true, - "peer": true, "requires": { "@react-native-community/cli-debugger-ui": "^6.0.0-rc.0", "@react-native-community/cli-tools": "^6.2.0", @@ -19147,7 +18500,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -19161,7 +18513,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "requires": { "@types/yargs-parser": "*" } @@ -19171,7 +18522,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -19184,7 +18534,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dev": true, - "peer": true, "requires": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -19197,7 +18546,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz", "integrity": "sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA==", "dev": true, - "peer": true, "requires": { "appdirsjs": "^1.2.4", "chalk": "^4.1.2", @@ -19213,8 +18561,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "peer": true + "dev": true } } }, @@ -19223,7 +18570,6 @@ "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-6.0.0.tgz", "integrity": "sha512-K493Fk2DMJC0ZM8s8gnfseKxGasIhuDaCUDeLZcoCSFlrjKEuEs1BKKEJiev0CARhKEXKOyyp/uqYM9nWhisNw==", "dev": true, - "peer": true, "requires": { "ora": "^3.4.0" } @@ -19232,22 +18578,19 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", "integrity": "sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ==", - "dev": true, - "peer": true + "dev": true }, "@react-native/normalize-color": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-1.0.0.tgz", "integrity": "sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg==", - "dev": true, - "peer": true + "dev": true }, "@react-native/polyfills": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-2.0.0.tgz", "integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==", - "dev": true, - "peer": true + "dev": true }, "@seald-io/binary-search-tree": { "version": "1.0.2", @@ -19259,7 +18602,6 @@ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", "dev": true, - "peer": true, "requires": { "@hapi/hoek": "^9.0.0" } @@ -19268,15 +18610,13 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", - "dev": true, - "peer": true + "dev": true }, "@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true, - "peer": true + "dev": true }, "@sinonjs/commons": { "version": "1.8.3", @@ -19296,6 +18636,12 @@ "@sinonjs/commons": "^1.7.0" } }, + "@socket.io/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==", + "dev": true + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -19327,9 +18673,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -19340,9 +18686,9 @@ } }, "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -19386,9 +18732,9 @@ "dev": true }, "@types/eslint": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", - "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.2.tgz", + "integrity": "sha512-nQxgB8/Sg+QKhnV8e0WzPpxjIGT3tuJDDzybkDi8ItE/IgTlHo07U0shaIjzhcvQxlq9SDRE42lsJ23uvEgJ2A==", "dev": true, "requires": { "@types/estree": "*", @@ -19396,9 +18742,9 @@ } }, "@types/eslint-scope": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.2.tgz", - "integrity": "sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", "dev": true, "requires": { "@types/eslint": "*", @@ -19421,9 +18767,9 @@ } }, "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "@types/istanbul-lib-report": { @@ -19445,9 +18791,9 @@ } }, "@types/jest": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", - "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", "dev": true, "requires": { "jest-diff": "^27.0.0", @@ -19467,15 +18813,15 @@ "dev": true }, "@types/node": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.1.tgz", - "integrity": "sha512-NXKvBVUzIbs6ylBwmOwHFkZS2EXCcjnqr8ZCRNaXBkHAf+3mn/rPcJxwrzuc6movh8fxQAsUUfYklJ/EG+hZqQ==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz", + "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==", "dev": true }, "@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", "dev": true }, "@types/stack-utils": { @@ -19697,7 +19043,6 @@ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "dev": true, - "peer": true, "requires": { "event-target-shim": "^5.0.0" } @@ -19706,8 +19051,7 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=", - "dev": true, - "peer": true + "dev": true }, "accepts": { "version": "1.3.7", @@ -19720,9 +19064,9 @@ } }, "acorn": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", - "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true }, "acorn-globals": { @@ -19795,8 +19139,7 @@ "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", - "dev": true, - "peer": true + "dev": true }, "ansi-colors": { "version": "4.1.1", @@ -19835,7 +19178,6 @@ "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==", "dev": true, - "peer": true, "requires": { "colorette": "^1.0.7", "slice-ansi": "^2.0.0", @@ -19846,15 +19188,13 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "peer": true + "dev": true }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "peer": true, "requires": { "ansi-regex": "^4.1.0" } @@ -19890,8 +19230,7 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.6.tgz", "integrity": "sha512-D8wJNkqMCeQs3kLasatELsddox/Xqkhp+J07iXGyL54fVN7oc+nmNfYzGuCs1IEP6uBw+TfpuO3JKwc+lECy4w==", - "dev": true, - "peer": true + "dev": true }, "arg": { "version": "4.1.3", @@ -19912,35 +19251,31 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "peer": true + "dev": true }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "peer": true + "dev": true }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "peer": true + "dev": true }, "array-back": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.0.tgz", - "integrity": "sha512-mixVv03GOOn/ubHE4STQ+uevX42ETdk0JoMVEjNkSOCT7WgERh7C8/+NyhWYNpE3BN69pxFyJIBcF7CxWz/+4A==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "dev": true }, "array-filter": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true, - "peer": true + "dev": true }, "array-includes": { "version": "3.1.4", @@ -19959,22 +19294,19 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true, - "peer": true + "dev": true }, "array-reduce": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true, - "peer": true + "dev": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "peer": true + "dev": true }, "array.prototype.flat": { "version": "1.2.5", @@ -20002,8 +19334,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true, - "peer": true + "dev": true }, "assertion-error": { "version": "1.1.0", @@ -20015,15 +19346,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "peer": true + "dev": true }, "ast-types": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", "dev": true, - "peer": true, "requires": { "tslib": "^2.0.1" } @@ -20032,15 +19361,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "peer": true + "dev": true }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "dev": true, - "peer": true, "requires": { "lodash": "^4.17.14" } @@ -20049,8 +19376,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true, - "peer": true + "dev": true }, "asynckit": { "version": "0.4.0", @@ -20062,33 +19388,30 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "peer": true + "dev": true }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, "babel-core": { "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", "dev": true, - "peer": true, "requires": {} }, "babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", "dev": true, "requires": { - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -20100,7 +19423,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "dev": true, - "peer": true, "requires": { "object.assign": "^4.1.0" } @@ -20116,27 +19438,6 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, "babel-plugin-jest-hoist": { @@ -20152,14 +19453,13 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", - "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", + "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", "dev": true, - "peer": true, "requires": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.0", + "@babel/helper-define-polyfill-provider": "^0.3.1", "semver": "^6.1.1" }, "dependencies": { @@ -20167,38 +19467,34 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "peer": true + "dev": true } } }, "babel-plugin-polyfill-corejs3": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", - "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz", + "integrity": "sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A==", "dev": true, - "peer": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0", - "core-js-compat": "^3.18.0" + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.20.0" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", - "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", "dev": true, - "peer": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0" + "@babel/helper-define-polyfill-provider": "^0.3.1" } }, "babel-plugin-syntax-trailing-function-commas": { "version": "7.0.0-beta.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", - "dev": true, - "peer": true + "dev": true }, "babel-preset-current-node-syntax": { "version": "1.0.1", @@ -20225,7 +19521,6 @@ "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", "dev": true, - "peer": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", @@ -20277,7 +19572,6 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, - "peer": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -20293,25 +19587,17 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^1.0.0" } } } }, - "base64-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", - "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", - "dev": true - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "peer": true + "dev": true }, "base64id": { "version": "2.0.0", @@ -20323,8 +19609,7 @@ "version": "1.6.51", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true, - "peer": true + "dev": true }, "binary-extensions": { "version": "2.2.0", @@ -20378,7 +19663,6 @@ "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", "dev": true, - "peer": true, "requires": { "stream-buffers": "2.2.x" } @@ -20388,7 +19672,6 @@ "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.0.tgz", "integrity": "sha512-zgmaRvT6AN1JpPPV+S0a1/FAtoxSreYDccZGIqEMSvZl9DMe70mJ7MFzpxa1X+gHVdkToE2haRUHHMiW1OdejA==", "dev": true, - "peer": true, "requires": { "big-integer": "1.6.x" } @@ -20481,7 +19764,6 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, - "peer": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -20517,7 +19799,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -20528,7 +19809,6 @@ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, - "peer": true, "requires": { "callsites": "^2.0.0" }, @@ -20537,8 +19817,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true, - "peer": true + "dev": true } } }, @@ -20547,7 +19826,6 @@ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, - "peer": true, "requires": { "caller-callsite": "^2.0.0" } @@ -20565,9 +19843,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001291", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001291.tgz", - "integrity": "sha512-roMV5V0HNGgJ88s42eE70sstqGW/gwFndosYrikHthw98N5tLnOTxFqMLQjZVRxTWFlJ4rn+MsgXrR7MDPY4jA==", + "version": "1.0.30001300", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz", + "integrity": "sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA==", "dev": true }, "capture-exit": { @@ -20575,7 +19853,6 @@ "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", "dev": true, - "peer": true, "requires": { "rsvp": "^4.8.4" } @@ -20632,9 +19909,9 @@ "dev": true }, "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -20670,7 +19947,6 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, - "peer": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -20683,7 +19959,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^0.1.0" } @@ -20693,7 +19968,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -20703,7 +19977,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -20715,7 +19988,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -20725,7 +19997,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -20737,7 +20008,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -20748,8 +20018,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "peer": true + "dev": true } } }, @@ -20758,7 +20027,6 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, - "peer": true, "requires": { "restore-cursor": "^2.0.0" } @@ -20767,8 +20035,7 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true, - "peer": true + "dev": true }, "cliui": { "version": "7.0.4", @@ -20785,8 +20052,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true, - "peer": true + "dev": true }, "clone-deep": { "version": "4.0.1", @@ -20826,7 +20092,6 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, - "peer": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -20851,8 +20116,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true, - "peer": true + "dev": true }, "colors": { "version": "1.4.0", @@ -20873,8 +20137,7 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true, - "peer": true + "dev": true }, "command-line-args": { "version": "5.2.0", @@ -20965,8 +20228,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true, - "peer": true + "dev": true }, "component-emitter": { "version": "1.3.0", @@ -20979,7 +20241,6 @@ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, - "peer": true, "requires": { "mime-db": ">= 1.43.0 < 2" } @@ -20989,7 +20250,6 @@ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, - "peer": true, "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -21004,15 +20264,13 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true, - "peer": true + "dev": true }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" } @@ -21021,8 +20279,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true } } }, @@ -21103,15 +20360,13 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "peer": true + "dev": true }, "core-js-compat": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.0.tgz", - "integrity": "sha512-relrah5h+sslXssTTOkvqcC/6RURifB0W5yhYBdBkaPYa5/2KBMiog3XiD+s3TwEHWxInWVv4Jx2/Lw0vng+IQ==", + "version": "3.20.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz", + "integrity": "sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw==", "dev": true, - "peer": true, "requires": { "browserslist": "^4.19.1", "semver": "7.0.0" @@ -21121,8 +20376,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "peer": true + "dev": true } } }, @@ -21130,8 +20384,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "peer": true + "dev": true }, "cors": { "version": "2.8.5", @@ -21148,7 +20401,6 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, - "peer": true, "requires": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", @@ -21229,8 +20481,7 @@ "version": "1.10.7", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", - "dev": true, - "peer": true + "dev": true }, "debug": { "version": "4.3.3", @@ -21257,8 +20508,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "peer": true + "dev": true }, "dedent": { "version": "0.7.0", @@ -21298,7 +20548,6 @@ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, - "peer": true, "requires": { "clone": "^1.0.2" } @@ -21307,7 +20556,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -21317,7 +20565,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, - "peer": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -21333,8 +20580,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true, - "peer": true + "dev": true }, "depd": { "version": "1.1.2", @@ -21346,8 +20592,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true, - "peer": true + "dev": true }, "detect-newline": { "version": "3.1.0", @@ -21446,9 +20691,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.24", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.24.tgz", - "integrity": "sha512-erwx5r69B/WFfFuF2jcNN0817BfDBdC4765kQ6WltOMuwsimlQo3JTEq0Cle+wpHralwdeX3OfAtw/mHxPK0Wg==", + "version": "1.4.48", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.48.tgz", + "integrity": "sha512-RT3SEmpv7XUA+tKXrZGudAWLDpa7f8qmhjcLaM6OD/ERxjQ/zAojT8/Vvo0BSzbArkElFZ1WyZ9FuwAYbkdBNA==", "dev": true }, "emittery": { @@ -21474,15 +20719,14 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "peer": true, "requires": { "once": "^1.4.0" } }, "engine.io": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.1.tgz", - "integrity": "sha512-AyMc20q8JUUdvKd46+thc9o7yCZ6iC6MoBCChG5Z1XmFMpp+2+y/oKvwpZTUJB0KCjxScw1dV9c2h5pjiYBLuQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.2.tgz", + "integrity": "sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -21507,12 +20751,12 @@ } }, "engine.io-parser": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz", - "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", + "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", "dev": true, "requires": { - "base64-arraybuffer": "~1.0.1" + "@socket.io/base64-arraybuffer": "~1.0.2" } }, "enhanced-resolve": { @@ -21566,7 +20810,6 @@ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", "dev": true, - "peer": true, "requires": { "stackframe": "^1.1.1" } @@ -21576,7 +20819,6 @@ "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", "dev": true, - "peer": true, "requires": { "accepts": "~1.3.7", "escape-html": "~1.0.3" @@ -21586,7 +20828,6 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", @@ -21620,7 +20861,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -21640,9 +20880,9 @@ "dev": true }, "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, "escodegen": { @@ -21811,14 +21051,13 @@ } }, "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", "dev": true, "requires": { "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "dependencies": { "debug": { @@ -21878,15 +21117,6 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } } } }, @@ -22181,15 +21411,13 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true, - "peer": true + "dev": true }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "peer": true + "dev": true }, "eventemitter3": { "version": "4.0.7", @@ -22207,8 +21435,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true, - "peer": true + "dev": true }, "execa": { "version": "5.1.1", @@ -22238,7 +21465,6 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, - "peer": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -22254,7 +21480,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" } @@ -22264,7 +21489,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^0.1.0" } @@ -22274,7 +21498,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -22284,7 +21507,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -22294,7 +21516,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -22306,7 +21527,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -22316,7 +21536,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -22328,7 +21547,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -22339,45 +21557,32 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "peer": true + "dev": true }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "peer": true + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true } } }, "expect": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", - "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", "dev": true, "requires": { "@jest/types": "^27.4.2", - "ansi-styles": "^5.0.0", "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-regex-util": "^27.4.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" } }, "extend": { @@ -22391,7 +21596,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, - "peer": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -22402,7 +21606,6 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, - "peer": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -22419,7 +21622,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^1.0.0" } @@ -22429,7 +21631,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -22438,8 +21639,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "peer": true + "dev": true } } }, @@ -22549,7 +21749,6 @@ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, - "peer": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -22561,7 +21760,6 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, - "peer": true, "requires": { "locate-path": "^3.0.0" } @@ -22571,7 +21769,6 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, - "peer": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -22582,7 +21779,6 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "peer": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -22593,7 +21789,6 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, - "peer": true, "requires": { "p-limit": "^2.0.0" } @@ -22602,22 +21797,19 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "peer": true + "dev": true }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "peer": true + "dev": true }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, - "peer": true, "requires": { "find-up": "^3.0.0" } @@ -22626,8 +21818,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true + "dev": true } } }, @@ -22692,8 +21883,7 @@ "version": "0.121.0", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==", - "dev": true, - "peer": true + "dev": true }, "follow-redirects": { "version": "1.14.7", @@ -22705,14 +21895,12 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "peer": true + "dev": true }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, "form-data": { "version": "3.0.1", @@ -22730,7 +21918,6 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, - "peer": true, "requires": { "map-cache": "^0.2.2" } @@ -22739,8 +21926,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true, - "peer": true + "dev": true }, "fs-extra": { "version": "8.1.0", @@ -22775,8 +21961,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -22806,7 +21991,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -22835,7 +22019,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -22845,8 +22028,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "peer": true + "dev": true }, "glob": { "version": "7.2.0", @@ -22884,9 +22066,9 @@ "dev": true }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "growl": { @@ -22912,7 +22094,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -22920,8 +22101,7 @@ "has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" }, "has-flag": { "version": "4.0.0", @@ -22932,14 +22112,12 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, "has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -22949,7 +22127,6 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, - "peer": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -22961,7 +22138,6 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, - "peer": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -22972,7 +22148,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -22982,7 +22157,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -22994,7 +22168,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -23011,22 +22184,19 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/hermes-engine/-/hermes-engine-0.9.0.tgz", "integrity": "sha512-r7U+Y4P2Qg/igFVZN+DpT7JFfXUn1MM4dFne8aW+cCrF6RRymof+VqrUHs1kl07j8h8V2CNesU19RKgWbr3qPw==", - "dev": true, - "peer": true + "dev": true }, "hermes-parser": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.4.7.tgz", "integrity": "sha512-jc+zCtXbtwTiXoMAoXOHepxAaGVFIp89wwE9qcdwnMd/uGVEtPoY8FaFSsx0ThPvyKirdR2EsIIDVrpbSXz1Ag==", - "dev": true, - "peer": true + "dev": true }, "hermes-profile-transformer": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz", "integrity": "sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==", "dev": true, - "peer": true, "requires": { "source-map": "^0.7.3" }, @@ -23035,8 +22205,7 @@ "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "peer": true + "dev": true } } }, @@ -23131,8 +22300,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", - "dev": true, - "peer": true + "dev": true }, "immediate": { "version": "3.0.6", @@ -23144,7 +22312,6 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, - "peer": true, "requires": { "caller-path": "^2.0.0", "resolve-from": "^3.0.0" @@ -23154,15 +22321,14 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true, - "peer": true + "dev": true } } }, "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "requires": { "pkg-dir": "^4.2.0", @@ -23188,14 +22354,12 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, "requires": { "get-intrinsic": "^1.1.0", "has": "^1.0.3", @@ -23213,7 +22377,6 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, - "peer": true, "requires": { "loose-envify": "^1.0.0" } @@ -23222,15 +22385,13 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true, - "peer": true + "dev": true }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "peer": true, "requires": { "kind-of": "^6.0.0" } @@ -23239,7 +22400,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -23255,7 +22415,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, "requires": { "has-bigints": "^1.0.1" } @@ -23273,7 +22432,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -23288,15 +22446,13 @@ "is-callable": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, - "peer": true, "requires": { "ci-info": "^2.0.0" }, @@ -23305,15 +22461,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true, - "peer": true + "dev": true } } }, "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "dev": true, "requires": { "has": "^1.0.3" @@ -23324,7 +22479,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "peer": true, "requires": { "kind-of": "^6.0.0" } @@ -23333,7 +22487,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -23343,7 +22496,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "peer": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -23354,15 +22506,13 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true, - "peer": true + "dev": true }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, - "peer": true, "requires": { "is-plain-object": "^2.0.4" } @@ -23377,8 +22527,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "peer": true + "dev": true }, "is-generator-fn": { "version": "2.1.0", @@ -23390,7 +22539,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -23407,8 +22555,7 @@ "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" }, "is-number": { "version": "7.0.0", @@ -23420,7 +22567,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -23450,7 +22596,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -23459,8 +22604,7 @@ "is-shared-array-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" }, "is-stream": { "version": "2.0.1", @@ -23472,7 +22616,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -23481,7 +22624,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -23490,7 +22632,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "dev": true, "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -23515,7 +22656,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, "requires": { "call-bind": "^1.0.2" } @@ -23524,22 +22664,19 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "peer": true + "dev": true }, "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true, - "peer": true + "dev": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "peer": true + "dev": true }, "isbinaryfile": { "version": "4.0.8", @@ -23566,14 +22703,15 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "requires": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "dependencies": { @@ -23608,9 +22746,9 @@ } }, "istanbul-reports": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.1.tgz", - "integrity": "sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -23618,14 +22756,14 @@ } }, "jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", - "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", "dev": true, "requires": { - "@jest/core": "^27.4.5", + "@jest/core": "^27.4.7", "import-local": "^3.0.2", - "jest-cli": "^27.4.5" + "jest-cli": "^27.4.7" } }, "jest-changed-files": { @@ -23640,92 +22778,92 @@ } }, "jest-circus": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", - "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" } }, "jest-cli": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", - "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", "dev": true, "requires": { - "@jest/core": "^27.4.5", - "@jest/test-result": "^27.4.2", + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.4.5", + "jest-config": "^27.4.7", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "prompts": "^2.0.1", "yargs": "^16.2.0" } }, "jest-config": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", - "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.4.5", + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", "@jest/types": "^27.4.2", - "babel-jest": "^27.4.5", + "babel-jest": "^27.4.6", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.5", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.5", + "jest-jasmine2": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-runner": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0" } }, "jest-diff": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", - "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^27.4.0", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" } }, "jest-docblock": { @@ -23738,44 +22876,44 @@ } }, "jest-each": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", - "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", "dev": true, "requires": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" } }, "jest-environment-jsdom": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", - "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2", "jsdom": "^16.6.0" } }, "jest-environment-node": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", - "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" } }, @@ -23786,9 +22924,9 @@ "dev": true }, "jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", "dev": true, "requires": { "@jest/types": "^27.4.2", @@ -23801,63 +22939,62 @@ "jest-regex-util": "^27.4.0", "jest-serializer": "^27.4.0", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "micromatch": "^4.0.4", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", - "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", "dev": true, "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "throat": "^6.0.1" } }, "jest-leak-detector": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", - "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", "dev": true, "requires": { "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" } }, "jest-matcher-utils": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", - "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" } }, "jest-message-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", - "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", @@ -23866,15 +23003,15 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", - "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", "dev": true, "requires": { "@jest/types": "^27.4.2", @@ -23895,44 +23032,44 @@ "dev": true }, "jest-resolve": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", - "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", "dev": true, "requires": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-pnp-resolver": "^1.2.2", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", - "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", "dev": true, "requires": { "@jest/types": "^27.4.2", "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.5" + "jest-snapshot": "^27.4.6" } }, "jest-runner": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", - "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", "dev": true, "requires": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -23940,51 +23077,47 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", - "jest-haste-map": "^27.4.5", - "jest-leak-detector": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", - "jest-runtime": "^27.4.5", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "source-map-support": "^0.5.6", "throat": "^6.0.1" } }, "jest-runtime": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", - "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", "dev": true, "requires": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/globals": "^27.4.4", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", - "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" + "strip-bom": "^4.0.0" } }, "jest-serializer": { @@ -23998,34 +23131,32 @@ } }, "jest-snapshot": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", - "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", "dev": true, "requires": { "@babel/core": "^7.7.2", "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.5", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "semver": "^7.3.2" } }, @@ -24044,9 +23175,9 @@ } }, "jest-validate": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", - "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", "dev": true, "requires": { "@jest/types": "^27.4.2", @@ -24054,24 +23185,24 @@ "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "dependencies": { "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true } } }, "jest-watcher": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", - "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", "dev": true, "requires": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -24081,9 +23212,9 @@ } }, "jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", "dev": true, "requires": { "@types/node": "*", @@ -24106,15 +23237,13 @@ "version": "1.6.8", "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.8.tgz", "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==", - "dev": true, - "peer": true + "dev": true }, "joi": { "version": "17.5.0", "resolved": "https://registry.npmjs.org/joi/-/joi-17.5.0.tgz", "integrity": "sha512-R7hR50COp7StzLnDi4ywOXHrBrgNXuUUfJWIR5lPY5Bm/pOD3jZaTwpluUXVLRWcoWZxkrHBBJ5hLxgnlehbdw==", "dev": true, - "peer": true, "requires": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", @@ -24152,15 +23281,13 @@ "version": "250230.2.1", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250230.2.1.tgz", "integrity": "sha512-KmxeBlRjwoqCnBBKGsihFtvsBHyUFlBxJPK4FzeYcIuBfdjv6jFys44JITAgSTbQD+vIdwMEfyZklsuQX0yI1Q==", - "dev": true, - "peer": true + "dev": true }, "jscodeshift": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.11.0.tgz", "integrity": "sha512-SdRK2C7jjs4k/kT2mwtO07KJN9RnjxtKn03d9JVj6c3j9WwaLcFYsICYDnLAzY0hp+wG2nxl+Cm2jWLiNVYb8g==", "dev": true, - "peer": true, "requires": { "@babel/core": "^7.1.6", "@babel/parser": "^7.1.6", @@ -24188,7 +23315,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "peer": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -24207,7 +23333,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -24219,7 +23344,6 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, - "peer": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -24232,7 +23356,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -24243,15 +23366,13 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "peer": true + "dev": true }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -24261,7 +23382,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -24273,7 +23393,6 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, - "peer": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -24295,7 +23414,6 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, - "peer": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -24306,7 +23424,6 @@ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, - "peer": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -24335,29 +23452,6 @@ "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", "underscore": "~1.13.1" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } } }, "jsdoc-api": { @@ -24487,8 +23581,7 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true, - "peer": true + "dev": true }, "jsx-ast-utils": { "version": "3.2.1", @@ -24501,15 +23594,15 @@ } }, "karma": { - "version": "6.3.9", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.9.tgz", - "integrity": "sha512-E/MqdLM9uVIhfuyVnrhlGBu4miafBdXEAEqCmwdEMh3n17C7UWC/8Kvm3AYKr91gc7scutekZ0xv6rxRaUCtnw==", + "version": "6.3.11", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.11.tgz", + "integrity": "sha512-QGUh4yXgizzDNPLB5nWTvP+wysKexngbyLVWFOyikB661hpa2RZLf5anZQzqliWtAQuYVep0ot0D1U7UQKpsxQ==", "dev": true, "requires": { "body-parser": "^1.19.0", "braces": "^3.0.2", "chokidar": "^3.5.1", - "colors": "^1.4.0", + "colors": "1.4.0", "connect": "^3.7.0", "di": "^0.0.1", "dom-serialize": "^2.2.1", @@ -24593,11 +23686,10 @@ "dev": true }, "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, - "peer": true, "requires": { "graceful-fs": "^4.1.9" } @@ -24700,8 +23792,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true, - "peer": true + "dev": true }, "lodash.memoize": { "version": "4.1.2", @@ -24731,8 +23822,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", - "dev": true, - "peer": true + "dev": true }, "lodash.truncate": { "version": "4.4.2", @@ -24768,7 +23858,6 @@ "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz", "integrity": "sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==", "dev": true, - "peer": true, "requires": { "ansi-fragments": "^0.2.1", "dayjs": "^1.8.15", @@ -24780,7 +23869,6 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "peer": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -24791,15 +23879,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "peer": true + "dev": true }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -24810,15 +23896,13 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "dev": true }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "peer": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -24838,7 +23922,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "peer": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -24900,15 +23983,13 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "peer": true + "dev": true }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, - "peer": true, "requires": { "object-visit": "^1.0.0" } @@ -24982,7 +24063,6 @@ "resolved": "https://registry.npmjs.org/metro/-/metro-0.66.2.tgz", "integrity": "sha512-uNsISfcQ3iKKSHoN5Q+LAh0l3jeeg7ZcNZ/4BAHGsk02erA0OP+l2m+b5qYVoPptHz9Oc3KyG5oGJoTu41pWjg==", "dev": true, - "peer": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/core": "^7.14.0", @@ -25043,7 +24123,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -25057,7 +24136,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "requires": { "@types/yargs-parser": "*" } @@ -25066,15 +24144,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true, - "peer": true + "dev": true }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "peer": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -25086,7 +24162,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" } @@ -25095,15 +24170,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "peer": true + "dev": true }, "fs-extra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", "dev": true, - "peer": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0", @@ -25115,7 +24188,6 @@ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", @@ -25137,15 +24209,13 @@ "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "peer": true + "dev": true }, "jest-serializer": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, - "peer": true, "requires": { "@types/node": "*", "graceful-fs": "^4.2.4" @@ -25156,7 +24226,6 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "@types/node": "*", @@ -25171,7 +24240,6 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, - "peer": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -25183,24 +24251,39 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, - "peer": true, "requires": { "graceful-fs": "^4.1.6" } }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "peer": true, "requires": { "glob": "^7.1.3" } @@ -25209,22 +24292,19 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "peer": true + "dev": true }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true, - "peer": true + "dev": true }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -25236,7 +24316,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dev": true, - "peer": true, "requires": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -25246,15 +24325,13 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "dev": true }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "peer": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -25274,7 +24351,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "peer": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -25287,7 +24363,6 @@ "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.66.2.tgz", "integrity": "sha512-3F+vsVubUPJYKfVMeol8/7pd8CC287Rw92QYzJD8LEmI980xcgwMUEVBZ0UIAUwlLgiJG/f4Mwhuji2EeBXrPg==", "dev": true, - "peer": true, "requires": { "@babel/core": "^7.14.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", @@ -25303,8 +24378,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "peer": true + "dev": true } } }, @@ -25313,7 +24387,6 @@ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.66.2.tgz", "integrity": "sha512-aJ/7fc/Xkofw8Fqa51OTDhBzBz26mmpIWrXAZcPdQ8MSTt883EWncxeCEjasc79NJ89BRi7sOkkaWZo2sXlKvw==", "dev": true, - "peer": true, "requires": { "@babel/core": "^7.14.0", "hermes-parser": "0.4.7", @@ -25326,19 +24399,26 @@ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.66.2.tgz", "integrity": "sha512-5QCYJtJOHoBSbL3H4/Fpl36oA697C3oYHqsce+Hk/dh2qtODUGpS3gOBhvP1B8iB+H8jJMyR75lZq129LJEsIQ==", "dev": true, - "peer": true, "requires": { "metro-core": "0.66.2", "mkdirp": "^0.5.1", "rimraf": "^2.5.4" }, "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "peer": true, "requires": { "glob": "^7.1.3" } @@ -25349,15 +24429,13 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.66.2.tgz", "integrity": "sha512-WtkNmRt41qOpHh1MkNA4nLiQ/m7iGL90ysSKD+fcLqlUnOBKJptPQm0ZUv8Kfqk18ddWX2KmsSbq+Sf3I6XohQ==", - "dev": true, - "peer": true + "dev": true }, "metro-config": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.66.2.tgz", "integrity": "sha512-0C+PrKKIBNNzLZUKN/8ZDJS2U5FLMOTXDWbvBHIdqb6YXz8WplXR2+xlSlaSCCi5b+GR7cWFWUNeKA4GQS1/AQ==", "dev": true, - "peer": true, "requires": { "cosmiconfig": "^5.0.5", "jest-validate": "^26.5.2", @@ -25372,7 +24450,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -25386,31 +24463,27 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "requires": { "@types/yargs-parser": "*" } }, "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", - "dev": true, - "peer": true + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true }, "jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "peer": true + "dev": true }, "jest-validate": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "camelcase": "^6.0.0", @@ -25425,7 +24498,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -25440,7 +24512,6 @@ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.66.2.tgz", "integrity": "sha512-JieLZkef/516yxXYvQxWnf3OWw5rcgWRy76K8JV/wr/i8LGVGulPAXlIi445/QZzXVydzRVASKAEVqyxM5F4mA==", "dev": true, - "peer": true, "requires": { "jest-haste-map": "^26.5.2", "lodash.throttle": "^4.1.1", @@ -25452,7 +24523,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -25466,7 +24536,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "requires": { "@types/yargs-parser": "*" } @@ -25476,7 +24545,6 @@ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", @@ -25498,15 +24566,13 @@ "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "peer": true + "dev": true }, "jest-serializer": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, - "peer": true, "requires": { "@types/node": "*", "graceful-fs": "^4.2.4" @@ -25517,7 +24583,6 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "@types/node": "*", @@ -25532,7 +24597,6 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, - "peer": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -25545,15 +24609,13 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.66.2.tgz", "integrity": "sha512-nCVL1g9uR6vrw5+X1wjwZruRyMkndnzGRMqjqoljf+nGEqBTD607CR7elXw4fMWn/EM+1y0Vdq5altUu9LdgCA==", - "dev": true, - "peer": true + "dev": true }, "metro-inspector-proxy": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.66.2.tgz", "integrity": "sha512-gnLc9121eznwP0iiA9tCBW8qZjwIsCgwHWMF1g1Qaki9le9tzeJv3dK4/lFNGxyfSaLO7vahQEhsEYsiRnTROg==", "dev": true, - "peer": true, "requires": { "connect": "^3.6.5", "debug": "^2.2.0", @@ -25566,7 +24628,6 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "peer": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -25578,7 +24639,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" } @@ -25587,22 +24647,19 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "peer": true + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -25614,7 +24671,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dev": true, - "peer": true, "requires": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -25624,15 +24680,13 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "dev": true }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "peer": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -25652,7 +24706,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "peer": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -25665,7 +24718,6 @@ "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.66.2.tgz", "integrity": "sha512-7TUK+L5CmB5x1PVnFbgmjzHW4CUadq9H5jgp0HfFoWT1skXAyEsx0DHkKDXwnot0khnNhBOEfl62ctQOnE110Q==", "dev": true, - "peer": true, "requires": { "uglify-es": "^3.1.9" } @@ -25675,7 +24727,6 @@ "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.66.2.tgz", "integrity": "sha512-H/nLBAz0MgfDloSe1FjyH4EnbokHFdncyERvLPXDACY3ROVRCeUyFNo70ywRGXW2NMbrV4H7KUyU4zkfWhC2HQ==", "dev": true, - "peer": true, "requires": { "@babel/core": "^7.14.0", "@babel/plugin-proposal-class-properties": "^7.0.0", @@ -25724,7 +24775,6 @@ "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.66.2.tgz", "integrity": "sha512-z1ab7ihIT0pJrwgi9q2IH+LcW/xUWMQ0hH+Mrk7wbKQB0RnJdXFoxphrfoVHBHMUu+TBPetUcEkKawkK1e7Cng==", "dev": true, - "peer": true, "requires": { "@babel/core": "^7.14.0", "babel-preset-fbjs": "^3.4.0", @@ -25740,7 +24790,6 @@ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.66.2.tgz", "integrity": "sha512-pXQAJR/xauRf4kWFj2/hN5a77B4jLl0Fom5I3PHp6Arw/KxSBp0cnguXpGLwNQ6zQC0nxKCoYGL9gQpzMnN7Hw==", "dev": true, - "peer": true, "requires": { "absolute-path": "^0.0.0" } @@ -25749,15 +24798,13 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.66.2.tgz", "integrity": "sha512-vFhKBk2ot9FS4b+2v0OTa/guCF/QDAOJubY0CNg7PzCS5+w4y3IvZIcPX4SSS1t8pYEZBLvtdtTDarlDl81xmg==", - "dev": true, - "peer": true + "dev": true }, "metro-source-map": { "version": "0.66.2", "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.66.2.tgz", "integrity": "sha512-038tFmB7vSh73VQcDWIbr5O1m+WXWyYafDaOy+1A/2K308YP0oj33gbEgDnZsLZDwcJ+xt1x6KUEBIzlX4YGeQ==", "dev": true, - "peer": true, "requires": { "@babel/traverse": "^7.14.0", "@babel/types": "^7.0.0", @@ -25773,8 +24820,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "peer": true + "dev": true } } }, @@ -25783,7 +24829,6 @@ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.66.2.tgz", "integrity": "sha512-u+DeQHyAFXVD7mVP+GST/894WHJ3i/U8oEJFnT7U3P52ZuLgX8n4tMNxhqZU12RcLR6etF8143aP0Ktx1gFLEQ==", "dev": true, - "peer": true, "requires": { "invariant": "^2.2.4", "metro-source-map": "0.66.2", @@ -25797,8 +24842,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "peer": true + "dev": true } } }, @@ -25807,7 +24851,6 @@ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.66.2.tgz", "integrity": "sha512-KTvqplh0ut7oDKovvDG6yzXM02R6X+9b2oVG+qYq8Zd3aCGTi51ASx4ThCNkAHyEvCuJdYg9fxXTL+j+wvhB5w==", "dev": true, - "peer": true, "requires": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", @@ -25821,7 +24864,6 @@ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.66.2.tgz", "integrity": "sha512-dO4PtYOMGB7Vzte8aIzX39xytODhmbJrBYPu+zYzlDjyefJZT7BkZ0LkPIThtyJi96xWcGqi9JBSo0CeRupAHw==", "dev": true, - "peer": true, "requires": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", @@ -25895,20 +24937,16 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, - "peer": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "mkdirp2": { "version": "1.0.5", @@ -25917,9 +24955,9 @@ "dev": true }, "mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.4.tgz", + "integrity": "sha512-+q2aV5VlJZuLgCWoBvGI5zEwPF9eEI0kr/sAA9Jm4xMND7RfIEyF8JE7C0JIg8WXRG+P1sdIAb5ccoHPlXLzcw==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", @@ -25954,6 +24992,22 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -25971,6 +25025,12 @@ } } }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -26070,6 +25130,15 @@ "ms": "2.0.0" } }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -26095,7 +25164,6 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, - "peer": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -26132,32 +25200,28 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true, - "peer": true + "dev": true }, "nocache": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==", - "dev": true, - "peer": true + "dev": true }, "node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", "dev": true, - "peer": true, "requires": { "minimatch": "^3.0.2" } }, "node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dev": true, - "peer": true, "requires": { "whatwg-url": "^5.0.0" }, @@ -26166,22 +25230,19 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true, - "peer": true + "dev": true }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true, - "peer": true + "dev": true }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "dev": true, - "peer": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -26205,8 +25266,7 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", - "dev": true, - "peer": true + "dev": true }, "normalize-package-data": { "version": "2.5.0", @@ -26247,8 +25307,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true, - "peer": true + "dev": true }, "nwsapi": { "version": "2.2.0", @@ -26260,8 +25319,7 @@ "version": "0.66.2", "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.66.2.tgz", "integrity": "sha512-RFewnL/RjE0qQBOuM+2bbY96zmJPIge/aDtsiDbLSb+MOiK8CReAhBHDgL+zrA3F1hQk00lMWpUwYcep750plA==", - "dev": true, - "peer": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -26274,7 +25332,6 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, - "peer": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -26286,7 +25343,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^0.1.0" } @@ -26296,7 +25352,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" } @@ -26306,7 +25361,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" } @@ -26316,7 +25370,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -26327,8 +25380,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "peer": true + "dev": true } } }, @@ -26337,7 +25389,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -26353,14 +25404,12 @@ "object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "dev": true + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-to-spawn-args": { "version": "2.0.1", @@ -26373,7 +25422,6 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, - "peer": true, "requires": { "isobject": "^3.0.0" } @@ -26382,7 +25430,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -26427,7 +25474,6 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, - "peer": true, "requires": { "isobject": "^3.0.1" } @@ -26456,8 +25502,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "peer": true + "dev": true }, "once": { "version": "1.4.0", @@ -26482,7 +25527,6 @@ "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", "dev": true, - "peer": true, "requires": { "is-wsl": "^1.1.0" } @@ -26505,15 +25549,13 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true, - "peer": true + "dev": true }, "ora": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", "dev": true, - "peer": true, "requires": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", @@ -26527,15 +25569,13 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "peer": true + "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "peer": true, "requires": { "color-convert": "^1.9.0" } @@ -26545,7 +25585,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "peer": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -26557,7 +25596,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "peer": true, "requires": { "color-name": "1.1.3" } @@ -26566,29 +25604,25 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true, - "peer": true + "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "peer": true + "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "peer": true + "dev": true }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, - "peer": true, "requires": { "chalk": "^2.0.1" } @@ -26598,7 +25632,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "peer": true, "requires": { "ansi-regex": "^4.1.0" } @@ -26608,7 +25641,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "peer": true, "requires": { "has-flag": "^3.0.0" } @@ -26619,15 +25651,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "peer": true + "dev": true }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "peer": true + "dev": true }, "p-limit": { "version": "2.3.0", @@ -26688,8 +25718,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "peer": true + "dev": true }, "path-browserify": { "version": "1.0.1", @@ -26743,9 +25772,9 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pify": { @@ -26911,7 +25940,6 @@ "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.4.tgz", "integrity": "sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg==", "dev": true, - "peer": true, "requires": { "base64-js": "^1.5.1", "xmlbuilder": "^9.0.7" @@ -26921,8 +25949,7 @@ "version": "9.0.7", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true, - "peer": true + "dev": true } } }, @@ -26930,8 +25957,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "peer": true + "dev": true }, "prelude-ls": { "version": "1.1.2", @@ -26940,12 +25966,11 @@ "dev": true }, "pretty-format": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", - "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", "dev": true, "requires": { - "@jest/types": "^27.4.2", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" @@ -26969,8 +25994,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "peer": true + "dev": true }, "progress": { "version": "2.0.3", @@ -26983,7 +26007,6 @@ "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", "dev": true, - "peer": true, "requires": { "asap": "~2.0.6" } @@ -26999,14 +26022,14 @@ } }, "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "react-is": "^16.13.1" }, "dependencies": { "react-is": { @@ -27028,7 +26051,6 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, - "peer": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -27091,11 +26113,10 @@ } }, "react-devtools-core": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.22.1.tgz", - "integrity": "sha512-pvpNDHE7p0FtcCmIWGazoY8LLVfBI9sw0Kf10kdHhPI9Tzt3OG/qEt16GrAbE0keuna5WzX3r1qPKVjqOqsuUg==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.19.1.tgz", + "integrity": "sha512-2wJiGffPWK0KggBjVwnTaAk+Z3MSxKInHmdzPTrBh1mAarexsa93Kw+WMX88+XjN+TtYgAiLe9xeTqcO5FfJTw==", "dev": true, - "peer": true, "requires": { "shell-quote": "^1.6.1", "ws": "^7" @@ -27112,7 +26133,6 @@ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.66.4.tgz", "integrity": "sha512-9vx5dlSfQlKbbDtr8+xMon6qsmSu7jvjdXWZpEKh3XVKpUidbbODv7048gwVKX8YAel1egeR7hN8vzSeI6ssTw==", "dev": true, - "peer": true, "requires": { "@jest/create-cache-key-function": "^27.0.1", "@react-native-community/cli": "^6.0.0", @@ -27152,7 +26172,6 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, - "peer": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -27166,7 +26185,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "peer": true, "requires": { "@types/yargs-parser": "*" } @@ -27176,7 +26194,6 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, - "peer": true, "requires": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -27189,7 +26206,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "dev": true, - "peer": true, "requires": { "async-limiter": "~1.0.0" } @@ -27201,7 +26217,6 @@ "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.7.tgz", "integrity": "sha512-dwNgR8zJ3ALr480QnAmpTiqvFo+rDtq6V5oCggKhYFlRjzOmVSFn3YD41u8ltvKS5G2nQ8gCs2vReFFnRGLYng==", "dev": true, - "peer": true, "requires": { "flow-parser": "^0.121.0", "jscodeshift": "^0.11.0", @@ -27212,8 +26227,7 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", "integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA==", - "dev": true, - "peer": true + "dev": true }, "read-pkg": { "version": "3.0.0", @@ -27292,7 +26306,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, - "peer": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -27316,15 +26329,13 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=", - "dev": true, - "peer": true + "dev": true }, "recast": { "version": "0.20.5", "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", "dev": true, - "peer": true, "requires": { "ast-types": "0.14.2", "esprima": "~4.0.0", @@ -27417,15 +26428,13 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "peer": true + "dev": true }, "regenerate-unicode-properties": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", "dev": true, - "peer": true, "requires": { "regenerate": "^1.4.2" } @@ -27434,15 +26443,13 @@ "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true, - "peer": true + "dev": true }, "regenerator-transform": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", "dev": true, - "peer": true, "requires": { "@babel/runtime": "^7.8.4" } @@ -27452,16 +26459,15 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, - "peer": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" } }, "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz", + "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -27479,7 +26485,6 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", "dev": true, - "peer": true, "requires": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^9.0.0", @@ -27493,15 +26498,13 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true, - "peer": true + "dev": true }, "regjsparser": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", "dev": true, - "peer": true, "requires": { "jsesc": "~0.5.0" }, @@ -27510,8 +26513,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true, - "peer": true + "dev": true } } }, @@ -27519,22 +26521,19 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true, - "peer": true + "dev": true }, "repeat-element": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "peer": true + "dev": true }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "peer": true + "dev": true }, "require-directory": { "version": "2.1.1", @@ -27552,8 +26551,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "peer": true + "dev": true }, "requires-port": { "version": "1.0.0", @@ -27571,13 +26569,14 @@ } }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", + "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==", "dev": true, "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-cwd": { @@ -27599,8 +26598,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true, - "peer": true + "dev": true }, "resolve.exports": { "version": "1.1.0", @@ -27613,7 +26611,6 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, - "peer": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -27623,15 +26620,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "peer": true + "dev": true }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, - "peer": true, "requires": { "mimic-fn": "^1.0.0" } @@ -27642,8 +26637,7 @@ "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "peer": true + "dev": true }, "rfdc": { "version": "1.3.0", @@ -27664,21 +26658,18 @@ "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true, - "peer": true + "dev": true }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, - "peer": true, "requires": { "ret": "~0.1.10" } @@ -27694,7 +26685,6 @@ "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", "dev": true, - "peer": true, "requires": { "@cnakazawa/watch": "^1.0.3", "anymatch": "^2.0.0", @@ -27712,7 +26702,6 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, - "peer": true, "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -27723,7 +26712,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "peer": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -27742,7 +26730,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -27754,7 +26741,6 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "peer": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -27768,7 +26754,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, - "peer": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -27784,7 +26769,6 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, - "peer": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -27797,7 +26781,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -27809,7 +26792,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, - "peer": true, "requires": { "pump": "^3.0.0" } @@ -27818,15 +26800,13 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "peer": true + "dev": true }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -27836,7 +26816,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -27847,15 +26826,13 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "peer": true + "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, - "peer": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -27877,7 +26854,6 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, - "peer": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -27887,7 +26863,6 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, - "peer": true, "requires": { "path-key": "^2.0.0" } @@ -27896,22 +26871,19 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "peer": true + "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true + "dev": true }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "peer": true, "requires": { "shebang-regex": "^1.0.0" } @@ -27920,15 +26892,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "peer": true + "dev": true }, "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, - "peer": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -27939,7 +26909,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "peer": true, "requires": { "isexe": "^2.0.0" } @@ -27950,8 +26919,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "peer": true + "dev": true }, "saxes": { "version": "5.0.1", @@ -27967,7 +26935,6 @@ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "dev": true, - "peer": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -27998,7 +26965,6 @@ "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dev": true, - "peer": true, "requires": { "debug": "2.6.9", "depd": "~1.1.2", @@ -28020,7 +26986,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" }, @@ -28029,8 +26994,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true } } }, @@ -28038,15 +27002,13 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "peer": true + "dev": true }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "peer": true + "dev": true } } }, @@ -28054,8 +27016,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", - "dev": true, - "peer": true + "dev": true }, "serialize-javascript": { "version": "6.0.0", @@ -28071,7 +27032,6 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dev": true, - "peer": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -28083,15 +27043,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "peer": true + "dev": true }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, - "peer": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -28104,7 +27062,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -28113,8 +27070,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "peer": true + "dev": true } } }, @@ -28159,7 +27115,6 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true, - "peer": true, "requires": { "array-filter": "~0.0.0", "array-map": "~0.0.0", @@ -28171,7 +27126,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -28189,7 +27143,6 @@ "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.0.tgz", "integrity": "sha512-uYWpeGFtZtVt2NhG4AHgpwx323zxD85x42heMJBan1qAiqqozIlaGrwrEt6kRjXWRWIXsuV1VLCvVmZan2B5dg==", "dev": true, - "peer": true, "requires": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.0", @@ -28213,7 +27166,6 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, - "peer": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", @@ -28225,7 +27177,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "peer": true, "requires": { "color-convert": "^1.9.0" } @@ -28235,7 +27186,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "peer": true, "requires": { "color-name": "1.1.3" } @@ -28244,8 +27194,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true, - "peer": true + "dev": true } } }, @@ -28254,7 +27203,6 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, - "peer": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -28271,7 +27219,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" } @@ -28281,7 +27228,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^0.1.0" } @@ -28291,7 +27237,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "peer": true, "requires": { "is-extendable": "^0.1.0" } @@ -28301,7 +27246,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -28311,7 +27255,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -28323,7 +27266,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -28333,7 +27275,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -28345,7 +27286,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -28356,29 +27296,25 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "peer": true + "dev": true }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "peer": true + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "peer": true + "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "peer": true + "dev": true } } }, @@ -28387,7 +27323,6 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, - "peer": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -28399,7 +27334,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^1.0.0" } @@ -28411,7 +27345,6 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, - "peer": true, "requires": { "kind-of": "^3.2.0" }, @@ -28421,7 +27354,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -28429,9 +27361,9 @@ } }, "socket.io": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.0.tgz", - "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz", + "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -28522,7 +27454,6 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, - "peer": true, "requires": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -28545,8 +27476,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true, - "peer": true + "dev": true }, "spdx-correct": { "version": "3.1.1", @@ -28585,7 +27515,6 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, - "peer": true, "requires": { "extend-shallow": "^3.0.0" } @@ -28603,29 +27532,19 @@ "dev": true, "requires": { "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } } }, "stackframe": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", - "dev": true, - "peer": true + "dev": true }, "stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", "dev": true, - "peer": true, "requires": { "type-fest": "^0.7.1" }, @@ -28634,8 +27553,7 @@ "version": "0.7.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true, - "peer": true + "dev": true } } }, @@ -28672,7 +27590,6 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, - "peer": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -28683,7 +27600,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "peer": true, "requires": { "is-descriptor": "^0.1.0" } @@ -28693,7 +27609,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -28703,7 +27618,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -28715,7 +27629,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -28725,7 +27638,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -28737,7 +27649,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "peer": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -28748,8 +27659,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "peer": true + "dev": true } } }, @@ -28763,8 +27673,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", - "dev": true, - "peer": true + "dev": true }, "stream-connect": { "version": "1.0.2", @@ -28816,7 +27725,6 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "peer": true, "requires": { "safe-buffer": "~5.1.0" } @@ -28870,7 +27778,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -28880,7 +27787,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -28905,8 +27811,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "peer": true + "dev": true }, "strip-final-newline": { "version": "2.0.0", @@ -28924,8 +27829,7 @@ "version": "9.2.1", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", - "dev": true, - "peer": true + "dev": true }, "supports-color": { "version": "7.2.0", @@ -28946,6 +27850,12 @@ "supports-color": "^7.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -28953,9 +27863,9 @@ "dev": true }, "table": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", - "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -28966,9 +27876,9 @@ }, "dependencies": { "ajv": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", - "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", + "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -29049,7 +27959,6 @@ "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", "dev": true, - "peer": true, "requires": { "os-tmpdir": "^1.0.0", "rimraf": "~2.2.6" @@ -29059,8 +27968,7 @@ "version": "2.2.8", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true, - "peer": true + "dev": true } } }, @@ -29167,7 +28075,6 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, - "peer": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -29208,7 +28115,6 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, - "peer": true, "requires": { "kind-of": "^3.0.2" }, @@ -29218,7 +28124,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "peer": true, "requires": { "is-buffer": "^1.1.5" } @@ -29230,7 +28135,6 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, - "peer": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -29274,9 +28178,9 @@ } }, "ts-jest": { - "version": "27.1.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.2.tgz", - "integrity": "sha512-eSOiJOWq6Hhs6Khzk5wKC5sgWIXgXqOCiIl1+3lfnearu58Hj4QpE5tUhQcA3xtZrELbcvAGCsd6HB8OsaVaTA==", + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", "dev": true, "requires": { "bs-logger": "0.x", @@ -29356,8 +28260,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true, - "peer": true + "dev": true }, "type-check": { "version": "0.3.2", @@ -29428,7 +28331,6 @@ "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", "dev": true, - "peer": true, "requires": { "commander": "~2.13.0", "source-map": "~0.6.1" @@ -29438,8 +28340,7 @@ "version": "2.13.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true, - "peer": true + "dev": true } } }, @@ -29454,14 +28355,12 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true, - "peer": true + "dev": true }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has-bigints": "^1.0.1", @@ -29479,15 +28378,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "peer": true + "dev": true }, "unicode-match-property-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, - "peer": true, "requires": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -29497,22 +28394,19 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true, - "peer": true + "dev": true }, "unicode-property-aliases-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", - "dev": true, - "peer": true + "dev": true }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, - "peer": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -29524,8 +28418,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "peer": true + "dev": true } } }, @@ -29546,7 +28439,6 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, - "peer": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -29557,7 +28449,6 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, - "peer": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -29569,7 +28460,6 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, - "peer": true, "requires": { "isarray": "1.0.0" } @@ -29580,8 +28470,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "peer": true + "dev": true } } }, @@ -29598,22 +28487,19 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true, - "peer": true + "dev": true }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "peer": true + "dev": true }, "use-subscription": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", "integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==", "dev": true, - "peer": true, "requires": { "object-assign": "^4.1.1" } @@ -29622,7 +28508,6 @@ "version": "0.12.4", "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, "requires": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -29636,8 +28521,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "peer": true + "dev": true }, "utils-merge": { "version": "1.0.1", @@ -29649,8 +28533,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "peer": true + "dev": true }, "v8-compile-cache": { "version": "2.3.0", @@ -29659,9 +28542,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -29697,8 +28580,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", - "dev": true, - "peer": true + "dev": true }, "void-elements": { "version": "2.0.1", @@ -29754,7 +28636,6 @@ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", "dev": true, - "peer": true, "requires": { "defaults": "^1.0.3" } @@ -29766,9 +28647,9 @@ "dev": true }, "webpack": { - "version": "5.65.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", - "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.66.0.tgz", + "integrity": "sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", @@ -29785,7 +28666,7 @@ "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "json-parse-better-errors": "^1.0.2", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -29836,9 +28717,9 @@ } }, "webpack-sources": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", - "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true }, "whatwg-encoding": { @@ -29854,8 +28735,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", - "dev": true, - "peer": true + "dev": true }, "whatwg-mimetype": { "version": "2.3.0", @@ -29887,7 +28767,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -29900,14 +28779,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true, - "peer": true + "dev": true }, "which-typed-array": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "dev": true, "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -30000,7 +28877,6 @@ "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz", "integrity": "sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==", "dev": true, - "peer": true, "requires": { "simple-plist": "^1.0.0", "uuid": "^3.3.2" @@ -30047,7 +28923,6 @@ "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", "integrity": "sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ==", "dev": true, - "peer": true, "requires": { "sax": "^1.2.1" } @@ -30056,8 +28931,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "peer": true + "dev": true }, "xvfb-maybe": { "version": "0.2.1", @@ -30141,9 +29015,9 @@ }, "dependencies": { "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true } } diff --git a/package.json b/package.json index 45d9f87..620f99e 100755 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ }, "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", - "localforage": "^1.9.0" + "localforage": "^1.9.0", + "util": "^0.12.4" }, "devDependencies": { "@react-native-async-storage/async-storage": "^1.15.9", @@ -63,6 +64,7 @@ "mocha-junit-reporter": "^2.0.0", "path-browserify": "^1.0.1", "process": "^0.11.10", + "react-native": "^0.66.0", "semver": "^7.3.5", "source-map-loader": "^2.0.2", "standard": "^16.0.3", @@ -71,7 +73,6 @@ "ts-jest": "^27.0.7", "ts-node": "^10.3.0", "typescript": "^4.4.4", - "util": "^0.12.4", "webpack": "^5.37.0", "webpack-cli": "^4.7.0", "xvfb-maybe": "^0.2.1" From 67a0c885b568c73f0efd0e436d347322634c125e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 20 Jan 2022 18:24:45 +0100 Subject: [PATCH 58/65] 3.0.0-4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c0601c8..837774d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-3", + "version": "3.0.0-4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@seald-io/nedb", - "version": "3.0.0-3", + "version": "3.0.0-4", "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", diff --git a/package.json b/package.json index 620f99e..f628fd0 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-3", + "version": "3.0.0-4", "files": [ "lib/**/*.js", "browser-version/**/*.js", From ebda00b8d259a1a2101f4f3aa8d729ef16bfae68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 21 Jan 2022 11:09:55 +0100 Subject: [PATCH 59/65] give the corruptionRate when there is an error --- CHANGELOG.md | 2 ++ lib/persistence.js | 43 ++++++++++++++++++++++------------ test/persistence.async.test.js | 22 +++++++++++++++-- test/persistence.test.js | 11 +++++++++ 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9908e36..4a6fc68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - The JSDoc is now much more exhaustive. - An auto-generated JSDoc file is generated: [API.md](./API.md). - Added `Datastore#dropDatabaseAsync` and its callback equivalent. +- The Error given when there the `Datastore#corruptAlertThreshold` is reached now has three properties: `dataLength` which is the amount of lines in the database file (excluding empty lines), `corruptItems` which is the amount of corrupted lines, `corruptionRate` which the rate of corruption between 0 and 1. ### Changed +- The `corrpuptionAlertThreshold` now doesn't take into account empty lines. - The `Datastore#update`'s callback has its signature slightly changed. The `upsert` flag is always defined either at `true` or `false` but not `null` nor `undefined`, and `affectedDocuments` is `null` when none is given rather than diff --git a/lib/persistence.js b/lib/persistence.js index 561b136..f6fd43b 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -177,11 +177,13 @@ class Persistence { const data = rawData.split('\n') const dataById = {} const indexes = {} + let dataLength = data.length // Last line of every data file is usually blank so not really corrupt - let corruptItems = -1 + let corruptItems = 0 for (const datum of data) { + if (datum === '') { dataLength--; continue } try { const doc = model.deserialize(this.beforeDeserialization(datum)) if (doc._id) { @@ -195,10 +197,16 @@ class Persistence { } // A bit lenient on corruption - if ( - data.length > 0 && - corruptItems / data.length > this.corruptAlertThreshold - ) throw new Error(`More than ${Math.floor(100 * this.corruptAlertThreshold)}% of the data file is corrupt, the wrong beforeDeserialization hook may be used. Cautiously refusing to start NeDB to prevent dataloss`) + if (dataLength > 0) { + const corruptionRate = corruptItems / dataLength + if (corruptionRate > this.corruptAlertThreshold) { + const error = new Error(`${Math.floor(100 * corruptionRate)}% of the data file is corrupt, more than given corruptAlertThreshold (${Math.floor(100 * this.corruptAlertThreshold)}%). Cautiously refusing to start NeDB to prevent dataloss.`) + error.corruptionRate = corruptionRate + error.corruptItems = corruptItems + error.dataLength = dataLength + throw error + } + } const tdata = Object.values(dataById) @@ -225,13 +233,13 @@ class Persistence { const indexes = {} - // Last line of every data file is usually blank so not really corrupt - let corruptItems = -1 + let corruptItems = 0 - const lineStream = byline(rawStream, { keepEmptyLines: true }) - let length = 0 + const lineStream = byline(rawStream) + let dataLength = 0 lineStream.on('data', (line) => { + if (line === '') return try { const doc = model.deserialize(this.beforeDeserialization(line)) if (doc._id) { @@ -243,17 +251,22 @@ class Persistence { corruptItems += 1 } - length++ + dataLength++ }) lineStream.on('end', () => { // A bit lenient on corruption - if (length > 0 && corruptItems / length > this.corruptAlertThreshold) { - const err = new Error(`More than ${Math.floor(100 * this.corruptAlertThreshold)}% of the data file is corrupt, the wrong beforeDeserialization hook may be used. Cautiously refusing to start NeDB to prevent dataloss`) - reject(err, null) - return + if (dataLength > 0) { + const corruptionRate = corruptItems / dataLength + if (corruptionRate > this.corruptAlertThreshold) { + const error = new Error(`${Math.floor(100 * corruptionRate)}% of the data file is corrupt, more than given corruptAlertThreshold (${Math.floor(100 * this.corruptAlertThreshold)}%). Cautiously refusing to start NeDB to prevent dataloss.`) + error.corruptionRate = corruptionRate + error.corruptItems = corruptItems + error.dataLength = dataLength + reject(error, null) + return + } } - const data = Object.values(dataById) resolve({ data, indexes: indexes }) diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index 1623cd3..10ca915 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -60,6 +60,7 @@ describe('Persistence async', function () { }) it('Badly formatted lines have no impact on the treated data', function () { + d.persistence.corruptAlertThreshold = 1 // to prevent a corruption alert const now = new Date() const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + 'garbage\n' + @@ -73,6 +74,7 @@ describe('Persistence async', function () { }) it('Badly formatted lines have no impact on the treated data (with stream)', async () => { + d.persistence.corruptAlertThreshold = 1 // to prevent a corruption alert const now = new Date() const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + 'garbage\n' + @@ -366,14 +368,30 @@ describe('Persistence async', function () { // Default corruptAlertThreshold d = new Datastore({ filename: corruptTestFilename }) - await assert.rejects(() => d.loadDatabaseAsync()) + await assert.rejects(() => d.loadDatabaseAsync(), err => { + assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptionRate')) + assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptItems')) + assert.ok(Object.prototype.hasOwnProperty.call(err, 'dataLength')) + assert.equal(err.corruptionRate, 0.25) + assert.equal(err.corruptItems, 1) + assert.equal(err.dataLength, 4) + return true + }) await fs.writeFile(corruptTestFilename, fakeData, 'utf8') d = new Datastore({ filename: corruptTestFilename, corruptAlertThreshold: 1 }) await d.loadDatabaseAsync() await fs.writeFile(corruptTestFilename, fakeData, 'utf8') d = new Datastore({ filename: corruptTestFilename, corruptAlertThreshold: 0 }) - await assert.rejects(() => d.loadDatabaseAsync()) + await assert.rejects(() => d.loadDatabaseAsync(), err => { + assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptionRate')) + assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptItems')) + assert.ok(Object.prototype.hasOwnProperty.call(err, 'dataLength')) + assert.equal(err.corruptionRate, 0.25) + assert.equal(err.corruptItems, 1) + assert.equal(err.dataLength, 4) + return true + }) }) it('Can listen to compaction events', async () => { diff --git a/test/persistence.test.js b/test/persistence.test.js index 774af46..8703cfc 100755 --- a/test/persistence.test.js +++ b/test/persistence.test.js @@ -82,6 +82,7 @@ describe('Persistence', function () { }) it('Badly formatted lines have no impact on the treated data', function () { + d.persistence.corruptAlertThreshold = 1 // to prevent a corruption alert const now = new Date() const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + 'garbage\n' + @@ -95,6 +96,7 @@ describe('Persistence', function () { }) it('Badly formatted lines have no impact on the treated data (with stream)', function (done) { + d.persistence.corruptAlertThreshold = 1 // to prevent a corruption alert const now = new Date() const rawData = model.serialize({ _id: '1', a: 2, ages: [1, 5, 12] }) + '\n' + 'garbage\n' + @@ -424,6 +426,10 @@ describe('Persistence', function () { d.loadDatabase(function (err) { assert.isDefined(err) assert.isNotNull(err) + assert.hasAllKeys(err, ['corruptionRate', 'corruptItems', 'dataLength']) + assert.strictEqual(err.corruptionRate, 0.25) + assert.strictEqual(err.corruptItems, 1) + assert.strictEqual(err.dataLength, 4) fs.writeFileSync(corruptTestFilename, fakeData, 'utf8') d = new Datastore({ filename: corruptTestFilename, corruptAlertThreshold: 1 }) @@ -436,6 +442,11 @@ describe('Persistence', function () { assert.isDefined(err) assert.isNotNull(err) + assert.hasAllKeys(err, ['corruptionRate', 'corruptItems', 'dataLength']) + assert.strictEqual(err.corruptionRate, 0.25) + assert.strictEqual(err.corruptItems, 1) + assert.strictEqual(err.dataLength, 4) + done() }) }) From ec9aa55c04f566b30ffa2a71ad9eced36d380837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 21 Jan 2022 11:11:54 +0100 Subject: [PATCH 60/65] wording in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a6fc68..41068dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - The Error given when there the `Datastore#corruptAlertThreshold` is reached now has three properties: `dataLength` which is the amount of lines in the database file (excluding empty lines), `corruptItems` which is the amount of corrupted lines, `corruptionRate` which the rate of corruption between 0 and 1. ### Changed -- The `corrpuptionAlertThreshold` now doesn't take into account empty lines. +- The `corruptionAlertThreshold` now doesn't take into account empty lines, and the error message is slightly changed. - The `Datastore#update`'s callback has its signature slightly changed. The `upsert` flag is always defined either at `true` or `false` but not `null` nor `undefined`, and `affectedDocuments` is `null` when none is given rather than From 84c554acee1365791390afb9becf6354f7d6476b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 21 Jan 2022 11:12:36 +0100 Subject: [PATCH 61/65] 3.0.0-5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 837774d..5464385 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-4", + "version": "3.0.0-5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@seald-io/nedb", - "version": "3.0.0-4", + "version": "3.0.0-5", "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", diff --git a/package.json b/package.json index f628fd0..259ee33 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-4", + "version": "3.0.0-5", "files": [ "lib/**/*.js", "browser-version/**/*.js", From 8c3aac50421dca62444221ed0675f93d98b85629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 27 Jan 2022 22:07:52 +0100 Subject: [PATCH 62/65] fix MR comments --- CHANGELOG.md | 4 +- browser-version/lib/storage.react-native.js | 2 +- lib/datastore.js | 11 +-- lib/persistence.js | 4 +- test/persistence.async.test.js | 92 +++++++-------------- 5 files changed, 39 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41068dc..23c07b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - The JSDoc is now much more exhaustive. - An auto-generated JSDoc file is generated: [API.md](./API.md). - Added `Datastore#dropDatabaseAsync` and its callback equivalent. -- The Error given when there the `Datastore#corruptAlertThreshold` is reached now has three properties: `dataLength` which is the amount of lines in the database file (excluding empty lines), `corruptItems` which is the amount of corrupted lines, `corruptionRate` which the rate of corruption between 0 and 1. +- The Error given when the `Datastore#corruptAlertThreshold` is reached now has three properties: `dataLength` which is the amount of lines in the database file (excluding empty lines), `corruptItems` which is the amount of corrupted lines, `corruptionRate` which the rate of corruption between 0 and 1. ### Changed - The `corruptionAlertThreshold` now doesn't take into account empty lines, and the error message is slightly changed. @@ -44,7 +44,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `Executor#buffer` & `Executor#queue` do not have the same signatures as before; - `Executor#push` replaced with `Executor#pushAsync` which is substantially different; - Storage modules : callback-based functions have been replaced with promise-based functions. - - Model module: it has been slightly re-written for clarity, but no changes in its interface was made. + - Model module: it has been slightly re-written for clarity, but no changes in its interface were made. - Typings were updated accordingly. ## Deprecated diff --git a/browser-version/lib/storage.react-native.js b/browser-version/lib/storage.react-native.js index ad7de93..1304822 100755 --- a/browser-version/lib/storage.react-native.js +++ b/browser-version/lib/storage.react-native.js @@ -3,7 +3,7 @@ * * This version is the React-Native version and uses [@react-native-async-storage/async-storage]{@link https://github.com/react-native-async-storage/async-storage}. * @module storageReactNative - * @see module:storagereact-native + * @see module:storageBrowser * @see module:storage * @private */ diff --git a/lib/datastore.js b/lib/datastore.js index 8cdc229..9f9b185 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -312,7 +312,7 @@ class Datastore extends EventEmitter { * @private * @type {null|number} */ - this.autocompactionIntervalId = null + this._autocompactionIntervalId = null } /** @@ -342,11 +342,12 @@ class Datastore extends EventEmitter { */ setAutocompactionInterval (interval) { const minInterval = 5000 + if (typeof interval !== 'number') throw new Error('Interval must be a number') const realInterval = Math.max(interval || 0, minInterval) this.stopAutocompaction() - this.autocompactionIntervalId = setInterval(() => { + this._autocompactionIntervalId = setInterval(() => { this.compactDatafile() }, realInterval) } @@ -355,9 +356,9 @@ class Datastore extends EventEmitter { * Stop autocompaction (do nothing if automatic compaction was not running) */ stopAutocompaction () { - if (this.autocompactionIntervalId) { - clearInterval(this.autocompactionIntervalId) - this.autocompactionIntervalId = null + if (this._autocompactionIntervalId) { + clearInterval(this._autocompactionIntervalId) + this._autocompactionIntervalId = null } } diff --git a/lib/persistence.js b/lib/persistence.js index f6fd43b..0efd7b1 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -115,7 +115,7 @@ class Persistence { * @see Persistence#compactDatafileAsync */ compactDatafile (callback) { - deprecate(callback => this.db.compactDatafile(callback), '@seald-io/nedb: calling Datastore#persistence#compactDatafile is deprecated, please use Datastore#compactDatafile, it will be removed in the next major version.')(callback) + deprecate(_callback => this.db.compactDatafile(_callback), '@seald-io/nedb: calling Datastore#persistence#compactDatafile is deprecated, please use Datastore#compactDatafile, it will be removed in the next major version.')(callback) } /** @@ -123,7 +123,7 @@ class Persistence { * @deprecated */ setAutocompactionInterval (interval) { - deprecate(interval => this.db.setAutocompactionInterval(interval), '@seald-io/nedb: calling Datastore#persistence#setAutocompactionInterval is deprecated, please use Datastore#setAutocompactionInterval, it will be removed in the next major version.')(interval) + deprecate(_interval => this.db.setAutocompactionInterval(_interval), '@seald-io/nedb: calling Datastore#persistence#setAutocompactionInterval is deprecated, please use Datastore#setAutocompactionInterval, it will be removed in the next major version.')(interval) } /** diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index 10ca915..c02df3b 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -11,6 +11,7 @@ const storage = require('../lib/storage') const { execFile, fork } = require('child_process') const { promisify } = require('util') const { ensureFileDoesntExistAsync } = require('../lib/storage') +const { once } = require('events') const Readable = require('stream').Readable describe('Persistence async', function () { @@ -337,29 +338,6 @@ describe('Persistence async', function () { assert.equal(doc2Reloaded, undefined) }) - it('Calling dropDatabase after the datafile was modified loads the new data', async () => { - await d.loadDatabaseAsync() - await d.insertAsync({ a: 1 }) - await d.insertAsync({ a: 2 }) - const data = d.getAllData() - const doc1 = data.find(doc => doc.a === 1) - const doc2 = data.find(doc => doc.a === 2) - assert.equal(data.length, 2) - assert.equal(doc1.a, 1) - assert.equal(doc2.a, 2) - - await fs.writeFile(testDb, '{"a":3,"_id":"aaa"}', 'utf8') - await d.loadDatabaseAsync() - const dataReloaded = d.getAllData() - const doc1Reloaded = dataReloaded.find(function (doc) { return doc.a === 1 }) - const doc2Reloaded = dataReloaded.find(function (doc) { return doc.a === 2 }) - const doc3Reloaded = dataReloaded.find(function (doc) { return doc.a === 3 }) - assert.equal(dataReloaded.length, 1) - assert.equal(doc3Reloaded.a, 3) - assert.equal(doc1Reloaded, undefined) - assert.equal(doc2Reloaded, undefined) - }) - it('When treating raw data, refuse to proceed if too much data is corrupt, to avoid data loss', async () => { const corruptTestFilename = 'workspace/corruptTest.db' const fakeData = '{"_id":"one","hello":"world"}\n' + 'Some corrupt data\n' + '{"_id":"two","hello":"earth"}\n' + '{"_id":"three","hello":"you"}\n' @@ -369,9 +347,8 @@ describe('Persistence async', function () { // Default corruptAlertThreshold d = new Datastore({ filename: corruptTestFilename }) await assert.rejects(() => d.loadDatabaseAsync(), err => { - assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptionRate')) - assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptItems')) - assert.ok(Object.prototype.hasOwnProperty.call(err, 'dataLength')) + assert.notEqual(err, undefined) + assert.notEqual(err, null) assert.equal(err.corruptionRate, 0.25) assert.equal(err.corruptItems, 1) assert.equal(err.dataLength, 4) @@ -384,9 +361,8 @@ describe('Persistence async', function () { await fs.writeFile(corruptTestFilename, fakeData, 'utf8') d = new Datastore({ filename: corruptTestFilename, corruptAlertThreshold: 0 }) await assert.rejects(() => d.loadDatabaseAsync(), err => { - assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptionRate')) - assert.ok(Object.prototype.hasOwnProperty.call(err, 'corruptItems')) - assert.ok(Object.prototype.hasOwnProperty.call(err, 'dataLength')) + assert.notEqual(err, undefined) + assert.notEqual(err, null) assert.equal(err.corruptionRate, 0.25) assert.equal(err.corruptItems, 1) assert.equal(err.dataLength, 4) @@ -847,40 +823,28 @@ describe('Persistence async', function () { // Loading it in a separate process that we will crash before finishing the loadDatabase const child = fork('test_lac/loadAndCrash.test', [], { stdio: 'inherit' }) - - await Promise.race([ - new Promise((resolve, reject) => child.on('error', reject)), - new Promise((resolve, reject) => { - child.on('exit', async function (code) { - try { - assert.equal(code, 1) // See test_lac/loadAndCrash.test.js - - assert.equal(await exists('workspace/lac.db'), true) - assert.equal(await exists('workspace/lac.db~'), true) - assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) - assert.equal((await fs.readFile('workspace/lac.db~', 'utf8')).length, 5000) - - // Reload database without a crash, check that no data was lost and fs state is clean (no temp file) - const db = new Datastore({ filename: 'workspace/lac.db' }) - await db.loadDatabaseAsync() - assert.equal(await exists('workspace/lac.db'), true) - assert.equal(await exists('workspace/lac.db~'), false) - assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) - - const docs = await db.findAsync({}) - assert.equal(docs.length, N) - for (i = 0; i < N; i += 1) { - docI = docs.find(d => d._id === 'anid_' + i) - assert.notEqual(docI, undefined) - assert.deepEqual({ hello: 'world', _id: 'anid_' + i }, docI) - } - resolve() - } catch (error) { - reject(error) - } - }) - }) - ]) + const [code] = await once(child, 'exit') + assert.equal(code, 1) // See test_lac/loadAndCrash.test.js + + assert.equal(await exists('workspace/lac.db'), true) + assert.equal(await exists('workspace/lac.db~'), true) + assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) + assert.equal((await fs.readFile('workspace/lac.db~', 'utf8')).length, 5000) + + // Reload database without a crash, check that no data was lost and fs state is clean (no temp file) + const db = new Datastore({ filename: 'workspace/lac.db' }) + await db.loadDatabaseAsync() + assert.equal(await exists('workspace/lac.db'), true) + assert.equal(await exists('workspace/lac.db~'), false) + assert.equal((await fs.readFile('workspace/lac.db', 'utf8')).length, datafileLength) + + const docs = await db.findAsync({}) + assert.equal(docs.length, N) + for (i = 0; i < N; i += 1) { + docI = docs.find(d => d._id === 'anid_' + i) + assert.notEqual(docI, undefined) + assert.deepEqual({ hello: 'world', _id: 'anid_' + i }, docI) + } }) // Not run on Windows as there is no clean way to set maximum file descriptors. Not an issue as the code itself is tested. @@ -946,7 +910,7 @@ describe('Persistence async', function () { d.setAutocompactionInterval(5000) await d.insertAsync({ hello: 'world' }) await d.dropDatabaseAsync() - assert.equal(d.autocompactionIntervalId, null) + assert.equal(d._autocompactionIntervalId, null) assert.equal(d.getAllData().length, 0) assert.equal(await exists(testDb), false) }) From 899bdf5a550119e875eb113a5dd8a53c346b6c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Thu, 27 Jan 2022 22:11:37 +0100 Subject: [PATCH 63/65] 3.0.0-6 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5464385..d04a678 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-5", + "version": "3.0.0-6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@seald-io/nedb", - "version": "3.0.0-5", + "version": "3.0.0-6", "license": "MIT", "dependencies": { "@seald-io/binary-search-tree": "^1.0.2", diff --git a/package.json b/package.json index 259ee33..52fa3bb 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seald-io/nedb", - "version": "3.0.0-5", + "version": "3.0.0-6", "files": [ "lib/**/*.js", "browser-version/**/*.js", From bf5e5e22187f931e128a67444cc5c48742bd597f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 28 Jan 2022 10:57:47 +0100 Subject: [PATCH 64/65] fix setAutocompaction interval type check + test simpler check for errors in tests --- lib/datastore.js | 4 +-- test/persistence.async.test.js | 60 ++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 9f9b185..32a8f6a 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -342,8 +342,8 @@ class Datastore extends EventEmitter { */ setAutocompactionInterval (interval) { const minInterval = 5000 - if (typeof interval !== 'number') throw new Error('Interval must be a number') - const realInterval = Math.max(interval || 0, minInterval) + if (Number.isNaN(Number(interval))) throw new Error('Interval must be a non-NaN number') + const realInterval = Math.max(Number(interval) || 0, minInterval) this.stopAutocompaction() diff --git a/test/persistence.async.test.js b/test/persistence.async.test.js index c02df3b..c414a36 100755 --- a/test/persistence.async.test.js +++ b/test/persistence.async.test.js @@ -12,6 +12,7 @@ const { execFile, fork } = require('child_process') const { promisify } = require('util') const { ensureFileDoesntExistAsync } = require('../lib/storage') const { once } = require('events') +const { wait } = require('./utils.test') const Readable = require('stream').Readable describe('Persistence async', function () { @@ -346,13 +347,11 @@ describe('Persistence async', function () { // Default corruptAlertThreshold d = new Datastore({ filename: corruptTestFilename }) - await assert.rejects(() => d.loadDatabaseAsync(), err => { - assert.notEqual(err, undefined) - assert.notEqual(err, null) - assert.equal(err.corruptionRate, 0.25) - assert.equal(err.corruptItems, 1) - assert.equal(err.dataLength, 4) - return true + await assert.rejects(() => d.loadDatabaseAsync(), { + corruptionRate: 0.25, + corruptItems: 1, + dataLength: 4, + message: '25% of the data file is corrupt, more than given corruptAlertThreshold (10%). Cautiously refusing to start NeDB to prevent dataloss.' }) await fs.writeFile(corruptTestFilename, fakeData, 'utf8') @@ -360,13 +359,11 @@ describe('Persistence async', function () { await d.loadDatabaseAsync() await fs.writeFile(corruptTestFilename, fakeData, 'utf8') d = new Datastore({ filename: corruptTestFilename, corruptAlertThreshold: 0 }) - await assert.rejects(() => d.loadDatabaseAsync(), err => { - assert.notEqual(err, undefined) - assert.notEqual(err, null) - assert.equal(err.corruptionRate, 0.25) - assert.equal(err.corruptItems, 1) - assert.equal(err.dataLength, 4) - return true + await assert.rejects(() => d.loadDatabaseAsync(), { + corruptionRate: 0.25, + corruptItems: 1, + dataLength: 4, + message: '25% of the data file is corrupt, more than given corruptAlertThreshold (0%). Cautiously refusing to start NeDB to prevent dataloss.' }) }) @@ -380,6 +377,41 @@ describe('Persistence async', function () { await compacted // should already be resolved when the function returns, but still awaiting for it }) + it('setAutocompaction fails gracefully when passed a NaN', async () => { + assert.throws(() => { + d.setAutocompactionInterval(Number.NaN) + }, { + message: 'Interval must be a non-NaN number' + }) + }) + + it('setAutocompaction fails gracefully when passed a string non castable to a number', async () => { + assert.throws(() => { + d.setAutocompactionInterval('a') + }, { + message: 'Interval must be a non-NaN number' + }) + }) + + it('setAutocompaction works if passed a number castable to a number below 5000ms', async () => { + let i = 0 + const backup = d.compactDatafile + d.compactDatafile = () => { + backup.call(d) + i++ + } + try { + d.setAutocompactionInterval('0') // it should set the actual interval to 5000 + await wait(6000) + assert.ok(i < 3) + assert.ok(i >= 1) + } finally { + d.compactDatafile = backup + d.stopAutocompaction() + assert.equal(d._autocompactionIntervalId, null) + } + }) + describe('Serialization hooks', async () => { const as = s => `before_${s}_after` const bd = s => s.substring(7, s.length - 6) From d54eed326023434347ac393d5ca0fc92b121c777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Rebours?= Date: Fri, 28 Jan 2022 13:17:15 +0100 Subject: [PATCH 65/65] simplify setAutocompactionInterval --- lib/datastore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/datastore.js b/lib/datastore.js index 32a8f6a..38629ea 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -343,7 +343,7 @@ class Datastore extends EventEmitter { setAutocompactionInterval (interval) { const minInterval = 5000 if (Number.isNaN(Number(interval))) throw new Error('Interval must be a non-NaN number') - const realInterval = Math.max(Number(interval) || 0, minInterval) + const realInterval = Math.max(Number(interval), minInterval) this.stopAutocompaction()