From 70197ee9d7107596b21fe223545acaa391b5ac17 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Tue, 28 Sep 2021 09:34:54 -0400 Subject: [PATCH 01/18] Convert callback functions to async in backend --- app/v1/about/controller.js | 15 +- app/v1/app.js | 84 ++-- app/v1/applications/controller.js | 630 +++++++++++------------------ app/v1/applications/helper.js | 347 +++++++--------- app/v1/applications/model.js | 321 ++++++--------- app/v1/certificates/controller.js | 162 ++++---- app/v1/groups/controller.js | 151 +++---- app/v1/groups/helper.js | 101 +++-- app/v1/groups/model.js | 280 ++++++------- app/v1/helpers/certificates.js | 15 +- app/v1/messages/controller.js | 150 ++++--- app/v1/messages/helper.js | 167 ++++---- app/v1/messages/model.js | 74 ++-- app/v1/module-config/controller.js | 231 +++++------ app/v1/module-config/helper.js | 23 +- app/v1/module-config/model.js | 58 ++- app/v1/permissions/controller.js | 57 ++- app/v1/permissions/helper.js | 22 +- app/v1/policy/controller.js | 46 ++- app/v1/policy/helper.js | 267 ++++++------ app/v1/policy/model.js | 401 +++++++++--------- app/v1/services/controller.js | 17 +- app/v1/services/helper.js | 19 +- app/v1/shaid/index.js | 120 +++--- app/v1/vehicle-data/controller.js | 196 ++++----- app/v1/vehicle-data/helper.js | 389 +++++++----------- custom/cache/index.js | 31 +- custom/databases/postgres/index.js | 77 +++- 28 files changed, 1919 insertions(+), 2532 deletions(-) diff --git a/app/v1/about/controller.js b/app/v1/about/controller.js index 177237b2..5410aaa3 100644 --- a/app/v1/about/controller.js +++ b/app/v1/about/controller.js @@ -33,25 +33,22 @@ exports.getInfo = function (req, res, next) { "certificate_authority": certificateController.openSSLEnabled }; + // cannot use promisify: there are two returns we need requestjs({ "method": "GET", "uri": "https://raw.githubusercontent.com/smartdevicelink/sdl_server/master/package.json", "timeout": 5000, "json": true - }, function(err, response, body){ - if(!err && response.statusCode >= 200 && response.statusCode < 300){ + }, async function (err, response, body) { + if (!err && response.statusCode >= 200 && response.statusCode < 300) { // success! data.latest_version = body.version; data.is_update_available = semver.lt(data.current_version, data.latest_version); data.update_type = semver.diff(data.current_version, data.latest_version); } - if(data.certificate_authority){ - return certificateController.checkAuthorityValidity(function(isAuthorityValid){ - data.is_authority_valid = isAuthorityValid && data.certificate_authority; - res.parcel.setStatus(200) - .setData(data) - .deliver(); - }) + if (data.certificate_authority) { + const isAuthorityValid = await certificateController.checkAuthorityValidity(); + data.is_authority_valid = isAuthorityValid && data.certificate_authority; } res.parcel.setStatus(200) diff --git a/app/v1/app.js b/app/v1/app.js index 65884252..a291d53e 100644 --- a/app/v1/app.js +++ b/app/v1/app.js @@ -117,56 +117,52 @@ function exposeRoutes () { app.get('/vehicle-data/type', auth.validateAuth, vehicleData.getValidTypes); } -//do not allow routes to be exposed until these async functions are completed -flame.async.parallel([ - //certificate expiration check and renewal for both applications and for the module config - applications.checkAndUpdateCertificates, - moduleConfig.checkAndUpdateCertificate, - //get and store permission info from SHAID on startup - function (next) { - permissions.update(function () { - log.info("Permissions updated"); - next(); - }); - }, - function (next) { +async function setup () { + //do not allow routes to be exposed until these async functions are completed + await Promise.all([ + //certificate expiration check and renewal for both applications and for the module config + applications.checkAndUpdateCertificates() + .catch(err => { + log.error(err); + }), + moduleConfig.checkAndUpdateCertificate() + .catch(err => { + log.error(err); + }), + //get and store permission info from SHAID on startup + permissions.update() + .catch(err => { + log.error(err); + }), // get and store app service type info from SHAID on startup - services.upsertTypes(function () { - log.info("App service types updated"); - next(); - }); - }, - function (next) { + services.upsertTypes() + .catch(err => { + log.error(err); + }), //get and store app categories from SHAID on startup - applications.queryAndStoreCategories(function() { - log.info('App categories updated'); - next(); - }); - }, - function (next) { + applications.queryAndStoreCategories() + .catch(err => { + log.error(err); + }), //get and store language code info from the GitHub SDL RPC specification on startup - messages.updateLanguages(function () { - log.info("Language list updated"); - next(); - }); - }, - function (next) { + messages.updateLanguages() + .catch(err => { + log.error(err); + }), //get and store app info from SHAID on startup - applications.queryAndStoreApplicationsFlow({}, false)(function () { - log.info("App information updated"); - next(); - }); - }, - function(next) { - vehicleData.updateRpcSpec(function() { - log.info("RPC Spec updated"); - next(); - }); - }, -], function () { + applications.queryAndStoreApplications({}, false) + .catch(err => { + log.error(err); + }), + vehicleData.updateRpcSpec() + .catch(err => { + log.error(err); + }), + ]); log.info("Start up complete. Exposing routes."); exposeRoutes(); -}); +} +setup(); //cron job for running updates. runs once a day at midnight new Cron('00 00 00 * * *', permissions.update, null, true); diff --git a/app/v1/applications/controller.js b/app/v1/applications/controller.js index e3ca1a60..c5220f65 100644 --- a/app/v1/applications/controller.js +++ b/app/v1/applications/controller.js @@ -9,285 +9,213 @@ const settings = require('../../../settings.js'); const certUtil = require('../helpers/certificates.js'); const certificates = require('../certificates/controller.js'); -function get (req, res, next) { +async function get (req, res, next) { //prioritize id, uuid, approval status, in that order. //only one parameter can be acted upon in one request - let chosenFlow; //to be determined + let apps; //to be determined if (req.query.id) { //filter by id if (Number.isNaN(Number(req.query.id))) { return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); } - chosenFlow = helper.createAppInfoFlow('idFilter', req.query.id); + apps = await helper.createAppInfoFlow('idFilter', req.query.id); } else if (req.query.uuid) { //filter by app uuid - chosenFlow = helper.createAppInfoFlow('multiFilter', {app_uuid: req.query.uuid}); + apps = await helper.createAppInfoFlow('multiFilter', {app_uuid: req.query.uuid}); } else if (req.query.approval_status || req.query.get_blacklist) { //filter by approval status - chosenFlow = helper.createAppInfoFlow('multiFilter', {approval_status: req.query.approval_status, get_blacklist: (req.query.get_blacklist == "true")}); + apps = await helper.createAppInfoFlow('multiFilter', {approval_status: req.query.approval_status, get_blacklist: (req.query.get_blacklist == "true")}); } else { //get all applications whose information are the latest versions - chosenFlow = helper.createAppInfoFlow('multiFilter'); + apps = await helper.createAppInfoFlow('multiFilter'); } - const finalFlow = flow([ - chosenFlow, - //include extra certificate information if just one app is returned and if the info exists - function (apps, next) { - //only if looking at a specific app and cert generation is enabled - if (apps.length === 1 && certificates.openSSLEnabled) { - const certInsertionFlow = flow([ - getAppCertificateByUuid.bind(null, apps[0].uuid), - function (appCert, next) { - const certificate = appCert.certificate; - if (!certificate) { - return next(null, apps); - } - certUtil.readKeyCertBundle(Buffer.from(certificate, 'base64')) - .then(keyBundle => { - apps[0].certificate = keyBundle.cert; - apps[0].private_key = keyBundle.key; - next(null, apps); - }) - .catch(next); - } - ], { method: "waterfall" }); - return certInsertionFlow(next); - } else { - return next(null, apps); + //include extra certificate information if just one app is returned and if the info exists + //only if looking at a specific app and cert generation is enabled + + try { + if (apps.length === 1 && certificates.openSSLEnabled) { + const appCert = await getAppCertificateByUuid(apps[0].uuid); + const certificate = appCert.certificate; + if (certificate) { + const keyBundle = await certUtil.readKeyCertBundle(Buffer.from(certificate, 'base64')); + apps[0].certificate = keyBundle.cert; + apps[0].private_key = keyBundle.key; } - }, - ], { method: 'waterfall' }); - - finalFlow(function (err, apps) { - if (err) { - app.locals.log.error(err) - return res.parcel.setStatus(500) - .setMessage("Internal Server Error") - .deliver(); } - return res.parcel.setStatus(200) + + res.parcel.setStatus(200) .setData({ applications: apps }) .deliver(); - }); - + } catch (err) { + app.locals.log.error(err) + return res.parcel.setStatus(500) + .setMessage("Internal Server Error") + .deliver(); + } } //TODO: emailing system for messaging the developer about the approval status change -function actionPost (req, res, next) { +async function actionPost (req, res, next) { helper.validateActionPost(req, res); helper.checkIdIntegerBody(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.runAsTransaction(function (client, callback) { - async.waterfall([ - // Blacklist/Unblacklist app - function (callback) { - if (req.body.blacklist) { - client.getOne(sql.insertAppBlacklist(req.body), callback); - } else { - client.getOne(sql.deleteAppBlacklist(req.body.uuid), callback); - } - }, - // Update approval status for app - function (blacklist, callback) { - client.getOne(sql.changeAppApprovalStatus(req.body.id, req.body.approval_status, (req.body.denial_message || null)), callback); - }, - // sync the status to SHAID - function (result, callback) { - if(!req.body.version_id){ - // skip notifying SHAID if there is no version ID (legacy support) - callback(null, null); - return; - } - app.locals.shaid.setApplicationApprovalVendor([{ - "uuid": req.body.uuid, - "blacklist": req.body.blacklist || false, - "version_id": req.body.version_id, - "approval_status": req.body.approval_status, - "notes": req.body.denial_message || null - }], callback); - } - ], callback); - }, function (err, response) { - if (err) { - app.locals.log.error(err); - return res.parcel.setStatus(500).deliver(); + await app.locals.db.asyncTransaction(async client => { + // Blacklist/Unblacklist app + if (req.body.blacklist) { + await client.getOne(sql.insertAppBlacklist(req.body)); } else { - return res.parcel.setStatus(200).deliver(); + await client.getOne(sql.deleteAppBlacklist(req.body.uuid)); } + + // Update approval status for app + await client.getOne(sql.changeAppApprovalStatus(req.body.id, req.body.approval_status, (req.body.denial_message || null))); + + // sync the status to SHAID + if (req.body.version_id) { + await app.locals.shaid.setApplicationApprovalVendor([{ + "uuid": req.body.uuid, + "blacklist": req.body.blacklist || false, + "version_id": req.body.version_id, + "approval_status": req.body.approval_status, + "notes": req.body.denial_message || null + }]); + } + // skip notifying SHAID if there is no version ID (legacy support) + }).then(() => { + res.parcel.setStatus(200).deliver(); + }).catch(err => { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); }); } -function hybridPost (req, res, next) { +async function hybridPost (req, res, next) { helper.validateHybridPost(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.runAsTransaction(function (client, callback) { - async.waterfall([ - function (callback) { - client.getOne(sql.getApp.base['uuidFilter'](req.body.uuid), callback); - }, - function (result, callback) { - if (!result) { - return callback("Unknown app"); - } - client.getOne(sql.deleteHybridPreference(req.body.uuid), callback); - }, - function(result, callback) { - client.getOne(sql.insertHybridPreference(req.body), callback); - } - ], callback); - }, function (err, response) { - if (err) { - app.locals.log.error(err); - return res.parcel.setStatus(500).deliver(); - } else { - return res.parcel.setStatus(200).deliver(); + await app.locals.db.asyncTransaction(async client => { + const result = await client.getOne(sql.getApp.base['uuidFilter'](req.body.uuid)); + if (!result) { + throw new Error("Unknown app"); } + await client.getOne(sql.deleteHybridPreference(req.body.uuid)); + await client.getOne(sql.insertHybridPreference(req.body)); + + }).then(() => { + res.parcel.setStatus(200).deliver(); + }).catch(err => { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); }); } -function rpcEncryptionPut (req, res, next) { +async function rpcEncryptionPut (req, res, next) { helper.validateRPCEncryptionPut(req, res); helper.checkIdIntegerBody(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.runAsTransaction(function (client, callback) { - async.waterfall([ - function (callback) { - client.getOne(sql.getApp.base['idFilter'](req.body.id), callback); - }, - function (result, callback) { - if (!result) { - return callback("Unknown app"); - } - client.getOne(sql.updateRPCEncryption(req.body), callback); - } - ], callback); - }, function (err, response) { - if (err) { - app.locals.log.error(err); - return res.parcel.setStatus(500).deliver(); - } else { - return res.parcel.setStatus(200).deliver(); + await app.locals.db.asyncTransaction(async client => { + const result = await client.getOne(sql.getApp.base['idFilter'](req.body.id)); + if (!result) { + throw new Error("Unknown app"); } + await client.getOne(sql.updateRPCEncryption(req.body)); + }).then(() => { + res.parcel.setStatus(200).deliver(); + }).catch(err => { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); }); } -function autoPost (req, res, next) { +async function autoPost (req, res, next) { helper.validateAutoPost(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.sqlCommand(sql.getApp.base['uuidFilter'](req.body.uuid), function(err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); if (!results.length) { return res.parcel.setStatus(400).deliver(); } - - let chosenCommand; if (req.body.is_auto_approved_enabled) { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.insertAppAutoApproval(req.body)); + await app.locals.db.asyncSql(sql.insertAppAutoApproval(req.body)); } else { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.deleteAutoApproval(req.body.uuid)); + await app.locals.db.asyncSql(sql.deleteAutoApproval(req.body.uuid)); } - - chosenCommand(function (err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } - return res.parcel.setStatus(200).deliver(); - }); - }); + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } -function administratorPost (req, res, next) { +async function administratorPost (req, res, next) { helper.validateAdministratorPost(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.sqlCommand(sql.getApp.base['uuidFilter'](req.body.uuid), function(err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); if (!results.length) { return res.parcel.setStatus(400).deliver(); } - - let chosenCommand; if (req.body.is_administrator_app) { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.insertAppAdministrator(req.body)); + await app.locals.db.asyncSql(sql.insertAppAdministrator(req.body)); } else { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.deleteAppAdministrator(req.body.uuid)); + await app.locals.db.asyncSql(sql.deleteAppAdministrator(req.body.uuid)); } - - chosenCommand(function (err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } - return res.parcel.setStatus(200).deliver(); - }); - }); + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } -function passthroughPost (req, res, next) { +async function passthroughPost (req, res, next) { helper.validatePassthroughPost(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.sqlCommand(sql.getApp.base['uuidFilter'](req.body.uuid), function(err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); if (!results.length) { return res.parcel.setStatus(400).deliver(); } - - let chosenCommand; if (req.body.allow_unknown_rpc_passthrough) { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.insertPassthrough(req.body)); + await app.locals.db.asyncSql(sql.insertPassthrough(req.body)); } else { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.deletePassthrough(req.body.uuid)); + await app.locals.db.asyncSql(sql.deletePassthrough(req.body.uuid)); } - - chosenCommand(function (err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } - return res.parcel.setStatus(200).deliver(); - }); - }); + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } -function putServicePermission (req, res, next) { +async function putServicePermission (req, res, next) { helper.validateServicePermissionPut(req, res); helper.checkIdIntegerBody(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.sqlCommand(sql.getApp.base['idFilter'](req.body.id), function(err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['idFilter'](req.body.id)); if (!results.length) { return res.parcel.setStatus(400).deliver(); } - if (results[0].approval_status == "ACCEPTED") { return res.parcel .setStatus(400) @@ -295,59 +223,48 @@ function putServicePermission (req, res, next) { .deliver(); } - let chosenCommand; if (req.body.is_selected) { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.insertAppServicePermission(req.body)); + await app.locals.db.asyncSql(sql.insertAppServicePermission(req.body)); } else { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.deleteAppServicePermission(req.body)); + await app.locals.db.asyncSql(sql.deleteAppServicePermission(req.body)); } - - chosenCommand(function (err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } - return res.parcel.setStatus(200).deliver(); - }); - }); + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } -function getFunctionalGroups (req, res, next) { - app.locals.db.getMany(sql.getAppFunctionalGroups(req.query), function(err, results) { - if (err) { - req.app.locals.log.error(err); - return res.parcel - .setStatus(500) - .deliver(); - } - return res.parcel +async function getFunctionalGroups (req, res, next) { + try { + const results = await app.locals.db.asyncSql(sql.getAppFunctionalGroups(req.query)); + res.parcel .setStatus(200) .setData({ "groups": results }) .deliver(); - }); + } catch (err) { + req.app.locals.log.error(err); + res.parcel + .setStatus(500) + .deliver(); + } } -function putFunctionalGroup (req, res, next) { +async function putFunctionalGroup (req, res, next) { helper.validateFunctionalGroupPut(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - app.locals.db.sqlCommand(sql.getApp.base['idFilter'](req.body.app_id), function(err, results) { - if (err) { - return res.parcel - .setStatus(500) - .setMessage("Internal service error.") - .deliver(); - } + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['idFilter'](req.body.app_id)); if (!results.length) { return res.parcel .setStatus(400) .setMessage("Invalid app.") .deliver(); } - if (results[0].approval_status == "ACCEPTED") { return res.parcel .setStatus(400) @@ -355,88 +272,68 @@ function putFunctionalGroup (req, res, next) { .deliver(); } - let chosenCommand; if (req.body.is_selected) { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.insertAppFunctionalGroup(req.body)); + await app.locals.db.asyncSql(sql.insertAppFunctionalGroup(req.body)); } else { - chosenCommand = app.locals.db.sqlCommand.bind(null, sql.deleteAppFunctionalGroup(req.body)); + await app.locals.db.asyncSql(sql.deleteAppFunctionalGroup(req.body)); } - chosenCommand(function (err, results) { - if (err) { - return res.parcel.setStatus(500).deliver(); - } - return res.parcel.setStatus(200).deliver(); - }); - }); + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } //expects a POST from SHAID -function webhook (req, res, next) { +async function webhook (req, res, next) { helper.validateWebHook(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - async.waterfall([ - (callback)=>{ - if(req.body.entity == "application"){ - const query = { - "uuid": req.body.uuid, - "include_deleted": true, - "include_blacklisted": true - }; - - switch(req.body.action){ - case "UPSERT": - const queryAndStoreFlow = queryAndStoreApplicationsFlow(query, true); - queryAndStoreFlow(callback); - break; - case "DELETE": - app.locals.db.sqlCommand(sql.purgeAppInfo(query), callback); - break; - case "BLACKLIST": - app.locals.db.sqlCommand(sql.insertAppBlacklist(query), callback); - break; - default: - callback(null, null); - } - }else{ - callback(null, null); + try { + if (req.body.entity == "application") { + const query = { + "uuid": req.body.uuid, + "include_deleted": true, + "include_blacklisted": true + }; + + switch(req.body.action){ + case "UPSERT": + await queryAndStoreApplications(query, true); + break; + case "DELETE": + await app.locals.db.asyncSql(sql.purgeAppInfo(query)); + break; + case "BLACKLIST": + await app.locals.db.asyncSql(sql.insertAppBlacklist(query)); + break; + default: } } - ], (err, result)=>{ - if (err) { - req.app.locals.log.error(err); - } - res.parcel.setStatus(200); - res.parcel.deliver(); - }); + } catch (err) { + req.app.locals.log.error(err); + } + + res.parcel.setStatus(200); + res.parcel.deliver(); } //queries SHAID to get applications and stores them into the database -function queryAndStoreApplicationsFlow (queryObj, notifyOEM = true) { - return flow([ - app.locals.shaid.getApplications.bind(null, queryObj), - helper.storeApps.bind(null, false, notifyOEM) - ], {method: 'waterfall', eventLoop: true}); +async function queryAndStoreApplications (queryObj, notifyOEM = true) { + const apps = await app.locals.shaid.getApplications(queryObj); + await helper.storeApps(false, notifyOEM, apps); } //helper function that attempts to find the associated certificate bundle in the database -function getAppCertificateByUuid(app_uuid, callback) { - app.locals.db.getOne(sql.getApp.certificate(app_uuid), function(err, result) { - if (err) { - return callback(err); - } - if (result) { - callback(null, result); - } else { - callback(null, {}); - } - }); +async function getAppCertificateByUuid (app_uuid) { + const result = await app.locals.db.asyncSql(sql.getApp.certificate(app_uuid)); + return result ? result : {}; } -function getAppCertificate(req, res, next) { +//todo +async function getAppCertificate (req, res, next) { if (!certificates.openSSLEnabled) { return res.parcel.setStatus(400) .setMessage('Security options have not been properly configured') @@ -455,19 +352,13 @@ function getAppCertificate(req, res, next) { .deliver(); } - getAppCertificateByUuid(app_uuid, function (err, appCert) { - if (err) { - app.locals.log.error(err); - return res.parcel.setStatus(500) - .setMessage('Internal Server Error') - .deliver(); - } - if (!appCert.certificate) { + try { + const appCert = await getAppCertificateByUuid(app_uuid); + if (!appCert.certificate) { return res.parcel.setStatus(400) .setMessage('Could not find certificate for app with that id') .deliver(); } - const expirationDate = moment.utc(appCert.expiration_ts); const currentDate = moment.utc(); @@ -481,10 +372,13 @@ function getAppCertificate(req, res, next) { .setData({ 'certificate': appCert.certificate }) .deliver(); } - }); + } catch (err) { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + } } -function updateAppCertificate(req, res, next) { +async function updateAppCertificate (req, res, next) { if (!certificates.openSSLEnabled) { return res.parcel.setStatus(400) .setMessage('Security options have not been properly configured') @@ -498,125 +392,67 @@ function updateAppCertificate(req, res, next) { } //make sure the passed in app uuid exists in the db - app.locals.db.sqlCommand(sql.getApp.base['uuidFilter'](req.body.options.app_uuid), function (err, results) { - if (err) { - return res.parcel - .setStatus(500) - .setMessage("Internal service error.") - .deliver(); - } + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.options.app_uuid)); if (!results.length) { return res.parcel .setStatus(400) .setMessage("Invalid app.") .deliver(); } - //valid app uuid. continue - certUtil.createKeyCertBundle(req.body.options.clientKey, req.body.options.certificate) - .then(keyCertBundle => { - model.updateAppCertificate(req.body.options.app_uuid, keyCertBundle, function (err) { - if (err) { - app.locals.log.error(err); - return res.parcel.setStatus(500) - .setMessage('Internal Server Error') - .deliver(); - } - return res.parcel.setStatus(200).deliver() - }); - }) - .catch(err => { - app.locals.log.error(err); - return res.parcel.setStatus(500) - .setMessage('Internal Server Error') - .deliver(); - }); - }); + //valid app uuid. continue + const keyCertBundle = await certUtil.createKeyCertBundle(req.body.options.clientKey, req.body.options.certificate); + await model.updateAppCertificate(req.body.options.app_uuid, keyCertBundle); + res.parcel.setStatus(200).deliver(); + } catch (err) { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + } } -function checkAndUpdateCertificates(cb){ +async function checkAndUpdateCertificates () { if (!certificates.openSSLEnabled) { - if (cb) { - cb(); - } return; } - app.locals.db.sqlCommand(sql.getApp.allExpiredCertificates(), parseAppCerts); + const expiredCertObjs = await app.locals.db.asyncSql(sql.getApp.allExpiredCertificates()) - function parseAppCerts(sqlErr, expiredCertObjs){ - if (sqlErr) { - app.locals.log.error(sqlErr); - if (cb) { - cb(); - } - return; - } + let failedApps = []; - async.mapSeries(expiredCertObjs, function (expiredCertObj, next) { - certUtil.readKeyCertBundle(Buffer.from((expiredCertObj.certificate || ""), 'base64')) - .then(keyBundle => { - app.locals.log.info("creating new cert for app with existing key"); - const appInfo = { - app_uuid: expiredCertObj.app_uuid, - private_key: keyBundle.key - } - next(null, appInfo); - }) - .catch(pkcsErr => { - app.locals.log.info("creating new key and cert for app"); - const appInfo = { - app_uuid: expiredCertObj.app_uuid, - } - next(null, appInfo); + for (let expiredCertObj of expiredCertObjs) { + await certUtil.readKeyCertBundle(Buffer.from((expiredCertObj.certificate || ""), 'base64')) + .then(keyBundle => { + app.locals.log.info("creating new cert for app with existing key"); + failedApps.push({ + app_uuid: expiredCertObj.app_uuid, + private_key: keyBundle.key }); - }, function (err, failedApps) { - if (err) { - app.locals.log.error(err); - if (cb) { - cb(); - } - return; - } - //create new certificates for the failed apps and save them - async.mapSeries(failedApps, helper.createFailedAppsCert, function (failedAppErr, results) { - if (failedAppErr) { - app.locals.log.error(failedAppErr); - } - helper.storeAppCertificates(results, function () { - if (cb) { - cb(); - } + }) + .catch(pkcsErr => { + app.locals.log.info("creating new key and cert for app"); + failedApps.push({ + app_uuid: expiredCertObj.app_uuid, }); }); - }); } + + //create new certificates for the failed apps and save them + const results = await Promise.all(failedApps.map(helper.createFailedAppsCert)); + + await helper.storeAppCertificates(results); } /** * queries SHAID to get new categories and stores them into the database */ -function queryAndStoreCategories(callback) { - return flow( - [ - app.locals.shaid.getCategories.bind(null, {}), - helper.storeCategories - ], - { method: 'waterfall', eventLoop: true } - )(function(err){ - if(err){ - app.locals.log.error("Error syncing App Categories."); - }else{ - app.locals.log.info("App Categories sync complete."); - } - - if(callback){ - callback(err); - } - }); +async function queryAndStoreCategories () { + const categories = await app.locals.shaid.getCategories({}); + await helper.storeCategories(categories); + app.locals.log.info("App categories sync complete."); } -function getStagingAppStore (req, res, next) { +async function getStagingAppStore (req, res, next) { let filterObj = { approval_status: 'STAGING', platform: 'EMBEDDED', @@ -629,29 +465,22 @@ function getStagingAppStore (req, res, next) { filterObj.transport_type = req.query.transport_type; } - let chosenFlow = helper.createAppInfoFlow('multiFilter', filterObj); - - const finalFlow = flow([ - chosenFlow, - helper.appStoreTransformation.bind(null, req.query.min_rpc_version, req.query.min_protocol_version), - ], { method: 'waterfall' }); - - finalFlow(function (err, apps) { - if (err) { - app.locals.log.error(err); - return res.parcel.setStatus(500) - .setMessage("Internal Server Error") - .deliver(); - } - return res.parcel.setStatus(200) + try { + const appInfo = await helper.createAppInfoFlow('multiFilter', filterObj); + const apps = helper.appStoreTransformation(req.query.min_rpc_version, req.query.min_protocol_version, appInfo); + + res.parcel.setStatus(200) .setData({ applications: apps, }) .deliver(); - }) + } catch (err) { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + } } -function getAppStore (req, res, next) { +async function getAppStore (req, res, next) { // only let embedded apps through let filterObj = { approval_status: 'ACCEPTED', @@ -665,26 +494,19 @@ function getAppStore (req, res, next) { filterObj.transport_type = req.query.transport_type; } - let chosenFlow = helper.createAppInfoFlow('multiFilter', filterObj); - - const finalFlow = flow([ - chosenFlow, - helper.appStoreTransformation.bind(null, req.query.min_rpc_version, req.query.min_protocol_version), - ], { method: 'waterfall' }); + try { + const appInfo = await helper.createAppInfoFlow('multiFilter', filterObj); + const apps = helper.appStoreTransformation(req.query.min_rpc_version, req.query.min_protocol_version, appInfo); - finalFlow(function (err, apps) { - if (err) { - app.locals.log.error(err) - return res.parcel.setStatus(500) - .setMessage("Internal Server Error") - .deliver(); - } - return res.parcel.setStatus(200) + res.parcel.setStatus(200) .setData({ applications: apps }) .deliver(); - }) + } catch (err) { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + } } module.exports = { @@ -699,7 +521,7 @@ module.exports = { getFunctionalGroups: getFunctionalGroups, putFunctionalGroup: putFunctionalGroup, webhook: webhook, - queryAndStoreApplicationsFlow: queryAndStoreApplicationsFlow, + queryAndStoreApplications: queryAndStoreApplications, queryAndStoreCategories: queryAndStoreCategories, getAppCertificate: getAppCertificate, updateAppCertificate: updateAppCertificate, diff --git a/app/v1/applications/helper.js b/app/v1/applications/helper.js index c09ee545..3d968015 100644 --- a/app/v1/applications/helper.js +++ b/app/v1/applications/helper.js @@ -1,7 +1,7 @@ const check = require('check-types'); const app = require('../app'); const model = require('./model.js'); -const setupSql = app.locals.db.setupSqlCommand; +const asyncSql = app.locals.db.asyncSql; const sql = require('./sql.js'); const flow = app.locals.flow; const flame = app.locals.flame; @@ -103,118 +103,93 @@ function validateWebHook (req, res) { //helper functions //gets back app information depending on the filters passed in -function createAppInfoFlow (filterTypeFunc, value) { - const getAppFlow = app.locals.flow({ - appBase: setupSql.bind(null, sql.getApp.base[filterTypeFunc](value)), - appCountries: setupSql.bind(null, sql.getApp.countries[filterTypeFunc](value)), - appDisplayNames: setupSql.bind(null, sql.getApp.displayNames[filterTypeFunc](value)), - appPermissions: setupSql.bind(null, sql.getApp.permissions[filterTypeFunc](value)), - appCategories: setupSql.bind(null, sql.getApp.category[filterTypeFunc](value)), - appAllCategories: setupSql.bind(null, sql.getApp.allCategories[filterTypeFunc](value)), - appServiceTypes: setupSql.bind(null, sql.getApp.serviceTypes[filterTypeFunc](value)), - appServiceTypeNames: setupSql.bind(null, sql.getApp.serviceTypeNames[filterTypeFunc](value)), - appServiceTypePermissions: setupSql.bind(null, sql.getApp.serviceTypePermissions[filterTypeFunc](value)), - appAutoApprovals: setupSql.bind(null, sql.getApp.autoApproval[filterTypeFunc](value)), - appBlacklist: setupSql.bind(null, sql.getApp.blacklist[filterTypeFunc](value)), - appAdministrators: setupSql.bind(null, sql.getApp.administrators[filterTypeFunc](value)), - appHybridPreference: setupSql.bind(null, sql.getApp.hybridPreference[filterTypeFunc](value)), - appPassthrough: setupSql.bind(null, sql.getApp.passthrough[filterTypeFunc](value)) - }, {method: 'parallel', eventLoop: true}); - - return app.locals.flow([getAppFlow, model.constructFullAppObjs], {method: "waterfall", eventLoop: true}); -} - -function storeCategories(categories, callback) { - const upsertCats = app.locals.db.setupSqlCommands(sql.upsertCategories(categories)); +async function createAppInfoFlow (filterTypeFunc, value) { + const getAppObj = { + appBase: asyncSql(sql.getApp.base[filterTypeFunc](value)), + appCountries: asyncSql(sql.getApp.countries[filterTypeFunc](value)), + appDisplayNames: asyncSql(sql.getApp.displayNames[filterTypeFunc](value)), + appPermissions: asyncSql(sql.getApp.permissions[filterTypeFunc](value)), + appCategories: asyncSql(sql.getApp.category[filterTypeFunc](value)), + appAllCategories: asyncSql(sql.getApp.allCategories[filterTypeFunc](value)), + appServiceTypes: asyncSql(sql.getApp.serviceTypes[filterTypeFunc](value)), + appServiceTypeNames: asyncSql(sql.getApp.serviceTypeNames[filterTypeFunc](value)), + appServiceTypePermissions: asyncSql(sql.getApp.serviceTypePermissions[filterTypeFunc](value)), + appAutoApprovals: asyncSql(sql.getApp.autoApproval[filterTypeFunc](value)), + appBlacklist: asyncSql(sql.getApp.blacklist[filterTypeFunc](value)), + appAdministrators: asyncSql(sql.getApp.administrators[filterTypeFunc](value)), + appHybridPreference: asyncSql(sql.getApp.hybridPreference[filterTypeFunc](value)), + appPassthrough: asyncSql(sql.getApp.passthrough[filterTypeFunc](value)) + }; + + for (let prop in getAppObj) { + getAppObj[prop] = await getAppObj[prop]; // resolve all promises into each property + } - const insertFlow = app.locals.flow([ - app.locals.flow(upsertCats, {method: 'parallel'}) - ], {method: 'series'}); + return model.constructFullAppObjs(getAppObj); +} - insertFlow(callback); +async function storeCategories (categories) { + await app.locals.db.asyncSqls(sql.upsertCategories(categories)); } //application store functions -function storeApps (includeApprovalStatus, notifyOEM, apps, callback) { - let queue = []; - function recStore(includeApprovalStatus, theseApps, cb){ - const fullFlow = flow([ - //first check if the apps need to be deleted from or stored in the database - flow(flame.map(theseApps, checkNeedsInsertionOrDeletion), {method: "parallel"}), - filterApps.bind(null, includeApprovalStatus), - //each app surviving the filter should be checked with the app_auto_approval table to see if it its status - //should change to be accepted - function (appObjs, next) { - flame.async.map(appObjs, autoApprovalModifier, next); - }, - function (appObjs, next) { - flame.async.map(appObjs, autoBlacklistModifier, next); - }, - function (appObjs, next) { - flame.async.map(appObjs, model.storeApp.bind(null, notifyOEM), next); - } - ], {method: "waterfall", eventLoop: true}); - - fullFlow(function (err, res) { - if (err) { - log.error(err); - // res returns an array with the app ID in the position that it was in in the shaid app query - // if the third app were to fail, then res would look like [ , , appID] - let appID = res[res.length - 1]; - if(appID && queue[queue.length - 1] !== appID){ // ensures that the appID is not null and not already in the queue - queue.push(appID); - } - if(res.length !== theseApps.length){ - let appsLeftover = theseApps.slice(res.length); - return recStore(includeApprovalStatus, appsLeftover, cb); - } - } - cb(); - }); +async function storeApps (includeApprovalStatus, notifyOEM, apps, callback) { + + async function recStore (includeApprovalStatus, theseApps) { + //first check if the apps need to be deleted from or stored in the database + const appResults = await Promise.all(theseApps.map(checkNeedsInsertionOrDeletion)); + let appObjs = await filterApps(includeApprovalStatus, appResults); + + //each app surviving the filter should be checked with the app_auto_approval table to see if it its status + //should change to be accepted + appObjs = await Promise.all(appObjs.map(autoApprovalModifier)); + appObjs = await Promise.all(appObjs.map(autoBlacklistModifier)); + + const succeededAppIds = (await Promise.allSettled(appObjs.map(model.storeApp.bind(null, notifyOEM)))).map(result => result.value); + // return all failed apps to try inserts again later + return appObjs.filter((appObj, index) => succeededAppIds[index] === undefined).map(appObj => appObj.uuid); } - recStore(includeApprovalStatus, apps, function(){ - callback(); - if(queue.length > 0){ - attemptRetry(300000, queue); - } - }); + + const queue = await recStore(includeApprovalStatus, apps); + + if (queue.length > 0) { + attemptRetry(300000, queue); + } + return; } //determine whether the object needs to be deleted or stored in the database -function checkNeedsInsertionOrDeletion (appObj, next) { - if(appObj.deleted_ts){ +async function checkNeedsInsertionOrDeletion (appObj) { + if (appObj.deleted_ts) { // delete! - db.sqlCommand(sql.purgeAppInfo(appObj), function(err, data){ - // delete attempt made, skip it! - next(null, null); - }); - }else if(appObj.blacklisted_ts){ + await db.asyncSql(sql.purgeAppInfo(appObj)); + // delete attempt made, skip it! + return null; + } else if (appObj.blacklisted_ts) { // blacklist! - db.sqlCommand(sql.insertAppBlacklist(appObj), function(err, data){ - // blacklist attempt made, skip it! - next(null, null); - }); - }else{ + await db.asyncSql(sql.insertAppBlacklist(appObj)); + // blacklist attempt made, skip it! + return null; + } else { // check if the version exists in the database before attempting insertion const getObjStr = sql.versionCheck('app_info', { app_uuid: appObj.uuid, version_id: appObj.version_id }); - db.sqlCommand(getObjStr, function (err, data) { - if(data.length > 0){ - // record exists, skip it! - next(null, null); - }else{ - next(null, appObj); - } - }); + const data = await db.asyncSql(getObjStr); + if (data.length > 0) { + // record exists, skip it! + return null; + } else { + return appObj; + } } } //any elements that are null are removed //furthermore, remove approval status here if necessary -function filterApps (includeApprovalStatus, appObjs, next) { +async function filterApps (includeApprovalStatus, appObjs) { let filtered = appObjs.filter(function (appObj) { return appObj !== null; }); @@ -226,130 +201,113 @@ function filterApps (includeApprovalStatus, appObjs, next) { } return appObj; }); - next(null, filtered); + return filtered; } //auto changes any app's approval status to ACCEPTED if a record was found for that app's uuid in the auto approval table -function autoApprovalModifier (appObj, next) { - +async function autoApprovalModifier (appObj) { // check if auto-approve *all apps* is enabled - if(config.autoApproveAllApps){ + if (config.autoApproveAllApps) { appObj.approval_status = 'ACCEPTED'; appObj.encryption_required = config.autoApproveSetRPCEncryption; - next(null, appObj); - return; + return appObj; } // check if auto-approve this specific app is enabled - db.sqlCommand(sql.checkAutoApproval(appObj.uuid), function (err, res) { - //if res is not an empty array, then a record was found in the app_auto_approval table - //change the status of this appObj to ACCEPTED - if (res.length > 0) { - appObj.approval_status = 'ACCEPTED'; - appObj.encryption_required = config.autoApproveSetRPCEncryption; - } - next(null, appObj); - }); + const res = await db.asyncSql(sql.checkAutoApproval(appObj.uuid)); + //if res is not an empty array, then a record was found in the app_auto_approval table + //change the status of this appObj to ACCEPTED + if (res.length > 0) { + appObj.approval_status = 'ACCEPTED'; + appObj.encryption_required = config.autoApproveSetRPCEncryption; + } + return appObj; } // Auto deny new application versions of an app that is blacklisted -function autoBlacklistModifier (appObj, next) { - db.sqlCommand(sql.getBlacklistedAppFullUuids(appObj.uuid), function (err, res) { - if (res.length > 0) { - appObj.approval_status = 'LIMITED'; - } - next(null, appObj); - }); +async function autoBlacklistModifier (appObj) { + const res = await db.asyncSql(sql.getBlacklistedAppFullUuids(appObj.uuid)); + + if (res.length > 0) { + appObj.approval_status = 'LIMITED'; + } + return appObj; } // checks a retry queue of app IDs to requery their information from SHAID and attempt insertion into the database -function attemptRetry(milliseconds, retryQueue){ - if(milliseconds > 14400000){ // do not take longer than 4 hours +function attemptRetry (milliseconds, retryQueue) { + if (milliseconds > 14400000) { // do not take longer than 4 hours milliseconds = 14400000; } log.error("Received app with incorrectly formatted info, will attempt to requery SHAID in " + (milliseconds / 60000) + " minutes"); - setTimeout(function(){ - flame.async.map(retryQueue, function(appID, callback){ - flame.async.waterfall([ - app.locals.shaid.getApplications.bind(null, { - "uuid": appID, - "include_deleted": true, - "include_blacklisted": true - }), - function(apps, callback){ - const fullFlow = flow([ - //first check if the apps need to be stored in the database - flow(flame.map(apps, checkNeedsInsertionOrDeletion), {method: "parallel"}), - filterApps.bind(null, false), - //each app surviving the filter should be checked with the app_auto_approval table to see if it its status - //should change to be accepted - function (appObjs, callback) { - flame.async.map(appObjs, autoApprovalModifier, callback); - }, - function (appObjs, callback) { - flame.async.map(appObjs, autoBlacklistModifier, callback); - }, - function (appObjs, callback) { - flame.async.map(appObjs, model.storeApp.bind(null, true), callback); - } - ], {method: "waterfall", eventLoop: true}); - fullFlow(function (err, res) { - if (err) { - log.error(err); - // increase wait time for retry by a factor of 5 - attemptRetry(milliseconds * 5, res, callback); - } else { - log.info("App with previously malformed data successfully stored"); - callback(); - } - }) - } - ], callback); - }, function(){ - log.info("Apps in retry queue successfully added to the database"); + + setTimeout(async function () { + const appGetPromises = retryQueue.map(async appID => { + return app.locals.shaid.getApplications({ + "uuid": appID, + "include_deleted": true, + "include_blacklisted": true + }); }); + + const appArrays = await Promise.all(appGetPromises); + let apps = []; + + appArrays.forEach(array => { + apps = apps.concat(array); + }); + + //first check if the apps need to be deleted from or stored in the database + const appResults = await Promise.all(apps.map(checkNeedsInsertionOrDeletion)); + + let appObjs = await filterApps(false, appResults); + //each app surviving the filter should be checked with the app_auto_approval table to see if it its status + //should change to be accepted + appObjs = await Promise.all(appObjs.map(autoApprovalModifier)); + appObjs = await Promise.all(appObjs.map(autoBlacklistModifier)); + + const succeededAppIds = (await Promise.allSettled(appObjs.map(model.storeApp.bind(null, true)))).map(result => result.value); + const failedAppIds = appObjs.filter((appObj, index) => succeededAppIds[index] === undefined).map(appObj => appObj.uuid); + + if (failedAppIds.length > 0) { + // increase wait time for retry by a factor of 5 + attemptRetry(milliseconds * 5, failedAppIds); + } else { + log.info("App with previously malformed data successfully stored"); + } }, milliseconds); } -function storeAppCertificates (insertObjs, next) { - app.locals.db.runAsTransaction(function (client, callback) { - async.mapSeries(insertObjs, function (insertObj, cb) { - app.locals.log.info("Updating certificate of " + insertObj.app_uuid); - model.updateAppCertificate(insertObj.app_uuid, insertObj.certificate, cb); - }, callback); - }, function (err, response) { - if(err){ - app.locals.log.error(err); - } - app.locals.log.info("App certificates updated"); - next(); - }); +async function storeAppCertificates (insertObjs) { + await app.locals.db.asyncTransaction(async client => { + for (const insertObj of insertObjs) { + app.locals.log.info("Updating certificate of " + insertObj.app_uuid); + await model.updateAppCertificate(insertObj.app_uuid, insertObj.certificate); + } + }).catch(err => { + app.locals.log.error(err); + }); + + app.locals.log.info("App certificates updated"); } -function createFailedAppsCert(failedApp, next){ +async function createFailedAppsCert (failedApp, next) { let options = certificates.getCertificateOptions({ serialNumber: failedApp.app_uuid, clientKey: failedApp.private_key }); - certificates.createCertificateFlow(options, function(err, keyBundle){ - if(err){ - return next(err, {}); - } - certUtil.createKeyCertBundle(keyBundle.clientKey, keyBundle.certificate) - .then(keyCertBundle => { - next(null, { - app_uuid: failedApp.app_uuid, - certificate: keyCertBundle - }); - }) - .catch(err => { - next(err) - }); - }); + const keyBundle = await certificates.asyncCreateCertificate(options); + + const keyCertBundle = await certUtil.createKeyCertBundle(keyBundle.clientKey, keyBundle.certificate); + + return { + app_uuid: failedApp.app_uuid, + certificate: keyCertBundle + } } -function appStoreTransformation (min_rpc_version, min_protocol_version, apps, next) { +function appStoreTransformation (min_rpc_version, min_protocol_version, apps) { // limit the information that's returned to the caller if (min_rpc_version) { apps = apps.filter(app => { @@ -384,7 +342,8 @@ function appStoreTransformation (min_rpc_version, min_protocol_version, apps, ne size_decompressed_bytes: app.size_decompressed_bytes, } })); - next(null, newApps); + + return newApps; } // compares two versions with this syntax: [major, minor, patch] @@ -430,15 +389,15 @@ function versionCompare (v1, v2) { } module.exports = { - validateActionPost: validateActionPost, - validateAutoPost: validateAutoPost, - validateAdministratorPost: validateAdministratorPost, - validatePassthroughPost: validatePassthroughPost, - validateHybridPost: validateHybridPost, - validateRPCEncryptionPut: validateRPCEncryptionPut, - validateServicePermissionPut: validateServicePermissionPut, - validateFunctionalGroupPut: validateFunctionalGroupPut, - validateUpdateAppCertificate: validateUpdateAppCertificate, + validateActionPost: validateActionPost, + validateAutoPost: validateAutoPost, + validateAdministratorPost: validateAdministratorPost, + validatePassthroughPost: validatePassthroughPost, + validateHybridPost: validateHybridPost, + validateRPCEncryptionPut: validateRPCEncryptionPut, + validateServicePermissionPut: validateServicePermissionPut, + validateFunctionalGroupPut: validateFunctionalGroupPut, + validateUpdateAppCertificate: validateUpdateAppCertificate, validateWebHook: validateWebHook, checkIdIntegerBody: checkIdIntegerBody, storeAppCertificates: storeAppCertificates, diff --git a/app/v1/applications/model.js b/app/v1/applications/model.js index f5fe42c2..bbd5b135 100644 --- a/app/v1/applications/model.js +++ b/app/v1/applications/model.js @@ -11,9 +11,10 @@ const certificates = require('../certificates/controller.js'); const certUtil = require('../helpers/certificates.js'); const webengineHandler = require('../../../customizable/webengine-bundle'); const Url = require('url').URL; +const promisify = require('util').promisify; //takes SQL data and converts it into a response for the UI to consume -function constructFullAppObjs (res, next) { +async function constructFullAppObjs (res) { //hash the below data for fast access later const hashedCategories = hashify({}, res.appCategories, elem => ({ location: [elem.id], @@ -135,222 +136,152 @@ function constructFullAppObjs (res, next) { fullApps.push(hashedApps[id]); } - next(null, fullApps); + return fullApps; } //store the information using a SQL transaction -function storeApp (notifyOEM, appObj, next) { - var storedApp = null; +async function storeApp (notifyOEM, appObj) { // process message groups synchronously (due to the SQL transaction) - db.runAsTransaction(function (client, callback) { - flame.async.waterfall([ - //stage 1: insert app info - client.getOne.bind(client, sql.insertAppInfo(appObj)), - //stage 2: insert countries, display names, permissions, app auto approvals, and certificates if enabled - function (app, next) { - log.info("New/updated app " + app.app_uuid + " added to the database"); - storedApp = app; - const allInserts = []; - if (appObj.countries.length > 0) { - allInserts.push(sql.insertAppCountries(appObj.countries, app.id)); - } - if (appObj.display_names.length > 0) { - allInserts.push(sql.insertAppDisplayNames(appObj.display_names, app.id)); - } - if (appObj.permissions.length > 0) { - allInserts.push(sql.insertAppPermissions(appObj.permissions, app.id)); - } - if (appObj.services.length > 0) { - allInserts.push(sql.insertAppServices(appObj.services, app.id)); - allInserts.push(sql.insertAppServiceNames(appObj.services, app.id)); - allInserts.push(sql.insertStandardAppServicePermissions(appObj.services, app.id)); - } - if (appObj.is_auto_approved_enabled) { - allInserts.push(sql.insertAppAutoApproval(appObj)); - } - if (appObj.categories.length > 0) { - allInserts.push(sql.insertAppCategories(appObj.categories, app.id)); - } - - //generate app certificate if cert generation is enabled - if (certificates.openSSLEnabled) { - //perform a cert check - client.getOne(sql.getApp.certificate(app.app_uuid), function (err, data) { - if (err) { //db error - log.error(err); - return next(err); - } - if (!data) { //no cert exists. make one - return finishCertCheck(true); - } - return finishCertCheck(false); //cert exists. let the cron update the cert if it's nearing expiration - }); - - function finishCertCheck (shouldCreateCert) { - if (!shouldCreateCert) { - return runInserts(); - } + return await db.asyncTransaction(async client => { + //stage 1: insert app info + const storedApp = await client.getOne(sql.insertAppInfo(appObj)); + //stage 2: insert countries, display names, permissions, app auto approvals, and certificates if enabled + log.info("New/updated app " + storedApp.app_uuid + " added to the database"); - log.info("Updating certificate of " + app.app_uuid); + const allInserts = []; + if (appObj.countries.length > 0) { + allInserts.push(sql.insertAppCountries(appObj.countries, storedApp.id)); + } + if (appObj.display_names.length > 0) { + allInserts.push(sql.insertAppDisplayNames(appObj.display_names, storedApp.id)); + } + if (appObj.permissions.length > 0) { + allInserts.push(sql.insertAppPermissions(appObj.permissions, storedApp.id)); + } + if (appObj.services.length > 0) { + allInserts.push(sql.insertAppServices(appObj.services, storedApp.id)); + allInserts.push(sql.insertAppServiceNames(appObj.services, storedApp.id)); + allInserts.push(sql.insertStandardAppServicePermissions(appObj.services, storedApp.id)); + } + if (appObj.is_auto_approved_enabled) { + allInserts.push(sql.insertAppAutoApproval(appObj)); + } + if (appObj.categories.length > 0) { + allInserts.push(sql.insertAppCategories(appObj.categories, storedApp.id)); + } - certificates.createCertificateFlow({ - serialNumber: app.app_uuid - }, function (crtErr, cert) { - if (crtErr) { - // issues arose in creating certificate - return next(crtErr, null); - } - certUtil.createKeyCertBundle(cert.clientKey, cert.certificate) - .then(keyCertBundle => { - //add the cert as part of the inserts - certUtil.extractExpirationDateBundle(keyCertBundle.pkcs12, function (err, expirationDate) { - if (err) { - return next(err); - } - const insertObj = { - app_uuid: app.app_uuid, - certificate: keyCertBundle.pkcs12.toString('base64'), - expirationDate: expirationDate - } - allInserts.push(sql.updateAppCertificate(insertObj)); - runInserts(); - }); - }) - .catch(err => { - next(err); - }); - }); - } - } - else { //cert generation disabled. continue on - runInserts(); - } + //generate app certificate if cert generation is enabled + if (certificates.openSSLEnabled) { + //perform a cert check + const data = await client.getOne(sql.getApp.certificate(storedApp.app_uuid)); + const shouldCreateCert = !data; - function runInserts () { - //execute all the sql statements. client.getOne needs client as context or the query will fail - flame.async.series(flame.map(allInserts, client.getOne, client), next); - } - }, - //stage 3: locales insert. this is a multi step process so it needs its own flow - function (res, next) { - if (!appObj.locales || appObj.locales.length === 0) { - return next(null, res); // no locales. skip + if (shouldCreateCert) { + //no cert exists. make one + log.info("Updating certificate of " + storedApp.app_uuid); + const cert = await certificates.asyncCreateCertificate({ + serialNumber: storedApp.app_uuid + }); + const keyCertBundle = await certUtil.createKeyCertBundle(cert.clientKey, cert.certificate); + //add the cert as part of the inserts + const expirationDate = await certUtil.extractExpirationDateBundle(keyCertBundle.pkcs12); + const insertObj = { + app_uuid: storedApp.app_uuid, + certificate: keyCertBundle.pkcs12.toString('base64'), + expirationDate: expirationDate } + allInserts.push(sql.updateAppCertificate(insertObj)); + } //cert exists. let the cron update the cert if it's nearing expiration + } - // attempt locale and tts chunks insert - const insertLocaleInfo = function (localeInfo, done) { - flame.async.waterfall([ - client.getOne.bind(client, sql.insertAppLocale(localeInfo, storedApp.id)), - function (localeResult, next) { - // continue with inserting ttschunks after retreiving the returned id - // use the passed in locales - if (localeInfo.tts_chunks.length === 0) { - // no tts chunks to process. stop early - return next(); - } - const query = sql.insertAppLocaleTtsChunks(localeInfo.tts_chunks, localeResult.id); - client.getOne(query, next); - } - ], done); - } + //execute all the sql statements + for (const insert of allInserts) { + await client.getOne(insert); + } - flame.async.parallel(flame.map(appObj.locales, insertLocaleInfo), function (err) { - next(err, res); - }); - }, - //stage 4: call custom routine to get the byte size of the bundle at the package url if it exists - function (res, next) { - if (appObj.transport_type === 'webengine' && appObj.package_url) { - webengineHandler.handleBundle(appObj.package_url, function (err, data) { - if (err) { - return next(err); - } - if (!data) { - return next('No object returned for the webengine bundle for uuid ' + appObj.uuid); - } - if (!data.url) { - return next('No url property for the webengine bundle for uuid ' + appObj.uuid); - } - if (!data.size_compressed_bytes) { - return next('No size_compressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); - } - if (!data.size_decompressed_bytes) { - return next('No size_decompressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); - } - // store the returned results of the custom webengine bundle handler function - const query = sql.updateWebengineBundleInfo(storedApp.id, data); - client.getOne(query, next); - }); - } - else { - next(null, res); - } - }, - //stage 5: sync with shaid - function (res, next) { - if(!storedApp.version_id){ - // skip sync with SHAID if no app version ID is present - next(null, res); - return; - } - app.locals.shaid.setApplicationApprovalVendor([storedApp], function(err, result){ - next(err, res); - }); - }, - //stage 6: notify OEM of pending app? - function(res, next) { - if(!( - notifyOEM - && app.locals.emailer.isSmtpConfigured() - && storedApp.approval_status == 'PENDING' - && app.locals.config.notification.appsPendingReview.email.frequency == "REALTIME" - && app.locals.config.notification.appsPendingReview.email.to - )){ - next(null, res); - return; + //stage 3: locales insert. this is a multi step process so it needs its own flow + if (!appObj.locales || appObj.locales.length === 0) { + // no locales. skip + } else { + // attempt locale and tts chunks insert + await Promise.all(appObj.locales.map(insertLocaleInfo)); + async function insertLocaleInfo (localeInfo) { + const localeResult = await client.getOne(sql.insertAppLocale(localeInfo, storedApp.id)); + // continue with inserting ttschunks after retreiving the returned id + // use the passed in locales + if (localeInfo.tts_chunks.length === 0) { + // no tts chunks to process + } else { + await client.getOne(sql.insertAppLocaleTtsChunks(localeInfo.tts_chunks, localeResult.id)); } + } + } + //stage 4: call custom routine to get the byte size of the bundle at the package url if it exists + if (appObj.transport_type === 'webengine' && appObj.package_url) { + const data = await promisify(webengineHandler.handleBundle)(appObj.package_url); - // attempt to send email - app.locals.emailer.send({ - to: app.locals.config.notification.appsPendingReview.email.to, - subject: "SDL App Pending Review", - html: emails.populate(emails.template.appPendingReview, { - action_url: app.locals.baseUrl + "/applications/" + storedApp.id, - app_name: storedApp.name - }) - }); - next(null, res); + if (!data) { + return new Error('No object returned for the webengine bundle for uuid ' + appObj.uuid); } - ], function(err, res){ - if(err){ - callback(err, appObj.uuid); + if (!data.url) { + return new Error('No url property for the webengine bundle for uuid ' + appObj.uuid); } - else { - callback(err, res); + if (!data.size_compressed_bytes) { + return new Error('No size_compressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); } - }); - }, next); -} - -//given an app uuid and pkcs12 bundle, stores their relation in the database -function updateAppCertificate (uuid, keyCertBundle, callback) { - certUtil.extractExpirationDateBundle(keyCertBundle.pkcs12, function (err, expirationDate) { - if (err) { - return callback(err); + if (!data.size_decompressed_bytes) { + return new Error('No size_decompressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); + } + // store the returned results of the custom webengine bundle handler function + await client.getOne(sql.updateWebengineBundleInfo(storedApp.id, data)); } - const insertObj = { - app_uuid: uuid, - certificate: keyCertBundle.pkcs12.toString('base64'), - expirationDate: expirationDate + //stage 5: sync with shaid + if(!storedApp.version_id){ + // skip sync with SHAID if no app version ID is present + } else { + await app.locals.shaid.setApplicationApprovalVendor([storedApp]); } - db.sqlCommand(sql.updateAppCertificate(insertObj), callback); + //stage 6: notify OEM of pending app? + if(!( + notifyOEM + && app.locals.emailer.isSmtpConfigured() + && storedApp.approval_status == 'PENDING' + && app.locals.config.notification.appsPendingReview.email.frequency == "REALTIME" + && app.locals.config.notification.appsPendingReview.email.to + )){ + // don't send email + } else { + // attempt to send email + app.locals.emailer.send({ + to: app.locals.config.notification.appsPendingReview.email.to, + subject: "SDL App Pending Review", + html: emails.populate(emails.template.appPendingReview, { + action_url: app.locals.baseUrl + "/applications/" + storedApp.id, + app_name: storedApp.name + }) + }); + } + + return appObj.uuid; }); +} + +//given an app uuid and pkcs12 bundle, stores their relation in the database +async function updateAppCertificate (uuid, keyCertBundle) { + const expirationDate = await certUtil.extractExpirationDateBundle(keyCertBundle.pkcs12); + + const insertObj = { + app_uuid: uuid, + certificate: keyCertBundle.pkcs12.toString('base64'), + expirationDate: expirationDate + } + await db.asyncSql(sql.updateAppCertificate(insertObj)); } -function getExpiredCerts (callback) { - db.sqlCommand(sql.getApp.allExpiredCertificates(), callback); +async function getExpiredCerts () { + return await db.asyncSql(sql.getApp.allExpiredCertificates()); } module.exports = { diff --git a/app/v1/certificates/controller.js b/app/v1/certificates/controller.js index 90538f7d..36323d2b 100644 --- a/app/v1/certificates/controller.js +++ b/app/v1/certificates/controller.js @@ -3,6 +3,7 @@ const pem = require('pem'); const fs = require('fs'); const tmp = require('tmp'); const logger = require('../../../custom/loggers/winston/index'); +const promisify = require('util').promisify; const settings = require('../../../settings.js'); const CA_DIR_PREFIX = __dirname + '/../../../customizable/ca/'; @@ -20,41 +21,40 @@ const authorityCertificate = (fs.existsSync(CA_DIR_PREFIX + settings.certificate const openSSLEnabled = authorityKey && authorityCertificate && settings.securityOptions.passphrase && settings.securityOptions.certificate.commonName; -function checkAuthorityValidity (cb){ +async function checkAuthorityValidity () { if (!openSSLEnabled) { - return cb(false); + return false; } - pem.createPkcs12( - authorityKey, - authorityCertificate, - settings.securityOptions.passphrase, - { - cipher: 'aes128', - clientKeyPassword: settings.securityOptions.passphrase - }, - function(err, pkcs12){ - cb((err) ? false : true); - } - ); + return new Promise((resolve) => { + pem.createPkcs12( + authorityKey, + authorityCertificate, + settings.securityOptions.passphrase, + { + cipher: 'aes128', + clientKeyPassword: settings.securityOptions.passphrase + }, + function (err, pkcs12) { + resolve((err) ? false : true); + } + ); + }); } -function createPrivateKey(req, res, next){ +async function createPrivateKey (req, res, next) { if (openSSLEnabled) { let options = getKeyOptions(req.body.options); - pem.createPrivateKey( - options.keyBitsize, - options, - function(err, privateKey){ - if(err){ - return res.parcel.setStatus(400) - .setData(err) - .deliver(); - } - return res.parcel.setStatus(200) - .setData(privateKey.key) - .deliver(); - } - ); + + try { + const privateKey = await promisify(pem.createPrivateKey)(options.keyBitsize, options); + return res.parcel.setStatus(200) + .setData(privateKey.key) + .deliver(); + } catch (err) { + return res.parcel.setStatus(400) + .setData(err) + .deliver(); + } } else { res.parcel.setStatus(400) .setMessage('Security options have not been properly configured') @@ -90,20 +90,20 @@ function getCertificateOptions(options = {}){ }; } -function createCertificate(req, res, next){ +async function createCertificate (req, res, next) { if (openSSLEnabled) { let options = req.body.options || {}; - createCertificateFlow(options, function(err, certificate){ - if(err){ - logger.error(err); - return res.parcel.setStatus(400) - .setData(err) - .deliver(); - } + try { + const certificate = await asyncCreateCertificate(options) return res.parcel.setStatus(200) .setData(certificate) .deliver(); - }); + } catch (err) { + logger.error(err); + return res.parcel.setStatus(400) + .setData(err) + .deliver(); + } } else { res.parcel.setStatus(400) .setMessage('Security options have not been properly configured') @@ -111,7 +111,7 @@ function createCertificate(req, res, next){ } } -function createCertificateFlow(options, next){ +async function asyncCreateCertificate (options) { if (openSSLEnabled) { options.serviceKey = authorityKey; options.serviceCertificate = authorityCertificate; @@ -122,46 +122,57 @@ function createCertificateFlow(options, next){ let keyOptions = getKeyOptions(options); //no client key so create one first - if (!csrOptions.clientKey) - { - tasks.push(function(cb){ - pem.createPrivateKey(keyOptions.keyBitsize, keyOptions, function(err, key){ - csrOptions.clientKey = key.key; - cb(err); - }); - }); + if (!csrOptions.clientKey) { + const key = await promisify(pem.createPrivateKey)(keyOptions.keyBitsize, keyOptions); + csrOptions.clientKey = key.key; } //write the CSR file for the pem module to use when generating the certificate - tasks.push(function(cb){ - writeCSRConfigFile(csrOptions, cb); - }); + const csrConfig = makeCSRConfigFile(csrOptions); + + //store the contents in a file for a moment for the pem module to read from + const tmpObj = await makeTmpFile(csrConfig); //create new csr using passed in key or newly generated one. - tasks.push(function(csrFilePath, doneReadingFile, cb){ - csrOptions.csrConfigFile = csrFilePath; - pem.createCSR(csrOptions, function(err, csr){ - doneReadingFile(); - cb(err, csr); - }); - }); + csrOptions.csrConfigFile = tmpObj.path; + const csr = await promisify(pem.createCSR)(csrOptions); + tmpObj.close(); // close the temp file //finally add the csr and create the certificate. - tasks.push(function(csr, cb){ - csrOptions.csr = csr.csr; - pem.createCertificate(csrOptions, function(err, certificate){ - cb(err, certificate); - }); - }); + csrOptions.csr = csr.csr; - //returns err,certificate - async.waterfall(tasks, next); + //returns certificate + return promisify(pem.createCertificate)(csrOptions); } else { - next('Security options have not been properly configured'); + throw new Error('Security options have not been properly configured'); } } -function writeCSRConfigFile (options, cb){ +async function makeTmpFile (contents) { + return new Promise((resolve, reject) => { + tmp.file(function (err, path, fd, done) { + if (err) { + return reject(err); + } + + fs.writeFile( + path, + contents, + function (err) { + if (err) { + return reject(err); + } + resolve({ + path: path, + close: done, + }); + } + ); + }); + }); +} + +function makeCSRConfigFile (options) { let csrConfig = '# OpenSSL configuration file for creating a CSR for an app certificate\n' + '[req]\n' + 'distinguished_name = req_distinguished_name\n' + @@ -195,20 +206,7 @@ function writeCSRConfigFile (options, cb){ csrConfig += 'serialNumber = ' + options.serialNumber; } - //store the contents in a file for a moment for the pem module to read from - tmp.file(function (err, path, fd, done) { - if (err) { - return cb(err); - } - - fs.writeFile( - path, - csrConfig, - function (err) { - cb(err, path, done); - } - ); - }); + return csrConfig; } module.exports = { @@ -216,7 +214,7 @@ module.exports = { authorityCertificate: authorityCertificate, createPrivateKey: createPrivateKey, createCertificate: createCertificate, - createCertificateFlow: createCertificateFlow, + asyncCreateCertificate: asyncCreateCertificate, checkAuthorityValidity: checkAuthorityValidity, getKeyOptions: getKeyOptions, getCertificateOptions: getCertificateOptions, diff --git a/app/v1/groups/controller.js b/app/v1/groups/controller.js index 81c22351..c2dcf4ea 100644 --- a/app/v1/groups/controller.js +++ b/app/v1/groups/controller.js @@ -1,42 +1,28 @@ const app = require('../app'); -const flow = app.locals.flow; const helper = require('./helper.js'); const model = require('./model.js'); const check = require('check-types'); const cache = require('../../../custom/cache'); -function get (req, res, next) { +async function get (req, res, next) { //if environment is not of value "staging", then set the environment to production const isProduction = req.query.environment && req.query.environment.toLowerCase() === 'staging' ? false: true; const returnTemplate = !!req.query.template; //coerce to boolean - let chosenFlow; //to be determined + let groups; //to be determined - if (returnTemplate) { //template mode. return just the shell of a functional group, rpcs included - chosenFlow = flow([ - helper.generateFunctionGroupTemplates.bind(null, isProduction), - function (template, next) { - next(null, [template]); //must be in an array + try { + if (returnTemplate) { //template mode. return just the shell of a functional group, rpcs included + groups = [await helper.generateFunctionGroupTemplates(isProduction)]; + } + else if (req.query.id) { //filter by id + if (Number.isNaN(Number(req.query.id))) { + return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); } - ], {method: 'waterfall'}); - } - else if (req.query.id) { //filter by id - if (Number.isNaN(Number(req.query.id))) { - return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); + groups = await helper.createFuncGroupFlow('idFilter', req.query.id, true, isProduction); } - chosenFlow = helper.createFuncGroupFlow('idFilter', req.query.id, true, isProduction); - } - else { //get all apps at the high level, filtering in PRODUCTION or STAGING mode - chosenFlow = helper.createFuncGroupFlow('statusFilter', isProduction, false, isProduction); - } - - chosenFlow(function (err, groups) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage("Internal server error") - .deliver(); + else { //get all apps at the high level, filtering in PRODUCTION or STAGING mode + groups = await helper.createFuncGroupFlow('statusFilter', isProduction, false, isProduction); } return res.parcel .setStatus(200) @@ -44,58 +30,61 @@ function get (req, res, next) { "groups": groups }) .deliver(); - }); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage("Internal server error") + .deliver(); + } } -function getGroupNamesStaging (req, res, next) { - helper.getGroupNamesStaging(function (err, groupNames) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage("Internal server error") - .deliver(); - } +async function getGroupNamesStaging (req, res, next) { + try { + const groupNames = await helper.getGroupNamesStaging(); return res.parcel .setStatus(200) .setData({ "names": groupNames }) .deliver(); - }); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage("Internal server error") + .deliver(); + } } -function postStaging (req, res, next) { - helper.validateFuncGroup(req, res, function () { - if (res.parcel.message) { - res.parcel.deliver(); - return; - } - //check in staging mode - helper.validatePromptExistence(false, req, res, function () { - if (res.parcel.message) { - res.parcel.deliver(); - return; - } - //force function group status to STAGING - model.insertFunctionalGroupsWithTransaction(false, [req.body], function (err) { - if (err) { - app.locals.log.error(err); - res.parcel - .setMessage("Interal server error") - .setStatus(500); - } - else { - cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); - res.parcel.setStatus(200); - } - res.parcel.deliver(); - }); - }); - }); +async function postStaging (req, res, next) { + helper.validateFuncGroup(req, res); + if (res.parcel.message) { + res.parcel.deliver(); + return; + } + //check in staging mode + await helper.validatePromptExistence(false, req, res); + if (res.parcel.message) { + res.parcel.deliver(); + return; + } + //force function group status to STAGING + try { + await model.insertFunctionalGroupsWithTransaction(false, [req.body]); + cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); + res.parcel.setStatus(200); + res.parcel.deliver(); + } catch (err) { + app.locals.log.error(err); + res.parcel + .setMessage("Interal server error") + .setStatus(500); + res.parcel.deliver(); + } } -function promoteIds (req, res, next) { +async function promoteIds (req, res, next) { helper.validatePromote(req, res); if (res.parcel.message) { return res.parcel.deliver(); @@ -105,31 +94,17 @@ function promoteIds (req, res, next) { req.body.id = [req.body.id]; } - const getFuncGroupsFlow = flow(req.body.id.map(function (id) { - return helper.createFuncGroupFlow('idFilter', id, true); - }), {method: 'parallel', eventLoop: true}); + const funcGroups = await Promise.all(req.body.id.map(id => helper.createFuncGroupFlow('idFilter', id, true))); - const getAndInsertFlow = app.locals.flow([ - getFuncGroupsFlow, - function (funcGroups, next) { - const notNullGroups = funcGroups.map(function (funcGroup) { - return funcGroup[0]; - }).filter(function (elem) { - return elem; - }); - //format the functional groups so it's a single array - next(null, notNullGroups); - }, - model.insertFunctionalGroupsWithTransaction.bind(null, true) - ], {method: 'waterfall'}); + const notNullGroups = funcGroups.map(funcGroup => funcGroup[0]) + .filter(elem => elem); - getAndInsertFlow(function () { - cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); - res.parcel - .setStatus(200) - .deliver(); //done - }); + await model.insertFunctionalGroupsWithTransaction(true, notNullGroups); + cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); + res.parcel + .setStatus(200) + .deliver(); //done } module.exports = { diff --git a/app/v1/groups/helper.js b/app/v1/groups/helper.js index b3e764cd..2fea808d 100644 --- a/app/v1/groups/helper.js +++ b/app/v1/groups/helper.js @@ -2,9 +2,6 @@ const check = require('check-types'); const model = require('./model.js'); const app = require('../app'); const messages = require('../messages/controller.js'); -const flow = app.locals.flow; -const flame = app.locals.flame; -const setupSql = app.locals.db.setupSqlCommand; const sql = require('./sql.js'); //validation functions @@ -20,7 +17,7 @@ function validatePromote (req, res) { //NOTE: this will not warn the user if a change is made in a consumer friendly message in STAGING //such that the STAGING value will be returned in staging mode but in PRODUCTION mode the older value gets used -function validatePromptExistence (isProduction, req, res, cb) { +async function validatePromptExistence (isProduction, req, res) { //find if the consentPrompt of this functional group exists in the context //of the target environment //if user_consent_prompt is an empty string, then also treat it as valid, but convert it into null @@ -32,44 +29,40 @@ function validatePromptExistence (isProduction, req, res, cb) { //if user_consent_prompt is null, then there is no prompt, which is a valid option if (consentPrompt === null) { - return cb(); //stop here + return; //stop here } - messages.getMessageGroups(false, true, function (err, categories) { - const category = categories.find(function (category) { - return category.message_category === consentPrompt; - }); - if (!category) { - res.parcel - .setStatus(400) - .setMessage("The user consent prompt does not exist under this environment: " + consentPrompt); - } - cb(); //done + const categories = await messages.getMessageGroups(false, true); + const category = categories.find(function (category) { + return category.message_category === consentPrompt; }); + if (!category) { + res.parcel + .setStatus(400) + .setMessage("The user consent prompt does not exist under this environment: " + consentPrompt); + } } -function validateFuncGroup (req, res, callback) { +function validateFuncGroup (req, res) { //base check - if (!check.string(req.body.name) || !check.boolean(req.body.is_default) || !check.array(req.body.rpcs)) { + if (!check.string(req.body.name) || req.body.name === '' || !check.boolean(req.body.is_default) || !check.array(req.body.rpcs)) { res.parcel .setStatus(400) .setMessage("Required for functional group: name, is_default, rpcs"); - return callback(); + return; } //rpcs check const rpcs = req.body.rpcs; - flow(flame.map(rpcs, validateRpc), {method: 'parallel', eventLoop: true})(function (err, res) { - callback(); - }); + rpcs.map(validateRpc); - function validateRpc (rpc, next) { + function validateRpc (rpc) { //base check if (!check.string(rpc.name) || !check.array(rpc.hmi_levels) || !check.boolean(rpc.selected) || !check.array(rpc.parameters)) { res.parcel .setStatus(400) .setMessage("Required for RPC element: name, hmi_levels, parameters, selected"); - return next(true); //error out early + return true; //error out early } //hmi levels check for (let j = 0; j < rpc.hmi_levels.length; j++) { @@ -78,7 +71,7 @@ function validateFuncGroup (req, res, callback) { res.parcel .setStatus(400) .setMessage("Required for HMI level: value, selected"); - return next(true); //error out early + return true; //error out early } } //parameters check @@ -88,50 +81,48 @@ function validateFuncGroup (req, res, callback) { res.parcel .setStatus(400) .setMessage("Required for parameter: key, selected"); - return next(true); //error out early + return true; //error out early } } - next(); } } //helper functions //only needs to be generated once, because the RPC list and permission relations cannot be changed after server start up -function generateFunctionGroupTemplates (isProduction = false, callback) { - const getTemplateInfo = flow({ - rpcs: setupSql.bind(null, sql.rpcs), - permissionRelations: setupSql.bind(null, sql.permissionRelationsNoModules(isProduction)), - hmiValues: setupSql.bind(null, sql.hmiLevels), - }, {method: 'parallel'}); - - const finalFlow = flow([ - getTemplateInfo, - model.generateTemplate - ], {method: 'waterfall'}); - - finalFlow(callback); +async function generateFunctionGroupTemplates (isProduction = false) { + const info = { + rpcs: app.locals.db.asyncSql(sql.rpcs), + permissionRelations: app.locals.db.asyncSql(sql.permissionRelationsNoModules(isProduction)), + hmiValues: app.locals.db.asyncSql(sql.hmiLevels), + }; + + for (let prop in info) { + info[prop] = await info[prop]; // resolve all promises into each property + } + + return await model.generateTemplate(info); } //helper function that allows retrieving functional group info easily -function createFuncGroupFlow (filterTypeProp, value, includeRpcs, isProduction) { - const getAllInfoFlow = flow({ - base: setupSql.bind(null, sql.getFuncGroup.base[filterTypeProp](value)), - hmiLevels: setupSql.bind(null, sql.getFuncGroup.hmiLevels[filterTypeProp](value)), - parameters: setupSql.bind(null, sql.getFuncGroup.parameters[filterTypeProp](value)), - messageGroups: messages.getMessageGroups.bind(null, isProduction, false), //get consent prompt values - }, {method: 'parallel'}); - - return flow([ - getAllInfoFlow, - model.makeFunctionGroups.bind(null, includeRpcs, isProduction) - ], {method: 'waterfall', eventLoop: true}); +async function createFuncGroupFlow (filterTypeProp, value, includeRpcs, isProduction) { + const info = { + base: app.locals.db.asyncSql(sql.getFuncGroup.base[filterTypeProp](value)), + hmiLevels: app.locals.db.asyncSql(sql.getFuncGroup.hmiLevels[filterTypeProp](value)), + parameters: app.locals.db.asyncSql(sql.getFuncGroup.parameters[filterTypeProp](value)), + messageGroups: messages.getMessageGroups(isProduction, false), //get consent prompt values + }; + + for (let prop in info) { + info[prop] = await info[prop]; // resolve all promises into each property + } + + return await model.makeFunctionGroups(includeRpcs, isProduction, info); } -function getGroupNamesStaging (callback) { - setupSql(sql.getGroupNamesStaging, function (err, names) { - callback(err, names.map(function (elem) {return elem.property_name;})); - }); +async function getGroupNamesStaging () { + const names = await app.locals.db.asyncSql(sql.getGroupNamesStaging); + return names.map(elem => elem.property_name); } module.exports = { diff --git a/app/v1/groups/model.js b/app/v1/groups/model.js index 91c511e3..8ca06e52 100644 --- a/app/v1/groups/model.js +++ b/app/v1/groups/model.js @@ -1,39 +1,32 @@ const app = require('../app'); -const flame = app.locals.flame; -const flow = app.locals.flow; -const setupSql = app.locals.db.setupSqlCommand; const sql = require('./sql.js'); const sqlBrick = require('sql-bricks-postgres'); const async = require('async'); //generates a single-element functional group info template object -function generateTemplate (info, next) { +async function generateTemplate (info) { //get what the full response would look like in hash form let rpcHash = generateRpcObjectHash(info.rpcs, info.permissionRelations, info.hmiValues); //convert the hash into an array - rpcHashToArray(rpcHash, function (err, rpcs) { - let template = baseTemplate(); - template.rpcs = rpcs; - next(err, template); - }); + const rpcs = rpcHashToArray(rpcHash); + let template = baseTemplate(); + template.rpcs = rpcs; + return template; } -function generateRpcHash (isProduction = false, callback) { - const getTemplateInfo = flow({ - rpcs: setupSql.bind(null, sql.rpcs), - permissionRelations: setupSql.bind(null, sql.permissionRelationsNoModules(isProduction)), - hmiValues: setupSql.bind(null, sql.hmiLevels), - }, {method: 'parallel'}); - - const finalFlow = flow([ - getTemplateInfo, - function (info, callback) { - callback(null, generateRpcObjectHash(info.rpcs, info.permissionRelations, info.hmiValues)); - } - ], {method: 'waterfall'}); +async function generateRpcHash (isProduction = false) { + const info = { + rpcs: app.locals.db.asyncSql(sql.rpcs), + permissionRelations: app.locals.db.asyncSql(sql.permissionRelationsNoModules(isProduction)), + hmiValues: app.locals.db.asyncSql(sql.hmiLevels), + }; + + for (let prop in info) { + info[prop] = await info[prop]; // resolve all promises into each property + } - finalFlow(callback); + return generateRpcObjectHash(info.rpcs, info.permissionRelations, info.hmiValues); } //only needs to be generated once, because the RPC list and permission relations cannot be changed after server start up @@ -77,16 +70,21 @@ function generateRpcObjectHash (rpcs, permissionRelations, hmiValues) { } //convert the rpc hash into an array suitable for responding to the UI -function rpcHashToArray (rpcHash, next) { - //asynchronously iterate over the hash - flame.async.map(rpcHash, handleRpc, function (err, rpcs) { - //sort the rpcs by name - flame.async.sortBy(rpcs, function (rpc, callback) { - callback(null, rpc.name); - }, next); +function rpcHashToArray (rpcHash) { + let rpcs = []; + for (let prop in rpcHash) { + rpcs.push(handleRpc(rpcHash[prop])); + } + //sort the rpcs by name + rpcs.sort((a, b) => { + if (a.name < b.name) return -1; + if (b.name < a.name) return 1; + return 0; }); - function handleRpc (rpc, callback) { + return rpcs; + + function handleRpc (rpc) { //make the hmi levels an array const hmiLevelArray = []; for (let hmiLevel in rpc.hmi_levels) { @@ -94,12 +92,21 @@ function rpcHashToArray (rpcHash, next) { } rpc.hmi_levels = hmiLevelArray; //sort the parameters by name, making it an array in the process - flame.async.sortBy(rpc.parameters, function (parameter, callback) { - callback(null, parameter.is_custom + parameter.name); - }, function (err, sortedParameters) { - rpc.parameters = sortedParameters; - callback(null, rpc); + //put all custom vehicle data at the bottom. use is_custom property which will equal true for custom data + //this forces all custom data to be later in the sort than non-custom data ('false' comes before 'true') + let parameters = []; + for (let prop in rpc.parameters) { + parameters.push(rpc.parameters[prop]); + } + + parameters.sort((a, b) => { + if (a.is_custom + a.name < b.is_custom + b.name) return -1; + if (b.is_custom + b.name < a.is_custom + a.name) return 1; + return 0; }); + + rpc.parameters = parameters; + return rpc; } } @@ -148,7 +155,7 @@ function baseTemplate (objOverride) { } //creates functional groups in a format the UI can understand -function makeFunctionGroups (includeRpcs, isProduction, info, next) { +async function makeFunctionGroups (includeRpcs, isProduction, info) { const baseInfo = info.base; const hmiLevels = info.hmiLevels; const parameters = info.parameters; @@ -172,34 +179,28 @@ function makeFunctionGroups (includeRpcs, isProduction, info, next) { //begin asynchronous logic below //populate the hashes above, using the functional group id as a key - const groupUpData = flow([ - flame.async.map.bind(null, hmiLevels, function (hmiLevel, next) { - const funcId = hmiLevel.function_group_id; - groupedData[funcId].hmiLevels.push(hmiLevel); - groupedRpcCount[funcId][hmiLevel.permission_name] = true; - next(); - }), - flame.async.map.bind(null, parameters, function (parameter, next) { - const funcId = parameter.function_group_id; - groupedData[funcId].parameters.push(parameter); - groupedParameterCount[funcId][parameter.parameter] = true; - next(); - }), - function (next) { - //count up the rpc results - for (let id in groupedRpcCount) { - groupedRpcCount[id] = Object.keys(groupedRpcCount[id]).length; - } - //count up the parameter results - for (let id in groupedParameterCount) { - groupedParameterCount[id] = Object.keys(groupedParameterCount[id]).length; - } - next(); - } - ], {method: 'series', eventLoop: true}); + hmiLevels.map(hmiLevel => { + const funcId = hmiLevel.function_group_id; + groupedData[funcId].hmiLevels.push(hmiLevel); + groupedRpcCount[funcId][hmiLevel.permission_name] = true; + }); + parameters.map(parameter => { + const funcId = parameter.function_group_id; + groupedData[funcId].parameters.push(parameter); + groupedParameterCount[funcId][parameter.parameter] = true; + }); + + //count up the rpc results + for (let id in groupedRpcCount) { + groupedRpcCount[id] = Object.keys(groupedRpcCount[id]).length; + } + //count up the parameter results + for (let id in groupedParameterCount) { + groupedParameterCount[id] = Object.keys(groupedParameterCount[id]).length; + } //functional group top level object creation - const createFunctionalGroupBaseFlow = flow(flame.map(baseInfo, function (baseElement, next) { + const functionalGroups = baseInfo.map(baseElement => { const funcGroup = baseTemplate(baseElement); //add defaults if (groupedRpcCount[baseElement.id] !== undefined) { funcGroup.selected_rpc_count = groupedRpcCount[baseElement.id]; @@ -222,53 +223,35 @@ function makeFunctionGroups (includeRpcs, isProduction, info, next) { else { funcGroup.user_consent_prompt = null; } - next(null, funcGroup); - }), {method: 'parallel', eventLoop: true}); + return funcGroup; + }); //rpc array creation - function rpcInsertion (functionalGroups, next) { - //if the template didn't specify rpcs, do not include selected rpc/parameter info in the response - if (includeRpcs) { - //create RPC arrays for each functional group id and attach it to the functional group - flame.async.waterfall([ - generateRpcHash.bind(null, isProduction), - function (rpcHashTemplate, callback) { - flame.async.map(functionalGroups, function(group, callback) { - const funcGroupData = groupedData[group.id]; - const rpcHash = populateRpcHash( - JSON.parse(JSON.stringify(rpcHashTemplate)), - funcGroupData.hmiLevels, - funcGroupData.parameters - ); - rpcHashToArray(rpcHash, function (err, rpcs) { - group.rpcs = rpcs; //attach the rpc array - callback(null, group); - }); - }, callback); - } - ], next); - } - else { - next(null, functionalGroups); //skip rpc insertion - } + //if the template didn't specify rpcs, do not include selected rpc/parameter info in the response + if (includeRpcs) { + //create RPC arrays for each functional group id and attach it to the functional group + const rpcHashTemplate = await generateRpcHash(isProduction); + functionalGroups.forEach(group => { + const funcGroupData = groupedData[group.id]; + const rpcHash = populateRpcHash( + JSON.parse(JSON.stringify(rpcHashTemplate)), + funcGroupData.hmiLevels, + funcGroupData.parameters + ); + const rpcs = rpcHashToArray(rpcHash); + + group.rpcs = rpcs; //attach the rpc array + }); } //order the functional groups by name - function asyncSortFunctionalGroups (functionalGroups, next) { - flame.async.sortBy(functionalGroups, function (funcGroup, callback) { - callback(null, funcGroup.name); - }, next); - } - - //combine all the steps above - const constructFunctionalGroupFlow = flow([ - groupUpData, - createFunctionalGroupBaseFlow, - rpcInsertion, - asyncSortFunctionalGroups - ], {method: 'waterfall', eventLoop: true}); + functionalGroups.sort((a, b) => { + if (a.name < b.name) return -1; + if (b.name < a.name) return 1; + return 0; + }); - constructFunctionalGroupFlow(next); //run it + return functionalGroups; } //uses an rpc hash and converts the selected values to true based on hmi level and parameter data that exists @@ -331,68 +314,43 @@ function convertToInsertablePermission (permissionObj, functionalGroupId, rpcNam }; } -function insertFunctionalGroupsWithTransaction(isProduction, rawFunctionalGroups, callback){ +async function insertFunctionalGroupsWithTransaction (isProduction, rawFunctionalGroups) { let wf = {}, status = isProduction ? "PRODUCTION" : "STAGING"; - app.locals.db.runAsTransaction(function (client, callback) { + await app.locals.db.asyncTransaction(async client => { // process groups synchronously (due to the SQL transaction) - async.eachSeries(rawFunctionalGroups, function (rawFunctionalGroup, callback) { - let insertedGroup = null; - async.waterfall([ - function (callback) { - // clean the functional group object for insertion and insert it into the db - let insertableObject = convertToInsertableFunctionalGroupInfo(rawFunctionalGroup, status); - let insert = sqlBrick.insert('function_group_info', insertableObject).returning('*'); - client.getOne(insert.toString(), callback); - }, - function (group, callback) { - insertedGroup = group; - // filter out any unselected rpc - async.filter(rawFunctionalGroup.rpcs, function (obj, callback) { - callback(null, (isProduction || obj.selected)); - }, callback); - }, - function (rawSelectedRPCs, callback) { - // process each selected RPC - async.eachSeries(rawSelectedRPCs, function (rawSelectedRPC, callback) { - async.waterfall([ - function (callback) { - // clean and insert RPC HMI Levels - async.eachSeries(rawSelectedRPC.hmi_levels, function (rawHMI, callback) { - // skip unselected HMIs - if(!(rawHMI.selected)){ - callback(null); - return; - } - // clean and insert HMI record - let insertableHMI = convertToInsertableHMI(rawHMI, insertedGroup.id, rawSelectedRPC.name); - let insert = sqlBrick.insert('function_group_hmi_levels', insertableHMI).returning('*'); - client.getOne(insert.toString(), callback); - }, callback); - }, - function (callback) { - // clean and insert permissions/parameters - async.eachSeries(rawSelectedRPC.parameters, function (rawPermission, callback) { - // skip unselected permissions - if(!(rawPermission.selected)){ - callback(null); - return; - } - // clean and insert permission record - let insertablePermission = convertToInsertablePermission(rawPermission, insertedGroup.id, rawSelectedRPC.name); - let insert = sqlBrick.insert('function_group_parameters', insertablePermission).returning('*'); - client.getOne(insert.toString(), callback); - }, callback); - } - ], callback); - }, callback); + for (let rawFunctionalGroup of rawFunctionalGroups) { + // clean the functional group object for insertion and insert it into the db + let insertableObject = convertToInsertableFunctionalGroupInfo(rawFunctionalGroup, status); + let insertedGroup = await client.getOne(sqlBrick.insert('function_group_info', insertableObject).returning('*').toString()); + // filter out any unselected rpc + const rawSelectedRpcs = rawFunctionalGroup.rpcs.filter(obj => isProduction || obj.selected); + + // process each selected RPC + for (let rawSelectedRpc of rawSelectedRpcs) { + // clean and insert RPC HMI Levels + for (let rawHmi of rawSelectedRpc.hmi_levels) { + // skip unselected HMIs + if (!rawHmi.selected) { + continue; + } + // clean and insert HMI record + let insertableHmi = convertToInsertableHMI(rawHmi, insertedGroup.id, rawSelectedRpc.name); + await client.getOne(sqlBrick.insert('function_group_hmi_levels', insertableHmi).returning('*').toString()); } - ], callback); - }, callback); - }, function (err,result) { - // done either successfully or post-rollback - callback(err); + // clean and insert permissions/parameters + for (let rawPermission of rawSelectedRpc.parameters) { + // skip unselected permissions + if (!rawPermission.selected) { + continue; + } + // clean and insert permission record + let insertablePermission = convertToInsertablePermission(rawPermission, insertedGroup.id, rawSelectedRpc.name); + await client.getOne(sqlBrick.insert('function_group_parameters', insertablePermission).returning('*').toString()); + } + } + } }); } diff --git a/app/v1/helpers/certificates.js b/app/v1/helpers/certificates.js index b8d44996..40f731e7 100644 --- a/app/v1/helpers/certificates.js +++ b/app/v1/helpers/certificates.js @@ -48,22 +48,19 @@ function parseCertificate (cert) { } //given a key cert bundle, returns the expiration date of the cert -function extractExpirationDateBundle (keyCertBundle, callback) { - readKeyCertBundle(keyCertBundle) +function extractExpirationDateBundle (keyCertBundle) { + return readKeyCertBundle(keyCertBundle) .then(keyBundle => { - return extractExpirationDateCertificate(keyBundle.cert, callback); + return extractExpirationDateCertificate(keyBundle.cert); }); } //given a cert, returns the expiration date of the cert -function extractExpirationDateCertificate (certificate, callback) { - parseCertificate(certificate) +function extractExpirationDateCertificate (certificate) { + return parseCertificate(certificate) .then(certInfo => { - callback(null, new Date(certInfo.validity.end)); + return new Date(certInfo.validity.end); }) - .catch(err => { - return callback(err); - }); } module.exports = { diff --git a/app/v1/messages/controller.js b/app/v1/messages/controller.js index fea847c3..d3d0a472 100644 --- a/app/v1/messages/controller.js +++ b/app/v1/messages/controller.js @@ -6,7 +6,7 @@ const async = require('async'); const sql = require('./sql.js'); const cache = require('../../../custom/cache'); -function getInfo (req, res, next) { +async function getInfo (req, res, next) { //if environment is not of value "staging", then set the environment to production const isProduction = req.query.environment && req.query.environment.toLowerCase() === 'staging' ? false: true; const returnTemplate = !!req.query.template; //coerce to boolean @@ -14,23 +14,19 @@ function getInfo (req, res, next) { //this is only for getting functional group details const alwaysHideDeleted = req.query.hide_deleted && req.query.hide_deleted == 'true' ? true: false; - if (returnTemplate) { //template mode. return just the shell of a message - chosenFlow = helper.makeCategoryTemplateFlow(); - } - else if (req.query.id) { //get messages of a specific id. this is the 'detailed' mode - if (Number.isNaN(Number(req.query.id))) { - return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); + try { + let messages; + if (returnTemplate) { //template mode. return just the shell of a message + messages = await helper.makeCategoryTemplate(); } - chosenFlow = helper.getMessageDetailsFlow(req.query.id); - } - else { //get all message info at the highest level, filtering in PRODUCTION or STAGING mode - chosenFlow = helper.getMessageGroups.bind(null, isProduction, alwaysHideDeleted); - } - - chosenFlow(function (err, messages) { - if (err) { - app.locals.log.error(err); - return res.parcel.setStatus(500).deliver(); + else if (req.query.id) { //get messages of a specific id. this is the 'detailed' mode + if (Number.isNaN(Number(req.query.id))) { + return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); + } + messages = await helper.getMessageDetails(req.query.id); + } + else { //get all message info at the highest level, filtering in PRODUCTION or STAGING mode + messages = await helper.getMessageGroups(isProduction, alwaysHideDeleted); } return res.parcel .setStatus(200) @@ -38,30 +34,32 @@ function getInfo (req, res, next) { "messages": messages }) .deliver(); - }); + } catch (err) { + app.locals.log.error(err); + return res.parcel.setStatus(500).deliver(); + } } - -function postStaging (req, res, next) { +async function postStaging (req, res, next) { helper.validatePost(req, res); if (res.parcel.message) { return res.parcel.deliver(); } - model.insertMessagesWithTransaction(false, req.body.messages, function(err){ - if(err){ - app.locals.log.error(err); - res.parcel - .setMessage("Interal server error") - .setStatus(500); - }else{ - cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); - res.parcel.setStatus(200); - } + try { + await model.insertMessagesWithTransaction(false, req.body.messages); + cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); + res.parcel.setStatus(200); + res.parcel.deliver(); + } catch (err) { + app.locals.log.error(err); + res.parcel + .setMessage("Interal server error") + .setStatus(500); res.parcel.deliver(); - }); + } } -function promoteIds (req, res, next) { +async function promoteIds (req, res, next) { helper.validatePromote(req, res); if (res.parcel.message) { return res.parcel.deliver(); @@ -70,71 +68,59 @@ function promoteIds (req, res, next) { if (check.number(req.body.id)) { req.body.id = [req.body.id]; } - //get all the info from the ids and insert them - async.waterfall([ - function (callback) { - async.parallel({ - "groups": function(callback){ - app.locals.db.getMany(sql.getMessages.groupsByIds(req.body.id), callback); - }, - "languages": function(callback){ - app.locals.db.getMany(sql.getMessages.byIds(req.body.id), callback); - } - }, callback); - }, - function (results, callback) { - model.mergeLanguagesIntoGroups(results.groups, results.languages, callback); - }, - function (groups, callback) { - model.insertMessagesWithTransaction(true, groups, callback); - } - ], function (err, result) { - if (err) { - app.locals.log.error(err); - res.parcel - .setMessage("Interal server error") - .setStatus(500); - } - else { - cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); - res.parcel.setStatus(200); - } + + try { + const results = await Promise.all([ + app.locals.db.asyncSql(sql.getMessages.groupsByIds(req.body.id)), + app.locals.db.asyncSql(sql.getMessages.byIds(req.body.id)) + ]); + //get all the info from the ids and insert them + const messageGroups = await model.mergeLanguagesIntoGroups(results[0], results[1]); + await model.insertMessagesWithTransaction(true, messageGroups); + + cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); + res.parcel.setStatus(200); res.parcel.deliver(); - }); + } catch (err) { + app.locals.log.error(err); + res.parcel + .setMessage("Interal server error") + .setStatus(500); + res.parcel.deliver(); + } } -function postUpdate (req, res, next) { - helper.updateLanguages(function (err) { - if (err) { - return res.parcel - .setStatus(500) - .deliver(); - } +async function postUpdate (req, res, next) { + try { + await helper.updateLanguages(); cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); res.parcel .setStatus(200) .deliver(); - return; - }); + } catch (err) { + return res.parcel + .setStatus(500) + .deliver(); + } } -function getMessageNamesStaging (req, res, next) { - helper.getMessageNamesStaging(function (err, names) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage("Internal server error") - .deliver(); - } +async function getMessageNamesStaging (req, res, next) { + try { + const names = await helper.getMessageNamesStaging(); return res.parcel .setStatus(200) .setData({ "names": names }) - .deliver(); - }); + .deliver(); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage("Internal server error") + .deliver(); + } } module.exports = { diff --git a/app/v1/messages/helper.js b/app/v1/messages/helper.js index 34098cba..1b64d97a 100644 --- a/app/v1/messages/helper.js +++ b/app/v1/messages/helper.js @@ -5,6 +5,7 @@ const sql = require('./sql.js'); const model = require('./model.js'); const parseXml = require('xml2js').parseString; const request = require('request'); +const promisify = require('util').promisify; //validation functions @@ -58,77 +59,41 @@ function validatePost (req, res) { //helper functions -function getMessageGroups (isProduction, alwaysHideDeleted, cb) { +async function getMessageGroups (isProduction, alwaysHideDeleted) { //TODO: make the language choice configurable const LANG_FILTER = 'en-us'; //need two pieces of info: all categories of a certain language (just en-us) //and the max id of every category. The first piece is so the message text preview is //in the language of the user, and the second category is in case an entry for that //category in that language doesn't exist, so fall back to another text - const getMessagesFlow = app.locals.flow({ - categoryByLanguage: setupSql.bind(null, sql.getMessages.categoryByLanguage(isProduction, LANG_FILTER)), - categoryByMaxId: setupSql.bind(null, sql.getMessages.categoryByMaxId(isProduction)), - messageStatuses: setupSql.bind(null, sql.getMessages.status(isProduction)), - messageGroups: setupSql.bind(null, sql.getMessages.group(isProduction, null, alwaysHideDeleted)) - }, {method: 'parallel'}); - - const getCategoriesFlow = app.locals.flow([ - getMessagesFlow, - model.combineMessageCategoryInfo - ], {method: 'waterfall', eventLoop: true}); - - getCategoriesFlow(cb); -} - -//for one id -function getMessageDetailsFlow (id) { - const getInfoFlow = app.locals.flow([ - makeCategoryTemplateFlow(), - setupSql.bind(null, sql.getMessages.byId(id)), - setupSql.bind(null, sql.getMessages.groupById(id)), - setupSql.bind(null, sql.getAttachedFunctionalGroupsById(id)) - ], {method: 'parallel'}); - - return app.locals.flow([ - getInfoFlow, - model.transformMessages - ], {method: 'waterfall'}); -} - -function makeCategoryTemplateFlow () { - const getTemplateInfo = app.locals.flow([ - setupSql.bind(null, sql.getLanguages), - ], {method: 'parallel'}); + const messageInfo = { + categoryByLanguage: app.locals.db.asyncSql(sql.getMessages.categoryByLanguage(isProduction, LANG_FILTER)), + categoryByMaxId: app.locals.db.asyncSql(sql.getMessages.categoryByMaxId(isProduction)), + messageStatuses: app.locals.db.asyncSql(sql.getMessages.status(isProduction)), + messageGroups: app.locals.db.asyncSql(sql.getMessages.group(isProduction, null, alwaysHideDeleted)) + }; - return app.locals.flow([ - getTemplateInfo, - generateCategoryTemplate - ], {method: 'waterfall', eventLoop: true}); -} + for (let prop in messageInfo) { + messageInfo[prop] = await messageInfo[prop]; // resolve all promises into each property + } -//for an array of ids. filters out PRODUCTION records. meant solely for the promotion route -//doesn't make an object out of the data -function getMessagesDetailsSqlFlow (ids) { - return app.locals.flow([ - setupSql.bind(null, sql.getMessages.groupsByIds(ids)), - setupSql.bind(null, sql.getMessages.byIds(ids)) - ], {method: 'parallel'}); + return await model.combineMessageCategoryInfo(messageInfo); } -function getBaseTemplate () { - return { - id: 0, - message_category: "", - status: "", - is_deleted: false, - created_ts: 0, - updated_ts: 0, - languages: [] - }; +//for one id +async function getMessageDetails (id) { + const info = await Promise.all([ + makeCategoryTemplate(), + app.locals.db.asyncSql(sql.getMessages.byId(id)), + app.locals.db.asyncSql(sql.getMessages.groupById(id)), + app.locals.db.asyncSql(sql.getAttachedFunctionalGroupsById(id)) + ]); + + return await model.transformMessages(info); } -function generateCategoryTemplate (info, next) { - const languages = info[0]; +async function makeCategoryTemplate () { + const languages = await app.locals.db.asyncSql(sql.getLanguages); let template = getBaseTemplate(); @@ -146,66 +111,74 @@ function generateCategoryTemplate (info, next) { label: "" }); } - next(null, [template]); + return [template]; } +//for an array of ids. filters out PRODUCTION records. meant solely for the promotion route +//doesn't make an object out of the data +async function getMessagesDetailsSql (ids) { + return await Promise.all([ + app.locals.db.asyncSql(sql.getMessages.groupsByIds(ids)), + app.locals.db.asyncSql(sql.getMessages.byIds(ids)), + ]); +} -//language-related functions +function getBaseTemplate () { + return { + id: 0, + message_category: "", + status: "", + is_deleted: false, + created_ts: 0, + updated_ts: 0, + languages: [] + }; +} -function updateLanguages (next) { - const messageStoreFlow = [ - getRpcSpec, - parseXml, - extractLanguages, - insertLanguages - ]; +//language-related functions - function insertLanguages (languages, next) { - app.locals.flow(app.locals.db.setupSqlCommands(sql.insert.languages(languages)), {method: 'parallel'})(next); - } +async function updateLanguages () { + const rpcSpec = await getRpcSpec(); + const parsedSpec = await promisify(parseXml)(rpcSpec); + const languages = await extractLanguages(parsedSpec); + await app.locals.db.asyncSqls(sql.insert.languages(languages)); - app.locals.flow(messageStoreFlow, {method: 'waterfall', eventLoop: true})(function (err, res) { - if (err) { - app.locals.log.error(err); - } - if (next) { - next(); //done - } - }); + app.locals.log.info("Language list updated"); } -function getRpcSpec(next) { - request( - { - method: 'GET', - url: app.locals.config.rpcSpecXmlUrl - }, function(err, res, body) { - next(err, body); - } - ); +async function getRpcSpec () { + return new Promise(resolve => { + request( + { + method: 'GET', + url: app.locals.config.rpcSpecXmlUrl + }, function (err, res, body) { + resolve(body); + } + ); + }); } -function extractLanguages (rpcSpec, next) { +async function extractLanguages (rpcSpec) { const languages = rpcSpec.interface.enum.find(function (elem) { return elem['$'].name === "Language"; }).element.map(function (language) { return language['$'].name.toLowerCase(); }); - next(null, languages); + return languages; } -function getMessageNamesStaging (callback) { - setupSql(sql.getMessageNamesStaging, function (err, names) { - callback(err, names.map(function (elem) {return elem.message_category;})); - }); +async function getMessageNamesStaging () { + const names = await app.locals.db.asyncSql(sql.getMessageNamesStaging); + return names.map(elem => elem.message_category); } module.exports = { getRpcSpec: getRpcSpec, getMessageGroups: getMessageGroups, - getMessageDetailsFlow: getMessageDetailsFlow, - makeCategoryTemplateFlow: makeCategoryTemplateFlow, - getMessagesDetailsSqlFlow: getMessagesDetailsSqlFlow, + getMessageDetails: getMessageDetails, + makeCategoryTemplate: makeCategoryTemplate, + getMessagesDetailsSql: getMessagesDetailsSql, validatePromote: validatePromote, validatePost: validatePost, updateLanguages: updateLanguages, diff --git a/app/v1/messages/model.js b/app/v1/messages/model.js index 13e7edac..1b7d4e6f 100644 --- a/app/v1/messages/model.js +++ b/app/v1/messages/model.js @@ -3,7 +3,7 @@ const setupSqlCommands = app.locals.db.setupSqlCommands; const sqlBrick = require('sql-bricks-postgres'); const async = require('async'); -function combineMessageCategoryInfo (messageInfo, next) { +async function combineMessageCategoryInfo (messageInfo) { const filteredCategories = messageInfo.categoryByLanguage; const fallbackCategories = messageInfo.categoryByMaxId; const allMessages = messageInfo.messageStatuses; //for finding how many languages exist per category @@ -48,7 +48,7 @@ function combineMessageCategoryInfo (messageInfo, next) { categories.push(groupsHash[category]); } - next(null, categories); + return categories; } function convertToInsertableGroup(messageGroupObj, statusOverride = null){ @@ -71,60 +71,34 @@ function convertToInsertableText (messageTextObj, messageGroupIdOverride = null) }; } -function insertMessagesWithTransaction (isProduction, rawMessageGroups, callback) { +async function insertMessagesWithTransaction (isProduction, rawMessageGroups) { let wf = {}, status = isProduction ? "PRODUCTION" : "STAGING"; - app.locals.db.runAsTransaction(function (client, callback) { + await app.locals.db.asyncTransaction(async client => { // process message groups synchronously (due to the SQL transaction) - async.eachSeries(rawMessageGroups, function (rawMessageGroup, callback) { - let insertedGroup = null; - async.waterfall([ - function (callback) { - // clean the message group object for insertion and insert it into the db - let messageGroup = convertToInsertableGroup(rawMessageGroup, status); - let insert = sqlBrick.insert('message_group', messageGroup).returning('*'); - client.getOne(insert.toString(), callback); - }, - function (group, callback) { - insertedGroup = group; - // filter out any unselected languages - async.filter(rawMessageGroup.languages, function (obj, callback) { - callback(null, (isProduction || obj.selected)); - }, callback); - }, - function (selectedLanguages, callback) { - // generate array of clean message text objects and do bulk insert - let messageGroupTexts = selectedLanguages.map(function (obj) { - return convertToInsertableText(obj, insertedGroup.id); - }); - if (messageGroupTexts.length < 1) { - callback(null, []); - return; - } - let insert = sqlBrick.insert('message_text', messageGroupTexts).returning('*'); - client.getMany(insert.toString(), callback); - } - ], callback); - }, callback); - }, function (err,result) { - // done either successfully or post-rollback - callback(err); + for (let rawMessageGroup of rawMessageGroups) { + // clean the message group object for insertion and insert it into the db + let messageGroup = convertToInsertableGroup(rawMessageGroup, status); + const insertedGroup = await client.getOne(sqlBrick.insert('message_group', messageGroup).returning('*').toString()); + // filter out any unselected languages + const selectedLanguages = rawMessageGroup.languages.filter(obj => isProduction || obj.selected); + // generate array of clean message text objects and do bulk insert + let messageGroupTexts = selectedLanguages.map(obj => convertToInsertableText(obj, insertedGroup.id)); + if (messageGroupTexts.length < 1) { + continue; + } + client.getMany(sqlBrick.insert('message_text', messageGroupTexts).returning('*').toString()); + } }); } // take an array of message groups and message languages and merge them -function mergeLanguagesIntoGroups (messageGroups, messageLanguages, callback){ - async.each(messageGroups, function (group, callback) { - async.filter(messageLanguages, function (language, callback) { - callback(null, language.message_group_id == group.id); - }, function (err, languages) { - group.languages = languages; - callback(); - }); - }, function (err) { - callback(err, messageGroups); +async function mergeLanguagesIntoGroups (messageGroups, messageLanguages) { + messageGroups.forEach(group => { + group.languages = messageLanguages.filter(language => language.message_group_id == group.id); }); + return messageGroups; } function hashifyTemplate (template) { @@ -145,7 +119,7 @@ function arrayifyTemplate (template) { return template; } -function transformMessages (info, next) { +function transformMessages (info) { let template = info[0][0]; //comes back as an array of messages const texts = info[1]; const group = info[2][0]; @@ -154,7 +128,7 @@ function transformMessages (info, next) { }); if (!group) { - return next(null, []); + return []; } template = hashifyTemplate(template); @@ -186,7 +160,7 @@ function transformMessages (info, next) { template = arrayifyTemplate(template); - next(null, [template]); + return [template]; } module.exports = { diff --git a/app/v1/module-config/controller.js b/app/v1/module-config/controller.js index 0317757c..8017dd49 100644 --- a/app/v1/module-config/controller.js +++ b/app/v1/module-config/controller.js @@ -11,34 +11,26 @@ const flow = app.locals.flow; const async = require('async'); const sqlBricks = require('sql-bricks-postgres'); -function get(req, res, next) { +async function get (req, res, next) { //if environment is not of value "staging", then set the environment to production const isProduction = !req.query.environment || req.query.environment.toLowerCase() !== 'staging'; - let chosenFlow; + try { + let data; - if (req.query.id) { //get module config of a specific id - if (Number.isNaN(Number(req.query.id))) { - return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); - } - chosenFlow = helper.getModuleConfigFlow('id', req.query.id); - } else { //get the most recent module config object - chosenFlow = helper.getModuleConfigFlow('status', isProduction); - } - - chosenFlow(function(err, data) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage('Internal server error') - .deliver(); + if (req.query.id) { //get module config of a specific id + if (Number.isNaN(Number(req.query.id))) { + return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); + } + data = await helper.getModuleConfig('id', req.query.id); + } else { //get the most recent module config object + data = await helper.getModuleConfig('status', isProduction); } if (!certController.openSSLEnabled) { // cert gen not enabled data.forEach(obj => { delete obj.certificate; delete obj.private_key - }) + }); } return res.parcel .setStatus(200) @@ -48,10 +40,16 @@ function get(req, res, next) { } ) .deliver(); - }); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage('Internal server error') + .deliver(); + } } -function post(isProduction, req, res, next) { +async function post (isProduction, req, res, next) { helper.validatePost(req, res); if (res.parcel.message) { app.locals.log.error(res.parcel.message); @@ -59,152 +57,115 @@ function post(isProduction, req, res, next) { } if (certController.openSSLEnabled && req.body.private_key && req.body.certificate) { - certUtil.extractExpirationDateCertificate(req.body.certificate, function (err, expirationDate) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setMessage('An error occurred when processing the private key and certificate data. If you are providing your own, please be certain of their accuracy and validity.') - .setStatus(400) - .deliver(); - } + let expirationDate; + try { + expirationDate = await certUtil.extractExpirationDateCertificate(req.body.certificate); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setMessage('An error occurred when processing the private key and certificate data. If you are providing your own, please be certain of their accuracy and validity.') + .setStatus(400) + .deliver(); + } - if (expirationDate < Date.now()) { //expired cert - return res.parcel - .setMessage('Certificate is expired') - .setStatus(400) - .deliver(); - } - //the expiration date is valid. add it to the module config body for storage in the DB - req.body.expiration_ts = expirationDate; + if (expirationDate < Date.now()) { //expired cert + return res.parcel + .setMessage('Certificate is expired') + .setStatus(400) + .deliver(); + } + //the expiration date is valid. add it to the module config body for storage in the DB + req.body.expiration_ts = expirationDate; + try { // while the keyCertBundle is not used, this is necessary to check that the private key and certificate match - certUtil.createKeyCertBundle(req.body.private_key, req.body.certificate) - .then(keyCertBundle => { - saveModuleConfig(); //save here - }) - .catch(err => { - app.locals.log.error(err); - return res.parcel.setStatus(500) - .setMessage('An error occurred in creating the certificate') - .deliver(); - }); - }); + await certUtil.createKeyCertBundle(req.body.private_key, req.body.certificate); + } catch (err) { + app.locals.log.error(err); + return res.parcel.setStatus(500) + .setMessage('An error occurred in creating the certificate') + .deliver(); + } } - else { - saveModuleConfig(); //save here - } - - function saveModuleConfig () { - model.insertModuleConfig(isProduction, req.body, function (err) { - if (err) { - app.locals.log.error(err); - res.parcel - .setMessage('Interal server error') - .setStatus(500); - } else { - cache.deleteCacheData(isProduction, app.locals.version, cache.policyTableKey); - res.parcel.setStatus(200); - } - res.parcel.deliver(); - }); + // save the data + try { + await model.insertModuleConfig(isProduction, req.body); + cache.deleteCacheData(isProduction, app.locals.version, cache.policyTableKey); + res.parcel.setStatus(200); + res.parcel.deliver(); + } catch (err) { + app.locals.log.error(err); + res.parcel + .setMessage('Interal server error') + .setStatus(500); + res.parcel.deliver(); } } -function promoteNoId (req, res, next) { +async function promoteNoId (req, res, next) { if (res.parcel.message) { return res.parcel.deliver(); } // retrieve the staging config - const flow = helper.getModuleConfigFlow('status', false); - - flow(function(err, data) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage('Internal server error') - .deliver(); - } + try { + const data = await helper.getModuleConfig('status', false); if (!certController.openSSLEnabled) { // cert gen not enabled data.forEach(obj => { delete obj.certificate; delete obj.private_key - }) + }); } // modify the body and pass the express parameters along as if we are posting to production req.body = data[0]; post(true, req, res, next); - }); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage('Internal server error') + .deliver(); + } } -function checkAndUpdateCertificate (cb) { +async function checkAndUpdateCertificate () { if (!certController.openSSLEnabled) { - if (cb) { - cb(); - } return; } - db.sqlCommand(sql.getAllExpiredModuleCertificates(), certCheckAndUpdateModuleConfigs); + const expiredModuleConfigs = await db.asyncSql(sql.getAllExpiredModuleCertificates()); - function certCheckAndUpdateModuleConfigs (err, expiredModuleConfigs) { - if (err) { - app.locals.log.error(err); - if (cb) { - cb(); - } - return; - } + for (let moduleConfig of expiredModuleConfigs) { + //cert expired. make a new one and add the new module config to the database + app.locals.log.info("creating new module config cert"); - async.mapSeries(expiredModuleConfigs, function (moduleConfig, next) { - //cert expired. make a new one and add the new module config to the database - app.locals.log.info("creating new module config cert"); + //use the existing private key to make a new cert + let options = certController.getCertificateOptions({ + clientKey: moduleConfig.private_key + }); - //use the existing private key to make a new cert - let options = certController.getCertificateOptions({ - clientKey: moduleConfig.private_key - }); + const keyBundle = await certController.asyncCreateCertificate(options); - certController.createCertificateFlow(options, function (err, keyBundle) { - if (err) { - app.locals.log.error(err); - return next(); - } + //new cert created! extract the key and cert and save the module config with them + moduleConfig.certificate = keyBundle.certificate; + moduleConfig.private_key = keyBundle.clientKey; - //new cert created! extract the key and cert and save the module config with them - moduleConfig.certificate = keyBundle.certificate; - moduleConfig.private_key = keyBundle.clientKey; - - certUtil.extractExpirationDateCertificate(keyBundle.certificate, function (err, newExpDate) { - if (err) { - app.locals.log.error(err); - return next(); - } - //the expiration date is valid. add it to the module config body for storage in the DB - moduleConfig.expiration_ts = newExpDate; - - const updateObj = { - certificate: moduleConfig.certificate, - private_key: moduleConfig.private_key, - expiration_ts: moduleConfig.expiration_ts, - updated_ts: sqlBricks('now()'), - }; - - cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); - cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); - db.sqlCommand(sql.updateModuleConfig(moduleConfig.id, updateObj), next); - }); - }); - }, function (err) { - if (err) { - app.locals.log.error(err); - } - if (cb) { - cb(); - } - }); + const newExpDate = await certUtil.extractExpirationDateCertificate(keyBundle.certificate); + //the expiration date is valid. add it to the module config body for storage in the DB + moduleConfig.expiration_ts = newExpDate; + + const updateObj = { + certificate: moduleConfig.certificate, + private_key: moduleConfig.private_key, + expiration_ts: moduleConfig.expiration_ts, + updated_ts: sqlBricks('now()'), + }; + + cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); + cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); + await db.asyncSql(sql.updateModuleConfig(moduleConfig.id, updateObj)); } + app.locals.log.info("Module certificates updated"); } module.exports = { diff --git a/app/v1/module-config/helper.js b/app/v1/module-config/helper.js index d18c3411..cdb4cf41 100644 --- a/app/v1/module-config/helper.js +++ b/app/v1/module-config/helper.js @@ -134,20 +134,21 @@ function validatePost (req, res) { //helper functions -function getModuleConfigFlow (property, value) { - const getInfoFlow = app.locals.flow({ - base: setupSql.bind(null, sql.moduleConfig[property](value)), - retrySeconds: setupSql.bind(null, sql.retrySeconds[property](value)), - endpointProperties: setupSql.bind(null, sql.endpointProperties[property](value)) - }, {method: 'parallel'}); +async function getModuleConfig (property, value) { + const info = { + base: app.locals.db.asyncSql(sql.moduleConfig[property](value)), + retrySeconds: app.locals.db.asyncSql(sql.retrySeconds[property](value)), + endpointProperties: app.locals.db.asyncSql(sql.endpointProperties[property](value)) + }; - return app.locals.flow([ - getInfoFlow, - model.transformModuleConfig - ], {method: 'waterfall', eventLoop: true}); + for (let prop in info) { + info[prop] = await info[prop]; // resolve all promises into each property + } + + return model.transformModuleConfig(info); } module.exports = { validatePost: validatePost, - getModuleConfigFlow: getModuleConfigFlow + getModuleConfig: getModuleConfig } \ No newline at end of file diff --git a/app/v1/module-config/model.js b/app/v1/module-config/model.js index e47b89cf..a47f4a29 100644 --- a/app/v1/module-config/model.js +++ b/app/v1/module-config/model.js @@ -6,8 +6,7 @@ const db = app.locals.db; const sql = require('./sql.js'); const _ = require('lodash'); -//keeping this synchronous due to how small the data is. pass this to the event loop -function transformModuleConfig (info, next) { +function transformModuleConfig (info) { const base = info.base; const retrySeconds = info.retrySeconds; const endpointProperties = info.endpointProperties; @@ -31,7 +30,7 @@ function transformModuleConfig (info, next) { moduleConfigs.push(baseTemplate(hashBase[id])); } - next(null, moduleConfigs); + return moduleConfigs; } function baseTemplate (objOverride) { @@ -123,47 +122,36 @@ function baseTemplate (objOverride) { } //store the information using a SQL transaction -function insertModuleConfig (isProduction, moduleConfig, next) { +async function insertModuleConfig (isProduction, moduleConfig) { //change status if (isProduction) { moduleConfig.status = "PRODUCTION"; } else { moduleConfig.status = "STAGING"; } - // process message groups synchronously (due to the SQL transaction) - db.runAsTransaction(function (client, callback) { - flame.async.waterfall([ - //stage 1: insert module config - client.getOne.bind(client, sql.insertModuleConfig(moduleConfig)), - //stage 2: insert module config retry seconds - function (newModConf, next) { - if (moduleConfig.seconds_between_retries.length > 0) { - client.getOne(sql.insertRetrySeconds(moduleConfig.seconds_between_retries, newModConf.id), function(err){ - next(err, newModConf); - }); - } else { - next(null, newModConf); - } - }, - //stage 3: insert module config endpoint properties - function (newModConf, next) { - //ensure that there is at least one value inside the properties - let foundPropertyValue = false; - for (let key in moduleConfig.endpoint_properties) { - for (propKey in moduleConfig.endpoint_properties[key]) { - foundPropertyValue = true; - } - } + // process message groups synchronously (due to the SQL transaction) + await db.asyncTransaction(async client => { + //stage 1: insert module config + let newModConf = await client.getOne(sql.insertModuleConfig(moduleConfig)); + //stage 2: insert module config retry seconds + if (moduleConfig.seconds_between_retries.length > 0) { + await client.getOne(sql.insertRetrySeconds(moduleConfig.seconds_between_retries, newModConf.id)); + } + //stage 3: insert module config endpoint properties + //ensure that there is at least one value inside the properties + let foundPropertyValue = false; - if (foundPropertyValue) { - client.getOne(sql.insertEndpointProperties(moduleConfig.endpoint_properties, newModConf.id), next); - } else { - next(); - } + for (let key in moduleConfig.endpoint_properties) { + for (propKey in moduleConfig.endpoint_properties[key]) { + foundPropertyValue = true; } - ], callback); - }, next); + } + + if (foundPropertyValue) { + await client.getOne(sql.insertEndpointProperties(moduleConfig.endpoint_properties, newModConf.id)); + } + }); } module.exports = { diff --git a/app/v1/permissions/controller.js b/app/v1/permissions/controller.js index 4c3ecc71..a6e02480 100644 --- a/app/v1/permissions/controller.js +++ b/app/v1/permissions/controller.js @@ -1,19 +1,14 @@ const app = require('../app'); -const setupSql = app.locals.db.setupSqlCommand; const sql = require('./sql.js'); const helper = require('./helper.js'); -function get (req, res, next) { +async function get (req, res, next) { //if environment is not of value "staging", then set the environment to production const isProduction = req.query.environment && req.query.environment.toLowerCase() === 'staging' ? false: true; - const findUnmappedPermissions = setupSql.bind(null, sql.findUnmappedPermissions(isProduction)) - findUnmappedPermissions(function (err, permissions) { - if (err) { - return res.parcel - .setStatus(500) - .setMessage("Internal server error") - .deliver(); - } + + try { + let permissions = await app.locals.db.asyncSql(sql.findUnmappedPermissions(isProduction)); + //get aggregate results let unmappedRpcCount = 0; let unmappedParameterCount = 0; @@ -40,39 +35,39 @@ function get (req, res, next) { unmapped_parameter_count: unmappedParameterCount }) .deliver(); - }); + } catch (err) { + console.log(err); + return res.parcel + .setStatus(500) + .setMessage("Internal server error") + .deliver(); + } } -function post (req, res, next) { - updatePermissions(function (err) { - if (err) { - return res.parcel - .setStatus(500) - .setMessage("Internal server error") - .deliver(); - } +async function post (req, res, next) { + try { + await updatePermissions(); return res.parcel .setStatus(200) .deliver(); - }); + } catch (err) { + return res.parcel + .setStatus(500) + .setMessage("Internal server error") + .deliver(); + } } -function updatePermissions (next) { +async function updatePermissions () { const queryObj = { include_hidden: true, include_parents: true }; - const permissionFlow = app.locals.flow([ - app.locals.shaid.getPermissions.bind(null, queryObj), - helper.storePermissions - ], {method: "waterfall"}); + + const permissions = await app.locals.shaid.getPermissions(queryObj); + await helper.storePermissions(permissions); - permissionFlow(function (err) { - app.locals.log.info("Permission information updated"); - if (next) { - next(err); - } - }); + app.locals.log.info("Permission information updated"); } module.exports = { diff --git a/app/v1/permissions/helper.js b/app/v1/permissions/helper.js index f17eba61..41f8c950 100644 --- a/app/v1/permissions/helper.js +++ b/app/v1/permissions/helper.js @@ -2,18 +2,20 @@ const app = require('../app'); const flame = app.locals.flame; const sql = require('./sql.js'); -function storePermissions (permissions, next) { +async function storePermissions (permissions) { //convert the data into objects that can be directly stored in the database let permissionObjs = []; let permissionRelationObjs = []; - flame.async.map(permissions, function (perm, next) { + + for (const perm of permissions) { permissionObjs.push({ //add permission "name": perm.key, "type": perm.type, "function_id": perm.function_id || null, "display_name": perm.name || null }); + if (perm.parent_permissions.length > 0) { for (let j = 0; j < perm.parent_permissions.length; j++) { permissionRelationObjs.push({ //add permission relation @@ -22,19 +24,11 @@ function storePermissions (permissions, next) { }); } } - next(); - }, function () { - //insert permissions first, then permission relations - const insertPermissions = app.locals.db.setupSqlCommands(sql.insertPermissions(permissionObjs)); - const insertPermissionRelations = app.locals.db.setupSqlCommands(sql.insertPermissionRelations(permissionRelationObjs)); - const insertArray = [ - app.locals.flow(insertPermissions, {method: 'parallel'}), - app.locals.flow(insertPermissionRelations, {method: 'parallel'}) - ]; - const insertFlow = app.locals.flow(insertArray, {method: 'series'}); - insertFlow(next); - }); + } + //insert permissions first, then permission relations + await app.locals.db.asyncSqls(sql.insertPermissions(permissionObjs)); + await app.locals.db.asyncSqls(sql.insertPermissionRelations(permissionRelationObjs)); } module.exports = { diff --git a/app/v1/policy/controller.js b/app/v1/policy/controller.js index 6a635088..0404aea4 100644 --- a/app/v1/policy/controller.js +++ b/app/v1/policy/controller.js @@ -5,45 +5,59 @@ const encryption = require('../../../customizable/encryption'); const GET = require('lodash').get; function postFromCore (isProduction) { - return function (req, res, next) { + return async function (req, res, next) { // attempt decryption of the policy table if it's defined - function processPolicies(policy_table){ + try { + const policy_table = await new Promise(resolve => { + encryption.decryptPolicyTable(req.body.policy_table, isProduction, function (policy_table) { + resolve(policy_table); + }); + }); + helper.validateCorePost(req, res); if (res.errorMsg) { return res.status(400).send({ error: res.errorMsg }); } const useLongUuids = GET(policy_table, "module_config.full_app_id_supported", false) ? true : false; - helper.generatePolicyTable(isProduction, useLongUuids, policy_table.app_policies, true, handlePolicyTableFlow.bind(null, res, isProduction)); + const returnPreview = true; + const pieces = await helper.generatePolicyTable(isProduction, useLongUuids, policy_table.app_policies, returnPreview); + createPolicyTableResponse(res, isProduction, pieces, returnPreview); + } catch (err) { + app.locals.log.error(err); + return res.parcel.setStatus(500).deliver(); } - - encryption.decryptPolicyTable(req.body.policy_table, isProduction, function(policy_table){ - processPolicies(policy_table); - }); } } -function getPreview (req, res, next) { +async function getPreview (req, res, next) { const isProduction = !req.query.environment || req.query.environment.toLowerCase() !== 'staging'; - helper.generatePolicyTable(isProduction, false, {}, true, handlePolicyTableFlow.bind(null, res, isProduction)); + + try { + const returnPreview = true; + const pieces = await helper.generatePolicyTable(isProduction, false, {}, returnPreview); + createPolicyTableResponse(res, isProduction, pieces, returnPreview); + } catch (err) { + app.locals.log.error(err); + return res.parcel.setStatus(500).deliver(); + } } -function postAppPolicy (req, res, next) { +async function postAppPolicy (req, res, next) { const isProduction = !req.query.environment || req.query.environment.toLowerCase() !== 'staging'; const useLongUuids = GET(req, "body.policy_table.module_config.full_app_id_supported", false) ? true : false; helper.validateAppPolicyOnlyPost(req, res); if (res.errorMsg) { return res.status(400).send({ error: res.errorMsg }); } - helper.generatePolicyTable(isProduction, useLongUuids, req.body.policy_table.app_policies, false, handlePolicyTableFlow.bind(null, res, isProduction)); -} -function handlePolicyTableFlow (res, isProduction, err, returnPreview = false, pieces) { - if (err) { + try { + const returnPreview = false; + const pieces = await helper.generatePolicyTable(isProduction, useLongUuids, req.body.policy_table.app_policies, returnPreview); + createPolicyTableResponse(res, isProduction, pieces, returnPreview); + } catch (err) { app.locals.log.error(err); return res.parcel.setStatus(500).deliver(); } - //convert from this point down to asynchronous to make use of certificate library - createPolicyTableResponse(res, isProduction, pieces, returnPreview); } function createPolicyTableResponse (res, isProduction, pieces, returnPreview = false) { diff --git a/app/v1/policy/helper.js b/app/v1/policy/helper.js index 8d4115e3..7141e121 100644 --- a/app/v1/policy/helper.js +++ b/app/v1/policy/helper.js @@ -42,171 +42,158 @@ function validateAppPolicyOnlyPost (req, res) { } //helper functions +async function generatePolicyTable (isProduction, useLongUuids = false, appPolicyObj, returnPreview) { + const start = Date.now(); + + let cacheNewData = false; + let policyTable = await cache.getCacheData(isProduction, app.locals.version, cache.policyTableKey); + if (!policyTable) { + policyTable = {}; + } -function generatePolicyTable (isProduction, useLongUuids = false, appPolicyObj, returnPreview, cb) { - let makePolicyTable = {}; if (appPolicyObj) { //existence of appPolicyObj implies to return the app policy object - makePolicyTable.appPolicies = setupAppPolicies(isProduction, useLongUuids, appPolicyObj); + policyTable.appPolicies = setupAppPolicies(isProduction, useLongUuids, appPolicyObj); } - cache.getCacheData(isProduction, app.locals.version, cache.policyTableKey, function (err, cacheData) { - if (GET(cacheData, "moduleConfig") - && GET(cacheData, "functionalGroups") - && GET(cacheData, "consumerFriendlyMessages") - && GET(cacheData, "vehicleData")) { - if(cacheData.moduleConfig){ - cacheData.moduleConfig.full_app_id_supported = useLongUuids; - } - const policyTableMakeFlow = flame.flow(makePolicyTable, {method: 'parallel', eventLoop: true}); - policyTableMakeFlow(function (err, data) { - cacheData.appPolicies = data.appPolicies; - cb(err, returnPreview, cacheData); - }); - } else { - if (returnPreview) { - makePolicyTable.moduleConfig = setupModuleConfig(isProduction, useLongUuids); - makePolicyTable.functionalGroups = setupFunctionalGroups(isProduction); - makePolicyTable.consumerFriendlyMessages = setupConsumerFriendlyMessages(isProduction); - makePolicyTable.vehicleData = setupVehicleData(isProduction); - } - const policyTableMakeFlow = flame.flow(makePolicyTable, {method: 'parallel', eventLoop: true}); - policyTableMakeFlow(function (err, data) { - cache.setCacheData(isProduction, app.locals.version, cache.policyTableKey, data); - cb(err, returnPreview, data); - }); + if (GET(policyTable, "moduleConfig") + && GET(policyTable, "functionalGroups") + && GET(policyTable, "consumerFriendlyMessages") + && GET(policyTable, "vehicleData")) { + if(policyTable.moduleConfig){ + policyTable.moduleConfig.full_app_id_supported = useLongUuids; } - }); + } else { + cacheNewData = true; + if (returnPreview) { + policyTable.moduleConfig = setupModuleConfig(isProduction, useLongUuids); + policyTable.functionalGroups = setupFunctionalGroups(isProduction); + policyTable.consumerFriendlyMessages = setupConsumerFriendlyMessages(isProduction); + policyTable.vehicleData = setupVehicleData(isProduction); + } + } + + for (let prop in policyTable) { + policyTable[prop] = await policyTable[prop]; // resolve all promises into each property + } + + if (cacheNewData) { + cache.setCacheData(isProduction, app.locals.version, cache.policyTableKey, policyTable); + } + + return policyTable; } -function setupVehicleData (isProduction) { - const dataFlow = flame.flow( - { - schemaVersion: setupSqlCommand.bind(null, sql.getVehicleDataSchemaVersion(isProduction)), - rawCustomVehicleData: setupSqlCommand.bind(null, vehicleDataSql.getVehicleData(isProduction)), - rawRpcSpecParams: setupSqlCommand.bind(null, sql.getRpcSpecParams()), - rawRpcSpecTypes: setupSqlCommand.bind(null, sql.getRpcSpecTypes()), - }, - { - method: 'parallel' - } - ); - - return flame.flow( - [ - dataFlow, - model.transformVehicleData.bind(null, isProduction) - ], - { - method: 'waterfall' - } - ); +async function setupVehicleData (isProduction) { + const data = { + schemaVersion: app.locals.db.asyncSql(sql.getVehicleDataSchemaVersion(isProduction)), + rawCustomVehicleData: app.locals.db.asyncSql(vehicleDataSql.getVehicleData(isProduction)), + rawRpcSpecParams: app.locals.db.asyncSql(sql.getRpcSpecParams()), + rawRpcSpecTypes: app.locals.db.asyncSql(sql.getRpcSpecTypes()), + }; + + for (let prop in data) { + data[prop] = await data[prop]; // resolve all promises into each property + } + + return await model.transformVehicleData(isProduction, data); } -function setupModuleConfig (isProduction, useLongUuids = false) { - const getModuleConfig = { - base: setupSqlCommand.bind(null, moduleConfigSql.moduleConfig.status(isProduction)), - retrySeconds: setupSqlCommand.bind(null, moduleConfigSql.retrySeconds.status(isProduction)), - endpointProperties: setupSqlCommand.bind(null, moduleConfigSql.endpointProperties.status(isProduction)), +async function setupModuleConfig (isProduction, useLongUuids = false) { + const moduleConfigData = { + base: app.locals.db.asyncSql(moduleConfigSql.moduleConfig.status(isProduction)), + retrySeconds: app.locals.db.asyncSql(moduleConfigSql.retrySeconds.status(isProduction)), + endpointProperties: app.locals.db.asyncSql(moduleConfigSql.endpointProperties.status(isProduction)), }; - const moduleConfigGetFlow = flame.flow(getModuleConfig, {method: 'parallel'}); - const makeModuleConfig = [ - moduleConfigGetFlow, - model.transformModuleConfig.bind(null, isProduction, useLongUuids) - ]; - return flame.flow(makeModuleConfig, {method: 'waterfall'}); + + for (let prop in moduleConfigData) { + moduleConfigData[prop] = await moduleConfigData[prop]; // resolve all promises into each property + } + + return await model.transformModuleConfig(isProduction, useLongUuids, moduleConfigData); } -function setupConsumerFriendlyMessages (isProduction) { - const getMessages = flame.flow({ - messageStatuses: setupSqlCommand.bind(null, messagesSql.getMessages.status(isProduction)), - messageGroups: setupSqlCommand.bind(null, messagesSql.getMessages.group(isProduction, false, true)), - highestMessageGroupId: setupSqlCommand.bind(null, messagesSql.getMessages.highestGroupId(isProduction, false)) - }, {method: 'parallel'}); +async function setupConsumerFriendlyMessages (isProduction) { + const messagesData = { + messageStatuses: app.locals.db.asyncSql(messagesSql.getMessages.status(isProduction)), + messageGroups: app.locals.db.asyncSql(messagesSql.getMessages.group(isProduction, false, true)), + highestMessageGroupId: app.locals.db.asyncSql(messagesSql.getMessages.highestGroupId(isProduction, false)) + }; - const makeMessages = [ - getMessages, - model.transformMessages - ]; + for (let prop in messagesData) { + messagesData[prop] = await messagesData[prop]; // resolve all promises into each property + } - return flame.flow(makeMessages, {method: 'waterfall'}); + return await model.transformMessages(messagesData); } -function setupFunctionalGroups (isProduction) { - const getFunctionGroupInfo = { - base: setupSqlCommand.bind(null, funcGroupSql.getFuncGroup.base.statusFilter(isProduction, true)), - hmiLevels: setupSqlCommand.bind(null, funcGroupSql.getFuncGroup.hmiLevels.statusFilter(isProduction, true)), - parameters: setupSqlCommand.bind(null, funcGroupSql.getFuncGroup.parameters.statusFilter(isProduction, true)), - messageGroups: messages.getMessageGroups.bind(null, isProduction, true), //get consent prompt values (always returns a value as if in STAGING mode) +async function setupFunctionalGroups (isProduction) { + const functionGroupInfo = { + base: app.locals.db.asyncSql(funcGroupSql.getFuncGroup.base.statusFilter(isProduction, true)), + hmiLevels: app.locals.db.asyncSql(funcGroupSql.getFuncGroup.hmiLevels.statusFilter(isProduction, true)), + parameters: app.locals.db.asyncSql(funcGroupSql.getFuncGroup.parameters.statusFilter(isProduction, true)), + messageGroups: messages.getMessageGroups(isProduction, true), //get consent prompt values (always returns a value as if in STAGING mode) }; - const funcGroupGetFlow = flame.flow(getFunctionGroupInfo, {method: 'parallel'}); - const makeFunctionGroupInfo = [ - funcGroupGetFlow, - model.transformFunctionalGroups.bind(null, isProduction) - ]; - return flame.flow(makeFunctionGroupInfo, {method: 'waterfall'}); + + for (let prop in functionGroupInfo) { + functionGroupInfo[prop] = await functionGroupInfo[prop]; // resolve all promises into each property + } + + return await model.transformFunctionalGroups(isProduction, functionGroupInfo); } -function setupAppPolicies (isProduction, useLongUuids = false, reqAppPolicy) { +async function setupAppPolicies (isProduction, useLongUuids = false, reqAppPolicy) { const uuids = Object.keys(reqAppPolicy); - let getAppPolicy = []; + let appObjs = []; if (uuids.length) { - getAppPolicy.push(setupSqlCommand.bind(null, sql.getBaseAppInfo(isProduction, useLongUuids, uuids))); - } - else { - getAppPolicy.push(function (callback) { - callback(null, []); - }); + appObjs = await app.locals.db.asyncSql(sql.getBaseAppInfo(isProduction, useLongUuids, uuids)); } - getAppPolicy.push(mapAppBaseInfo.bind(null, isProduction, useLongUuids, uuids, reqAppPolicy)); - return flame.flow(getAppPolicy, {method: 'waterfall'}); + + return await mapAppBaseInfo(isProduction, useLongUuids, uuids, reqAppPolicy, appObjs); } -function mapAppBaseInfo (isProduction, useLongUuids = false, requestedUuids, incomingAppObjs, appObjs, callback) { - const makeAppPolicyFlow = flame.flow(flame.map(appObjs, function (appObj, next) { - const getInfoFlow = flame.flow({ - categories: setupSqlCommand.bind(null, sqlApps.getAppCategoriesNames(appObj.id)), - displayNames: setupSqlCommand.bind(null, sql.getAppDisplayNames(appObj.id)), - moduleNames: setupSqlCommand.bind(null, sql.getAppModules(appObj.id)), - funcGroupNames: setupSqlCommand.bind(null, sql.getAppFunctionalGroups(isProduction, appObj)), - serviceTypes: setupSqlCommand.bind(null, sqlApps.getApp.serviceTypes.idFilter(appObj.id)), - serviceTypeNames: setupSqlCommand.bind(null, sqlApps.getApp.serviceTypeNames.idFilter(appObj.id)), - serviceTypePermissions: setupSqlCommand.bind(null, sqlApps.getApp.serviceTypePermissions.idFilter(appObj.id)), - hybridPreference: setupSqlCommand.bind(null, sqlApps.getApp.hybridPreference.idFilter(appObj.id)), - appPassthrough: setupSqlCommand.bind(null, sqlApps.getApp.passthrough.idFilter(appObj.id)), - incomingAppPolicy: function(callback){ - callback(null, incomingAppObjs[(useLongUuids ? appObj.app_uuid : appObj.app_short_uuid)]); - } - }, {method: 'parallel'}); - - flame.flow([ - getInfoFlow, - model.constructAppPolicy.bind(null, appObj, useLongUuids) - ], {method: 'waterfall'})(next); //run it - }), {method: 'parallel'}); - - const getAllDataFlow = flame.flow({ - policyObjs: makeAppPolicyFlow, - requestedUuids: function(callback){ - callback(null, requestedUuids); - }, - useLongUuids: function(callback){ - callback(null, useLongUuids); - }, - defaultFuncGroups: setupSqlCommand.bind(null, sql.getDefaultFunctionalGroups(isProduction)), - preDataConsentFuncGroups: setupSqlCommand.bind(null, sql.getPreDataConsentFunctionalGroups(isProduction)), - deviceFuncGroups: setupSqlCommand.bind(null, sql.getDeviceFunctionalGroups(isProduction)), - blacklistedApps: function (callback) { - if (requestedUuids.length > 0) { - setupSqlCommand(sqlApps.getBlacklistedApps(requestedUuids, useLongUuids), callback); - } else { - callback(null, []); - } +async function mapAppBaseInfo (isProduction, useLongUuids = false, requestedUuids, incomingAppObjs, appObjs) { + const appObjPromises = appObjs.map(async appObj => { + const promiseObjects = { // start all promises in parallel + categories: app.locals.db.asyncSql(sqlApps.getAppCategoriesNames(appObj.id)), + displayNames: app.locals.db.asyncSql(sql.getAppDisplayNames(appObj.id)), + moduleNames: app.locals.db.asyncSql(sql.getAppModules(appObj.id)), + funcGroupNames: app.locals.db.asyncSql(sql.getAppFunctionalGroups(isProduction, appObj)), + serviceTypes: app.locals.db.asyncSql(sqlApps.getApp.serviceTypes.idFilter(appObj.id)), + serviceTypeNames: app.locals.db.asyncSql(sqlApps.getApp.serviceTypeNames.idFilter(appObj.id)), + serviceTypePermissions: app.locals.db.asyncSql(sqlApps.getApp.serviceTypePermissions.idFilter(appObj.id)), + hybridPreference: app.locals.db.asyncSql(sqlApps.getApp.hybridPreference.idFilter(appObj.id)), + appPassthrough: app.locals.db.asyncSql(sqlApps.getApp.passthrough.idFilter(appObj.id)), + incomingAppPolicy: Promise.resolve(incomingAppObjs[(useLongUuids ? appObj.app_uuid : appObj.app_short_uuid)]) + }; + + for (let prop in promiseObjects) { + promiseObjects[prop] = await promiseObjects[prop]; // resolve all promises into each property } - }, {method: 'parallel'}); - flame.flow([ - getAllDataFlow, - model.aggregateResults - ], {method: 'waterfall'})(callback); + + return model.constructAppPolicy(appObj, useLongUuids, promiseObjects); + }); + + const appObjsResolved = await Promise.all(appObjPromises); + + const allDataPromises = { // start all promises in parallel + policyObjs: appObjsResolved, + requestedUuids: Promise.resolve(requestedUuids), + useLongUuids: Promise.resolve(useLongUuids), + defaultFuncGroups: app.locals.db.asyncSql(sql.getDefaultFunctionalGroups(isProduction)), + preDataConsentFuncGroups: app.locals.db.asyncSql(sql.getPreDataConsentFunctionalGroups(isProduction)), + deviceFuncGroups: app.locals.db.asyncSql(sql.getDeviceFunctionalGroups(isProduction)), + }; + if (requestedUuids.length > 0) { + allDataPromises.blacklistedApps = app.locals.db.asyncSql(sqlApps.getBlacklistedApps(requestedUuids, useLongUuids)); + } else { + allDataPromises.blacklistedApps = Promise.resolve([]); + } + + for (let prop in allDataPromises) { + allDataPromises[prop] = await allDataPromises[prop]; // resolve all promises into each property + } + + return model.aggregateResults(allDataPromises); } module.exports = { diff --git a/app/v1/policy/model.js b/app/v1/policy/model.js index 8d40c7e7..626f13a6 100644 --- a/app/v1/policy/model.js +++ b/app/v1/policy/model.js @@ -9,8 +9,7 @@ const certUtil = require('../helpers/certificates'); //module config -//keeping this synchronous due to how small the data is. pass this to the event loop -function transformModuleConfig (isProduction, useLongUuids = false, info, next) { +async function transformModuleConfig (isProduction, useLongUuids = false, info) { //expecting only one module config const base = info.base[0]; const retrySeconds = info.retrySeconds.map(function (secondObj) { @@ -30,150 +29,145 @@ function transformModuleConfig (isProduction, useLongUuids = false, info, next) } // asynchronous and synchronous if branches need to be controlled - let certificateResolution; - - if(certController.openSSLEnabled && base.certificate && base.private_key){ - if (settings.securityOptions.moduleConfigEncryptCertBundle) { - certificateResolution = certUtil.createKeyCertBundle(base.private_key, base.certificate); - } else { - certificateResolution = Promise.resolve(base.certificate + '\n' + base.private_key); + let certificateResult; + + try { + if(certController.openSSLEnabled && base.certificate && base.private_key){ + if (settings.securityOptions.moduleConfigEncryptCertBundle) { + certificateResult = await certUtil.createKeyCertBundle(base.private_key, base.certificate); + } else { + certificateResult = base.certificate + '\n' + base.private_key; + } + } + else { + certificateResult = undefined; } - } - else { - certificateResolution = Promise.resolve(undefined); - } - certificateResolution.then(result => { if (settings.securityOptions.moduleConfigEncryptCertBundle) { - base.certificate = result.pkcs12.toString('base64'); + base.certificate = certificateResult.pkcs12.toString('base64'); } else { - base.certificate = result; + base.certificate = certificateResult; } - }).catch(err => { + } catch (err) { // something went wrong with bundling the cert + key. fallback to default - console.error(err); + app.locals.log.error(err); base.certificate += '\n' + base.private_key; - }).finally(() => { - var moduleConfig = { - "full_app_id_supported": useLongUuids, - "exchange_after_x_ignition_cycles": base.exchange_after_x_ignition_cycles, - "exchange_after_x_kilometers": base.exchange_after_x_kilometers, - "exchange_after_x_days": base.exchange_after_x_days, - "timeout_after_x_seconds": base.timeout_after_x_seconds, - "seconds_between_retries": retrySeconds, - "lock_screen_dismissal_enabled": base.lock_screen_dismissal_enabled, - "endpoints": { - "0x07": { - default: [ protocol + settings.policyServerHost + concatPort + "/api/v1/" + (isProduction ? "production" : "staging") + "/policy"] - }, - "0x04": { - default: [base.endpoint_0x04] - }, - "queryAppsUrl": { - default: [base.query_apps_url] - }, - "lock_screen_icon_url": { - default: [base.lock_screen_default_url] - }, + } + + const moduleConfig = { + "full_app_id_supported": useLongUuids, + "exchange_after_x_ignition_cycles": base.exchange_after_x_ignition_cycles, + "exchange_after_x_kilometers": base.exchange_after_x_kilometers, + "exchange_after_x_days": base.exchange_after_x_days, + "timeout_after_x_seconds": base.timeout_after_x_seconds, + "seconds_between_retries": retrySeconds, + "lock_screen_dismissal_enabled": base.lock_screen_dismissal_enabled, + "endpoints": { + "0x07": { + default: [ protocol + settings.policyServerHost + concatPort + "/api/v1/" + (isProduction ? "production" : "staging") + "/policy"] }, - "endpoint_properties": { - // to be populated + "0x04": { + default: [base.endpoint_0x04] }, - "notifications_per_minute_by_priority": { - "EMERGENCY": base.emergency_notifications, - "NAVIGATION": base.navigation_notifications, - "PROJECTION": base.projection_notifications, - "VOICECOM": base.voicecom_notifications, - "COMMUNICATION": base.communication_notifications, - "NORMAL": base.normal_notifications, - "NONE": base.none_notifications + "queryAppsUrl": { + default: [base.query_apps_url] }, - "subtle_notifications_per_minute_by_priority": { - "EMERGENCY": base.subtle_emergency_notifications, - "NAVIGATION": base.subtle_navigation_notifications, - "PROJECTION": base.subtle_projection_notifications, - "VOICECOM": base.subtle_voicecom_notifications, - "COMMUNICATION": base.subtle_communication_notifications, - "NORMAL": base.subtle_normal_notifications, - "NONE": base.subtle_none_notifications + "lock_screen_icon_url": { + default: [base.lock_screen_default_url] }, - "certificate": base.certificate, + }, + "endpoint_properties": { + // to be populated + }, + "notifications_per_minute_by_priority": { + "EMERGENCY": base.emergency_notifications, + "NAVIGATION": base.navigation_notifications, + "PROJECTION": base.projection_notifications, + "VOICECOM": base.voicecom_notifications, + "COMMUNICATION": base.communication_notifications, + "NORMAL": base.normal_notifications, + "NONE": base.none_notifications + }, + "subtle_notifications_per_minute_by_priority": { + "EMERGENCY": base.subtle_emergency_notifications, + "NAVIGATION": base.subtle_navigation_notifications, + "PROJECTION": base.subtle_projection_notifications, + "VOICECOM": base.subtle_voicecom_notifications, + "COMMUNICATION": base.subtle_communication_notifications, + "NORMAL": base.subtle_normal_notifications, + "NONE": base.subtle_none_notifications + }, + "certificate": base.certificate, + }; + + // only have custom_vehicle_data_mapping_url present if set by OEM, + // according to evolution proposal + if(base.custom_vehicle_data_mapping_url){ + moduleConfig.endpoints.custom_vehicle_data_mapping_url = { + default: [base.custom_vehicle_data_mapping_url] }; + } - // only have custom_vehicle_data_mapping_url present if set by OEM, - // according to evolution proposal - if(base.custom_vehicle_data_mapping_url){ - moduleConfig.endpoints.custom_vehicle_data_mapping_url = { - default: [base.custom_vehicle_data_mapping_url] - }; + // inject endpoint properties we have from the database + _.forEach(endpointProperties, function (endProp, index) { + if (!moduleConfig.endpoint_properties[endProp.endpoint_name] && moduleConfig.endpoints[endProp.endpoint_name]) { + moduleConfig.endpoint_properties[endProp.endpoint_name] = {}; + } + if (moduleConfig.endpoint_properties[endProp.endpoint_name] && endProp.property_value) { + moduleConfig.endpoint_properties[endProp.endpoint_name][endProp.property_name] = endProp.property_value; } - - // inject endpoint properties we have from the database - _.forEach(endpointProperties, function (endProp, index) { - if (!moduleConfig.endpoint_properties[endProp.endpoint_name] && moduleConfig.endpoints[endProp.endpoint_name]) { - moduleConfig.endpoint_properties[endProp.endpoint_name] = {}; - } - if (moduleConfig.endpoint_properties[endProp.endpoint_name] && endProp.property_value) { - moduleConfig.endpoint_properties[endProp.endpoint_name][endProp.property_name] = endProp.property_value; - } - }); - - next(null, moduleConfig); }); + + return moduleConfig; } //consumer messages -function transformMessages (info, cb) { +async function transformMessages (info) { const allMessages = info.messageStatuses; const groups = info.messageGroups; const highestMessageGroupId = info.highestMessageGroupId[0] ? info.highestMessageGroupId[0].id : 0; // used to help generate a version number const versionString = Number(highestMessageGroupId).toLocaleString().replace(/,/g,'.').padStart(11, "000."); // ###.###.### format up to the id of 999,999,999 - const transformFlow = flame.flow([ - //hash the message groups by message_category - flame.async.groupBy.bind(null, groups, function (group, callback) { - callback(null, group.message_category); - }), - //filter out messages that don't exist in the hashed message groups - function (hashedGroups, next) { - flame.async.filter(allMessages, function (message, callback) { - callback(null, hashedGroups[message.message_category]); - }, next); - }, - //finish constructing the consumer messages object - function (finalMessages, next) { - let messageObj = {}; - flame.async.map(finalMessages, function (msg, next) { - if (!messageObj[msg.message_category]) { - messageObj[msg.message_category] = {}; - messageObj[msg.message_category].languages = {}; - } - if (!messageObj[msg.message_category].languages[msg.language_id]) { - messageObj[msg.message_category].languages[msg.language_id] = {}; - } - const langObj = messageObj[msg.message_category].languages[msg.language_id]; - langObj.tts = msg.tts ? msg.tts : undefined; - langObj.line1 = msg.line1 ? msg.line1 : undefined; - langObj.line2 = msg.line2 ? msg.line2 : undefined; - langObj.textBody = msg.text_body ? msg.text_body : undefined; - langObj.label = msg.label ? msg.label : undefined; - next(); - }, function () { - next(null, { - "version": versionString, - "messages": messageObj - }); - }); - } - ], {method: 'waterfall'}); + const hashedGroups = {}; - transformFlow(cb); + //hash the message groups by message_category + groups.forEach(group => { + if (!Array.isArray(hashedGroups[group.message_category])) { + hashedGroups[group.message_category] = []; + } + hashedGroups[group.message_category].push(group); + }); + + let messageObj = {}; + //filter out messages that don't exist in the hashed message groups + const finalMessages = allMessages + .filter(message => hashedGroups[message.message_category]) + .forEach(msg => { + if (!messageObj[msg.message_category]) { + messageObj[msg.message_category] = {}; + messageObj[msg.message_category].languages = {}; + } + if (!messageObj[msg.message_category].languages[msg.language_id]) { + messageObj[msg.message_category].languages[msg.language_id] = {}; + } + const langObj = messageObj[msg.message_category].languages[msg.language_id]; + langObj.tts = msg.tts ? msg.tts : undefined; + langObj.line1 = msg.line1 ? msg.line1 : undefined; + langObj.line2 = msg.line2 ? msg.line2 : undefined; + langObj.textBody = msg.text_body ? msg.text_body : undefined; + langObj.label = msg.label ? msg.label : undefined; + }); + //finish constructing the consumer messages object + return { + "version": versionString, + "messages": messageObj + }; } //functional groups -function transformFunctionalGroups (isProduction, info, next) { +async function transformFunctionalGroups (isProduction, info) { const baseInfo = info.base; const hmiLevels = info.hmiLevels; const parameters = info.parameters; @@ -206,91 +200,74 @@ function transformFunctionalGroups (isProduction, info, next) { //populate the hash above, using the functional group id as a key //include the hmi levels and parameter data - const groupUpData = flame.flow([ - flame.async.map.bind(null, hmiLevels, function (hmiLevel, next) { - const funcId = hmiLevel.function_group_id; - if (!groupedData[funcId].rpcs) { - groupedData[funcId].rpcs = {}; - } - if (!groupedData[funcId].rpcs[hmiLevel.permission_name]) { - groupedData[funcId].rpcs[hmiLevel.permission_name] = {}; - groupedData[funcId].rpcs[hmiLevel.permission_name].hmi_levels = {}; - groupedData[funcId].rpcs[hmiLevel.permission_name].parameters = {}; - groupedData[funcId].rpcs[hmiLevel.permission_name].possible_parameter_count = parseInt(hmiLevel.possible_parameter_count) || 0; - } - groupedData[funcId].rpcs[hmiLevel.permission_name].hmi_levels[hmiLevel.hmi_level] = true; - next(); - }), - flame.async.map.bind(null, parameters, function (parameter, next) { - const funcId = parameter.function_group_id; - groupedData[funcId].rpcs[parameter.rpc_name].parameters[parameter.parameter] = true; - next(); - }), - ], {method: 'series', eventLoop: true}); + hmiLevels.map(hmiLevel => { + const funcId = hmiLevel.function_group_id; + if (!groupedData[funcId].rpcs) { + groupedData[funcId].rpcs = {}; + } + if (!groupedData[funcId].rpcs[hmiLevel.permission_name]) { + groupedData[funcId].rpcs[hmiLevel.permission_name] = {}; + groupedData[funcId].rpcs[hmiLevel.permission_name].hmi_levels = {}; + groupedData[funcId].rpcs[hmiLevel.permission_name].parameters = {}; + groupedData[funcId].rpcs[hmiLevel.permission_name].possible_parameter_count = parseInt(hmiLevel.possible_parameter_count) || 0; + } + groupedData[funcId].rpcs[hmiLevel.permission_name].hmi_levels[hmiLevel.hmi_level] = true; + }); + + parameters.map(parameter => { + const funcId = parameter.function_group_id; + groupedData[funcId].rpcs[parameter.rpc_name].parameters[parameter.parameter] = true; + }); //transform groupedData into valid functional group rpc objects under the keys //modifies the original object - function hashToRpcObject (_, next) { - //asynchronously iterate over groupedData - flame.async.map(groupedData, function (group, callback) { - for (let rpc in group.rpcs) { - //hmi_levels and parameters property needs to be an array - const data = group.rpcs[rpc]; - let hmiLevels = []; - let parameters = []; - //manually insert hmi levels. preserve order of BACKGROUND, FULL, LIMITED, NONE - if (data.hmi_levels.BACKGROUND) { - hmiLevels.push("BACKGROUND"); - } - if (data.hmi_levels.FULL) { - hmiLevels.push("FULL"); - } - if (data.hmi_levels.LIMITED) { - hmiLevels.push("LIMITED"); - } - if (data.hmi_levels.NONE) { - hmiLevels.push("NONE"); - } - for (let parameter in data.parameters) { - parameters.push(parameter); - } - //erase and replace - delete data.hmi_levels; - delete data.parameters; - if (hmiLevels.length > 0) { - data.hmi_levels = hmiLevels; - } - - if (data.possible_parameter_count > 0) { - //sort the parameters array - data.parameters = parameters.sort(); - } - delete data.possible_parameter_count; + for (let prop in groupedData) { + const group = groupedData[prop]; + for (let rpc in group.rpcs) { + //hmi_levels and parameters property needs to be an array + const data = group.rpcs[rpc]; + let hmiLevels = []; + let parameters = []; + //manually insert hmi levels. preserve order of BACKGROUND, FULL, LIMITED, NONE + if (data.hmi_levels.BACKGROUND) { + hmiLevels.push("BACKGROUND"); + } + if (data.hmi_levels.FULL) { + hmiLevels.push("FULL"); + } + if (data.hmi_levels.LIMITED) { + hmiLevels.push("LIMITED"); + } + if (data.hmi_levels.NONE) { + hmiLevels.push("NONE"); + } + for (let parameter in data.parameters) { + parameters.push(parameter); + } + //erase and replace + delete data.hmi_levels; + delete data.parameters; + if (hmiLevels.length > 0) { + data.hmi_levels = hmiLevels; } - callback(); - }, next); - } - function constructFullObject (_, next) { - let functionalGroupings = {}; - for (let id in groupedData) { - const propertyName = hashIdToPropertyName[id]; - functionalGroupings[propertyName] = groupedData[id]; + if (data.possible_parameter_count > 0) { + //sort the parameters array + data.parameters = parameters.sort(); + } + delete data.possible_parameter_count; } - next(null, functionalGroupings); } - //combine all the steps above - const constructFunctionalGroupFlow = flame.flow([ - groupUpData, - hashToRpcObject, - constructFullObject - ], {method: 'waterfall', eventLoop: true}); - - constructFunctionalGroupFlow(next); //run it + let functionalGroupings = {}; + for (let id in groupedData) { + const propertyName = hashIdToPropertyName[id]; + functionalGroupings[propertyName] = groupedData[id]; + } + return functionalGroupings; } -function transformRpcVehicleData (rpcTypes = [], rpcParams = [], isForPolicyTable = false, cb) { +function transformRpcVehicleData (rpcTypes = [], rpcParams = [], isForPolicyTable = false) { let result = []; let typeByName = {}; let typeById = {}; @@ -345,39 +322,30 @@ function transformRpcVehicleData (rpcTypes = [], rpcParams = [], isForPolicyTabl result = paramBuilder(vehicleDataParams); - cb(null, result); + return result; } -function transformVehicleData (isProduction, info, next) { +async function transformVehicleData (isProduction, info) { let vehicleData = { "schema_version": info.schemaVersion[0].version, "schema_items": [] // to be populated }; - flame.async.parallel({ - "customVehicleData": function(callback){ - vehicleDataHelper.getNestedCustomVehicleData(info.rawCustomVehicleData, true, callback); - }, - "rpcVehicleData": function(callback){ - // recursively loop through the RPC Spec data to build the nested objects - transformRpcVehicleData(info.rawRpcSpecTypes, info.rawRpcSpecParams, true, callback); - } - }, function(err, transformations){ - if(!err){ - vehicleData.schema_items = _.uniqBy( - _.concat(transformations.rpcVehicleData, transformations.customVehicleData), - function(item){ - return item.name; - } - ); + const customVehicleData = vehicleDataHelper.getNestedCustomVehicleData(info.rawCustomVehicleData, true); + const rpcVehicleData = transformRpcVehicleData(info.rawRpcSpecTypes, info.rawRpcSpecParams, true); + + vehicleData.schema_items = _.uniqBy( + _.concat(rpcVehicleData, customVehicleData), + function (item) { + return item.name; } - next(err, vehicleData); - }); + ); + return vehicleData; } //application policies -function constructAppPolicy (appObj, useLongUuids = false, res, next) { +async function constructAppPolicy (appObj, useLongUuids = false, res) { const displayNames = res.displayNames.map(function (elem) { return elem.display_text; }); @@ -439,10 +407,10 @@ function constructAppPolicy (appObj, useLongUuids = false, res, next) { if (res.incomingAppPolicy.auth_token !== undefined) appPolicyObj[uuidProp].auth_token = res.incomingAppPolicy.auth_token; } - next(null, appPolicyObj); + return appPolicyObj; } -function aggregateResults (res, next) { +async function aggregateResults (res) { const policyObjs = res.policyObjs; const defaultFuncGroups = res.defaultFuncGroups.map(function (obj) { return obj.property_name; @@ -503,7 +471,8 @@ function aggregateResults (res, next) { "RequestType": [], "RequestSubType": [] }; - next(null, appPolicy); + + return appPolicy; } module.exports = { diff --git a/app/v1/services/controller.js b/app/v1/services/controller.js index f17a70a8..06fb61d5 100644 --- a/app/v1/services/controller.js +++ b/app/v1/services/controller.js @@ -3,22 +3,15 @@ const setupSql = app.locals.db.setupSqlCommand; const sql = require('./sql.js'); const helper = require('./helper.js'); - -function upsertTypes (next) { +async function upsertTypes () { const queryObj = { include_permissions: true }; - const flow = app.locals.flow([ - app.locals.shaid.getServices.bind(null, queryObj), - helper.upsertTypes - ], {method: "waterfall"}); - flow(function (err) { - app.locals.log.info("Service type information updated"); - if (next) { - next(err); - } - }); + const services = await app.locals.shaid.getServices(queryObj); + await helper.upsertTypes(services); + + app.locals.log.info("Service type information updated"); } module.exports = { diff --git a/app/v1/services/helper.js b/app/v1/services/helper.js index f4d51cc5..f716316b 100644 --- a/app/v1/services/helper.js +++ b/app/v1/services/helper.js @@ -2,12 +2,12 @@ const app = require('../app'); const flame = app.locals.flame; const sql = require('./sql.js'); -function upsertTypes (services, next) { +async function upsertTypes (services) { //convert the data into objects that can be directly stored in the database let serviceTypes = []; let servicePermissions = []; - flame.async.map(services, function (service, next) { + for (const service of services) { serviceTypes.push({ "name": service.name, "display_name": service.display_name @@ -20,19 +20,10 @@ function upsertTypes (services, next) { }); } } - next(); - }, function () { - const upsertServiceTypes = app.locals.db.setupSqlCommands(sql.upsertServiceTypes(serviceTypes)); - const upsertServicePermissions = app.locals.db.setupSqlCommands(sql.upsertServiceTypePermissions(servicePermissions)); - - const insertFlow = app.locals.flow([ - app.locals.flow(upsertServiceTypes, {method: 'parallel'}), - app.locals.flow(upsertServicePermissions, {method: 'parallel'}) - ], {method: 'series'}); - - insertFlow(next); - }); + } + await app.locals.db.asyncSqls(sql.upsertServiceTypes(serviceTypes)); + await app.locals.db.asyncSqls(sql.upsertServiceTypePermissions(servicePermissions)); } module.exports = { diff --git a/app/v1/shaid/index.js b/app/v1/shaid/index.js index 72a9f6e3..227d0eeb 100644 --- a/app/v1/shaid/index.js +++ b/app/v1/shaid/index.js @@ -23,32 +23,38 @@ if (process.env.SHAID_URL) { const shaid = new shaidkit(shaidInitObj); const self = module.exports = { - getCountries: function (queryObj, next) { - shaid.read(shaid.entity.country, queryObj, function (err, res) { - next(err, res.data.countries); + getCountries: function (queryObj) { + return new Promise(resolve => { + shaid.read(shaid.entity.country, queryObj, function (err, res) { + resolve(res.data.countries); + }); }); }, - getCategories: function (queryObj, next) { - shaid.read(shaid.entity.category, queryObj, function (err, res) { - next(err, res.data.categories); + getCategories: function (queryObj) { + return new Promise(resolve => { + shaid.read(shaid.entity.category, queryObj, function (err, res) { + resolve(res.data.categories); + }); }); }, - setApplicationApprovalVendor: function(applications, next) { - if(!Array.isArray(applications)){ + setApplicationApprovalVendor: function (applications) { + if (!Array.isArray(applications)) { applications = [applications]; } - shaid.update( - shaid.entity["application/approval/vendor"], - { - "applications": applications - }, - function (err, res) { - next(err, null); - } - ); + return new Promise(resolve => { + shaid.update( + shaid.entity["application/approval/vendor"], + { + "applications": applications + }, + function (err, res) { + resolve(null); + } + ); + }); }, - getApplications: function (queryObj, next) { + getApplications: function (queryObj) { //enforce limits if they do not already exist let enforcedLimit; if (queryObj.limit !== undefined && queryObj.limit <= MAX_APPLICATION_QUERY) { @@ -61,49 +67,53 @@ const self = module.exports = { let apps = []; //the total apps when readRecurse finishes - readRecurse(); - function readRecurse () { - //read the applications - shaid.read(shaid.entity.application, queryObj, function (err, res) { - const appsInQuery = res.data.applications; - apps = apps.concat(appsInQuery); //add to the total apps found + return new Promise(resolve => { + readRecurse(); + function readRecurse () { + //read the applications + shaid.read(shaid.entity.application, queryObj, function (err, res) { + const appsInQuery = res.data.applications; + apps = apps.concat(appsInQuery); //add to the total apps found - if (appsInQuery.length === enforcedLimit) { - //got max apps back. this could mean there are more we need to get - if (queryObj.offset === undefined) { - queryObj.offset = 0; + if (appsInQuery.length === enforcedLimit) { + //got max apps back. this could mean there are more we need to get + if (queryObj.offset === undefined) { + queryObj.offset = 0; + } + queryObj.offset += enforcedLimit; //increase the offset + readRecurse(); } - queryObj.offset += enforcedLimit; //increase the offset - readRecurse(); - } - else { //got all the rest of the apps back - next(null, apps); - } - }); - } + else { //got all the rest of the apps back + resolve(apps); + } + }); + } + }); }, - getPermissions: function (queryObj, callback) { - shaid.read(shaid.entity.permission, queryObj, function (err, res) { - //parse through the first array of objects and extract just the permissions - let permissions = []; + getPermissions: function (queryObj) { + return new Promise(resolve => { + shaid.read(shaid.entity.permission, queryObj, function (err, res) { + //parse through the first array of objects and extract just the permissions + let permissions = []; - flame.async.map(res.data.permission_categories, function (permissionBlock, next) { - for (let j = 0; j < permissionBlock.permissions.length; j++) { - permissions.push(permissionBlock.permissions[j]); - } - next(); - }, function () { - callback(null, permissions); + res.data.permission_categories.forEach(permissionBlock => { + for (let j = 0; j < permissionBlock.permissions.length; j++) { + permissions.push(permissionBlock.permissions[j]); + } + }); + resolve(permissions); }); }); }, - getServices: function(queryObj, callback) { - shaid.read( - shaid.entity.service, - queryObj, - function (err, res) { - callback(err, res.data.services); - } - ); + getServices: function(queryObj) { + return new Promise(resolve => { + shaid.read( + shaid.entity.service, + queryObj, + function (err, res) { + resolve(res.data.services); + } + ); + }); } }; diff --git a/app/v1/vehicle-data/controller.js b/app/v1/vehicle-data/controller.js index d7378bc6..ddf3255b 100644 --- a/app/v1/vehicle-data/controller.js +++ b/app/v1/vehicle-data/controller.js @@ -1,10 +1,9 @@ //Copyright (c) 2019, Livio, Inc. const app = require('../app'); const helper = require('./helper.js'); -const async = require('async'); const cache = require('../../../custom/cache'); -function get(req, res, next) { +async function get (req, res, next) { const isProduction = !req.query.environment || req.query.environment.toLowerCase() !== 'staging'; const returnTemplate = !!req.query.template; //coerce to boolean @@ -16,29 +15,21 @@ function get(req, res, next) { return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); } - async.waterfall( - [ - function(cb) { - helper.getVehicleData(isProduction, req.query.id, cb); - }, - ], - function(err, custom_vehicle_data) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage('Internal server error') - .deliver(); - } - const responseData = { + try { + const custom_vehicle_data = await helper.getVehicleData(isProduction, req.query.id); + return res.parcel + .setStatus(200) + .setData({ custom_vehicle_data: custom_vehicle_data - }; - return res.parcel - .setStatus(200) - .setData(responseData) - .deliver(); - } - ); + }) + .deliver(); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage('Internal server error') + .deliver(); + } } /** @@ -47,41 +38,35 @@ function get(req, res, next) { * @param next * @returns {*|void} */ -function post(req, res, next) { +async function post (req, res, next) { helper.validatePost(req, res); if (res.parcel.message) { app.locals.log.error(res.parcel.message); return res.parcel.deliver(); } - async.waterfall( - [ - function(cb) { - app.locals.db.runAsTransaction(function(client, callback) { - helper.insertCustomVehicleDataItem(client, req.body, callback); - }, cb); - }, - ], - function(err, result) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage('Internal server error') - .deliver(); - } - cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); - const responseData = { - custom_vehicle_data: [result] - }; + try { + const result = await app.locals.db.asyncTransaction(async client => { + return await helper.insertCustomVehicleDataItem(client, req.body); + }); - return res.parcel - .setData(responseData) - .setStatus(200) - .deliver(); - } - ); + cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); + const responseData = { + custom_vehicle_data: [result] + }; + + return res.parcel + .setData(responseData) + .setStatus(200) + .deliver(); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage('Internal server error') + .deliver(); + } } /** @@ -90,81 +75,56 @@ function post(req, res, next) { * @param next * @returns {*|void} */ -function promote(req, res, next) { - - async.waterfall( - [ - function(cb) { - helper.promote(cb); - }, - ], - function(err) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage('Internal server error') - .deliver(); - } - cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); +async function promote (req, res, next) { + try { + await helper.promote(); + cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); + return res.parcel + .setStatus(200) + .deliver(); + } catch (err) { + app.locals.log.error(err); return res.parcel - .setStatus(200) + .setStatus(500) + .setMessage('Internal server error') .deliver(); - } - ); - + } } -function getValidTypes(req, res) { - async.waterfall( - [ - function(cb) { - helper.getValidTypes(cb); - }, - ], - function(err, data) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage('Internal server error') - .deliver(); - } - const responseData = { +async function getValidTypes (req, res) { + try { + const data = await helper.getValidTypes(); + return res.parcel + .setData({ type: data - }; - return res.parcel - .setData(responseData) - .setStatus(200) - .deliver(); - } - ); + }) + .setStatus(200) + .deliver(); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage('Internal server error') + .deliver(); + } } -function getTemplate(req, res) { - async.waterfall( - [ - function(cb) { - helper.getTemplate(cb); - }, - ], - function(err, templateData) { - if (err) { - app.locals.log.error(err); - return res.parcel - .setStatus(500) - .setMessage('Internal server error') - .deliver(); - } - const responseData = { +async function getTemplate (req, res) { + try { + const templateData = await helper.getTemplate(); + return res.parcel + .setData({ custom_vehicle_data: [templateData] - }; - return res.parcel - .setData(responseData) - .setStatus(200) - .deliver(); - } - ); + }) + .setStatus(200) + .deliver(); + } catch (err) { + app.locals.log.error(err); + return res.parcel + .setStatus(500) + .setMessage('Internal server error') + .deliver(); + } } module.exports = { diff --git a/app/v1/vehicle-data/helper.js b/app/v1/vehicle-data/helper.js index f2717049..29d8da3a 100644 --- a/app/v1/vehicle-data/helper.js +++ b/app/v1/vehicle-data/helper.js @@ -2,11 +2,11 @@ const app = require('../app'); const sql = require('./sql.js'); const parseXml = require('xml2js').parseString; -const async = require('async'); const _ = require('lodash'); const check = require('check-types'); const getRpcSpec = require('./../messages/helper').getRpcSpec; const cache = require('../../../custom/cache'); +const promisify = require('util').promisify; /** * Required fields are name, type, and key. All other fields are @@ -37,55 +37,35 @@ function validatePost(req, res) { return; } -function promoteCustomVehicleData(client, obj, parentObjectMapping = {}) { - return function(cb) { - let originalParentId = obj.parent_id; - if (obj.parent_id) { - let parent = parentObjectMapping[obj.parent_id]; - if (!parent.id) { - return cb(`Orphaned record`); - } - //assign parent_id based on parentIdMapping. - obj.parent_id = parent.id; - obj.is_deleted = parent.is_deleted === true; +async function promoteCustomVehicleData (client, obj, parentObjectMapping = {}) { + let originalParentId = obj.parent_id; + if (obj.parent_id) { + let parent = parentObjectMapping[obj.parent_id]; + if (!parent.id) { + return new Error('Orphaned record'); } + //assign parent_id based on parentIdMapping. + obj.parent_id = parent.id; + obj.is_deleted = parent.is_deleted === true; + } - async.waterfall( - [ - function(callback) { - //skip update if status is on production and not a child that has had its parentId changed. - if (obj.status === 'PRODUCTION' && !(obj.parent_id && obj.parent_id != originalParentId)) { - parentObjectMapping[obj.id] = obj; - return callback(null); - } - client.getOne(sql.insertCustomVehicleData(obj, true), function(err, result) { - if (!err && result) { - parentObjectMapping[obj.id] = result; - } - callback(err, result); - }); - } - ], function(err) { - if (err) { - return cb(err); - } - - //update children. - if (obj.params && obj.params.length > 0) { - let functions = []; - for (let param of obj.params) { - functions.push(promoteCustomVehicleData(client, param, parentObjectMapping)); - } - return async.waterfall(functions, function(err) { - cb(err); - }); - } else { - cb(err); - } + //skip update if status is on production and not a child that has had its parentId changed. + if (obj.status === 'PRODUCTION' && !(obj.parent_id && obj.parent_id != originalParentId)) { + parentObjectMapping[obj.id] = obj; + return; + } - } - ); - }; + const result = await client.getOne(sql.insertCustomVehicleData(obj, true)); + if (result) { + parentObjectMapping[obj.id] = result; + } + + //update children. + if (obj.params && obj.params.length > 0) { + for (let param of obj.params) { + await promoteCustomVehicleData(client, param, parentObjectMapping); + } + } } /** @@ -99,72 +79,35 @@ function promoteCustomVehicleData(client, obj, parentObjectMapping = {}) { * * This will be done as a single transaction with top level records being created first. * - * - * @param cb */ -function promote(cb) { - app.locals.db.runAsTransaction(function(client, callback) { - async.waterfall( - [ - function(callback) { - app.locals.db.sqlCommand(sql.getVehicleData(false), function(err, res) { - callback(null, res); - }); - }, - //create nested data. - function(data, callback) { - return getNestedCustomVehicleData(data, false, callback); - }, - //insert data - function(data, callback) { - let functions = []; - for (let customVehicleDataItem of data) { - functions.push(promoteCustomVehicleData(client, customVehicleDataItem)); - } - async.waterfall(functions, callback); - } - ], callback - ); - }, cb); - +async function promote () { + await app.locals.db.asyncTransaction(async client => { + let data = await app.locals.db.asyncSql(sql.getVehicleData(false)); + //create nested data. + data = getNestedCustomVehicleData(data, false); + + //insert data + for (let customVehicleDataItem of data) { + await promoteCustomVehicleData(client, customVehicleDataItem); + } + }); } -function insertCustomVehicleDataItem(client, data, cb) { - async.waterfall( - [ - function(callback) { - client.getOne(sql.insertCustomVehicleData(data, false), function(err, res) { - if (err) { - return cb(err, res); - } - callback(err, res); - }); - }, - function(res, callback) { //insert new children - let functions = []; - if (data.params) { - for (let child of data.params) { - child.status = 'STAGING'; - child.parent_id = res.id; - functions.push(function(cb) { - insertCustomVehicleDataItem(client, child, cb); - }); - } - } - - async.parallel(functions, function(err) { - if (err) { - return callback(err); - } - return callback(err); - }); - }, - ], cb - ); - +async function insertCustomVehicleDataItem (client, data) { + const res = await client.getOne(sql.insertCustomVehicleData(data, false)); + //insert new children + let promises = []; + if (data.params) { + for (let child of data.params) { + child.status = 'STAGING'; + child.parent_id = res.id; + promises.push(insertCustomVehicleDataItem(client, child)); + } + } + return Promise.all(promises); } -function transformVehicleDataItem(customVehicleDataItem, isForPolicyTable) { +function transformVehicleDataItem (customVehicleDataItem, isForPolicyTable) { if (!isForPolicyTable) { return customVehicleDataItem; } @@ -263,9 +206,8 @@ function transformVehicleDataItem(customVehicleDataItem, isForPolicyTable) { * * @param customVehicleDataItems * @param isForPolicyTable - * @param cb */ -function getNestedCustomVehicleData(customVehicleDataItems, isForPolicyTable, cb) { +function getNestedCustomVehicleData (customVehicleDataItems, isForPolicyTable) { let vehicleDataById = {}; for (let customVehicleDataItem of customVehicleDataItems) { vehicleDataById[customVehicleDataItem.id] = customVehicleDataItem; @@ -285,38 +227,28 @@ function getNestedCustomVehicleData(customVehicleDataItems, isForPolicyTable, cb result.push(transformVehicleDataItem(customVehicleDataItem, isForPolicyTable)); } } - cb(null, result); + return result; } /** * Returns a list of custom vehicle data items filtered by status and optionally by id. * @param isProduction - If true return status = PRODUCTION otherwise status = STAGING * @param id - return only this id and child params. - * @param cb */ -function getVehicleData(isProduction, id, cb) { - async.waterfall( - [ - app.locals.db.sqlCommand.bind(null, sql.getVehicleData(isProduction, id)), - function(data, callback) { - getNestedCustomVehicleData(data, false, callback); - } - ], function(err, response) { - cb(err, response); - } - ); +async function getVehicleData (isProduction, id) { + const data = await app.locals.db.asyncSql(sql.getVehicleData(isProduction, id)); + return getNestedCustomVehicleData(data, false); } -function extractRpcSpecVersion(data, next) { +function extractRpcSpecVersion (data) { data.rpcSpec = { version: _.get(data.xml, 'interface.$.version', null), min_version: _.get(data.xml, 'interface.$.minVersion', null), date: _.get(data.xml, 'interface.$.date', null) }; - next(null, data); } -function extractRpcSpecTypes(data, next) { +function extractRpcSpecTypes (data) { let mapping = { 'name': 'name', 'since': 'since', @@ -359,13 +291,16 @@ function extractRpcSpecTypes(data, next) { const functions = _.get(data, 'xml.interface.function'); if (!enumerations) { - return next('enum not defined in the imported rpc spec'); + app.locals.log.error('enum not defined in the imported rpc spec'); + return false; } if (!structs) { - return next('struct not defined in the imported rpc spec'); + app.locals.log.error('struct not defined in the imported rpc spec'); + return false; } if (!functions) { - return next('function not defined in the imported rpc spec'); + app.locals.log.error('function not defined in the imported rpc spec'); + return false; } //extract enums @@ -377,10 +312,12 @@ function extractRpcSpecTypes(data, next) { const enumerationAttributes = _.get(enumeration, '$', {}); if (!enumerationAttributes['name']) { - return next('Enum must have a name defined.'); + app.locals.log.error('Enum must have a name defined.'); + return false; } if (!enumeration['element']) { - return next('Enum must have element defined.'); + app.locals.log.error('Enum must have element defined.'); + return false; } for (let key in mapping) { @@ -397,7 +334,8 @@ function extractRpcSpecTypes(data, next) { const elementAttributes = _.get(element, '$', {}); if (!elementAttributes['name']) { - return next('Element of enum must have a name defined.'); + app.locals.log.error('Element of enum must have a name defined.'); + return false; } for (let key in paramMapping) { @@ -419,7 +357,8 @@ function extractRpcSpecTypes(data, next) { const attributes = _.get(struct, '$', {}); if (!attributes['name']) { - return next('Struct must have a name defined.'); + app.locals.log.error('Struct must have a name defined.'); + return false; } for (let key in mapping) { @@ -440,7 +379,8 @@ function extractRpcSpecTypes(data, next) { const elementAttributes = _.get(element, '$', {}); if (!elementAttributes['name']) { - return next('Param of struct must have a name defined.'); + app.locals.log.error('Param of struct must have a name defined.'); + return false; } for (let key in paramMapping) { @@ -461,7 +401,8 @@ function extractRpcSpecTypes(data, next) { const attributes = _.get(func, '$', {}); if (!attributes['name']) { - return next('Struct must have a name defined.'); + app.locals.log.error('Struct must have a name defined.'); + return false; } if (!func['param']) { @@ -486,7 +427,8 @@ function extractRpcSpecTypes(data, next) { const elementAttributes = _.get(element, '$', {}); if (!elementAttributes['name']) { - return next('Param of func must have a name defined.'); + app.locals.log.error('Param of func must have a name defined.'); + return false; } for (let key in paramMapping) { @@ -501,109 +443,75 @@ function extractRpcSpecTypes(data, next) { data.rpcSpecTypes = rpcSpecTypes; - next(null, data); + return true; } -function updateRpcSpec(next) { - - app.locals.db.runAsTransaction(function(client, callback) { - async.waterfall( - [ - getRpcSpec, - function(rpcString, callback) { - parseXml(rpcString, function(err, xml) { - callback(err, { xml: xml }); - }); - }, - extractRpcSpecVersion, - //check rpc version exists exit if already exists. - function(data, callback) { - let rpcSpec = data.rpcSpec; - client.getOne(sql.getLatestRpcSpec(), function(err, result) { - if (result && result.version) { - if (rpcSpec.version === result.version) { - return callback({ skipReason: 'Rpc spec no update required' }); - } - } - callback(err, data); - }); - }, - function(data, callback) { - let rpcSpec = data.rpcSpec; - client.getOne(sql.insertRpcSpec(rpcSpec), function(err, result) { - data.rpcSpecInsert = result; - callback(err, data); - }); - }, - extractRpcSpecTypes, - function(data, callback) { - client.getMany(sql.insertRpcSpecType(data.rpcSpecInsert.id, data.rpcSpecTypes), function(err, result) { - - data.rpcSpecTypesByName = {}; - - for (let rpcSpecType of result) { - let name = rpcSpecType.name; - if (rpcSpecType.message_type) { - name = `${name}.${rpcSpecType.message_type}`; - } - data.rpcSpecTypesByName[name] = rpcSpecType; - } - callback(err, data); - }); - }, - function(data, callback) { - client.getOne(sql.insertRpcSpecParam(data.rpcSpecParams, data.rpcSpecTypesByName), function(err, result) { - callback(err, data); - }); - } - ], callback); - }, function(err, response) { - - if (err) { - if (err.skipReason) { - //warning only, spec already imported etc. - app.locals.log.info(err.skipReason); - } else { - app.locals.log.error(err); +async function updateRpcSpec () { + await app.locals.db.asyncTransaction(async client => { + const rpcString = await getRpcSpec(); + const data = { + xml: await promisify(parseXml)(rpcString) + }; + extractRpcSpecVersion(data); + //check if the rpc version exists. exit if already exists. + const result = await client.getOne(sql.getLatestRpcSpec()); + if (result && result.version) { + if (data.rpcSpec.version === result.version) { + app.locals.log.info('Rpc spec: no update required'); + return; } - } else { - cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); - cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); - app.locals.log.info('New RPC Spec saved'); + } + // insert rpc spec contents and return them + data.rpcSpecInsert = await client.getOne(sql.insertRpcSpec(data.rpcSpec)); + const success = extractRpcSpecTypes(data); + if (!success) { + return; } - if (typeof next == 'function') { - next(); + const insertTypesResult = await client.getMany(sql.insertRpcSpecType(data.rpcSpecInsert.id, data.rpcSpecTypes)); + data.rpcSpecTypesByName = {}; + + for (let rpcSpecType of insertTypesResult) { + let name = rpcSpecType.name; + if (rpcSpecType.message_type) { + name = `${name}.${rpcSpecType.message_type}`; + } + data.rpcSpecTypesByName[name] = rpcSpecType; } - }); + await client.getOne(sql.insertRpcSpecParam(data.rpcSpecParams, data.rpcSpecTypesByName)); + + // done + cache.deleteCacheData(true, app.locals.version, cache.policyTableKey); + cache.deleteCacheData(false, app.locals.version, cache.policyTableKey); + app.locals.log.info('New RPC Spec updated and saved'); + }).catch(err => { + app.locals.log.error(err); + }); } -function getTemplate(cb) { - return cb( - null, - { - 'id': null, - 'parent_id': null, - 'status': 'STAGING', - 'name': null, - 'type': null, - 'key': null, - 'mandatory': false, - 'min_length': null, - 'max_length': null, - 'min_size': null, - 'max_size': null, - 'min_value': null, - 'max_value': null, - 'array': false, - 'params': [], - 'is_deleted': false - } - ); +function getTemplate () { + return { + 'id': null, + 'parent_id': null, + 'status': 'STAGING', + 'name': null, + 'type': null, + 'key': null, + 'mandatory': false, + 'min_length': null, + 'max_length': null, + 'min_size': null, + 'max_size': null, + 'min_value': null, + 'max_value': null, + 'array': false, + 'params': [], + 'is_deleted': false + } } -function getValidTypes(cb) { +async function getValidTypes () { //primitive types and structgetVehicleDataParamTypes let types = [ @@ -629,21 +537,18 @@ function getValidTypes(cb) { } ]; - app.locals.db.sqlCommand(sql.getEnums(), function(err, enums) { - if (err) { - return cb(err); - } - for (let item of enums) { - types.push( - { - name: item.name, - allow_params: false - } - ); - } + const enums = await app.locals.db.asyncSql(sql.getEnums()); - return cb(null, types); - }); + for (let item of enums) { + types.push( + { + name: item.name, + allow_params: false + } + ); + } + + return types; } module.exports = { diff --git a/custom/cache/index.js b/custom/cache/index.js index a051af07..94eca9ab 100644 --- a/custom/cache/index.js +++ b/custom/cache/index.js @@ -1,5 +1,6 @@ const config = require('../../settings'); const log = require('../../custom/loggers/winston'); +const promisify = require('util').promisify; var cache try { cache = require(`./${config.cacheModule}`); @@ -9,36 +10,32 @@ try { const policyTableKey = 'policyTableKey'; -function getCacheData(isProduction, version, key, callback) { +async function getCacheData (isProduction, version, key) { if (cache) { - cache.get(makeKey(isProduction, version, key), callback); - } else { - callback(null, null); + return await promisify(cache.get)(makeKey(isProduction, version, key)); } + return null; }; -function setCacheData(isProduction, version, key, value, callback) { +async function setCacheData (isProduction, version, key, value) { if (cache) { - cache.set(makeKey(isProduction, version, key), value, callback); - } else if (callback) { - callback(null, null); - } + return await promisify(cache.set)(makeKey(isProduction, version, key), value); + } + return null; }; -function deleteCacheData(isProduction, version, key, callback) { +async function deleteCacheData (isProduction, version, key) { if (cache) { - cache.del(makeKey(isProduction, version, key), callback); - } else if (callback) { - callback(null, null); + return await promisify(cache.del)(makeKey(isProduction, version, key)); } + return null; }; -function flushAll(callback) { +async function flushAll () { if (cache) { - cache.flushall(callback); - } else if (callback) { - callback(null, null); + return await promisify(cache.flushall)(); } + return null; }; function makeKey(isProduction, version, key) { diff --git a/custom/databases/postgres/index.js b/custom/databases/postgres/index.js index 4915105d..410f639c 100644 --- a/custom/databases/postgres/index.js +++ b/custom/databases/postgres/index.js @@ -2,26 +2,37 @@ const pg = require('pg'); //handles connections to the postgres database const async = require('async'); const sqlBrick = require('sql-bricks-postgres'); +const promisify = require('util').promisify; const config = require('../../../settings.js'); //get configurations from environment variables // extend the Postgres client to easily fetch a single expected result as an object -pg.Client.prototype.getOne = pg.Pool.prototype.getOne = function(query, callback){ +pg.Client.prototype.getOne = pg.Pool.prototype.getOne = async function (query) { if (typeof query !== "string") { query = query.toString(); } - this.query(query, function(err, result) { - callback(err, result && Array.isArray(result.rows) && result.rows.length ? result.rows[0] : null); + return new Promise((resolve, reject) => { + this.query(query, function (err, result) { + if (err) { + return reject(err); + } + resolve(result && Array.isArray(result.rows) && result.rows.length ? result.rows[0] : null); + }); }); }; // extend the Postgres client to easily fetch multiple expected results as an array -pg.Client.prototype.getMany = pg.Pool.prototype.getMany = function(query, callback){ +pg.Client.prototype.getMany = pg.Pool.prototype.getMany = async function (query) { if (typeof query !== "string") { query = query.toString(); } - this.query(query, function(err, result) { - callback(err, (result && result.rows) ? result.rows : []); + return new Promise((resolve, reject) => { + this.query(query, function (err, result) { + if (err) { + return reject(err); + } + resolve((result && result.rows) ? result.rows : []); + }); }); }; @@ -70,15 +81,40 @@ module.exports = function (log) { }); const self = { + /* getOne(query, params, callback){ pool.getOne(query, params, callback); }, getMany(query, params, callback){ pool.getMany(query, params, callback); }, + */ //exported functions. these are required to implement //this function executes the SQL command in and returns a response using the callback function //the callback requires an error parameter and a response from the SQL query + asyncSql: async function (query) { + if (typeof query !== "string") { + query = query.toString(); + } + return new Promise((resolve, reject) => { + pool.query(query, function (err, res) { + if (err) { + log.error(err); + log.error(query); + return reject(err); + } + //always return an array + resolve((res && res.rows) ? res.rows : []); + }); + }); + }, + asyncSqls: async function (sqlStringArray, propagateErrors) { + if (!Array.isArray(sqlStringArray)) { //if its just a single sql statement, make it into an array + sqlStringArray = [sqlStringArray]; + } + const promiseMethod = propagateErrors ? 'all' : 'allSettled'; + return Promise[promiseMethod](sqlStringArray.map(sql => self.asyncSql(sql))); + }, sqlCommand: function (query, callback) { if (typeof query !== "string") { query = query.toString(); @@ -92,6 +128,7 @@ module.exports = function (log) { callback(err, (res && res.rows) ? res.rows : []); }); }, + /* //TODO: remove these two functions //given a SQL command, sets up a function to execute the query and pass back the results setupSqlCommand: function (sqlString, next) { @@ -125,6 +162,7 @@ module.exports = function (log) { } }); }, + */ getClient: function (callback){ // reserve a client connection ("client") and its associated release callback ("done") // callback(err, client, done) @@ -181,6 +219,33 @@ module.exports = function (log) { } callback(err, result); }); + }, + asyncTransaction: async function (logic) { + let client; + let done; + return new Promise(resolve => { + self.getClient((err, thisClient, thisDone) => { + client = thisClient; + done = thisDone; + self.begin(client, resolve); // start transaction + }); + }).then(() => { + // pass the client back to the requester logic (Promise) + return logic(client); + }).then(result => { + // requester has finished their logic. commit the db changes + return new Promise(resolve => { + self.commit(client, done, err => { + if (err) { + return reject(err); + } + return resolve(result); + }); + }); + }).catch(err => { + // error + self.rollback(client, done); + }); } } return self; From c4d892bbdd9c68433e163caa957a46743bb0addf Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Mon, 13 Dec 2021 13:36:50 -0500 Subject: [PATCH 02/18] Remove no longer needed libraries --- app/v1/app.js | 3 - app/v1/applications/controller.js | 2 - app/v1/applications/helper.js | 3 - app/v1/applications/model.js | 2 - app/v1/certificates/controller.js | 1 - app/v1/messages/controller.js | 1 - app/v1/messages/model.js | 1 - app/v1/module-config/controller.js | 2 - app/v1/module-config/helper.js | 1 - app/v1/module-config/model.js | 2 - app/v1/permissions/helper.js | 1 - app/v1/policy/helper.js | 1 - app/v1/policy/model.js | 1 - app/v1/services/helper.js | 1 - app/v1/shaid/index.js | 2 - custom/databases/postgres/index.js | 88 --------------- lib/flame-box/index.js | 172 ----------------------------- package-lock.json | 8 -- package.json | 1 - 19 files changed, 293 deletions(-) delete mode 100644 lib/flame-box/index.js diff --git a/app/v1/app.js b/app/v1/app.js index a291d53e..2c7c84b7 100644 --- a/app/v1/app.js +++ b/app/v1/app.js @@ -8,7 +8,6 @@ const path = require('path'); const config = require('../../settings'); //configuration module const log = require(`../../custom/loggers/${config.loggerModule}/index.js`); const db = require(`../../custom/databases/${config.dbModule}/index.js`)(log); //pass in the logger module that's loaded -const flame = require('../../lib/flame-box'); const hashify = require('../../lib/hashify'); const arrayify = require('../../lib/arrayify'); const emailer = require('../../lib/emailer'); @@ -19,11 +18,9 @@ const Cron = require('cron').CronJob; app.locals.config = config; app.locals.log = log; app.locals.db = db; -app.locals.flow = flame.flow; app.locals.hashify = hashify; app.locals.arrayify = arrayify; app.locals.emailer = emailer; -app.locals.flame = flame; app.locals.version = path.basename(__dirname); // construct base URL, e.g. "http://localhost:3000" diff --git a/app/v1/applications/controller.js b/app/v1/applications/controller.js index c5220f65..041e3d36 100644 --- a/app/v1/applications/controller.js +++ b/app/v1/applications/controller.js @@ -2,8 +2,6 @@ const app = require('../app'); const helper = require('./helper.js'); const model = require('./model.js'); const sql = require('./sql.js'); -const flow = app.locals.flow; -const async = require('async'); const moment = require('moment'); const settings = require('../../../settings.js'); const certUtil = require('../helpers/certificates.js'); diff --git a/app/v1/applications/helper.js b/app/v1/applications/helper.js index 3d968015..2bff17d7 100644 --- a/app/v1/applications/helper.js +++ b/app/v1/applications/helper.js @@ -3,12 +3,9 @@ const app = require('../app'); const model = require('./model.js'); const asyncSql = app.locals.db.asyncSql; const sql = require('./sql.js'); -const flow = app.locals.flow; -const flame = app.locals.flame; const log = app.locals.log; const db = app.locals.db; const config = app.locals.config; -const async = require('async'); const certificates = require('../certificates/controller.js'); const certUtil = require('../helpers/certificates.js'); diff --git a/app/v1/applications/model.js b/app/v1/applications/model.js index bbd5b135..094f4f9d 100644 --- a/app/v1/applications/model.js +++ b/app/v1/applications/model.js @@ -1,7 +1,5 @@ const app = require('../app'); const db = app.locals.db; -const flow = app.locals.flow; -const flame = app.locals.flame; const hashify = app.locals.hashify; const arrayify = app.locals.arrayify; const log = app.locals.log; diff --git a/app/v1/certificates/controller.js b/app/v1/certificates/controller.js index 36323d2b..978314d3 100644 --- a/app/v1/certificates/controller.js +++ b/app/v1/certificates/controller.js @@ -1,4 +1,3 @@ -const async = require('async'); const pem = require('pem'); const fs = require('fs'); const tmp = require('tmp'); diff --git a/app/v1/messages/controller.js b/app/v1/messages/controller.js index d3d0a472..9440f095 100644 --- a/app/v1/messages/controller.js +++ b/app/v1/messages/controller.js @@ -2,7 +2,6 @@ const app = require('../app'); const check = require('check-types'); const model = require('./model.js'); const helper = require('./helper.js'); -const async = require('async'); const sql = require('./sql.js'); const cache = require('../../../custom/cache'); diff --git a/app/v1/messages/model.js b/app/v1/messages/model.js index 1b7d4e6f..1c618b98 100644 --- a/app/v1/messages/model.js +++ b/app/v1/messages/model.js @@ -1,7 +1,6 @@ const app = require('../app'); const setupSqlCommands = app.locals.db.setupSqlCommands; const sqlBrick = require('sql-bricks-postgres'); -const async = require('async'); async function combineMessageCategoryInfo (messageInfo) { const filteredCategories = messageInfo.categoryByLanguage; diff --git a/app/v1/module-config/controller.js b/app/v1/module-config/controller.js index 8017dd49..c7e20841 100644 --- a/app/v1/module-config/controller.js +++ b/app/v1/module-config/controller.js @@ -7,8 +7,6 @@ const cache = require('../../../custom/cache'); const certUtil = require('../helpers/certificates'); const certController = require('../certificates/controller'); const db = app.locals.db; -const flow = app.locals.flow; -const async = require('async'); const sqlBricks = require('sql-bricks-postgres'); async function get (req, res, next) { diff --git a/app/v1/module-config/helper.js b/app/v1/module-config/helper.js index cdb4cf41..15225436 100644 --- a/app/v1/module-config/helper.js +++ b/app/v1/module-config/helper.js @@ -2,7 +2,6 @@ const check = require('check-types'); const model = require('./model.js'); const app = require('../app'); -const flow = app.locals.flow; const setupSql = app.locals.db.setupSqlCommand; const sql = require('./sql.js'); diff --git a/app/v1/module-config/model.js b/app/v1/module-config/model.js index a47f4a29..341a008f 100644 --- a/app/v1/module-config/model.js +++ b/app/v1/module-config/model.js @@ -1,7 +1,5 @@ //Copyright (c) 2018, Livio, Inc. const app = require('../app'); -const flame = app.locals.flame; -const flow = app.locals.flow; const db = app.locals.db; const sql = require('./sql.js'); const _ = require('lodash'); diff --git a/app/v1/permissions/helper.js b/app/v1/permissions/helper.js index 41f8c950..92da5077 100644 --- a/app/v1/permissions/helper.js +++ b/app/v1/permissions/helper.js @@ -1,5 +1,4 @@ const app = require('../app'); -const flame = app.locals.flame; const sql = require('./sql.js'); async function storePermissions (permissions) { diff --git a/app/v1/policy/helper.js b/app/v1/policy/helper.js index 7141e121..fd4dd04a 100644 --- a/app/v1/policy/helper.js +++ b/app/v1/policy/helper.js @@ -1,6 +1,5 @@ //Copyright (c) 2018, Livio, Inc. const app = require('../app'); -const flame = app.locals.flame; const model = require('./model.js'); const setupSqlCommand = app.locals.db.setupSqlCommand; const sql = require('./sql.js'); diff --git a/app/v1/policy/model.js b/app/v1/policy/model.js index 626f13a6..1f2915ed 100644 --- a/app/v1/policy/model.js +++ b/app/v1/policy/model.js @@ -1,5 +1,4 @@ const app = require('../app'); -const flame = app.locals.flame; const settings = require('../../../settings.js'); const sqlApp = require('../applications/sql.js'); const _ = require('lodash'); diff --git a/app/v1/services/helper.js b/app/v1/services/helper.js index f716316b..b4caefe6 100644 --- a/app/v1/services/helper.js +++ b/app/v1/services/helper.js @@ -1,5 +1,4 @@ const app = require('../app'); -const flame = app.locals.flame; const sql = require('./sql.js'); async function upsertTypes (services) { diff --git a/app/v1/shaid/index.js b/app/v1/shaid/index.js index 227d0eeb..7785c2c3 100644 --- a/app/v1/shaid/index.js +++ b/app/v1/shaid/index.js @@ -3,8 +3,6 @@ const shaidkit = require('shaidkit'); const config = require('../../../settings.js'); const package = require('../../../package.json'); const app = require('../app'); -const flow = app.locals.flow; -const flame = app.locals.flame; //a constant that informs the policy server the maximum number of apps returned at once from SHAID const MAX_APPLICATION_QUERY = 50; diff --git a/custom/databases/postgres/index.js b/custom/databases/postgres/index.js index 410f639c..ff0b5a48 100644 --- a/custom/databases/postgres/index.js +++ b/custom/databases/postgres/index.js @@ -81,14 +81,6 @@ module.exports = function (log) { }); const self = { - /* - getOne(query, params, callback){ - pool.getOne(query, params, callback); - }, - getMany(query, params, callback){ - pool.getMany(query, params, callback); - }, - */ //exported functions. these are required to implement //this function executes the SQL command in and returns a response using the callback function //the callback requires an error parameter and a response from the SQL query @@ -115,54 +107,6 @@ module.exports = function (log) { const promiseMethod = propagateErrors ? 'all' : 'allSettled'; return Promise[promiseMethod](sqlStringArray.map(sql => self.asyncSql(sql))); }, - sqlCommand: function (query, callback) { - if (typeof query !== "string") { - query = query.toString(); - } - pool.query(query, function (err, res) { - if (err) { - log.error(err); - log.error(query); - } - //always return an array - callback(err, (res && res.rows) ? res.rows : []); - }); - }, - /* - //TODO: remove these two functions - //given a SQL command, sets up a function to execute the query and pass back the results - setupSqlCommand: function (sqlString, next) { - self.sqlCommand(sqlString, function (err, res) { - if (err) { - log.error(err); - log.error(sqlString); - } - next(err, res); - }); - }, - setupSqlCommands: function (sqlStringArray, propagateErrors) { - if (!Array.isArray(sqlStringArray)) { //if its just a single sql statement, make it into an array - sqlStringArray = [sqlStringArray]; - } - return sqlStringArray.map(function (str) { - return function (next) { - self.setupSqlCommand.bind(null, str)(function (err, res) { - if (err) { - log.error(err); - log.error(sqlString); - } - if (propagateErrors) { - next(err, res); - } - else { - next(null, res); //do not propagate errors. if an error happens, continue anyway - } - - }); - } - }); - }, - */ getClient: function (callback){ // reserve a client connection ("client") and its associated release callback ("done") // callback(err, client, done) @@ -188,38 +132,6 @@ module.exports = function (log) { callback(err, result); }); }, - runAsTransaction: function(logic, callback){ - let wf = {}; - async.waterfall([ - function(callback){ - // fetch a SQL client - self.getClient(callback); - }, - function(client, done, callback){ - // start the transaction - wf.client = client; - wf.done = done; - self.begin(client, callback); - }, - function(callback){ - // pass the client back to the requester logic - logic(wf.client, function(err, result){ - callback(err, result); - }); - }, - function(result, callback){ - // requester has finished their logic, commit the db changes - self.commit(wf.client, wf.done, function(err){ - callback(err, result); - }); - } - ], function(err, result){ - if(err){ - self.rollback(wf.client, wf.done); - } - callback(err, result); - }); - }, asyncTransaction: async function (logic) { let client; let done; diff --git a/lib/flame-box/index.js b/lib/flame-box/index.js deleted file mode 100644 index 0b9259bf..00000000 --- a/lib/flame-box/index.js +++ /dev/null @@ -1,172 +0,0 @@ -//a library of functions useful for organizing and executing loops and callback-style functions -const async = require('async'); - -//flattens nested callbacks when running async in multiple stages while still allowing data passing -function flow (tasks, style, callback) { - //check the case where tasks is an object passed in (which will work if thrown into functions like async.parallel unchanged) - //but the style object has a value for the pass property which requires iteration over tasks as if it is an array. error out - //the map function is used for when eventLoop is true, which permits an object as an argument because order doesn't matter - //when it comes to the pass property, order matters in how the arguments get appended. order cannot be assumed for an object - const isAnObject = !Array.isArray(tasks) && tasks === Object(tasks); - if (isAnObject && style.pass) { - throw new Error("Cannot use tasks as an object if a pass style is specified"); - } - return function () { - const lastArg = arguments.length - 1; - const next = arguments[lastArg]; //this is the callback function (it is always the last parameter) - //parameter insertion behavior changes depending on the value of style.pass - //one: pass in the parameters from the previous function to the first function - //all: pass in the parameters from the previous function to all functions - if (tasks.length > 0) { //if tasks is an object, this will always be false, which is a good thing - //this section is purely for when style.pass has a value and functions need parameters inserted - let finalIndex = -1; //default: do not replace any functions - if (style.pass === 'one') { - finalIndex = 0; - } - else if (style.pass === 'all') { - finalIndex = tasks.length - 1; - } - //take the tasks array and insert arguments passed in, if any, once this function is invoked - for (let h = 0; h <= finalIndex; h++) { - let newTask = tasks[h]; - for (let i = 0; i < lastArg; i++) { - newTask = newTask.bind(newTask, arguments[i]); - } - tasks[h] = newTask; //tasks with arguments inserted - } - } - if (style.eventLoop) { //use eventuate so that the task gets thrown into the event loop - tasks = map(tasks, function (task) { //using map allows tasks to be an object - return eventuate(task); - }); - } - async[style.method](tasks, function (err, res) { - if (!callback) { - next(err, res); //if no callback is specified, use this default - } - else { - callback(err, res, next); - } - }); - } -} - -//a shortcut function that uses the function passed in to be applied to the collection using the error/response style -//this also avoids the context-losing problem for deeply nested functions by passing in a context as the third argument -//meant for inserting into flow or async -function flowMap (collection, func, context) { - return map(collection, function (value) { - return function (next) { - if (context) { - func.call(context, value, next); - } - else { - func(value, next); - } - } - }); -} - -//collection is an array or an object to be iterated over -//funcArray will invoke its first element on every element of array. -//funcArray will invoke its second element on every element in a collection in the array, etc. -function loop (collection, funcArray, flowOpts) { - if (!flowOpts) { - flowOpts = {}; - } - if (!flowOpts.method) { //default to parallel if no options were given - flowOpts.method = 'parallel'; - } - if (!Array.isArray(funcArray)) { //funcArray can just be a single function, and loop will handle that case - funcArray = [funcArray]; - } - return { - //breadth-first traversal. funcArray's elements will be invoked one at a time - breadth: function (cb) { - loopBreadth(collection, funcArray, flowOpts, cb); - }, - //depth-first traversal. collection's elements will be processed one at a time - depth: function (cb) { - loopDepth(collection, funcArray, flowOpts, cb); - } - }; -} - -//recursively iterates through a collection, invoking funcArray's elements as if they were maps to the data -//elements are processed fully one at a time. the functions should pass data via returns and not callback-style -function loopDepth (data, funcArray, flowOpts, cb) { - if (funcArray.length > 0) { - const func = funcArray.shift(); //the new function to map over the collection - const taskCollection = map(data, function (value, index, obj) { //iteration step - return function (next) { - const newValue = func(value, index, obj); //apply map - loopDepth(newValue, funcArray.slice(), flowOpts, next); //apply the next function to newValue now - } - }); - flow(taskCollection, flowOpts)(cb); //begin execution - } - else { - cb(null, data); //leaf found. do not transform the data - } -} - -//recursively iterates through a collection, invoking funcArray's elements as if they were maps to the data -//top-level elements are processed before going deeper into the object -function loopBreadth (data, funcArray, flowOpts, cb) { - if (funcArray.length > 0) { - const func = funcArray.shift(); //the new function to map over the collection - const taskCollection = map(data, function (value, index, obj) { //iteration step - return function (next) { - const newValue = func(value, index, obj); //apply map - next(null, newValue); //pass the value through to finish the map - } - }); - flow(taskCollection, flowOpts)(function (err, newData) { //begin execution - //one "depth level" of the collection is done. proceed to the next one - const taskCollectionNew = map(newData, function (value) { - return function (next) { - loopBreadth(value, funcArray.slice(), flowOpts, next); - } - }); - flow(taskCollectionNew, flowOpts)(cb); //begin execution - }); - } - else { - cb(null, data); //leaf found. do not transform the data - } -} - -//interally used function -//pass in an object or array, and this function will iterate over it appropriately -function map (data, cb) { - if (Array.isArray(data)) { //array - return data.map(cb); - } - else if (data === Object(data)) { //object. make a new object reference for the return value - //note: modifying properties in nested objects using the map will mutate the original object - //Array.map has the same behavior. Don't mutate the values in the callback and do not return - //the same reference passed in if you want completely different references for all the elements - const newObj = {}; - for (prop in data) { - //do not iterate along the prototype chain - if (data.hasOwnProperty(prop)) { - const value = data[prop]; - newObj[prop] = cb(value, prop, data); - } - } - return newObj; - } -} - -//converts a function into one that will get thrown into the event loop -function eventuate (func, context) { - return setImmediate.bind(context, func); -} - -module.exports = { - flow: flow, - loop: loop, - async: async, - map: flowMap, - eventuate: eventuate, -}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 217b7126..1b0edd78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2620,14 +2620,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", - "requires": { - "lodash": "^4.14.0" - } - }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", diff --git a/package.json b/package.json index 6ec592ea..b1f7e2fc 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ }, "dependencies": { "@popperjs/core": "^2.4.4", - "async": "2.5.0", "body-parser": "1.18.2", "bootstrap": "4.5.2", "bootstrap-vue": "2.17.3", From 9dbb11e3b66459ddd8de175426dbdde5eadf7cfa Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Mon, 13 Dec 2021 17:08:37 -0500 Subject: [PATCH 03/18] Remove todo --- app/v1/applications/controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/v1/applications/controller.js b/app/v1/applications/controller.js index 041e3d36..17f3ebcf 100644 --- a/app/v1/applications/controller.js +++ b/app/v1/applications/controller.js @@ -330,7 +330,6 @@ async function getAppCertificateByUuid (app_uuid) { return result ? result : {}; } -//todo async function getAppCertificate (req, res, next) { if (!certificates.openSSLEnabled) { return res.parcel.setStatus(400) From 36a8dea856f3b632437d366f941ebd0a0e0c235a Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Mon, 20 Dec 2021 13:41:49 -0500 Subject: [PATCH 04/18] Prevent empty name fields from being entered in the UI --- app/v1/messages/helper.js | 6 ++++++ src/components/ConsumerMessageDetails.vue | 18 ++++++++++++++++-- src/components/FunctionalGroupDetails.vue | 19 +++++++++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/app/v1/messages/helper.js b/app/v1/messages/helper.js index 1b64d97a..510a81df 100644 --- a/app/v1/messages/helper.js +++ b/app/v1/messages/helper.js @@ -20,6 +20,12 @@ function validatePromote (req, res) { function validatePost (req, res) { //base check + if (!check.string(req.body.name) || req.body.name === '') { + res.parcel + .setStatus(400) + .setMessage("Required field for consumer message: name"); + return; + } if (!check.array(req.body.messages)) { res.parcel .setStatus(400) diff --git a/src/components/ConsumerMessageDetails.vue b/src/components/ConsumerMessageDetails.vue index 30882d24..5fd97e96 100644 --- a/src/components/ConsumerMessageDetails.vue +++ b/src/components/ConsumerMessageDetails.vue @@ -41,12 +41,19 @@ +
+
+ +
+
@@ -217,7 +224,14 @@ }); } }); - } + }, + "isNameDefined": function () { + if (!this.message.message_category) { + return false; //no name defined + } + + return true; //no issues + }, }, computed: { fieldsDisabled: function () { diff --git a/src/components/FunctionalGroupDetails.vue b/src/components/FunctionalGroupDetails.vue index 9d5cacc1..4211efd5 100644 --- a/src/components/FunctionalGroupDetails.vue +++ b/src/components/FunctionalGroupDetails.vue @@ -127,12 +127,20 @@
+ +
+
+ +
+
@@ -375,7 +383,14 @@ import { eventBus } from '../main.js'; }); } }); - } + }, + "isNameDefined": function () { + if (!this.fg.name) { + return false; //no name defined + } + + return true; //no issues + }, }, computed: { consentPromptOptions: function () { From 8682e2f9dded915a8db598a5a7525c01c2f54593 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Fri, 7 Jan 2022 14:29:44 -0500 Subject: [PATCH 05/18] Apply feedback and fix unit tests --- app/v1/applications/controller.js | 2 +- app/v1/applications/model.js | 27 +++++++----------- app/v1/groups/model.js | 1 - custom/databases/postgres/index.js | 3 +- test/api/v1/module/module.js | 14 ++++++++-- test/api/v1/module/promote.js | 14 ++++++++-- test/cache/cache.js | 44 ++++++++++-------------------- test/test.js | 1 + 8 files changed, 52 insertions(+), 54 deletions(-) diff --git a/app/v1/applications/controller.js b/app/v1/applications/controller.js index 17f3ebcf..db8efa14 100644 --- a/app/v1/applications/controller.js +++ b/app/v1/applications/controller.js @@ -327,7 +327,7 @@ async function queryAndStoreApplications (queryObj, notifyOEM = true) { //helper function that attempts to find the associated certificate bundle in the database async function getAppCertificateByUuid (app_uuid) { const result = await app.locals.db.asyncSql(sql.getApp.certificate(app_uuid)); - return result ? result : {}; + return result && result.length > 0 ? result[0] : {}; } async function getAppCertificate (req, res, next) { diff --git a/app/v1/applications/model.js b/app/v1/applications/model.js index 094f4f9d..94dcadfb 100644 --- a/app/v1/applications/model.js +++ b/app/v1/applications/model.js @@ -199,57 +199,50 @@ async function storeApp (notifyOEM, appObj) { } //stage 3: locales insert. this is a multi step process so it needs its own flow - if (!appObj.locales || appObj.locales.length === 0) { - // no locales. skip - } else { + if (appObj.locales && appObj.locales.length !== 0) { // attempt locale and tts chunks insert await Promise.all(appObj.locales.map(insertLocaleInfo)); async function insertLocaleInfo (localeInfo) { const localeResult = await client.getOne(sql.insertAppLocale(localeInfo, storedApp.id)); // continue with inserting ttschunks after retreiving the returned id // use the passed in locales - if (localeInfo.tts_chunks.length === 0) { - // no tts chunks to process - } else { + if (localeInfo.tts_chunks.length !== 0) { await client.getOne(sql.insertAppLocaleTtsChunks(localeInfo.tts_chunks, localeResult.id)); } } } + //stage 4: call custom routine to get the byte size of the bundle at the package url if it exists if (appObj.transport_type === 'webengine' && appObj.package_url) { const data = await promisify(webengineHandler.handleBundle)(appObj.package_url); if (!data) { - return new Error('No object returned for the webengine bundle for uuid ' + appObj.uuid); + throw new Error('No object returned for the webengine bundle for uuid ' + appObj.uuid); } if (!data.url) { - return new Error('No url property for the webengine bundle for uuid ' + appObj.uuid); + throw new Error('No url property for the webengine bundle for uuid ' + appObj.uuid); } if (!data.size_compressed_bytes) { - return new Error('No size_compressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); + throw new Error('No size_compressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); } if (!data.size_decompressed_bytes) { - return new Error('No size_decompressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); + throw new Error('No size_decompressed_bytes property for the webengine bundle for uuid ' + appObj.uuid); } // store the returned results of the custom webengine bundle handler function await client.getOne(sql.updateWebengineBundleInfo(storedApp.id, data)); } //stage 5: sync with shaid - if(!storedApp.version_id){ - // skip sync with SHAID if no app version ID is present - } else { + if (storedApp.version_id) { await app.locals.shaid.setApplicationApprovalVendor([storedApp]); } //stage 6: notify OEM of pending app? - if(!( + if ( notifyOEM && app.locals.emailer.isSmtpConfigured() && storedApp.approval_status == 'PENDING' && app.locals.config.notification.appsPendingReview.email.frequency == "REALTIME" && app.locals.config.notification.appsPendingReview.email.to - )){ - // don't send email - } else { + ) { // attempt to send email app.locals.emailer.send({ to: app.locals.config.notification.appsPendingReview.email.to, diff --git a/app/v1/groups/model.js b/app/v1/groups/model.js index 8ca06e52..e427a847 100644 --- a/app/v1/groups/model.js +++ b/app/v1/groups/model.js @@ -1,7 +1,6 @@ const app = require('../app'); const sql = require('./sql.js'); const sqlBrick = require('sql-bricks-postgres'); -const async = require('async'); //generates a single-element functional group info template object async function generateTemplate (info) { diff --git a/custom/databases/postgres/index.js b/custom/databases/postgres/index.js index ff0b5a48..3c4a5a0b 100644 --- a/custom/databases/postgres/index.js +++ b/custom/databases/postgres/index.js @@ -1,6 +1,5 @@ //PostgreSQL Communication Module const pg = require('pg'); //handles connections to the postgres database -const async = require('async'); const sqlBrick = require('sql-bricks-postgres'); const promisify = require('util').promisify; const config = require('../../../settings.js'); @@ -157,6 +156,8 @@ module.exports = function (log) { }).catch(err => { // error self.rollback(client, done); + // after rolling back, re-throw the error so the server can handle it further if needed + throw new Error("Transaction failed."); }); } } diff --git a/test/api/v1/module/module.js b/test/api/v1/module/module.js index 0776ef49..2cfca8f5 100644 --- a/test/api/v1/module/module.js +++ b/test/api/v1/module/module.js @@ -44,7 +44,7 @@ common.post( { preloaded_pt: true, exchange_after_x_ignition_cycles: 20, - exchange_after_x_kilometers: 777, + exchange_after_x_kilometers: 200, exchange_after_x_days: 30, timeout_after_x_seconds: 15, seconds_between_retries: [ 10, 30, 90 ], @@ -65,7 +65,17 @@ common.post( VOICECOM: 5, COMMUNICATION: 5, NORMAL: 5, - NONE: 0 + NONE: 0, + PROJECTION: 10 + }, + subtle_notifications_per_minute_by_priority: { + EMERGENCY: 60, + NAVIGATION: 5, + VOICECOM: 5, + COMMUNICATION: 5, + NORMAL: 5, + NONE: 0, + PROJECTION: 10 }, lock_screen_dismissal_enabled: true }, diff --git a/test/api/v1/module/promote.js b/test/api/v1/module/promote.js index 442ac683..dde94c89 100644 --- a/test/api/v1/module/promote.js +++ b/test/api/v1/module/promote.js @@ -8,7 +8,7 @@ common.post( { preloaded_pt: true, exchange_after_x_ignition_cycles: 20, - exchange_after_x_kilometers: 777, + exchange_after_x_kilometers: 200, exchange_after_x_days: 30, timeout_after_x_seconds: 15, seconds_between_retries: [ 10, 30, 90 ], @@ -29,7 +29,17 @@ common.post( VOICECOM: 5, COMMUNICATION: 5, NORMAL: 5, - NONE: 0 + NONE: 0, + PROJECTION: 10 + }, + subtle_notifications_per_minute_by_priority: { + EMERGENCY: 60, + NAVIGATION: 5, + VOICECOM: 5, + COMMUNICATION: 5, + NORMAL: 5, + NONE: 0, + PROJECTION: 10 }, lock_screen_dismissal_enabled: true }, diff --git a/test/cache/cache.js b/test/cache/cache.js index 178fc51f..d9e1cd9e 100644 --- a/test/cache/cache.js +++ b/test/cache/cache.js @@ -7,38 +7,22 @@ it('should be enabled', (done) => { done(); }); -it('should set a value in the cache and get the value back', (done) => { - cache.setCacheData(true, 'test', 'key', 'someValue', (err, res) => { - expect(err).to.be.null; - cache.getCacheData(true, 'test', 'key', (err, res) => { - expect(err).to.be.null; - expect(res).to.equal('someValue'); - done(); - }); - }); +it('should set a value in the cache and get the value back', async () => { + await cache.setCacheData(true, 'test', 'key', 'someValue'); + const res = await cache.getCacheData(true, 'test', 'key'); + expect(res).to.equal('someValue'); }); -it('should delete a value from the cache', (done) => { - cache.deleteCacheData(true, 'test', 'key', (err, res) => { - expect(err).to.be.null; - cache.getCacheData(true, 'test', 'key', (err, res) => { - expect(err).to.be.null; - expect(res).to.be.null; - done(); - }); - }); +it('should delete a value from the cache', async () => { + await cache.deleteCacheData(true, 'test', 'key'); + + const res = await cache.getCacheData(true, 'test', 'key'); + expect(res).to.be.null; }); -it('should delete everything from the cache', (done) => { - cache.setCacheData(false, 'test', 'key', 'flush', (err, res) => { - expect(err).to.be.null; - cache.flushAll( (err, res) => { - expect(err).to.be.null; - cache.getCacheData(false, 'test', 'key', (err, res) => { - expect(err).to.be.null; - expect(res).to.be.null; - done(); - }); - }); - }); +it('should delete everything from the cache', async () => { + await cache.setCacheData(false, 'test', 'key', 'flush'); + await cache.flushAll(); + const res = await cache.getCacheData(false, 'test', 'key') + expect(res).to.be.null; }); diff --git a/test/test.js b/test/test.js index 27622db3..995569d6 100644 --- a/test/test.js +++ b/test/test.js @@ -4,6 +4,7 @@ var sdlServer = require('../index.js'); function importTest(name, path) { describe(name, function() { + this.timeout(10000); require(path); }); } From b9bedd4ea5ddf2ca33ada117284fd324547048a6 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Tue, 11 Jan 2022 11:04:14 -0500 Subject: [PATCH 06/18] Convert tabs to spaces --- app/v1/about/controller.js | 94 +-- app/v1/app.js | 188 ++--- app/v1/applications/controller.js | 758 +++++++++---------- app/v1/applications/helper.js | 174 ++--- app/v1/forgot/controller.js | 32 +- app/v1/groups/helper.js | 8 +- app/v1/login/controller.js | 16 +- app/v1/messages/controller.js | 4 +- app/v1/middleware/auth.js | 20 +- app/v1/policy/controller.js | 8 +- app/v1/register/controller.js | 38 +- app/v1/static/emails/app_pending_review.html | 8 +- index.js | 146 ++-- scripts/generate-categories/index.js | 20 +- scripts/generate-func-groups/index.js | 106 +-- scripts/generate-messages/index.js | 34 +- scripts/utils.js | 12 +- src/main.js | 106 +-- test/api/v1/login/login.js | 8 +- vue.config.js | 4 +- 20 files changed, 892 insertions(+), 892 deletions(-) diff --git a/app/v1/about/controller.js b/app/v1/about/controller.js index 5410aaa3..636fade2 100644 --- a/app/v1/about/controller.js +++ b/app/v1/about/controller.js @@ -6,53 +6,53 @@ const semver = require('semver'); const certificateController = require('../certificates/controller.js'); exports.getInfo = function (req, res, next) { - var data = { - "current_version": packageJson.version, - "latest_version": packageJson.version, - "is_update_available": false, - "ssl_port": config.ssl.policyServerPort, - "cache_module": config.cacheModule, - "auth_type": config.authType, - "auto_approve_all_apps": config.autoApproveAllApps, - "encryption_required": config.autoApproveSetRPCEncryption, - "base_url": app.locals.baseUrl, - "notification": { - "appsPendingReview": { - "email": { - "enabled": ( - config.smtp.host - && config.smtp.from - && ["REALTIME"].includes(config.notification.appsPendingReview.email.frequency) - && config.notification.appsPendingReview.email.to.split(",").length - ), - "frequency": config.notification.appsPendingReview.email.frequency, - "to_count": config.notification.appsPendingReview.email.to.split(",").length - } - } - }, - "certificate_authority": certificateController.openSSLEnabled - }; + var data = { + "current_version": packageJson.version, + "latest_version": packageJson.version, + "is_update_available": false, + "ssl_port": config.ssl.policyServerPort, + "cache_module": config.cacheModule, + "auth_type": config.authType, + "auto_approve_all_apps": config.autoApproveAllApps, + "encryption_required": config.autoApproveSetRPCEncryption, + "base_url": app.locals.baseUrl, + "notification": { + "appsPendingReview": { + "email": { + "enabled": ( + config.smtp.host + && config.smtp.from + && ["REALTIME"].includes(config.notification.appsPendingReview.email.frequency) + && config.notification.appsPendingReview.email.to.split(",").length + ), + "frequency": config.notification.appsPendingReview.email.frequency, + "to_count": config.notification.appsPendingReview.email.to.split(",").length + } + } + }, + "certificate_authority": certificateController.openSSLEnabled + }; - // cannot use promisify: there are two returns we need - requestjs({ - "method": "GET", - "uri": "https://raw.githubusercontent.com/smartdevicelink/sdl_server/master/package.json", - "timeout": 5000, - "json": true - }, async function (err, response, body) { - if (!err && response.statusCode >= 200 && response.statusCode < 300) { - // success! - data.latest_version = body.version; - data.is_update_available = semver.lt(data.current_version, data.latest_version); - data.update_type = semver.diff(data.current_version, data.latest_version); - } - if (data.certificate_authority) { - const isAuthorityValid = await certificateController.checkAuthorityValidity(); - data.is_authority_valid = isAuthorityValid && data.certificate_authority; - } + // cannot use promisify: there are two returns we need + requestjs({ + "method": "GET", + "uri": "https://raw.githubusercontent.com/smartdevicelink/sdl_server/master/package.json", + "timeout": 5000, + "json": true + }, async function (err, response, body) { + if (!err && response.statusCode >= 200 && response.statusCode < 300) { + // success! + data.latest_version = body.version; + data.is_update_available = semver.lt(data.current_version, data.latest_version); + data.update_type = semver.diff(data.current_version, data.latest_version); + } + if (data.certificate_authority) { + const isAuthorityValid = await certificateController.checkAuthorityValidity(); + data.is_authority_valid = isAuthorityValid && data.certificate_authority; + } - res.parcel.setStatus(200) - .setData(data) - .deliver(); - }); + res.parcel.setStatus(200) + .setData(data) + .deliver(); + }); } diff --git a/app/v1/app.js b/app/v1/app.js index 2c7c84b7..85580644 100644 --- a/app/v1/app.js +++ b/app/v1/app.js @@ -55,58 +55,58 @@ const certificates = require('./certificates/controller.js'); const vehicleData = require('./vehicle-data/controller.js'); function exposeRoutes () { - // use helmet middleware for security - app.use(helmet()); - // extend response builder to all routes - app.route("*").all(parcel.extendExpress); + // use helmet middleware for security + app.use(helmet()); + // extend response builder to all routes + app.route("*").all(parcel.extendExpress); - //route definitions - //app.post('/forgot', forgot.post); - //app.post('/register', register.post); - app.post('/login', login.validateAuth); - app.get('/applications', auth.validateAuth, applications.get); - app.post('/applications/action', auth.validateAuth, applications.actionPost); - app.post('/applications/auto', auth.validateAuth, applications.autoPost); - app.post('/applications/administrator', auth.validateAuth, applications.administratorPost); - app.post('/applications/passthrough', auth.validateAuth, applications.passthroughPost); - app.post('/applications/hybrid', auth.validateAuth, applications.hybridPost); - app.put('/applications/rpcencryption', auth.validateAuth, applications.rpcEncryptionPut); - app.put('/applications/service/permission', auth.validateAuth, applications.putServicePermission); - app.post('/applications/certificate/get', applications.getAppCertificate); - app.get('/applications/certificate/get', applications.getAppCertificate); - app.post('/applications/certificate', applications.updateAppCertificate); - app.get('/applications/groups', auth.validateAuth, applications.getFunctionalGroups); - app.put('/applications/groups', auth.validateAuth, applications.putFunctionalGroup); - // webengine app store - app.get('/applications/store', cors(), applications.getAppStore); - app.get('/applications/store/staging', cors(), applications.getStagingAppStore); - app.post('/webhook', applications.webhook); //webhook route - //begin policy table routes - app.options('/staging/policy', cors()) - app.options('/production/policy', cors()) - app.post('/staging/policy', cors(), policy.postFromCoreStaging); - app.post('/production/policy', cors(), policy.postFromCoreProduction); - app.get('/policy/preview', policy.getPreview); - app.post('/policy/apps', policy.postAppPolicy); - //end policy table routes - app.post('/permissions/update', auth.validateAuth, permissions.post); - app.get('/permissions/unmapped', auth.validateAuth, permissions.get); - app.get('/groups', auth.validateAuth, groups.get); - app.get('/groups/names', auth.validateAuth, groups.getNames); - app.post('/groups', auth.validateAuth, groups.postAddGroup); - app.post('/groups/promote', auth.validateAuth, groups.postPromote); - app.get('/messages', auth.validateAuth, messages.getInfo); - app.get('/messages/names', auth.validateAuth, messages.getNames); - app.post('/messages', auth.validateAuth, messages.postAddMessage); - app.post('/messages/promote', auth.validateAuth, messages.postPromoteMessages); - app.post('/messages/update', auth.validateAuth, messages.postUpdate); - app.get('/module', auth.validateAuth, moduleConfig.get); - app.post('/module', auth.validateAuth, moduleConfig.post); - app.post('/module/promote', auth.validateAuth, moduleConfig.promote); - app.post('/module/promoteNoId', auth.validateAuth, moduleConfig.promoteNoId); - app.get('/about', auth.validateAuth, about.getInfo); - app.post('/security/certificate', certificates.createCertificate); - app.post('/security/private', certificates.createPrivateKey); + //route definitions + //app.post('/forgot', forgot.post); + //app.post('/register', register.post); + app.post('/login', login.validateAuth); + app.get('/applications', auth.validateAuth, applications.get); + app.post('/applications/action', auth.validateAuth, applications.actionPost); + app.post('/applications/auto', auth.validateAuth, applications.autoPost); + app.post('/applications/administrator', auth.validateAuth, applications.administratorPost); + app.post('/applications/passthrough', auth.validateAuth, applications.passthroughPost); + app.post('/applications/hybrid', auth.validateAuth, applications.hybridPost); + app.put('/applications/rpcencryption', auth.validateAuth, applications.rpcEncryptionPut); + app.put('/applications/service/permission', auth.validateAuth, applications.putServicePermission); + app.post('/applications/certificate/get', applications.getAppCertificate); + app.get('/applications/certificate/get', applications.getAppCertificate); + app.post('/applications/certificate', applications.updateAppCertificate); + app.get('/applications/groups', auth.validateAuth, applications.getFunctionalGroups); + app.put('/applications/groups', auth.validateAuth, applications.putFunctionalGroup); + // webengine app store + app.get('/applications/store', cors(), applications.getAppStore); + app.get('/applications/store/staging', cors(), applications.getStagingAppStore); + app.post('/webhook', applications.webhook); //webhook route + //begin policy table routes + app.options('/staging/policy', cors()) + app.options('/production/policy', cors()) + app.post('/staging/policy', cors(), policy.postFromCoreStaging); + app.post('/production/policy', cors(), policy.postFromCoreProduction); + app.get('/policy/preview', policy.getPreview); + app.post('/policy/apps', policy.postAppPolicy); + //end policy table routes + app.post('/permissions/update', auth.validateAuth, permissions.post); + app.get('/permissions/unmapped', auth.validateAuth, permissions.get); + app.get('/groups', auth.validateAuth, groups.get); + app.get('/groups/names', auth.validateAuth, groups.getNames); + app.post('/groups', auth.validateAuth, groups.postAddGroup); + app.post('/groups/promote', auth.validateAuth, groups.postPromote); + app.get('/messages', auth.validateAuth, messages.getInfo); + app.get('/messages/names', auth.validateAuth, messages.getNames); + app.post('/messages', auth.validateAuth, messages.postAddMessage); + app.post('/messages/promote', auth.validateAuth, messages.postPromoteMessages); + app.post('/messages/update', auth.validateAuth, messages.postUpdate); + app.get('/module', auth.validateAuth, moduleConfig.get); + app.post('/module', auth.validateAuth, moduleConfig.post); + app.post('/module/promote', auth.validateAuth, moduleConfig.promote); + app.post('/module/promoteNoId', auth.validateAuth, moduleConfig.promoteNoId); + app.get('/about', auth.validateAuth, about.getInfo); + app.post('/security/certificate', certificates.createCertificate); + app.post('/security/private', certificates.createPrivateKey); //begin vehicle data routes app.post('/vehicle-data', auth.validateAuth, vehicleData.post); app.get('/vehicle-data', auth.validateAuth, vehicleData.get); @@ -115,49 +115,49 @@ function exposeRoutes () { } async function setup () { - //do not allow routes to be exposed until these async functions are completed - await Promise.all([ - //certificate expiration check and renewal for both applications and for the module config - applications.checkAndUpdateCertificates() - .catch(err => { - log.error(err); - }), - moduleConfig.checkAndUpdateCertificate() - .catch(err => { - log.error(err); - }), - //get and store permission info from SHAID on startup - permissions.update() - .catch(err => { - log.error(err); - }), - // get and store app service type info from SHAID on startup - services.upsertTypes() - .catch(err => { - log.error(err); - }), - //get and store app categories from SHAID on startup - applications.queryAndStoreCategories() - .catch(err => { - log.error(err); - }), - //get and store language code info from the GitHub SDL RPC specification on startup - messages.updateLanguages() - .catch(err => { - log.error(err); - }), - //get and store app info from SHAID on startup - applications.queryAndStoreApplications({}, false) - .catch(err => { - log.error(err); - }), - vehicleData.updateRpcSpec() - .catch(err => { - log.error(err); - }), - ]); - log.info("Start up complete. Exposing routes."); - exposeRoutes(); + //do not allow routes to be exposed until these async functions are completed + await Promise.all([ + //certificate expiration check and renewal for both applications and for the module config + applications.checkAndUpdateCertificates() + .catch(err => { + log.error(err); + }), + moduleConfig.checkAndUpdateCertificate() + .catch(err => { + log.error(err); + }), + //get and store permission info from SHAID on startup + permissions.update() + .catch(err => { + log.error(err); + }), + // get and store app service type info from SHAID on startup + services.upsertTypes() + .catch(err => { + log.error(err); + }), + //get and store app categories from SHAID on startup + applications.queryAndStoreCategories() + .catch(err => { + log.error(err); + }), + //get and store language code info from the GitHub SDL RPC specification on startup + messages.updateLanguages() + .catch(err => { + log.error(err); + }), + //get and store app info from SHAID on startup + applications.queryAndStoreApplications({}, false) + .catch(err => { + log.error(err); + }), + vehicleData.updateRpcSpec() + .catch(err => { + log.error(err); + }), + ]); + log.info("Start up complete. Exposing routes."); + exposeRoutes(); } setup(); diff --git a/app/v1/applications/controller.js b/app/v1/applications/controller.js index db8efa14..15d0d542 100644 --- a/app/v1/applications/controller.js +++ b/app/v1/applications/controller.js @@ -8,278 +8,278 @@ const certUtil = require('../helpers/certificates.js'); const certificates = require('../certificates/controller.js'); async function get (req, res, next) { - //prioritize id, uuid, approval status, in that order. - //only one parameter can be acted upon in one request - let apps; //to be determined + //prioritize id, uuid, approval status, in that order. + //only one parameter can be acted upon in one request + let apps; //to be determined - if (req.query.id) { //filter by id - if (Number.isNaN(Number(req.query.id))) { + if (req.query.id) { //filter by id + if (Number.isNaN(Number(req.query.id))) { return res.parcel.setStatus(400).setMessage("id must be an integer").deliver(); } - apps = await helper.createAppInfoFlow('idFilter', req.query.id); - } - else if (req.query.uuid) { //filter by app uuid - apps = await helper.createAppInfoFlow('multiFilter', {app_uuid: req.query.uuid}); - } - else if (req.query.approval_status || req.query.get_blacklist) { //filter by approval status - apps = await helper.createAppInfoFlow('multiFilter', {approval_status: req.query.approval_status, get_blacklist: (req.query.get_blacklist == "true")}); - } - else { //get all applications whose information are the latest versions - apps = await helper.createAppInfoFlow('multiFilter'); - } - - //include extra certificate information if just one app is returned and if the info exists - //only if looking at a specific app and cert generation is enabled - - try { - if (apps.length === 1 && certificates.openSSLEnabled) { - const appCert = await getAppCertificateByUuid(apps[0].uuid); - const certificate = appCert.certificate; - if (certificate) { - const keyBundle = await certUtil.readKeyCertBundle(Buffer.from(certificate, 'base64')); - apps[0].certificate = keyBundle.cert; - apps[0].private_key = keyBundle.key; - } - } - - res.parcel.setStatus(200) - .setData({ - applications: apps - }) - .deliver(); - } catch (err) { - app.locals.log.error(err) - return res.parcel.setStatus(500) - .setMessage("Internal Server Error") - .deliver(); - } + apps = await helper.createAppInfoFlow('idFilter', req.query.id); + } + else if (req.query.uuid) { //filter by app uuid + apps = await helper.createAppInfoFlow('multiFilter', {app_uuid: req.query.uuid}); + } + else if (req.query.approval_status || req.query.get_blacklist) { //filter by approval status + apps = await helper.createAppInfoFlow('multiFilter', {approval_status: req.query.approval_status, get_blacklist: (req.query.get_blacklist == "true")}); + } + else { //get all applications whose information are the latest versions + apps = await helper.createAppInfoFlow('multiFilter'); + } + + //include extra certificate information if just one app is returned and if the info exists + //only if looking at a specific app and cert generation is enabled + + try { + if (apps.length === 1 && certificates.openSSLEnabled) { + const appCert = await getAppCertificateByUuid(apps[0].uuid); + const certificate = appCert.certificate; + if (certificate) { + const keyBundle = await certUtil.readKeyCertBundle(Buffer.from(certificate, 'base64')); + apps[0].certificate = keyBundle.cert; + apps[0].private_key = keyBundle.key; + } + } + + res.parcel.setStatus(200) + .setData({ + applications: apps + }) + .deliver(); + } catch (err) { + app.locals.log.error(err) + return res.parcel.setStatus(500) + .setMessage("Internal Server Error") + .deliver(); + } } //TODO: emailing system for messaging the developer about the approval status change async function actionPost (req, res, next) { - helper.validateActionPost(req, res); - helper.checkIdIntegerBody(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - await app.locals.db.asyncTransaction(async client => { - // Blacklist/Unblacklist app - if (req.body.blacklist) { - await client.getOne(sql.insertAppBlacklist(req.body)); - } else { - await client.getOne(sql.deleteAppBlacklist(req.body.uuid)); - } - - // Update approval status for app - await client.getOne(sql.changeAppApprovalStatus(req.body.id, req.body.approval_status, (req.body.denial_message || null))); - - // sync the status to SHAID - if (req.body.version_id) { - await app.locals.shaid.setApplicationApprovalVendor([{ - "uuid": req.body.uuid, - "blacklist": req.body.blacklist || false, - "version_id": req.body.version_id, - "approval_status": req.body.approval_status, - "notes": req.body.denial_message || null - }]); - } - // skip notifying SHAID if there is no version ID (legacy support) - }).then(() => { - res.parcel.setStatus(200).deliver(); - }).catch(err => { - app.locals.log.error(err); - res.parcel.setStatus(500).deliver(); - }); + helper.validateActionPost(req, res); + helper.checkIdIntegerBody(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + await app.locals.db.asyncTransaction(async client => { + // Blacklist/Unblacklist app + if (req.body.blacklist) { + await client.getOne(sql.insertAppBlacklist(req.body)); + } else { + await client.getOne(sql.deleteAppBlacklist(req.body.uuid)); + } + + // Update approval status for app + await client.getOne(sql.changeAppApprovalStatus(req.body.id, req.body.approval_status, (req.body.denial_message || null))); + + // sync the status to SHAID + if (req.body.version_id) { + await app.locals.shaid.setApplicationApprovalVendor([{ + "uuid": req.body.uuid, + "blacklist": req.body.blacklist || false, + "version_id": req.body.version_id, + "approval_status": req.body.approval_status, + "notes": req.body.denial_message || null + }]); + } + // skip notifying SHAID if there is no version ID (legacy support) + }).then(() => { + res.parcel.setStatus(200).deliver(); + }).catch(err => { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + }); } async function hybridPost (req, res, next) { - helper.validateHybridPost(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - await app.locals.db.asyncTransaction(async client => { - const result = await client.getOne(sql.getApp.base['uuidFilter'](req.body.uuid)); - if (!result) { - throw new Error("Unknown app"); - } - await client.getOne(sql.deleteHybridPreference(req.body.uuid)); - await client.getOne(sql.insertHybridPreference(req.body)); - - }).then(() => { - res.parcel.setStatus(200).deliver(); - }).catch(err => { - app.locals.log.error(err); - res.parcel.setStatus(500).deliver(); - }); + helper.validateHybridPost(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + await app.locals.db.asyncTransaction(async client => { + const result = await client.getOne(sql.getApp.base['uuidFilter'](req.body.uuid)); + if (!result) { + throw new Error("Unknown app"); + } + await client.getOne(sql.deleteHybridPreference(req.body.uuid)); + await client.getOne(sql.insertHybridPreference(req.body)); + + }).then(() => { + res.parcel.setStatus(200).deliver(); + }).catch(err => { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + }); } async function rpcEncryptionPut (req, res, next) { - helper.validateRPCEncryptionPut(req, res); - helper.checkIdIntegerBody(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - await app.locals.db.asyncTransaction(async client => { - const result = await client.getOne(sql.getApp.base['idFilter'](req.body.id)); - if (!result) { - throw new Error("Unknown app"); - } - await client.getOne(sql.updateRPCEncryption(req.body)); - }).then(() => { - res.parcel.setStatus(200).deliver(); - }).catch(err => { - app.locals.log.error(err); - res.parcel.setStatus(500).deliver(); - }); + helper.validateRPCEncryptionPut(req, res); + helper.checkIdIntegerBody(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + await app.locals.db.asyncTransaction(async client => { + const result = await client.getOne(sql.getApp.base['idFilter'](req.body.id)); + if (!result) { + throw new Error("Unknown app"); + } + await client.getOne(sql.updateRPCEncryption(req.body)); + }).then(() => { + res.parcel.setStatus(200).deliver(); + }).catch(err => { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + }); } async function autoPost (req, res, next) { - helper.validateAutoPost(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - try { - const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); - if (!results.length) { - return res.parcel.setStatus(400).deliver(); - } - if (req.body.is_auto_approved_enabled) { - await app.locals.db.asyncSql(sql.insertAppAutoApproval(req.body)); - } else { - await app.locals.db.asyncSql(sql.deleteAutoApproval(req.body.uuid)); - } - res.parcel.setStatus(200).deliver(); - } catch (err) { - res.parcel.setStatus(500).deliver(); - } + helper.validateAutoPost(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); + if (!results.length) { + return res.parcel.setStatus(400).deliver(); + } + if (req.body.is_auto_approved_enabled) { + await app.locals.db.asyncSql(sql.insertAppAutoApproval(req.body)); + } else { + await app.locals.db.asyncSql(sql.deleteAutoApproval(req.body.uuid)); + } + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } async function administratorPost (req, res, next) { - helper.validateAdministratorPost(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - try { - const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); - if (!results.length) { - return res.parcel.setStatus(400).deliver(); - } - if (req.body.is_administrator_app) { - await app.locals.db.asyncSql(sql.insertAppAdministrator(req.body)); - } else { - await app.locals.db.asyncSql(sql.deleteAppAdministrator(req.body.uuid)); - } - res.parcel.setStatus(200).deliver(); - } catch (err) { - res.parcel.setStatus(500).deliver(); - } + helper.validateAdministratorPost(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); + if (!results.length) { + return res.parcel.setStatus(400).deliver(); + } + if (req.body.is_administrator_app) { + await app.locals.db.asyncSql(sql.insertAppAdministrator(req.body)); + } else { + await app.locals.db.asyncSql(sql.deleteAppAdministrator(req.body.uuid)); + } + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } async function passthroughPost (req, res, next) { - helper.validatePassthroughPost(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - try { - const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); - if (!results.length) { - return res.parcel.setStatus(400).deliver(); - } - if (req.body.allow_unknown_rpc_passthrough) { - await app.locals.db.asyncSql(sql.insertPassthrough(req.body)); - } else { - await app.locals.db.asyncSql(sql.deletePassthrough(req.body.uuid)); - } - res.parcel.setStatus(200).deliver(); - } catch (err) { - res.parcel.setStatus(500).deliver(); - } + helper.validatePassthroughPost(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.uuid)); + if (!results.length) { + return res.parcel.setStatus(400).deliver(); + } + if (req.body.allow_unknown_rpc_passthrough) { + await app.locals.db.asyncSql(sql.insertPassthrough(req.body)); + } else { + await app.locals.db.asyncSql(sql.deletePassthrough(req.body.uuid)); + } + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } async function putServicePermission (req, res, next) { - helper.validateServicePermissionPut(req, res); - helper.checkIdIntegerBody(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - try { - const results = await app.locals.db.asyncSql(sql.getApp.base['idFilter'](req.body.id)); - if (!results.length) { - return res.parcel.setStatus(400).deliver(); - } - if (results[0].approval_status == "ACCEPTED") { - return res.parcel - .setStatus(400) - .setMessage("You may not modify the app service permissions of a production application.") - .deliver(); - } - - if (req.body.is_selected) { - await app.locals.db.asyncSql(sql.insertAppServicePermission(req.body)); - } else { - await app.locals.db.asyncSql(sql.deleteAppServicePermission(req.body)); - } - res.parcel.setStatus(200).deliver(); - } catch (err) { - res.parcel.setStatus(500).deliver(); - } + helper.validateServicePermissionPut(req, res); + helper.checkIdIntegerBody(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['idFilter'](req.body.id)); + if (!results.length) { + return res.parcel.setStatus(400).deliver(); + } + if (results[0].approval_status == "ACCEPTED") { + return res.parcel + .setStatus(400) + .setMessage("You may not modify the app service permissions of a production application.") + .deliver(); + } + + if (req.body.is_selected) { + await app.locals.db.asyncSql(sql.insertAppServicePermission(req.body)); + } else { + await app.locals.db.asyncSql(sql.deleteAppServicePermission(req.body)); + } + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } async function getFunctionalGroups (req, res, next) { - try { - const results = await app.locals.db.asyncSql(sql.getAppFunctionalGroups(req.query)); - res.parcel - .setStatus(200) - .setData({ - "groups": results - }) - .deliver(); - } catch (err) { - req.app.locals.log.error(err); - res.parcel - .setStatus(500) - .deliver(); - } + try { + const results = await app.locals.db.asyncSql(sql.getAppFunctionalGroups(req.query)); + res.parcel + .setStatus(200) + .setData({ + "groups": results + }) + .deliver(); + } catch (err) { + req.app.locals.log.error(err); + res.parcel + .setStatus(500) + .deliver(); + } } async function putFunctionalGroup (req, res, next) { - helper.validateFunctionalGroupPut(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } - - try { - const results = await app.locals.db.asyncSql(sql.getApp.base['idFilter'](req.body.app_id)); - if (!results.length) { - return res.parcel - .setStatus(400) - .setMessage("Invalid app.") - .deliver(); - } - if (results[0].approval_status == "ACCEPTED") { - return res.parcel - .setStatus(400) - .setMessage("You may not modify the functional group grants of a production application.") - .deliver(); - } - - if (req.body.is_selected) { - await app.locals.db.asyncSql(sql.insertAppFunctionalGroup(req.body)); - } else { - await app.locals.db.asyncSql(sql.deleteAppFunctionalGroup(req.body)); - } - - res.parcel.setStatus(200).deliver(); - } catch (err) { - res.parcel.setStatus(500).deliver(); - } + helper.validateFunctionalGroupPut(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } + + try { + const results = await app.locals.db.asyncSql(sql.getApp.base['idFilter'](req.body.app_id)); + if (!results.length) { + return res.parcel + .setStatus(400) + .setMessage("Invalid app.") + .deliver(); + } + if (results[0].approval_status == "ACCEPTED") { + return res.parcel + .setStatus(400) + .setMessage("You may not modify the functional group grants of a production application.") + .deliver(); + } + + if (req.body.is_selected) { + await app.locals.db.asyncSql(sql.insertAppFunctionalGroup(req.body)); + } else { + await app.locals.db.asyncSql(sql.deleteAppFunctionalGroup(req.body)); + } + + res.parcel.setStatus(200).deliver(); + } catch (err) { + res.parcel.setStatus(500).deliver(); + } } //expects a POST from SHAID @@ -290,38 +290,38 @@ async function webhook (req, res, next) { } try { - if (req.body.entity == "application") { - const query = { - "uuid": req.body.uuid, - "include_deleted": true, - "include_blacklisted": true - }; - - switch(req.body.action){ - case "UPSERT": - await queryAndStoreApplications(query, true); - break; - case "DELETE": - await app.locals.db.asyncSql(sql.purgeAppInfo(query)); - break; - case "BLACKLIST": - await app.locals.db.asyncSql(sql.insertAppBlacklist(query)); - break; - default: - } - } + if (req.body.entity == "application") { + const query = { + "uuid": req.body.uuid, + "include_deleted": true, + "include_blacklisted": true + }; + + switch(req.body.action){ + case "UPSERT": + await queryAndStoreApplications(query, true); + break; + case "DELETE": + await app.locals.db.asyncSql(sql.purgeAppInfo(query)); + break; + case "BLACKLIST": + await app.locals.db.asyncSql(sql.insertAppBlacklist(query)); + break; + default: + } + } } catch (err) { - req.app.locals.log.error(err); + req.app.locals.log.error(err); } - res.parcel.setStatus(200); - res.parcel.deliver(); + res.parcel.setStatus(200); + res.parcel.deliver(); } //queries SHAID to get applications and stores them into the database async function queryAndStoreApplications (queryObj, notifyOEM = true) { - const apps = await app.locals.shaid.getApplications(queryObj); - await helper.storeApps(false, notifyOEM, apps); + const apps = await app.locals.shaid.getApplications(queryObj); + await helper.storeApps(false, notifyOEM, apps); } //helper function that attempts to find the associated certificate bundle in the database @@ -350,8 +350,8 @@ async function getAppCertificate (req, res, next) { } try { - const appCert = await getAppCertificateByUuid(app_uuid); - if (!appCert.certificate) { + const appCert = await getAppCertificateByUuid(app_uuid); + if (!appCert.certificate) { return res.parcel.setStatus(400) .setMessage('Could not find certificate for app with that id') .deliver(); @@ -360,17 +360,17 @@ async function getAppCertificate (req, res, next) { const currentDate = moment.utc(); if (moment(expirationDate).isBefore(currentDate)) { - return res.parcel.setStatus(500) + return res.parcel.setStatus(500) .setMessage('App certificate is expired') .deliver(); } else { - res.parcel.setStatus(200) - .setData({ 'certificate': appCert.certificate }) - .deliver(); + res.parcel.setStatus(200) + .setData({ 'certificate': appCert.certificate }) + .deliver(); } } catch (err) { - app.locals.log.error(err); + app.locals.log.error(err); res.parcel.setStatus(500).deliver(); } } @@ -382,107 +382,107 @@ async function updateAppCertificate (req, res, next) { .deliver(); } - helper.validateUpdateAppCertificate(req, res); + helper.validateUpdateAppCertificate(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } + if (res.parcel.message) { + return res.parcel.deliver(); + } //make sure the passed in app uuid exists in the db try { - const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.options.app_uuid)); - if (!results.length) { - return res.parcel - .setStatus(400) - .setMessage("Invalid app.") - .deliver(); - } - - //valid app uuid. continue - const keyCertBundle = await certUtil.createKeyCertBundle(req.body.options.clientKey, req.body.options.certificate); - await model.updateAppCertificate(req.body.options.app_uuid, keyCertBundle); - res.parcel.setStatus(200).deliver(); + const results = await app.locals.db.asyncSql(sql.getApp.base['uuidFilter'](req.body.options.app_uuid)); + if (!results.length) { + return res.parcel + .setStatus(400) + .setMessage("Invalid app.") + .deliver(); + } + + //valid app uuid. continue + const keyCertBundle = await certUtil.createKeyCertBundle(req.body.options.clientKey, req.body.options.certificate); + await model.updateAppCertificate(req.body.options.app_uuid, keyCertBundle); + res.parcel.setStatus(200).deliver(); } catch (err) { - app.locals.log.error(err); - res.parcel.setStatus(500).deliver(); + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); } } async function checkAndUpdateCertificates () { - if (!certificates.openSSLEnabled) { - return; - } - - const expiredCertObjs = await app.locals.db.asyncSql(sql.getApp.allExpiredCertificates()) - - let failedApps = []; - - for (let expiredCertObj of expiredCertObjs) { - await certUtil.readKeyCertBundle(Buffer.from((expiredCertObj.certificate || ""), 'base64')) - .then(keyBundle => { - app.locals.log.info("creating new cert for app with existing key"); - failedApps.push({ - app_uuid: expiredCertObj.app_uuid, - private_key: keyBundle.key - }); - }) - .catch(pkcsErr => { - app.locals.log.info("creating new key and cert for app"); - failedApps.push({ - app_uuid: expiredCertObj.app_uuid, - }); - }); - } - - //create new certificates for the failed apps and save them - const results = await Promise.all(failedApps.map(helper.createFailedAppsCert)); - - await helper.storeAppCertificates(results); + if (!certificates.openSSLEnabled) { + return; + } + + const expiredCertObjs = await app.locals.db.asyncSql(sql.getApp.allExpiredCertificates()) + + let failedApps = []; + + for (let expiredCertObj of expiredCertObjs) { + await certUtil.readKeyCertBundle(Buffer.from((expiredCertObj.certificate || ""), 'base64')) + .then(keyBundle => { + app.locals.log.info("creating new cert for app with existing key"); + failedApps.push({ + app_uuid: expiredCertObj.app_uuid, + private_key: keyBundle.key + }); + }) + .catch(pkcsErr => { + app.locals.log.info("creating new key and cert for app"); + failedApps.push({ + app_uuid: expiredCertObj.app_uuid, + }); + }); + } + + //create new certificates for the failed apps and save them + const results = await Promise.all(failedApps.map(helper.createFailedAppsCert)); + + await helper.storeAppCertificates(results); } /** * queries SHAID to get new categories and stores them into the database */ async function queryAndStoreCategories () { - const categories = await app.locals.shaid.getCategories({}); - await helper.storeCategories(categories); - app.locals.log.info("App categories sync complete."); + const categories = await app.locals.shaid.getCategories({}); + await helper.storeCategories(categories); + app.locals.log.info("App categories sync complete."); } async function getStagingAppStore (req, res, next) { - let filterObj = { - approval_status: 'STAGING', - platform: 'EMBEDDED', - }; - - if (req.query.uuid) { - filterObj.app_uuid = req.query.uuid; - } - if (req.query.transport_type) { - filterObj.transport_type = req.query.transport_type; - } - - try { - const appInfo = await helper.createAppInfoFlow('multiFilter', filterObj); - const apps = helper.appStoreTransformation(req.query.min_rpc_version, req.query.min_protocol_version, appInfo); - - res.parcel.setStatus(200) - .setData({ - applications: apps, - }) - .deliver(); - } catch (err) { - app.locals.log.error(err); - res.parcel.setStatus(500).deliver(); - } + let filterObj = { + approval_status: 'STAGING', + platform: 'EMBEDDED', + }; + + if (req.query.uuid) { + filterObj.app_uuid = req.query.uuid; + } + if (req.query.transport_type) { + filterObj.transport_type = req.query.transport_type; + } + + try { + const appInfo = await helper.createAppInfoFlow('multiFilter', filterObj); + const apps = helper.appStoreTransformation(req.query.min_rpc_version, req.query.min_protocol_version, appInfo); + + res.parcel.setStatus(200) + .setData({ + applications: apps, + }) + .deliver(); + } catch (err) { + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); + } } async function getAppStore (req, res, next) { // only let embedded apps through - let filterObj = { - approval_status: 'ACCEPTED', + let filterObj = { + approval_status: 'ACCEPTED', platform: 'EMBEDDED', - }; + }; if (req.query.uuid) { //filter by app uuid filterObj.app_uuid = req.query.uuid; @@ -492,37 +492,37 @@ async function getAppStore (req, res, next) { } try { - const appInfo = await helper.createAppInfoFlow('multiFilter', filterObj); - const apps = helper.appStoreTransformation(req.query.min_rpc_version, req.query.min_protocol_version, appInfo); - - res.parcel.setStatus(200) - .setData({ - applications: apps - }) - .deliver(); + const appInfo = await helper.createAppInfoFlow('multiFilter', filterObj); + const apps = helper.appStoreTransformation(req.query.min_rpc_version, req.query.min_protocol_version, appInfo); + + res.parcel.setStatus(200) + .setData({ + applications: apps + }) + .deliver(); } catch (err) { - app.locals.log.error(err); - res.parcel.setStatus(500).deliver(); + app.locals.log.error(err); + res.parcel.setStatus(500).deliver(); } } module.exports = { - get: get, - actionPost: actionPost, - putServicePermission: putServicePermission, - autoPost: autoPost, - administratorPost: administratorPost, - passthroughPost: passthroughPost, - rpcEncryptionPut: rpcEncryptionPut, - hybridPost: hybridPost, - getFunctionalGroups: getFunctionalGroups, - putFunctionalGroup: putFunctionalGroup, - webhook: webhook, - queryAndStoreApplications: queryAndStoreApplications, - queryAndStoreCategories: queryAndStoreCategories, - getAppCertificate: getAppCertificate, - updateAppCertificate: updateAppCertificate, - checkAndUpdateCertificates: checkAndUpdateCertificates, - getAppStore: getAppStore, - getStagingAppStore: getStagingAppStore, + get: get, + actionPost: actionPost, + putServicePermission: putServicePermission, + autoPost: autoPost, + administratorPost: administratorPost, + passthroughPost: passthroughPost, + rpcEncryptionPut: rpcEncryptionPut, + hybridPost: hybridPost, + getFunctionalGroups: getFunctionalGroups, + putFunctionalGroup: putFunctionalGroup, + webhook: webhook, + queryAndStoreApplications: queryAndStoreApplications, + queryAndStoreCategories: queryAndStoreCategories, + getAppCertificate: getAppCertificate, + updateAppCertificate: updateAppCertificate, + checkAndUpdateCertificates: checkAndUpdateCertificates, + getAppStore: getAppStore, + getStagingAppStore: getStagingAppStore, }; diff --git a/app/v1/applications/helper.js b/app/v1/applications/helper.js index 2bff17d7..4aeef7cb 100644 --- a/app/v1/applications/helper.js +++ b/app/v1/applications/helper.js @@ -18,63 +18,63 @@ function checkIdIntegerBody (req, res) { } function validateActionPost (req, res) { - if (!req.body.id || !req.body.approval_status) { - res.parcel.setStatus(400).setMessage("Id and approval status required"); - } else if (req.body.approval_status !== 'PENDING' - && req.body.approval_status !== 'STAGING' + if (!req.body.id || !req.body.approval_status) { + res.parcel.setStatus(400).setMessage("Id and approval status required"); + } else if (req.body.approval_status !== 'PENDING' + && req.body.approval_status !== 'STAGING' && req.body.approval_status !== 'ACCEPTED' - && req.body.approval_status !== 'LIMITED') { - res.parcel.setStatus(400).setMessage("Invalid approval status value"); - } - return; + && req.body.approval_status !== 'LIMITED') { + res.parcel.setStatus(400).setMessage("Invalid approval status value"); + } + return; } function validateServicePermissionPut (req, res) { - if (!req.body.id || !check.boolean(req.body.is_selected) || !check.string(req.body.service_type_name) || !check.string(req.body.permission_name)) { - res.parcel.setStatus(400).setMessage("id, is_selected, service_type_name, and permission_name are required"); - } + if (!req.body.id || !check.boolean(req.body.is_selected) || !check.string(req.body.service_type_name) || !check.string(req.body.permission_name)) { + res.parcel.setStatus(400).setMessage("id, is_selected, service_type_name, and permission_name are required"); + } return; } function validateFunctionalGroupPut (req, res) { - if (!req.body.app_id || !check.boolean(req.body.is_selected) || !check.string(req.body.property_name)) { - res.parcel.setStatus(400).setMessage("app_id, is_selected, and property_name are required"); - } + if (!req.body.app_id || !check.boolean(req.body.is_selected) || !check.string(req.body.property_name)) { + res.parcel.setStatus(400).setMessage("app_id, is_selected, and property_name are required"); + } return; } function validateHybridPost (req, res) { - if (!check.string(req.body.uuid) || !check.includes(["CLOUD","MOBILE","BOTH"], req.body.hybrid_preference)) { - res.parcel.setStatus(400).setMessage("uuid and a valid hybrid_preference are required"); - } + if (!check.string(req.body.uuid) || !check.includes(["CLOUD","MOBILE","BOTH"], req.body.hybrid_preference)) { + res.parcel.setStatus(400).setMessage("uuid and a valid hybrid_preference are required"); + } return; } function validateAutoPost (req, res) { - if (!check.string(req.body.uuid) || !check.boolean(req.body.is_auto_approved_enabled)) { - res.parcel.setStatus(400).setMessage("Uuid and auto approved required"); - } + if (!check.string(req.body.uuid) || !check.boolean(req.body.is_auto_approved_enabled)) { + res.parcel.setStatus(400).setMessage("Uuid and auto approved required"); + } return; } function validateRPCEncryptionPut (req, res) { - if (!req.body.id || !check.boolean(req.body.encryption_required)) { - res.parcel.setStatus(400).setMessage("id and encryption_required required"); - } + if (!req.body.id || !check.boolean(req.body.encryption_required)) { + res.parcel.setStatus(400).setMessage("id and encryption_required required"); + } return; } function validateAdministratorPost (req, res) { - if (!check.string(req.body.uuid) || !check.boolean(req.body.is_administrator_app)) { - res.parcel.setStatus(400).setMessage("uuid and is_administrator_app required"); - } + if (!check.string(req.body.uuid) || !check.boolean(req.body.is_administrator_app)) { + res.parcel.setStatus(400).setMessage("uuid and is_administrator_app required"); + } return; } function validatePassthroughPost (req, res) { - if (!check.string(req.body.uuid) || !check.boolean(req.body.allow_unknown_rpc_passthrough)) { - res.parcel.setStatus(400).setMessage("uuid and allow_unknown_rpc_passthrough required"); - } + if (!check.string(req.body.uuid) || !check.boolean(req.body.allow_unknown_rpc_passthrough)) { + res.parcel.setStatus(400).setMessage("uuid and allow_unknown_rpc_passthrough required"); + } return; } @@ -90,39 +90,39 @@ function validateUpdateAppCertificate (req, res) { } function validateWebHook (req, res) { - if(req.headers["public_key"] != app.locals.config.shaidPublicKey){ - // request cannot be verified as authentic + if(req.headers["public_key"] != app.locals.config.shaidPublicKey){ + // request cannot be verified as authentic res.parcel.setStatus(401).setMessage("Unable to validate webhook with SHAID public key"); - } - return; + } + return; } //helper functions //gets back app information depending on the filters passed in async function createAppInfoFlow (filterTypeFunc, value) { - const getAppObj = { - appBase: asyncSql(sql.getApp.base[filterTypeFunc](value)), - appCountries: asyncSql(sql.getApp.countries[filterTypeFunc](value)), - appDisplayNames: asyncSql(sql.getApp.displayNames[filterTypeFunc](value)), - appPermissions: asyncSql(sql.getApp.permissions[filterTypeFunc](value)), + const getAppObj = { + appBase: asyncSql(sql.getApp.base[filterTypeFunc](value)), + appCountries: asyncSql(sql.getApp.countries[filterTypeFunc](value)), + appDisplayNames: asyncSql(sql.getApp.displayNames[filterTypeFunc](value)), + appPermissions: asyncSql(sql.getApp.permissions[filterTypeFunc](value)), appCategories: asyncSql(sql.getApp.category[filterTypeFunc](value)), - appAllCategories: asyncSql(sql.getApp.allCategories[filterTypeFunc](value)), - appServiceTypes: asyncSql(sql.getApp.serviceTypes[filterTypeFunc](value)), - appServiceTypeNames: asyncSql(sql.getApp.serviceTypeNames[filterTypeFunc](value)), - appServiceTypePermissions: asyncSql(sql.getApp.serviceTypePermissions[filterTypeFunc](value)), - appAutoApprovals: asyncSql(sql.getApp.autoApproval[filterTypeFunc](value)), - appBlacklist: asyncSql(sql.getApp.blacklist[filterTypeFunc](value)), - appAdministrators: asyncSql(sql.getApp.administrators[filterTypeFunc](value)), - appHybridPreference: asyncSql(sql.getApp.hybridPreference[filterTypeFunc](value)), - appPassthrough: asyncSql(sql.getApp.passthrough[filterTypeFunc](value)) - }; + appAllCategories: asyncSql(sql.getApp.allCategories[filterTypeFunc](value)), + appServiceTypes: asyncSql(sql.getApp.serviceTypes[filterTypeFunc](value)), + appServiceTypeNames: asyncSql(sql.getApp.serviceTypeNames[filterTypeFunc](value)), + appServiceTypePermissions: asyncSql(sql.getApp.serviceTypePermissions[filterTypeFunc](value)), + appAutoApprovals: asyncSql(sql.getApp.autoApproval[filterTypeFunc](value)), + appBlacklist: asyncSql(sql.getApp.blacklist[filterTypeFunc](value)), + appAdministrators: asyncSql(sql.getApp.administrators[filterTypeFunc](value)), + appHybridPreference: asyncSql(sql.getApp.hybridPreference[filterTypeFunc](value)), + appPassthrough: asyncSql(sql.getApp.passthrough[filterTypeFunc](value)) + }; for (let prop in getAppObj) { getAppObj[prop] = await getAppObj[prop]; // resolve all promises into each property } - return model.constructFullAppObjs(getAppObj); + return model.constructFullAppObjs(getAppObj); } async function storeCategories (categories) { @@ -158,30 +158,30 @@ async function storeApps (includeApprovalStatus, notifyOEM, apps, callback) { //determine whether the object needs to be deleted or stored in the database async function checkNeedsInsertionOrDeletion (appObj) { - if (appObj.deleted_ts) { - // delete! + if (appObj.deleted_ts) { + // delete! await db.asyncSql(sql.purgeAppInfo(appObj)); // delete attempt made, skip it! return null; - } else if (appObj.blacklisted_ts) { - // blacklist! - await db.asyncSql(sql.insertAppBlacklist(appObj)); - // blacklist attempt made, skip it! + } else if (appObj.blacklisted_ts) { + // blacklist! + await db.asyncSql(sql.insertAppBlacklist(appObj)); + // blacklist attempt made, skip it! return null; - } else { - // check if the version exists in the database before attempting insertion - const getObjStr = sql.versionCheck('app_info', { - app_uuid: appObj.uuid, - version_id: appObj.version_id - }); - const data = await db.asyncSql(getObjStr); - if (data.length > 0) { - // record exists, skip it! - return null; - } else { - return appObj; - } - } + } else { + // check if the version exists in the database before attempting insertion + const getObjStr = sql.versionCheck('app_info', { + app_uuid: appObj.uuid, + version_id: appObj.version_id + }); + const data = await db.asyncSql(getObjStr); + if (data.length > 0) { + // record exists, skip it! + return null; + } else { + return appObj; + } + } } //any elements that are null are removed @@ -203,31 +203,31 @@ async function filterApps (includeApprovalStatus, appObjs) { //auto changes any app's approval status to ACCEPTED if a record was found for that app's uuid in the auto approval table async function autoApprovalModifier (appObj) { - // check if auto-approve *all apps* is enabled - if (config.autoApproveAllApps) { - appObj.approval_status = 'ACCEPTED'; - appObj.encryption_required = config.autoApproveSetRPCEncryption; - return appObj; - } - - // check if auto-approve this specific app is enabled + // check if auto-approve *all apps* is enabled + if (config.autoApproveAllApps) { + appObj.approval_status = 'ACCEPTED'; + appObj.encryption_required = config.autoApproveSetRPCEncryption; + return appObj; + } + + // check if auto-approve this specific app is enabled const res = await db.asyncSql(sql.checkAutoApproval(appObj.uuid)); //if res is not an empty array, then a record was found in the app_auto_approval table //change the status of this appObj to ACCEPTED if (res.length > 0) { appObj.approval_status = 'ACCEPTED'; - appObj.encryption_required = config.autoApproveSetRPCEncryption; + appObj.encryption_required = config.autoApproveSetRPCEncryption; } return appObj; } // Auto deny new application versions of an app that is blacklisted async function autoBlacklistModifier (appObj) { - const res = await db.asyncSql(sql.getBlacklistedAppFullUuids(appObj.uuid)); + const res = await db.asyncSql(sql.getBlacklistedAppFullUuids(appObj.uuid)); - if (res.length > 0) { - appObj.approval_status = 'LIMITED'; - } + if (res.length > 0) { + appObj.approval_status = 'LIMITED'; + } return appObj; } @@ -289,12 +289,12 @@ async function storeAppCertificates (insertObjs) { } async function createFailedAppsCert (failedApp, next) { - let options = certificates.getCertificateOptions({ - serialNumber: failedApp.app_uuid, - clientKey: failedApp.private_key - }); + let options = certificates.getCertificateOptions({ + serialNumber: failedApp.app_uuid, + clientKey: failedApp.private_key + }); - const keyBundle = await certificates.asyncCreateCertificate(options); + const keyBundle = await certificates.asyncCreateCertificate(options); const keyCertBundle = await certUtil.createKeyCertBundle(keyBundle.clientKey, keyBundle.certificate); diff --git a/app/v1/forgot/controller.js b/app/v1/forgot/controller.js index 686b51b3..0848d42b 100644 --- a/app/v1/forgot/controller.js +++ b/app/v1/forgot/controller.js @@ -1,25 +1,25 @@ function post (req, res, next) { - validatePost(req, res); - if (res.parcel.message) { - res.parcel.deliver(); - return; - } + validatePost(req, res); + if (res.parcel.message) { + res.parcel.deliver(); + return; + } - //TODO: STUB - res.parcel - .setStatus(200) - .deliver(); + //TODO: STUB + res.parcel + .setStatus(200) + .deliver(); } function validatePost (req, res) { - if (!req.body.email) { - res.parcel - .setStatus(400) - .setMessage("Email required"); - } - return; + if (!req.body.email) { + res.parcel + .setStatus(400) + .setMessage("Email required"); + } + return; } module.exports = { - post: post + post: post }; \ No newline at end of file diff --git a/app/v1/groups/helper.js b/app/v1/groups/helper.js index 2fea808d..7effd37c 100644 --- a/app/v1/groups/helper.js +++ b/app/v1/groups/helper.js @@ -126,10 +126,10 @@ async function getGroupNamesStaging () { } module.exports = { - createFuncGroupFlow: createFuncGroupFlow, - validatePromote: validatePromote, - validatePromptExistence: validatePromptExistence, - validateFuncGroup: validateFuncGroup, + createFuncGroupFlow: createFuncGroupFlow, + validatePromote: validatePromote, + validatePromptExistence: validatePromptExistence, + validateFuncGroup: validateFuncGroup, getGroupNamesStaging: getGroupNamesStaging, generateFunctionGroupTemplates: generateFunctionGroupTemplates } \ No newline at end of file diff --git a/app/v1/login/controller.js b/app/v1/login/controller.js index 6edd7735..7850b63a 100644 --- a/app/v1/login/controller.js +++ b/app/v1/login/controller.js @@ -2,15 +2,15 @@ const settings = require('../../../settings.js'); // validates authentication based on the server's defined authentication settings function validateAuth (req, res) { - if(!settings.authType - || (settings.authType == "basic" && req.body.password == settings.basicAuthPassword)){ - res.parcel.setStatus(200); - }else{ - res.parcel.setStatus(401); - } - res.parcel.deliver(); + if(!settings.authType + || (settings.authType == "basic" && req.body.password == settings.basicAuthPassword)){ + res.parcel.setStatus(200); + }else{ + res.parcel.setStatus(401); + } + res.parcel.deliver(); } module.exports = { - validateAuth: validateAuth + validateAuth: validateAuth }; \ No newline at end of file diff --git a/app/v1/messages/controller.js b/app/v1/messages/controller.js index 9440f095..9ba47a70 100644 --- a/app/v1/messages/controller.js +++ b/app/v1/messages/controller.js @@ -61,8 +61,8 @@ async function postStaging (req, res, next) { async function promoteIds (req, res, next) { helper.validatePromote(req, res); if (res.parcel.message) { - return res.parcel.deliver(); - } + return res.parcel.deliver(); + } //make sure the data in id is an array in the end if (check.number(req.body.id)) { req.body.id = [req.body.id]; diff --git a/app/v1/middleware/auth.js b/app/v1/middleware/auth.js index efbd1a0c..b8af124c 100644 --- a/app/v1/middleware/auth.js +++ b/app/v1/middleware/auth.js @@ -1,17 +1,17 @@ const settings = require('../../../settings.js'); function validateAuth (req, res, next) { - if(settings.authType == "basic" && settings.basicAuthPassword - && req.get("BASIC-AUTH-PASSWORD") != settings.basicAuthPassword){ - res.parcel.setStatus(401) - .setMessage("Invalid basic authentication password") - .deliver(); - return; - }else{ - next(); - } + if(settings.authType == "basic" && settings.basicAuthPassword + && req.get("BASIC-AUTH-PASSWORD") != settings.basicAuthPassword){ + res.parcel.setStatus(401) + .setMessage("Invalid basic authentication password") + .deliver(); + return; + }else{ + next(); + } } module.exports = { - validateAuth: validateAuth + validateAuth: validateAuth }; \ No newline at end of file diff --git a/app/v1/policy/controller.js b/app/v1/policy/controller.js index 0404aea4..8b12ae37 100644 --- a/app/v1/policy/controller.js +++ b/app/v1/policy/controller.js @@ -5,7 +5,7 @@ const encryption = require('../../../customizable/encryption'); const GET = require('lodash').get; function postFromCore (isProduction) { - return async function (req, res, next) { + return async function (req, res, next) { // attempt decryption of the policy table if it's defined try { const policy_table = await new Promise(resolve => { @@ -26,7 +26,7 @@ function postFromCore (isProduction) { app.locals.log.error(err); return res.parcel.setStatus(500).deliver(); } - } + } } async function getPreview (req, res, next) { @@ -44,7 +44,7 @@ async function getPreview (req, res, next) { async function postAppPolicy (req, res, next) { const isProduction = !req.query.environment || req.query.environment.toLowerCase() !== 'staging'; - const useLongUuids = GET(req, "body.policy_table.module_config.full_app_id_supported", false) ? true : false; + const useLongUuids = GET(req, "body.policy_table.module_config.full_app_id_supported", false) ? true : false; helper.validateAppPolicyOnlyPost(req, res); if (res.errorMsg) { return res.status(400).send({ error: res.errorMsg }); @@ -61,7 +61,7 @@ async function postAppPolicy (req, res, next) { } function createPolicyTableResponse (res, isProduction, pieces, returnPreview = false) { - const policy_table = [ + const policy_table = [ { policy_table: { module_config: pieces.moduleConfig, diff --git a/app/v1/register/controller.js b/app/v1/register/controller.js index e046d9a8..69213a90 100644 --- a/app/v1/register/controller.js +++ b/app/v1/register/controller.js @@ -1,28 +1,28 @@ function post (req, res, next) { - validatePost(req, res); - if (res.parcel.message) { - return res.parcel.deliver(); - } + validatePost(req, res); + if (res.parcel.message) { + return res.parcel.deliver(); + } - //TODO: STUB - const response = { - token: "12345678" - } - res.parcel - .setStatus(200) - .setData(response) - .deliver(); + //TODO: STUB + const response = { + token: "12345678" + } + res.parcel + .setStatus(200) + .setData(response) + .deliver(); } function validatePost (req, res) { - if (!req.body.email || !req.body.password || !req.body.new_password_1 || !req.body.new_password_2) { - res.parcel - .setStatus(400) - .setMessage("Invalid credentials"); - } - return; + if (!req.body.email || !req.body.password || !req.body.new_password_1 || !req.body.new_password_2) { + res.parcel + .setStatus(400) + .setMessage("Invalid credentials"); + } + return; } module.exports = { - post: post + post: post }; \ No newline at end of file diff --git a/app/v1/static/emails/app_pending_review.html b/app/v1/static/emails/app_pending_review.html index 283f692b..84d1a0ab 100644 --- a/app/v1/static/emails/app_pending_review.html +++ b/app/v1/static/emails/app_pending_review.html @@ -148,22 +148,22 @@ display:block !important; } - } @media only screen and (max-width: 510px){ + } @media only screen and (max-width: 510px){ .w-sm-full{ width:100% !important; } - } @media only screen and (max-width: 550px){ + } @media only screen and (max-width: 550px){ .w-med-full{ width:100% !important; } - } @media only screen and (max-width: 510px){ + } @media only screen and (max-width: 510px){ .w-sm-80{ width:80% !important; } - } @media only screen and (max-width: 510px){ + } @media only screen and (max-width: 510px){ .pt-sm-30{ padding-top:30px !important; } diff --git a/index.js b/index.js index 10b8d651..ba89ae4a 100644 --- a/index.js +++ b/index.js @@ -15,86 +15,86 @@ const htmlLocation = __dirname + '/dist/index.html'; //TODO: callback once the routes are opened if (process.env.OVERRIDE_ENTRY_POINT) { - //do not run the API server, which will allow a parent module to control execution and pass in their own express app + //do not run the API server, which will allow a parent module to control execution and pass in their own express app } else { - start(); + start(); } //running this starts the API server function start (overrideApp) { - let app; - if (overrideApp) { - app = overrideApp; - } - else { - app = express(); - } - app.use(helmet()); - app.use(bodyParser.json({limit: "1mb"})); //allow json parsing - app.use(bodyParser.urlencoded({extended: true, limit: "1mb"})); //for parsing application/x-www-form-urlencoded - - //load all routes located in the app directory using a v naming convention - for (let i in versions){ - app.use(["/api/v"+versions[i], "/api/"+versions[i]], require("./app/v" + versions[i] + "/app")); - } - - //load up the html, js and css content that makes up the UI - app.use(express.static(__dirname + '/dist')); - //expose everything in the static folder - app.use(express.static(__dirname + '/static')); - - //global routes - - //basic health check endpoint - app.get("/health", function (req, res) { - res.sendStatus(200); - }); - - //version endpoint (based on package.json version) - app.get("/version", function (req, res) { - res.status(200).send(packageJson.version) - }); - - //error catcher - // eslint-disable-next-line no-unused-vars - app.use(function (err, req, res, next) { - log.error(err); - res.sendStatus(500); - return; - }); - - if (!overrideApp) { - //catch-all route. serve the index.html file again. this is so vue-router's history mode functions - app.use(function (req, res) { - res.sendFile(htmlLocation); - }); - } - - // Invalidate previous data in the cache on startup - cache.flushAll(); - - //start the server - // if SSL is configured, load the cert and listen on the secure port - if(config.ssl.policyServerPort && config.ssl.privateKeyFilename && config.ssl.certificateFilename){ - log.info(`Listening for secure connections on port ${config.ssl.policyServerPort}!`); - - //start listening on secure port - https.createServer({ - "key": fs.readFileSync('./customizable/ssl/' + config.ssl.privateKeyFilename), - "cert": fs.readFileSync('./customizable/ssl/' + config.ssl.certificateFilename) - }, app).listen(config.ssl.policyServerPort); - } - - - if (!overrideApp) { - //start the server on the unsecure port - app.listen(config.policyServerPort, function () { - log.info(`Policy server started on port ${config.policyServerPort}!`); - }); - } + let app; + if (overrideApp) { + app = overrideApp; + } + else { + app = express(); + } + app.use(helmet()); + app.use(bodyParser.json({limit: "1mb"})); //allow json parsing + app.use(bodyParser.urlencoded({extended: true, limit: "1mb"})); //for parsing application/x-www-form-urlencoded + + //load all routes located in the app directory using a v naming convention + for (let i in versions){ + app.use(["/api/v"+versions[i], "/api/"+versions[i]], require("./app/v" + versions[i] + "/app")); + } + + //load up the html, js and css content that makes up the UI + app.use(express.static(__dirname + '/dist')); + //expose everything in the static folder + app.use(express.static(__dirname + '/static')); + + //global routes + + //basic health check endpoint + app.get("/health", function (req, res) { + res.sendStatus(200); + }); + + //version endpoint (based on package.json version) + app.get("/version", function (req, res) { + res.status(200).send(packageJson.version) + }); + + //error catcher + // eslint-disable-next-line no-unused-vars + app.use(function (err, req, res, next) { + log.error(err); + res.sendStatus(500); + return; + }); + + if (!overrideApp) { + //catch-all route. serve the index.html file again. this is so vue-router's history mode functions + app.use(function (req, res) { + res.sendFile(htmlLocation); + }); + } + + // Invalidate previous data in the cache on startup + cache.flushAll(); + + //start the server + // if SSL is configured, load the cert and listen on the secure port + if(config.ssl.policyServerPort && config.ssl.privateKeyFilename && config.ssl.certificateFilename){ + log.info(`Listening for secure connections on port ${config.ssl.policyServerPort}!`); + + //start listening on secure port + https.createServer({ + "key": fs.readFileSync('./customizable/ssl/' + config.ssl.privateKeyFilename), + "cert": fs.readFileSync('./customizable/ssl/' + config.ssl.certificateFilename) + }, app).listen(config.ssl.policyServerPort); + } + + + if (!overrideApp) { + //start the server on the unsecure port + app.listen(config.policyServerPort, function () { + log.info(`Policy server started on port ${config.policyServerPort}!`); + }); + } } module.exports = function (app) { - start(app); + start(app); } diff --git a/scripts/generate-categories/index.js b/scripts/generate-categories/index.js index 6a8b0e5b..4276773f 100644 --- a/scripts/generate-categories/index.js +++ b/scripts/generate-categories/index.js @@ -1,7 +1,7 @@ //Generates the SQL commands necessary to insert this data into the database. For dev use only. //load the environment variables from the .env file in the same directory require('dotenv').config({ - path: '../../.env' + path: '../../.env' }); const utils = require('../utils.js'); const sql = require('sql-bricks'); //generates SQL statements to be logged to the console @@ -11,12 +11,12 @@ const shaid = require('../../lib/shaid'); //module for communicating with SHAID //CATEGORIES OUTPUT shaid.getCategories({}, function (err, res) { - const catObjs = res.map(function (category) { - return { - id: category.id, - display_name: category.display_name - }; - }); + const catObjs = res.map(function (category) { + return { + id: category.id, + display_name: category.display_name + }; + }); const categoryStatement = catObjs.map(function (category) { @@ -32,9 +32,9 @@ WHERE NOT EXISTS ( }); writeToBuffer(categoryStatement.join('')); - - //write to file and finish - utils.writeToFile(outputFileName, outputBuffer); + + //write to file and finish + utils.writeToFile(outputFileName, outputBuffer); }); function writeToBuffer (string) { diff --git a/scripts/generate-func-groups/index.js b/scripts/generate-func-groups/index.js index 8eb5ec8b..71ef84e6 100644 --- a/scripts/generate-func-groups/index.js +++ b/scripts/generate-func-groups/index.js @@ -15,7 +15,7 @@ const outputFileName = 'output.log'; //the name of the output file //DO NOT USE. PERMISSION DEFINITIONS NOW RECEIVED THROUGH SHAID /* const permissionStatement = permissions.permissionNames.map(function (permission) { - return ` + return ` INSERT INTO permissions (name, type) SELECT '${permission.name}' AS name, '${permission.type}' AS type WHERE NOT EXISTS ( @@ -31,15 +31,15 @@ writeToBuffer(permissionStatement.join('')); //FUNCTION GROUP INFO OUTPUT const funcGroupNames = Object.keys(funcGroups); const funcGroupInfoStatement = funcGroupNames.map(function (funcGroupName) { - const funcGroupObj = funcGroups[funcGroupName]; - const alwaysAllowed = functionGroupInfo.alwaysAllowedObj[funcGroupName]; - if (funcGroupObj.user_consent_prompt === undefined) { - funcGroupObj.user_consent_prompt = null; - } - else { //manually add quotes around the string - funcGroupObj.user_consent_prompt = "'" + funcGroupObj.user_consent_prompt + "'"; - } - return ` + const funcGroupObj = funcGroups[funcGroupName]; + const alwaysAllowed = functionGroupInfo.alwaysAllowedObj[funcGroupName]; + if (funcGroupObj.user_consent_prompt === undefined) { + funcGroupObj.user_consent_prompt = null; + } + else { //manually add quotes around the string + funcGroupObj.user_consent_prompt = "'" + funcGroupObj.user_consent_prompt + "'"; + } + return ` INSERT INTO function_group_info (property_name, user_consent_prompt, is_default, status) SELECT '${funcGroupName}' AS property_name, ${funcGroupObj.user_consent_prompt} AS user_consent_prompt, '${alwaysAllowed}' AS is_default, 'PRODUCTION' AS status WHERE NOT EXISTS ( @@ -57,7 +57,7 @@ writeToBuffer(funcGroupInfoStatement.join('')); /* const relationStatement = permissions.permissionRelations.map(function (permRelation) { - return ` + return ` INSERT INTO permission_relations (child_permission_name, parent_permission_name) SELECT '${permRelation.child_permission_name}' AS child_permission_name, '${permRelation.parent_permission_name}' AS parent_permission_name WHERE NOT EXISTS ( @@ -79,33 +79,33 @@ let functionGroupHmiLevels = []; let functionGroupParameters = []; for (let i = 0; i < funcGroupNames.length; i++) { - const funcGroupObj = funcGroups[funcGroupNames[i]]; - const rpcObjs = funcGroupObj.rpcs; - let vehicleParameterPermissions = {}; + const funcGroupObj = funcGroups[funcGroupNames[i]]; + const rpcObjs = funcGroupObj.rpcs; + let vehicleParameterPermissions = {}; - for (let rpcName in rpcObjs) { - const hmiLevels = rpcObjs[rpcName].hmi_levels; - const parameters = rpcObjs[rpcName].parameters; - funcGroupPermissions.push({ - groupName: funcGroupNames[i], - permissionName: rpcName - }); - addHmiLevels(functionGroupHmiLevels, funcGroupNames[i], rpcName, hmiLevels); - if (parameters && parameters.length) { - const addParameterPermissions = setupContext(funcGroupNames[i], rpcName); - addParameterPermissions(vehicleParameterPermissions, parameters); - } - } - for (let permissionName in vehicleParameterPermissions) { - funcGroupPermissions.push({ - groupName: funcGroupNames[i], - permissionName: permissionName - }); - } + for (let rpcName in rpcObjs) { + const hmiLevels = rpcObjs[rpcName].hmi_levels; + const parameters = rpcObjs[rpcName].parameters; + funcGroupPermissions.push({ + groupName: funcGroupNames[i], + permissionName: rpcName + }); + addHmiLevels(functionGroupHmiLevels, funcGroupNames[i], rpcName, hmiLevels); + if (parameters && parameters.length) { + const addParameterPermissions = setupContext(funcGroupNames[i], rpcName); + addParameterPermissions(vehicleParameterPermissions, parameters); + } + } + for (let permissionName in vehicleParameterPermissions) { + funcGroupPermissions.push({ + groupName: funcGroupNames[i], + permissionName: permissionName + }); + } } /* const funcGroupPermissionStatement = funcGroupPermissions.map(function (obj) { - return ` + return ` INSERT INTO function_group_permissions(function_group_id, permission_name) SELECT fgi.id AS function_group_id, ${obj.permissionName} AS permission_name FROM function_group_info fgi @@ -125,7 +125,7 @@ writeToBuffer(funcGroupPermissionStatement.join('')); */ //FUNCTION GROUP HMI LEVELS OUTPUT const functionGroupHmiLevelStatement = functionGroupHmiLevels.map(function (obj) { - return ` + return ` INSERT INTO function_group_hmi_levels(function_group_id, permission_name, hmi_level) SELECT id AS function_group_id, '${obj.permissionName}' AS permission_name, '${obj.hmiLevel}' AS hmi_level FROM function_group_info @@ -136,7 +136,7 @@ writeToBuffer(functionGroupHmiLevelStatement.join('')); //FUNCTION GROUP PARAMETERS OUTPUT const functionGroupParameterStatement = functionGroupParameters.map(function (obj) { - return ` + return ` INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, '${obj.rpcName}' AS rpc_name, '${obj.parameter}' AS parameter FROM function_group_info @@ -148,26 +148,26 @@ writeToBuffer(functionGroupParameterStatement.join('')); //returns a function that allows parameter permissions and function group parameters to be added //functionGroupName and rpcName is necessary for function group parameters function setupContext (functionGroupName, rpcName) { - return function (vehicleParameterPermissions, parameters) { - for (let i = 0; i < parameters.length; i++) { - vehicleParameterPermissions[parameters[i]] = null; - functionGroupParameters.push({ - groupName: functionGroupName, - rpcName: rpcName, - parameter: parameters[i] - }); - } - } + return function (vehicleParameterPermissions, parameters) { + for (let i = 0; i < parameters.length; i++) { + vehicleParameterPermissions[parameters[i]] = null; + functionGroupParameters.push({ + groupName: functionGroupName, + rpcName: rpcName, + parameter: parameters[i] + }); + } + } } function addHmiLevels (functionGroupHmiLevels, groupName, permName, hmiLevels) { - for (let i = 0; i < hmiLevels.length; i++) { - functionGroupHmiLevels.push({ - groupName: groupName, - permissionName: permName, - hmiLevel: hmiLevels[i] - }); - } + for (let i = 0; i < hmiLevels.length; i++) { + functionGroupHmiLevels.push({ + groupName: groupName, + permissionName: permName, + hmiLevel: hmiLevels[i] + }); + } } //write to file and finish diff --git a/scripts/generate-messages/index.js b/scripts/generate-messages/index.js index 37ac28ce..f7171066 100644 --- a/scripts/generate-messages/index.js +++ b/scripts/generate-messages/index.js @@ -11,9 +11,9 @@ const outputFileName = 'output.log'; //the name of the output file //find the first message category and generate the languages table from its languages const languages = messages[Object.keys(messages)[0]].languages; const languageNameObjs = Object.keys(languages).map(function (languageName) { - return { - id: languageName - }; + return { + id: languageName + }; }); const languageStatement = sql.insert('languages').values(languageNameObjs).toString(); writeToBuffer(utils.formatInsertOutput(languageStatement)); @@ -22,20 +22,20 @@ writeToBuffer(utils.formatInsertOutput(languageStatement)); //transform the language text into SQL insertion statements let messageObjs = []; for (let messageCategory in messages) { - const catObj = messages[messageCategory]; - const languageObjs = Object.keys(catObj.languages).map(function (languageName) { - const langObj = catObj.languages[languageName]; - return { - label: langObj.label, - language_id: languageName, - line1: langObj.line1, - line2: langObj.line2, - message_category: messageCategory, - text_body: langObj.text_body, - tts: langObj.tts - }; - }); - messageObjs = messageObjs.concat(languageObjs); + const catObj = messages[messageCategory]; + const languageObjs = Object.keys(catObj.languages).map(function (languageName) { + const langObj = catObj.languages[languageName]; + return { + label: langObj.label, + language_id: languageName, + line1: langObj.line1, + line2: langObj.line2, + message_category: messageCategory, + text_body: langObj.text_body, + tts: langObj.tts + }; + }); + messageObjs = messageObjs.concat(languageObjs); } const messageStatement = sql.insert('message_text').values(messageObjs).toString(); diff --git a/scripts/utils.js b/scripts/utils.js index dc847d47..9d56647d 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -1,8 +1,8 @@ const fs = require('fs'); module.exports = { - writeToFile: writeToFile, - formatInsertOutput: formatInsertOutput + writeToFile: writeToFile, + formatInsertOutput: formatInsertOutput } function writeToFile (fileName, string) { @@ -14,8 +14,8 @@ function writeToFile (fileName, string) { } function formatInsertOutput (insertString) { - insertString = insertString + ';'; - const insertStatement = insertString.split("VALUES")[0] + '\n'; - const valuesStatement = insertString.split("VALUES")[1].trim().replace(/\), /g, '),\n'); - return insertStatement + 'VALUES\n' + valuesStatement + '\n\n'; + insertString = insertString + ';'; + const insertStatement = insertString.split("VALUES")[0] + '\n'; + const valuesStatement = insertString.split("VALUES")[1].trim().replace(/\), /g, '),\n'); + return insertStatement + 'VALUES\n' + valuesStatement + '\n\n'; } \ No newline at end of file diff --git a/src/main.js b/src/main.js index 734fb2d5..40e4515e 100644 --- a/src/main.js +++ b/src/main.js @@ -61,59 +61,59 @@ export const eventBus = new Vue(); //reusable methods Vue.mixin({ - methods: { - "httpRequest": function (action, route, options = {}, cb) { - if(!options){ - options = {}; - } - if(!options.headers){ - options.headers = {}; - } - if(!options.body){ - options.body = {}; - } - if(this.$session.get("BASIC_AUTH_PASSWORD")){ - options.headers["BASIC-AUTH-PASSWORD"] = this.$session.get("BASIC_AUTH_PASSWORD"); - } - if(["post","put","patch"].indexOf(action) >= 0){ - this.$http[action](route, options.body, options) - .then(response => { - cb(null, response); - }, response => { - if(response.status == 401 && !options.preventAuthRedirect){ - this.$session.destroy(); - this.$router.go(); - }else{ - cb(response, null); - } - }); - }else{ - this.$http[action](route, options) - .then(response => { - cb(null, response); - }, response => { - if(response.status == 401 && !options.preventAuthRedirect){ - this.$session.destroy(); - this.$router.go(); - }else{ - cb(response, null); - } - }); - } - }, - "handleModalClick": function (loadingProp, modalName, methodName) { - //show a loading icon for the modal, and call the methodName passed in - //when finished, turn off the loading icon, hide the modal, and reload the info - this[loadingProp] = true; - this[methodName](() => { - this[loadingProp] = false; - if (modalName) { - this.$refs[modalName].hide(); - } - this.environmentClick(); - }); - } - } + methods: { + "httpRequest": function (action, route, options = {}, cb) { + if(!options){ + options = {}; + } + if(!options.headers){ + options.headers = {}; + } + if(!options.body){ + options.body = {}; + } + if(this.$session.get("BASIC_AUTH_PASSWORD")){ + options.headers["BASIC-AUTH-PASSWORD"] = this.$session.get("BASIC_AUTH_PASSWORD"); + } + if(["post","put","patch"].indexOf(action) >= 0){ + this.$http[action](route, options.body, options) + .then(response => { + cb(null, response); + }, response => { + if(response.status == 401 && !options.preventAuthRedirect){ + this.$session.destroy(); + this.$router.go(); + }else{ + cb(response, null); + } + }); + }else{ + this.$http[action](route, options) + .then(response => { + cb(null, response); + }, response => { + if(response.status == 401 && !options.preventAuthRedirect){ + this.$session.destroy(); + this.$router.go(); + }else{ + cb(response, null); + } + }); + } + }, + "handleModalClick": function (loadingProp, modalName, methodName) { + //show a loading icon for the modal, and call the methodName passed in + //when finished, turn off the loading icon, hide the modal, and reload the info + this[loadingProp] = true; + this[methodName](() => { + this[loadingProp] = false; + if (modalName) { + this.$refs[modalName].hide(); + } + this.environmentClick(); + }); + } + } }) diff --git a/test/api/v1/login/login.js b/test/api/v1/login/login.js index 12591c1d..c2c68b45 100644 --- a/test/api/v1/login/login.js +++ b/test/api/v1/login/login.js @@ -11,7 +11,7 @@ common.post( 'return a 401 when trying to login with the wrong password', endpoint, { - password: 'nope' + password: 'nope' }, (err, res, done) => { expect(err).to.be.null; @@ -24,15 +24,15 @@ common.post( 'return a 200 when trying to login with the right password', endpoint, { - password: 'testing' + password: 'testing' }, (err, res, done) => { expect(err).to.be.null; expect(res).to.have.status(200); //reset - common.config.authType = undefined; - common.config.basicAuthPassword = oldPassword; + common.config.authType = undefined; + common.config.basicAuthPassword = oldPassword; done(); } diff --git a/vue.config.js b/vue.config.js index 1d436532..f35c5247 100644 --- a/vue.config.js +++ b/vue.config.js @@ -6,8 +6,8 @@ process.env.OVERRIDE_ENTRY_POINT = true; // do not run the server immediately const app = require('./index.js'); module.exports = { - devServer: { - before: app, + devServer: { + before: app, port: settings.policyServerPort } } \ No newline at end of file From 50effbb37a9f4640dba8956d41f6234b14f28fc7 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Thu, 13 Jan 2022 09:48:27 -0500 Subject: [PATCH 07/18] Convert other non-js files created for the project --- .../20170629152307-init-policy-table-up.sql | 60 +++++++++---------- .../sqls/20180424123545-app-blacklist-up.sql | 16 ++--- ...180905171105-move-app-vendor-info-down.sql | 2 +- .../sqls/20190221202046-app-services-up.sql | 12 ++-- .../20200409193442-webengine-catalog-up.sql | 2 +- .../20200825174000-gear-status-0266-up.sql | 8 +-- .../20200827165346-window-status-0261-up.sql | 8 +-- ...00827171314-hands-off-steering-0257-up.sql | 8 +-- ...2952-stability-controls-status-0253-up.sql | 8 +-- .../20210120182618-seat-occupancy-0262-up.sql | 8 +-- .../20210129160807-climate-data-0269-up.sql | 8 +-- src/assets/css/style.css | 30 +++++----- 12 files changed, 85 insertions(+), 85 deletions(-) diff --git a/migrations/sqls/20170629152307-init-policy-table-up.sql b/migrations/sqls/20170629152307-init-policy-table-up.sql index f1f48716..599061b3 100644 --- a/migrations/sqls/20170629152307-init-policy-table-up.sql +++ b/migrations/sqls/20170629152307-init-policy-table-up.sql @@ -41,7 +41,7 @@ CREATE TABLE languages ( WITH ( OIDS = FALSE ); CREATE TABLE message_text ( - "id" SERIAL NOT NULL, + "id" SERIAL NOT NULL, "language_id" CHAR(5) REFERENCES languages (id) ON UPDATE CASCADE ON DELETE CASCADE, "message_category" TEXT NOT NULL, "tts" TEXT, @@ -57,7 +57,7 @@ CREATE TABLE message_text ( WITH ( OIDS = FALSE ); CREATE TABLE function_group_info ( - "id" SERIAL NOT NULL, + "id" SERIAL NOT NULL, "property_name" TEXT NOT NULL, "user_consent_prompt" TEXT, "status" edit_status NOT NULL DEFAULT 'STAGING', @@ -71,37 +71,37 @@ CREATE TABLE function_group_info ( WITH ( OIDS = FALSE ); CREATE TABLE rpc_names ( - "id" SERIAL NOT NULL, + "id" SERIAL NOT NULL, "rpc_name" TEXT NOT NULL, PRIMARY KEY (id) ) WITH ( OIDS = FALSE ); CREATE TABLE vehicle_data ( - "id" SERIAL NOT NULL, + "id" SERIAL NOT NULL, "component_name" TEXT NOT NULL, PRIMARY KEY (id) ) WITH ( OIDS = FALSE ); CREATE TABLE rpc_permission ( - "function_group_id" SERIAL REFERENCES function_group_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "rpc_id" SERIAL REFERENCES rpc_names (id) ON UPDATE CASCADE ON DELETE CASCADE, + "function_group_id" SERIAL REFERENCES function_group_info (id) ON UPDATE CASCADE ON DELETE CASCADE, + "rpc_id" SERIAL REFERENCES rpc_names (id) ON UPDATE CASCADE ON DELETE CASCADE, PRIMARY KEY (function_group_id, rpc_id) ) WITH ( OIDS = FALSE ); CREATE TABLE rpc_vehicle_parameters ( - "function_group_id" SERIAL REFERENCES function_group_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "rpc_id" SERIAL REFERENCES rpc_names (id) ON UPDATE CASCADE ON DELETE CASCADE, - "vehicle_id" SERIAL REFERENCES vehicle_data (id) ON UPDATE CASCADE ON DELETE CASCADE, + "function_group_id" SERIAL REFERENCES function_group_info (id) ON UPDATE CASCADE ON DELETE CASCADE, + "rpc_id" SERIAL REFERENCES rpc_names (id) ON UPDATE CASCADE ON DELETE CASCADE, + "vehicle_id" SERIAL REFERENCES vehicle_data (id) ON UPDATE CASCADE ON DELETE CASCADE, PRIMARY KEY (function_group_id, rpc_id, vehicle_id) ) WITH ( OIDS = FALSE ); CREATE TABLE changelog ( - "status" edit_status NOT NULL DEFAULT 'STAGING', - "timestamp" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(), + "status" edit_status NOT NULL DEFAULT 'STAGING', + "timestamp" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(), PRIMARY KEY (status, timestamp) ) WITH ( OIDS = FALSE ); @@ -109,7 +109,7 @@ WITH ( OIDS = FALSE ); CREATE TABLE vendors ( - "id" SERIAL NOT NULL, + "id" SERIAL NOT NULL, "vendor_name" TEXT NOT NULL, "vendor_email" TEXT NOT NULL, PRIMARY KEY (id) @@ -117,7 +117,7 @@ CREATE TABLE vendors ( WITH ( OIDS = FALSE ); CREATE TABLE categories ( - "id" INT NOT NULL, + "id" INT NOT NULL, "display_name" TEXT NOT NULL, PRIMARY KEY (id) ) @@ -137,43 +137,43 @@ CREATE TABLE hmi_levels ( WITH ( OIDS = FALSE ); CREATE TABLE app_info ( - "id" SERIAL NOT NULL, - "app_uuid" VARCHAR(36) NOT NULL, - "name" TEXT NOT NULL, - "vendor_id" INT REFERENCES vendors (id) ON UPDATE CASCADE ON DELETE CASCADE, - "platform" application_platform NOT NULL, - "platform_app_id" TEXT, - "status" application_status NOT NULL, - "can_background_alert" BOOLEAN NOT NULL, - "can_steal_focus" BOOLEAN NOT NULL, - "default_hmi_level" TEXT NOT NULL REFERENCES hmi_levels (id) ON UPDATE CASCADE ON DELETE CASCADE, - "tech_email" TEXT, - "tech_phone" TEXT, + "id" SERIAL NOT NULL, + "app_uuid" VARCHAR(36) NOT NULL, + "name" TEXT NOT NULL, + "vendor_id" INT REFERENCES vendors (id) ON UPDATE CASCADE ON DELETE CASCADE, + "platform" application_platform NOT NULL, + "platform_app_id" TEXT, + "status" application_status NOT NULL, + "can_background_alert" BOOLEAN NOT NULL, + "can_steal_focus" BOOLEAN NOT NULL, + "default_hmi_level" TEXT NOT NULL REFERENCES hmi_levels (id) ON UPDATE CASCADE ON DELETE CASCADE, + "tech_email" TEXT, + "tech_phone" TEXT, "created_ts" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(), "updated_ts" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(), - "category_id" INT REFERENCES categories (id) ON UPDATE CASCADE ON DELETE CASCADE, - "approval_status" approval_status NOT NULL DEFAULT 'PENDING', + "category_id" INT REFERENCES categories (id) ON UPDATE CASCADE ON DELETE CASCADE, + "approval_status" approval_status NOT NULL DEFAULT 'PENDING', PRIMARY KEY (id) ) WITH ( OIDS = FALSE ); CREATE TABLE app_countries ( "app_id" SERIAL REFERENCES app_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "country_iso" CHAR(2) REFERENCES countries (iso) ON UPDATE CASCADE ON DELETE CASCADE, + "country_iso" CHAR(2) REFERENCES countries (iso) ON UPDATE CASCADE ON DELETE CASCADE, PRIMARY KEY (app_id, country_iso) ) WITH ( OIDS = FALSE ); CREATE TABLE display_names ( "app_id" SERIAL REFERENCES app_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "display_text" VARCHAR(100) NOT NULL, + "display_text" VARCHAR(100) NOT NULL, PRIMARY KEY (app_id, display_text) ) WITH ( OIDS = FALSE ); CREATE TABLE app_vehicle_permissions ( "app_id" SERIAL REFERENCES app_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "vehicle_id" SERIAL REFERENCES vehicle_data (id) ON UPDATE CASCADE ON DELETE CASCADE, + "vehicle_id" SERIAL REFERENCES vehicle_data (id) ON UPDATE CASCADE ON DELETE CASCADE, PRIMARY KEY (app_id, vehicle_id) ) WITH ( OIDS = FALSE ); diff --git a/migrations/sqls/20180424123545-app-blacklist-up.sql b/migrations/sqls/20180424123545-app-blacklist-up.sql index 09a57762..a2f4b18a 100644 --- a/migrations/sqls/20180424123545-app-blacklist-up.sql +++ b/migrations/sqls/20180424123545-app-blacklist-up.sql @@ -11,18 +11,18 @@ ALTER TYPE approval_status RENAME TO approval_status_temp; CREATE TYPE approval_status AS ENUM ('PENDING', 'STAGING', 'ACCEPTED', 'LIMITED'); ALTER TABLE app_info - ALTER COLUMN approval_status DROP DEFAULT, - ALTER COLUMN approval_status TYPE TEXT; + ALTER COLUMN approval_status DROP DEFAULT, + ALTER COLUMN approval_status TYPE TEXT; UPDATE app_info - SET approval_status = 'LIMITED' - WHERE approval_status = 'DENIED'; + SET approval_status = 'LIMITED' + WHERE approval_status = 'DENIED'; ALTER TABLE app_info - ALTER COLUMN approval_status - SET DATA TYPE approval_status - USING approval_status::text::approval_status, - ALTER COLUMN approval_status SET DEFAULT 'PENDING'; + ALTER COLUMN approval_status + SET DATA TYPE approval_status + USING approval_status::text::approval_status, + ALTER COLUMN approval_status SET DEFAULT 'PENDING'; DROP TYPE approval_status_temp; CREATE OR REPLACE VIEW view_partial_app_info AS diff --git a/migrations/sqls/20180905171105-move-app-vendor-info-down.sql b/migrations/sqls/20180905171105-move-app-vendor-info-down.sql index 8acd3f56..04cc177a 100644 --- a/migrations/sqls/20180905171105-move-app-vendor-info-down.sql +++ b/migrations/sqls/20180905171105-move-app-vendor-info-down.sql @@ -1,7 +1,7 @@ -- this is only a partial down migration. full downward migration of the vendor data is not supported. CREATE TABLE vendors ( - "id" SERIAL NOT NULL, + "id" SERIAL NOT NULL, "vendor_name" TEXT NOT NULL, "vendor_email" TEXT NOT NULL, PRIMARY KEY (id) diff --git a/migrations/sqls/20190221202046-app-services-up.sql b/migrations/sqls/20190221202046-app-services-up.sql index 7034f4b9..17556dbb 100644 --- a/migrations/sqls/20190221202046-app-services-up.sql +++ b/migrations/sqls/20190221202046-app-services-up.sql @@ -10,7 +10,7 @@ ADD COLUMN IF NOT EXISTS display_name TEXT; CREATE TABLE service_types ( - "name" TEXT NOT NULL, + "name" TEXT NOT NULL, "display_name" TEXT NOT NULL, CONSTRAINT service_type_pk PRIMARY KEY (name) ) @@ -18,8 +18,8 @@ WITH ( OIDS = FALSE ); CREATE TABLE service_type_permissions ( - "service_type_name" TEXT NOT NULL, - "permission_name" VARCHAR(64) NOT NULL, + "service_type_name" TEXT NOT NULL, + "permission_name" VARCHAR(64) NOT NULL, CONSTRAINT service_type_permission_pk PRIMARY KEY (service_type_name, permission_name) ) WITH ( OIDS = FALSE ); @@ -27,7 +27,7 @@ WITH ( OIDS = FALSE ); CREATE TABLE app_service_types ( "app_id" SERIAL REFERENCES app_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "service_type_name" TEXT REFERENCES service_types (name) ON UPDATE CASCADE ON DELETE CASCADE, + "service_type_name" TEXT REFERENCES service_types (name) ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT app_service_types_pk PRIMARY KEY (app_id, service_type_name) ) WITH ( OIDS = FALSE ); @@ -35,7 +35,7 @@ WITH ( OIDS = FALSE ); CREATE TABLE app_service_type_names ( "app_id" SERIAL REFERENCES app_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "service_type_name" TEXT REFERENCES service_types (name) ON UPDATE CASCADE ON DELETE CASCADE, + "service_type_name" TEXT REFERENCES service_types (name) ON UPDATE CASCADE ON DELETE CASCADE, "service_name" VARCHAR(255), CONSTRAINT app_service_type_names_pk PRIMARY KEY (app_id, service_type_name, service_name) ) @@ -44,7 +44,7 @@ WITH ( OIDS = FALSE ); CREATE TABLE app_service_type_permissions ( "app_id" SERIAL REFERENCES app_info (id) ON UPDATE CASCADE ON DELETE CASCADE, - "service_type_name" TEXT REFERENCES service_types (name) ON UPDATE CASCADE ON DELETE CASCADE, + "service_type_name" TEXT REFERENCES service_types (name) ON UPDATE CASCADE ON DELETE CASCADE, "permission_name" VARCHAR(64) REFERENCES permissions (name) ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT app_service_type_permissions_pk PRIMARY KEY (app_id, service_type_name, permission_name) ) diff --git a/migrations/sqls/20200409193442-webengine-catalog-up.sql b/migrations/sqls/20200409193442-webengine-catalog-up.sql index c7a087a8..8da72411 100644 --- a/migrations/sqls/20200409193442-webengine-catalog-up.sql +++ b/migrations/sqls/20200409193442-webengine-catalog-up.sql @@ -1,7 +1,7 @@ CREATE TYPE transport_type as enum ('webengine', 'websocket'); ALTER TABLE app_info - ADD COLUMN IF NOT EXISTS min_rpc_version TEXT, + ADD COLUMN IF NOT EXISTS min_rpc_version TEXT, ADD COLUMN IF NOT EXISTS min_protocol_version TEXT, ADD COLUMN IF NOT EXISTS developer_version TEXT, ADD COLUMN IF NOT EXISTS package_url TEXT, diff --git a/migrations/sqls/20200825174000-gear-status-0266-up.sql b/migrations/sqls/20200825174000-gear-status-0266-up.sql index 0165d5f6..b136e94e 100644 --- a/migrations/sqls/20200825174000-gear-status-0266-up.sql +++ b/migrations/sqls/20200825174000-gear-status-0266-up.sql @@ -9,7 +9,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'GetVehicleData' AS rpc_name, 'gearStatus' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -21,7 +21,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'OnVehicleData' AS rpc_name, 'gearStatus' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -33,7 +33,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'SubscribeVehicleData' AS rpc_name, 'gearStatus' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -45,7 +45,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'UnsubscribeVehicleData' AS rpc_name, 'gearStatus' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' diff --git a/migrations/sqls/20200827165346-window-status-0261-up.sql b/migrations/sqls/20200827165346-window-status-0261-up.sql index db0c2708..cfb682fd 100644 --- a/migrations/sqls/20200827165346-window-status-0261-up.sql +++ b/migrations/sqls/20200827165346-window-status-0261-up.sql @@ -9,7 +9,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'GetVehicleData' AS rpc_name, 'windowStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -21,7 +21,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'OnVehicleData' AS rpc_name, 'windowStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -33,7 +33,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'SubscribeVehicleData' AS rpc_name, 'windowStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -45,7 +45,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'UnsubscribeVehicleData' AS rpc_name, 'windowStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' diff --git a/migrations/sqls/20200827171314-hands-off-steering-0257-up.sql b/migrations/sqls/20200827171314-hands-off-steering-0257-up.sql index cc89c8f9..c153237d 100644 --- a/migrations/sqls/20200827171314-hands-off-steering-0257-up.sql +++ b/migrations/sqls/20200827171314-hands-off-steering-0257-up.sql @@ -9,7 +9,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'GetVehicleData' AS rpc_name, 'handsOffSteering' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -21,7 +21,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'OnVehicleData' AS rpc_name, 'handsOffSteering' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -33,7 +33,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'SubscribeVehicleData' AS rpc_name, 'handsOffSteering' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -45,7 +45,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'UnsubscribeVehicleData' AS rpc_name, 'handsOffSteering' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' diff --git a/migrations/sqls/20200827172952-stability-controls-status-0253-up.sql b/migrations/sqls/20200827172952-stability-controls-status-0253-up.sql index a6ac99c5..753f1f47 100644 --- a/migrations/sqls/20200827172952-stability-controls-status-0253-up.sql +++ b/migrations/sqls/20200827172952-stability-controls-status-0253-up.sql @@ -9,7 +9,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'GetVehicleData' AS rpc_name, 'stabilityControlsStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -21,7 +21,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'OnVehicleData' AS rpc_name, 'stabilityControlsStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -33,7 +33,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'SubscribeVehicleData' AS rpc_name, 'stabilityControlsStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -45,7 +45,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'UnsubscribeVehicleData' AS rpc_name, 'stabilityControlsStatus' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' diff --git a/migrations/sqls/20210120182618-seat-occupancy-0262-up.sql b/migrations/sqls/20210120182618-seat-occupancy-0262-up.sql index cb985dbd..8b9ff240 100644 --- a/migrations/sqls/20210120182618-seat-occupancy-0262-up.sql +++ b/migrations/sqls/20210120182618-seat-occupancy-0262-up.sql @@ -9,7 +9,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'GetVehicleData' AS rpc_name, 'seatOccupancy' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -21,7 +21,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'OnVehicleData' AS rpc_name, 'seatOccupancy' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -33,7 +33,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'SubscribeVehicleData' AS rpc_name, 'seatOccupancy' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' @@ -45,7 +45,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'UnsubscribeVehicleData' AS rpc_name, 'seatOccupancy' AS parameter FROM function_group_info WHERE property_name = 'DrivingCharacteristics-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'DrivingCharacteristics-3' diff --git a/migrations/sqls/20210129160807-climate-data-0269-up.sql b/migrations/sqls/20210129160807-climate-data-0269-up.sql index 9aeaa1fa..0875fc70 100644 --- a/migrations/sqls/20210129160807-climate-data-0269-up.sql +++ b/migrations/sqls/20210129160807-climate-data-0269-up.sql @@ -9,7 +9,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'GetVehicleData' AS rpc_name, 'climateData' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -21,7 +21,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'OnVehicleData' AS rpc_name, 'climateData' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -33,7 +33,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'SubscribeVehicleData' AS rpc_name, 'climateData' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' @@ -45,7 +45,7 @@ INSERT INTO function_group_parameters(function_group_id, rpc_name, parameter) SELECT id AS function_group_id, 'UnsubscribeVehicleData' AS rpc_name, 'climateData' AS parameter FROM function_group_info WHERE property_name = 'VehicleInfo-3' - AND NOT EXISTS( + AND NOT EXISTS( SELECT 1 FROM function_group_parameters WHERE property_name = 'VehicleInfo-3' diff --git a/src/assets/css/style.css b/src/assets/css/style.css index 5f0038e8..f6c3b85e 100644 --- a/src/assets/css/style.css +++ b/src/assets/css/style.css @@ -368,26 +368,26 @@ div.horizontal-divider .text { .tiles { display: -moz-flex; - display: -webkit-flex; - display: -ms-flex; - display: flex; - -moz-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - position: relative; - margin: 0em 0 0 -1em; + display: -webkit-flex; + display: -ms-flex; + display: flex; + -moz-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + position: relative; + margin: 0em 0 0 -1em; } .tiles > a { -moz-transition: -moz-transform 0.4s ease, opacity 0.4s ease; - -webkit-transition: -webkit-transform 0.4s ease, opacity 0.4s ease; - -ms-transition: -ms-transform 0.4s ease, opacity 0.4s ease; - transition: transform 0.4s ease, opacity 0.4s ease; - position: relative; - width: calc(33.33333% - 1em); + -webkit-transition: -webkit-transform 0.4s ease, opacity 0.4s ease; + -ms-transition: -ms-transform 0.4s ease, opacity 0.4s ease; + transition: transform 0.4s ease, opacity 0.4s ease; + position: relative; + width: calc(33.33333% - 1em); min-width: 340px; - margin: 1em 0 0 1em; + margin: 1em 0 0 1em; padding: 20px; color: #384F61; background-color: #FFFFFF; From 07d5d252980cba9cf37b9357eb37f7960966ed84 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Wed, 19 Jan 2022 16:45:54 -0500 Subject: [PATCH 08/18] Clean up package.json scripts, update all tests and ensure they pass --- app/v1/messages/helper.js | 7 - database.json | 18 -- entry.js | 74 +++++++ package-lock.json | 166 +++++++------- package.json | 21 +- test/api/v1/about/about.js | 16 +- test/api/v1/applications/action.js | 90 +++----- test/api/v1/applications/administrator.js | 103 +++------ test/api/v1/applications/applications.js | 55 ++--- test/api/v1/applications/auto.js | 111 ++++------ test/api/v1/applications/certificate-get.js | 60 ++--- test/api/v1/applications/certificate.js | 178 ++++++--------- test/api/v1/applications/groups.js | 163 +++++--------- test/api/v1/applications/hybrid.js | 131 ++++------- test/api/v1/applications/passthrough.js | 102 +++------ test/api/v1/applications/permission.js | 125 ++++------- test/api/v1/applications/rpcencryption.js | 99 +++------ test/api/v1/applications/store.js | 77 +++++++ test/api/v1/groups/groups.js | 137 ++++-------- test/api/v1/groups/names.js | 28 +-- test/api/v1/groups/promote.js | 66 ++---- test/api/v1/login/login.js | 41 ++-- test/api/v1/messages/messages.js | 121 ++++------ test/api/v1/messages/names.js | 28 +-- test/api/v1/messages/promote.js | 66 ++---- test/api/v1/messages/update.js | 20 +- test/api/v1/module/module.js | 85 +++----- test/api/v1/module/promote.js | 36 +-- test/api/v1/permissions/unmapped.js | 48 ++-- test/api/v1/permissions/update.js | 20 +- test/api/v1/policy/apps.js | 123 +++++------ test/api/v1/policy/preview.js | 34 +-- test/api/v1/policy/production.js | 53 ++--- test/api/v1/policy/staging.js | 52 ++--- test/api/v1/security/certificate.js | 80 +++---- test/api/v1/security/private.js | 34 +-- test/api/v1/vehicle-data/type.js | 22 +- test/api/v1/vehicle-data/vehicle-data.js | 230 ++++++-------------- test/api/v1/webhook/webhook.js | 58 +++++ test/basicAuth/basicAuth.js | 10 +- test/cache/cache.js | 6 +- test/common.js | 59 ++++- test/test.js | 17 +- 43 files changed, 1222 insertions(+), 1848 deletions(-) create mode 100644 entry.js create mode 100644 test/api/v1/applications/store.js create mode 100644 test/api/v1/webhook/webhook.js diff --git a/app/v1/messages/helper.js b/app/v1/messages/helper.js index 510a81df..e6a0a64e 100644 --- a/app/v1/messages/helper.js +++ b/app/v1/messages/helper.js @@ -19,13 +19,6 @@ function validatePromote (req, res) { } function validatePost (req, res) { - //base check - if (!check.string(req.body.name) || req.body.name === '') { - res.parcel - .setStatus(400) - .setMessage("Required field for consumer message: name"); - return; - } if (!check.array(req.body.messages)) { res.parcel .setStatus(400) diff --git a/database.json b/database.json index 147b2394..ad02eddb 100644 --- a/database.json +++ b/database.json @@ -1,22 +1,4 @@ { - "pg-staging": { - "driver": "pg", - "user": {"ENV": "STAGING_PG_USER"}, - "password": {"ENV": "STAGING_PG_PASSWORD"}, - "host": {"ENV": "STAGING_PG_HOST"}, - "database": {"ENV": "STAGING_PG_DATABASE"}, - "port": {"ENV": "STAGING_PG_PORT"}, - "schema": "public" - }, - "pg-production": { - "driver": "pg", - "user": {"ENV": "PRODUCTION_PG_USER"}, - "password": {"ENV": "PRODUCTION_PG_PASSWORD"}, - "host": {"ENV": "PRODUCTION_PG_HOST"}, - "database": {"ENV": "PRODUCTION_PG_DATABASE"}, - "port": {"ENV": "PRODUCTION_PG_PORT"}, - "schema": "public" - }, "pg-test": { "driver": "pg", "user": {"ENV": "TEST_PG_USER"}, diff --git a/entry.js b/entry.js new file mode 100644 index 00000000..a77d757d --- /dev/null +++ b/entry.js @@ -0,0 +1,74 @@ +require('dotenv').config(); +const { spawn } = require('child_process'); + +let mainEnvs = { + DB_USER: process.env.DB_USER, + DB_PASSWORD: process.env.DB_PASSWORD, + DB_HOST: process.env.DB_HOST, + DB_DATABASE: process.env.DB_DATABASE, + DB_PORT: process.env.DB_PORT, +} +let testEnvs = { + TEST_PG_USER: process.env.TEST_PG_USER, + TEST_PG_PASSWORD: process.env.TEST_PG_PASSWORD, + TEST_PG_HOST: process.env.TEST_PG_HOST, + TEST_PG_DATABASE: process.env.TEST_PG_DATABASE, + TEST_PG_PORT: process.env.TEST_PG_PORT, +} + +main(); +async function main () { + let state = process.env.RUN_STATE; + try { + if (state === "startup") { + await migrateUp('pg-policy'); + await startServer(); + } else if (state === "dev") { + await migrateUp('pg-policy'); + await startDev(); + } else if (state === "reset") { + await reset('pg-policy'); + } else if (state === "test") { + await reset('pg-test'); + await migrateUp('pg-test'); + await test(); + await reset('pg-test'); + } else if (state === "migrate-up") { + await migrateUp('pg-policy'); + } + } catch (err) { + console.error("Aborting command(s)"); + } +} + +async function migrateUp (environment) { + await executeCommand('db-migrate', ['up', '-e', environment], { env: mainEnvs }); +} +async function reset (environment) { + await executeCommand('db-migrate', ['reset', '-e', environment], { env: mainEnvs }); +} +async function startServer () { + await executeCommand('npm', ['start'], { env: { ...process.env }}); +} +async function startDev () { + await executeCommand('./node_modules/.bin/vue-cli-service', ['serve'], { env: { ...process.env }}); +} +async function test () { + await executeCommand('mocha', [], { env: { ...process.env }}); +} + +async function executeCommand (cmd, args) { + return new Promise((resolve, reject) => { + const child = spawn(cmd, args); + + child.stdout.setEncoding('utf8'); + child.stderr.setEncoding('utf8'); + child.stdout.on('data', e => process.stdout.write(e)); + child.stderr.on('data', e => process.stdout.write(e)); + + child.on('close', (code) => { + if (code === 1) reject(); + if (code === 0) resolve(); + }); + }); +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b91ffad2..83eb9fc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1804,6 +1804,16 @@ "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", @@ -1850,6 +1860,34 @@ } } }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, "cssnano": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", @@ -1889,6 +1927,25 @@ "path-exists": "^4.0.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -1975,6 +2032,16 @@ "minipass": "^3.1.1" } }, + "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, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, "terser-webpack-plugin": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", @@ -1991,6 +2058,18 @@ "terser": "^4.6.12", "webpack-sources": "^1.4.3" } + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.8.3", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", + "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + } } } }, @@ -5039,9 +5118,9 @@ } }, "dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-11.0.0.tgz", + "integrity": "sha512-Fp/b504Y5W+e+FpCxTFMUZ7ZEQkQYF0rx+KZtmwixJxGQbLHrhCwo3FjZgNC8vIfrSi29PABNbMoCGD9YoiXbQ==" }, "dotenv-expand": { "version": "5.1.0", @@ -13019,87 +13098,6 @@ } } }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.2.0", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.2.0.tgz", - "integrity": "sha512-TitGhqSQ61RJljMmhIGvfWzJ2zk9m1Qug049Ugml6QP3t0e95o0XJjk29roNEiPKJQBEi8Ord5hFuSuELzSp8Q==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "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, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "vue-resource": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/vue-resource/-/vue-resource-1.3.4.tgz", diff --git a/package.json b/package.json index 58249d61..a1b0fa5b 100644 --- a/package.json +++ b/package.json @@ -11,24 +11,15 @@ ], "private": true, "scripts": { - "dev": "npm run-script db-migrate-up && NODE_ENV=staging vue-cli-service serve", + "dev": "RUN_STATE=dev node entry.js", "serve": "vue-cli-service serve", "build": "NODE_ENV=build vue-cli-service build", "lint": "vue-cli-service lint", "start": "npm run dev", - "test": "npm run db-migrate-reset-pg-test > /dev/null 2>&1 && npm run db-migrate-up-pg-test > /dev/null 2>&1 && NODE_ENV=test mocha", - "start-pg-staging": "npm run build && npm run db-migrate-up-pg-staging && NODE_ENV=staging node index.js", - "start-pg-production": "npm run build && npm run db-migrate-up-pg-production && NODE_ENV=production node index.js", - "db-migrate": "node_modules/db-migrate/bin/db-migrate", - "db-migrate-up-pg-staging": "npm run db-migrate -- up -e pg-staging", - "db-migrate-up-pg-production": "npm run db-migrate -- up -e pg-production", - "db-migrate-reset-pg-staging": "npm run db-migrate -- reset -e pg-staging", - "db-migrate-up-pg-test": "npm run db-migrate -- up -e pg-test", - "db-migrate-reset-pg-test": "npm run db-migrate -- reset -e pg-test", - "start-server": "npm run build && npm run db-migrate-up && node index.js", - "start-test": "npm run db-migrate-reset > /dev/null 2>&1 && npm run db-migrate-up > /dev/null 2>&1 && NODE_ENV=production mocha", - "db-migrate-up": "npm run db-migrate -- up -e pg-policy", - "db-migrate-reset": "npm run db-migrate -- reset -e pg-policy" + "test": "RUN_STATE=test node entry.js", + "db-migrate-up": "RUN_STATE=migrate-up node entry.js", + "start-server": "npm run build && RUN_STATE=startup node entry.js", + "db-migrate-reset": "RUN_STATE=reset node entry.js" }, "dependencies": { "@popperjs/core": "^2.4.4", @@ -41,7 +32,7 @@ "cron": "1.3.0", "db-migrate": "^0.11.10", "db-migrate-pg": "1.2.2", - "dotenv": "4.0.0", + "dotenv": "^11.0.0", "express": "4.16.0", "helmet": "^3.15.1", "jquery": "^3.4.1", diff --git a/test/api/v1/about/about.js b/test/api/v1/about/about.js index 25ff8937..67a4d3f2 100644 --- a/test/api/v1/about/about.js +++ b/test/api/v1/about/about.js @@ -2,14 +2,8 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/about'; -common.get( - 'should return information about the policy server configuration', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data).to.be.an('object'); - done(); - } -); +common.startTest('should return information about the policy server configuration', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data).to.be.an('object'); +}); diff --git a/test/api/v1/applications/action.js b/test/api/v1/applications/action.js index 04c26f87..baa75ca5 100644 --- a/test/api/v1/applications/action.js +++ b/test/api/v1/applications/action.js @@ -1,69 +1,33 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/applications/action'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/applications/action'; -common.post( - 'should change application status', - endpoint, - {id: 1, approval_status: 'LIMITED'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should change application status', async function () { + const res = await common.post(endpoint, {id: 1, approval_status: 'LIMITED'}); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with only id', - endpoint, - {id: 1}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only id', async function () { + const res = await common.post(endpoint, {id: 1}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with only approval_status', - endpoint, - {approval_status: 'ACCEPTED'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only approval_status', async function () { + const res = await common.post(endpoint, {approval_status: 'ACCEPTED'}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with invalid approval_status', - endpoint, - {id: 1, approval_status: 'INVALID'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with invalid approval_status', async function () { + const res = await common.post(endpoint, {id: 1, approval_status: 'INVALID'}); + expect(res).to.have.status(400); +}); -common.post( - 'should not change status fo an invalid application id', - endpoint, - {id: 10000, approval_status: 'ACCEPTED'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should not change status for an invalid application id', async function () { + const res = await common.post(endpoint, {id: 10000, approval_status: 'ACCEPTED'}); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 when no body is specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 when no body is specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); \ No newline at end of file diff --git a/test/api/v1/applications/administrator.js b/test/api/v1/applications/administrator.js index c1151c84..a861f778 100644 --- a/test/api/v1/applications/administrator.js +++ b/test/api/v1/applications/administrator.js @@ -2,79 +2,42 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/applications/administrator'; -common.post( - 'should add the given uuid to the app_oem_enablements table', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', is_administrator_app: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should add the given uuid to the app_oem_enablements table', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, is_administrator_app: true}); + expect(res).to.have.status(200); +}); -common.post( - 'should remove the given uuid from the app_oem_enablements table', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', is_administrator_app: false}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should remove the given uuid from the app_oem_enablements table', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, is_administrator_app: false}); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with only uuid specified', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only uuid specified', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with only is_administrator_app specified', - endpoint, - {is_administrator_app: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only is_administrator_app specified', async function () { + const res = await common.post(endpoint, {is_administrator_app: true}); + expect(res).to.have.status(400); +}); -common.post( - 'should not add invalid uuid to the app_oem_enablements table', - endpoint, - {uuid: 'INVALID', is_administrator_app: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should not add invalid uuid to the app_oem_enablements table', async function () { + const res = await common.post(endpoint, {uuid: 'INVALID', is_administrator_app: true}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with invalid is_administrator_app', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802', is_administrator_app: 7}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with invalid is_administrator_app', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, is_administrator_app: 7}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); diff --git a/test/api/v1/applications/applications.js b/test/api/v1/applications/applications.js index 792ffaf3..79445f5e 100644 --- a/test/api/v1/applications/applications.js +++ b/test/api/v1/applications/applications.js @@ -1,39 +1,22 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/applications'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/applications'; -common.get( - 'should return all applications', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - //expect(res.body.data.applications).to.have.lengthOf.above(0); - done(); - } -); +common.startTest('should return all applications', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.applications).to.have.lengthOf.above(0); +}); -common.get( - 'should return the application with the given id', - endpoint, - {id: 1}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - //expect(res.body.data.applications).to.have.lengthOf(1); - done(); - } -); +common.startTest('should return the application with the given id', async function () { + const res = await common.get(endpoint, {id: 1}); + expect(res).to.have.status(200); + expect(res.body.data.applications).to.have.lengthOf(1); +}); -common.get( - 'should return the applications with the given uuid', - endpoint, - {uuid: '4b5145c5-0970-4a42-ba4b-08a9ff47aea3'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - //expect(res.body.data.applications).to.have.lengthOf.above(0); - done(); - } -); +common.startTest('should return the application with the given uuid', async function () { + const uuid = (await common.get(endpoint, {id: 1})).body.data.applications[0].uuid; + const res = await common.get(endpoint, {uuid: uuid}); + expect(res).to.have.status(200); + expect(res.body.data.applications).to.have.lengthOf.above(0); +}); \ No newline at end of file diff --git a/test/api/v1/applications/auto.js b/test/api/v1/applications/auto.js index 1efe51cd..b8eba889 100644 --- a/test/api/v1/applications/auto.js +++ b/test/api/v1/applications/auto.js @@ -1,80 +1,45 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/applications/auto'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/applications/auto'; -common.post( - 'should add the given uuid to the app_oem_enablements table', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', is_auto_approved_enabled: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should add the given uuid to the app_oem_enablements table', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, is_auto_approved_enabled: true}); + expect(res).to.have.status(200); +}); -common.post( - 'should remove the given uuid to the app_oem_enablements table', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', is_auto_approved_enabled: false}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should remove the given uuid to the app_oem_enablements table', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, is_auto_approved_enabled: false}); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with only uuid specified', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only uuid specified', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with only is_auto_approved_enabled specified', - endpoint, - {is_auto_approved_enabled: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only is_auto_approved_enabled specified', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {is_auto_approved_enabled: true}); + expect(res).to.have.status(400); +}); -common.post( - 'should not add invalid uuid to the app_oem_enablements table', - endpoint, - {uuid: 'INVALID', is_auto_approved_enabled: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should not add invalid uuid to the app_oem_enablements table', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: 'INVALID', is_auto_approved_enabled: true}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with invalid is_auto_approved_enabled', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802', is_auto_approved_enabled: 7}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with invalid is_auto_approved_enabled', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802', is_auto_approved_enabled: 7}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with no body specified', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/applications/certificate-get.js b/test/api/v1/applications/certificate-get.js index ccd5200f..f8114019 100644 --- a/test/api/v1/applications/certificate-get.js +++ b/test/api/v1/applications/certificate-get.js @@ -10,46 +10,26 @@ if (!common.config.certificateAuthority.authorityKeyFileName || return; } -common.get( - 'should return certificate data for an app (GET)', - endpoint, - {appId: '30ea6bce-91de-4b18-8b52-68d82112eee6'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should return certificate data for an app (GET)', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.get(endpoint, {appId: uuid}); + expect(res).to.have.status(200); +}); -common.post( - 'should return certificate data for an app (POST)', - endpoint, - {appId: '30ea6bce-91de-4b18-8b52-68d82112eee6'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should return certificate data for an app (POST)', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {appId: uuid}); + expect(res).to.have.status(200); +}); -common.get( - 'should return 400 with an invalid app id (GET)', - endpoint, - {appId: '0'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with an invalid app id (GET)', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.get(endpoint, {appId: '0'}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with an invalid app id (POST)', - endpoint, - {appId: '0'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); \ No newline at end of file +common.startTest('should return 400 with an invalid app id (POST)', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {appId: '0'}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/applications/certificate.js b/test/api/v1/applications/certificate.js index 90ddd05a..beaa1a1b 100644 --- a/test/api/v1/applications/certificate.js +++ b/test/api/v1/applications/certificate.js @@ -11,133 +11,89 @@ if (!common.config.certificateAuthority.authorityKeyFileName || return; } -function generateCertificate (done) { - chai.request(common.BASE_URL) - .post('/api/v1/security/certificate') - .set('Accept', 'application/json') - .set('Content-Type', 'application/json') - .set('BASIC-AUTH-PASSWORD', common.config.basicAuthPassword) - .send({}) - .end(done); +async function generateCertificate () { + const res = await common.post('/api/v1/security/certificate', {}); + expect(res).to.have.status(200); + expect(res).to.have.nested.property('body.data.certificate'); + expect(res).to.have.nested.property('body.data.serviceKey'); + return res.body.data; } -it('should store an app certificate with valid cert and key data', (done) => { - generateCertificate( (err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res).to.have.nested.property('body.data.certificate'); - expect(res).to.have.nested.property('body.data.serviceKey'); - - //store thee cert and key received - chai.request(common.BASE_URL) - .post(endpoint) - .set('Accept', 'application/json') - .set('Content-Type', 'application/json') - .set('BASIC-AUTH-PASSWORD', common.config.basicAuthPassword) - .send({ - options: { - app_uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', - clientKey: res.body.data.clientKey, - certificate: res.body.data.certificate, - }, - }) - .end((err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - }); +common.startTest('should store an app certificate with valid cert and key data', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const certData = await generateCertificate(); + //store the cert and key received + const res = await common.post(endpoint, { + options: { + app_uuid: uuid, + clientKey: certData.clientKey, + certificate: certData.certificate, + }, }); + expect(res).to.have.status(200); }); -common.post( - 'should fail storing an app certificate with invalid cert and key data', - endpoint, - { +common.startTest('should fail storing an app certificate with invalid cert and key data', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + //store the cert and key received + const res = await common.post(endpoint, { options: { - app_uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', + app_uuid: uuid, clientKey: 'test1', certificate: 'test2', } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(500); - done(); - } -); + }); + expect(res).to.have.status(500); +}); -common.post( - 'should fail storing an app certificate with no app uuid', - endpoint, - { +common.startTest('should fail storing an app certificate with no app uuid', async function () { + const certData = await generateCertificate(); + //store the cert and key received + const res = await common.post(endpoint, { options: { - clientKey: 'test1', - certificate: 'test2', + clientKey: certData.clientKey, + certificate: certData.certificate } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); -common.post( - 'should fail storing an app certificate with no clientKey', - endpoint, - { +common.startTest('should fail storing an app certificate with no clientKey', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const certData = await generateCertificate(); + //store the cert and key received + const res = await common.post(endpoint, { options: { - app_uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', - certificate: 'test2', - } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + app_uuid: uuid, + certificate: certData.certificate + }, + }); + expect(res).to.have.status(400); +}); -common.post( - 'should fail storing an app certificate with no certificate', - endpoint, - { +common.startTest('should fail storing an app certificate with no certificate', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const certData = await generateCertificate(); + //store the cert and key received + const res = await common.post(endpoint, { options: { - app_uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', - clientKey: 'test1', - } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -it('should return 400 when storing a certificate with an invalid app uuid', (done) => { - generateCertificate( (err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res).to.have.nested.property('body.data.certificate'); - expect(res).to.have.nested.property('body.data.serviceKey'); + app_uuid: uuid, + clientKey: certData.clientKey + }, + }); + expect(res).to.have.status(400); +}); - //store thee cert and key received - chai.request(common.BASE_URL) - .post(endpoint) - .set('Accept', 'application/json') - .set('Content-Type', 'application/json') - .set('BASIC-AUTH-PASSWORD', common.config.basicAuthPassword) - .send({ - options: { - app_uuid: '-1', - clientKey: res.body.data.clientKey, - certificate: res.body.data.certificate, - }, - }) - .end((err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - }); +common.startTest('should return 400 when storing a certificate with an invalid app uuid', async function () { + const certData = await generateCertificate(); + //store the cert and key received + const res = await common.post(endpoint, { + options: { + app_uuid: '-1', + clientKey: certData.clientKey, + certificate: certData.certificate, + }, }); + expect(res).to.have.status(400); }); + diff --git a/test/api/v1/applications/groups.js b/test/api/v1/applications/groups.js index 2a3f18f2..842d4c5b 100644 --- a/test/api/v1/applications/groups.js +++ b/test/api/v1/applications/groups.js @@ -4,120 +4,59 @@ const endpoint = '/api/v1/applications/groups'; //PUT TESTS -common.put( - 'should change functional group selection (selected)', - endpoint, - {app_id: 1, property_name: 'Notifications', is_selected: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); - -common.put( - 'should change functional group selection (unselected)', - endpoint, - {app_id: 1, property_name: 'Notifications', is_selected: false}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); - -common.put( - 'should return 400 when no parameters are provided', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with missing is_selected', - endpoint, - {app_id: 1, property_name: 'Notifications'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with missing property_name', - endpoint, - {app_id: 1, is_selected: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with missing app_id', - endpoint, - {property_name: 'Notifications', is_selected: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should not accept an invalid application id', - endpoint, - {app_id: 10000, property_name: 'Notifications', is_selected: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - +common.startTest('should change functional group selection (selected)', async function () { + const res = await common.put(endpoint, {app_id: 1, property_name: 'Notifications', is_selected: true}); + expect(res).to.have.status(200); +}); + +common.startTest('should change functional group selection (unselected)', async function () { + const res = await common.put(endpoint, {app_id: 1, property_name: 'Notifications', is_selected: false}); + expect(res).to.have.status(200); +}); + +common.startTest('should return 400 when no parameters are provided', async function () { + const res = await common.put(endpoint, {}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with missing is_selected', async function () { + const res = await common.put(endpoint, {app_id: 1, property_name: 'Notifications'}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with missing property_name', async function () { + const res = await common.put(endpoint, {app_id: 1, is_selected: true}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with missing app_id', async function () { + const res = await common.put(endpoint, {property_name: 'Notifications', is_selected: true}); + expect(res).to.have.status(400); +}); + +common.startTest('should not accept an invalid application id', async function () { + const res = await common.put(endpoint, {app_id: 10000, property_name: 'Notifications', is_selected: true}); + expect(res).to.have.status(400); +}); //GET TESTS -common.get( - 'should return an array of assignable non-proprietary functional groups for a valid app id', - endpoint, - {app_id: 1, is_proprietary_group: false, environment: "STAGING"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.groups).to.be.an('array').that.is.not.empty; - done(); - } -); - -common.get( - 'should return an empty array for an invalid app id', - endpoint, - {app_id: 10000, is_proprietary_group: true, environment: "STAGING"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.groups).to.be.an('array').that.is.empty; - done(); - } -); - -common.get( - 'should return an empty array for a valid app id but with is_proprietary_group set to true when theres none available', - endpoint, - {app_id: 1, is_proprietary_group: true, environment: "STAGING"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.groups).to.be.an('array').that.is.empty; - done(); - } -); +common.startTest('should return an array of assignable non-proprietary functional groups for a valid app id', async function () { + const res = await common.get(endpoint, {app_id: 1, is_proprietary_group: false, environment: "STAGING"}); + expect(res).to.have.status(200); + expect(res.body.data.groups).to.be.an('array').that.is.not.empty; +}); + +common.startTest('should return an empty array for an invalid app id', async function () { + const res = await common.get(endpoint, {app_id: 10000, is_proprietary_group: true, environment: "STAGING"}); + expect(res).to.have.status(200); + expect(res.body.data.groups).to.be.an('array').that.is.empty; +}); + +common.startTest('should return an empty array for a valid app id but with is_proprietary_group set to true when theres none available', async function () { + const res = await common.get(endpoint, {app_id: 1, is_proprietary_group: true, environment: "STAGING"}); + expect(res).to.have.status(200); + expect(res.body.data.groups).to.be.an('array').that.is.empty; +}); diff --git a/test/api/v1/applications/hybrid.js b/test/api/v1/applications/hybrid.js index eea574f9..2d5d64a8 100644 --- a/test/api/v1/applications/hybrid.js +++ b/test/api/v1/applications/hybrid.js @@ -2,90 +2,49 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/applications/hybrid'; -common.post( - 'should add the given uuid to the app_hybrid_preference table with value CLOUD', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', hybrid_preference: "CLOUD"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should add the given uuid to the app_hybrid_preference table with value CLOUD', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, hybrid_preference: "CLOUD"}); + expect(res).to.have.status(200); +}); + +common.startTest('should add the given uuid to the app_hybrid_preference table with value MOBILE', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, hybrid_preference: "MOBILE"}); + expect(res).to.have.status(200); +}); + +common.startTest('should add the given uuid to the app_hybrid_preference table with value BOTH', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, hybrid_preference: "BOTH"}); + expect(res).to.have.status(200); +}); + +common.startTest('should return 500 with only uuid specified', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid}); + expect(res).to.have.status(500); +}); + +common.startTest('should return 400 with only hybrid_preference specified', async function () { + const res = await common.post(endpoint, {hybrid_preference: "BOTH"}); + expect(res).to.have.status(400); +}); + +common.startTest('should not add invalid uuid to the app_hybrid_preference table', async function () { + const res = await common.post(endpoint, {uuid: 'INVALID', hybrid_preference: "BOTH"}); + expect(res).to.have.status(500); +}); + +common.startTest('should return 400 with invalid hybrid_preference', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, hybrid_preference: "TESTING"}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with no body specified', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); -common.post( - 'should add the given uuid to the app_hybrid_preference table with value MOBILE', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', hybrid_preference: "MOBILE"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); - -common.post( - 'should add the given uuid to the app_hybrid_preference table with value BOTH', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', hybrid_preference: "BOTH"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); - -common.post( - 'should return 500 with only uuid specified', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(500); - done(); - } -); - -common.post( - 'should return 400 with only hybrid_preference specified', - endpoint, - {hybrid_preference: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.post( - 'should not add invalid uuid to the app_hybrid_preference table', - endpoint, - {uuid: 'INVALID', hybrid_preference: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.post( - 'should return 400 with invalid hybrid_preference', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802', hybrid_preference: "TESTING"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); diff --git a/test/api/v1/applications/passthrough.js b/test/api/v1/applications/passthrough.js index 9e42d283..2266dc83 100644 --- a/test/api/v1/applications/passthrough.js +++ b/test/api/v1/applications/passthrough.js @@ -2,79 +2,41 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/applications/passthrough'; -common.post( - 'should add the given uuid to the app_oem_enablements table', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', allow_unknown_rpc_passthrough: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should add the given uuid to the app_oem_enablements table', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, allow_unknown_rpc_passthrough: true}); + expect(res).to.have.status(200); +}); -common.post( - 'should remove the given uuid from the app_oem_enablements table', - endpoint, - {uuid: '30ea6bce-91de-4b18-8b52-68d82112eee6', allow_unknown_rpc_passthrough: false}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should remove the given uuid from the app_oem_enablements table', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, allow_unknown_rpc_passthrough: false}); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with only uuid specified', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only uuid specified', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with only allow_unknown_rpc_passthrough specified', - endpoint, - {allow_unknown_rpc_passthrough: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only allow_unknown_rpc_passthrough specified', async function () { + const res = await common.post(endpoint, {allow_unknown_rpc_passthrough: true}); + expect(res).to.have.status(400); +}); -common.post( - 'should not add invalid uuid to the app_oem_enablements table', - endpoint, - {uuid: 'INVALID', allow_unknown_rpc_passthrough: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should not add invalid uuid to the app_oem_enablements table', async function () { + const res = await common.post(endpoint, {uuid: 'INVALID', allow_unknown_rpc_passthrough: true}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with invalid allow_unknown_rpc_passthrough', - endpoint, - {uuid: 'dfda5c35-700e-487e-87d2-ea4b2c572802', allow_unknown_rpc_passthrough: 7}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with invalid allow_unknown_rpc_passthrough', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, {uuid: uuid, allow_unknown_rpc_passthrough: 7}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); \ No newline at end of file diff --git a/test/api/v1/applications/permission.js b/test/api/v1/applications/permission.js index 7eb7c476..6c5d989e 100644 --- a/test/api/v1/applications/permission.js +++ b/test/api/v1/applications/permission.js @@ -2,90 +2,43 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/applications/service/permission'; -common.put( - 'should add the application service permission info to the app_service_type_permissions table', - endpoint, - {id: 1, is_selected: true, service_type_name: "MEDIA", permission_name: "ButtonPress"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should add the application service permission info to the app_service_type_permissions table', async function () { + const res = await common.put(endpoint, {id: 1, is_selected: true, service_type_name: "MEDIA", permission_name: "ButtonPress"}); + expect(res).to.have.status(200); +}); + +common.startTest('should remove the application service permission info from the app_service_type_permissions table', async function () { + const res = await common.put(endpoint, {id: 1, is_selected: false, service_type_name: "MEDIA", permission_name: "ButtonPress"}); + expect(res).to.have.status(200); +}); + +common.startTest('should return 400 using an invalid id', async function () { + const res = await common.put(endpoint, {id: -1, is_selected: false, service_type_name: "MEDIA", permission_name: "ButtonPress"}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with only id', async function () { + const res = await common.put(endpoint, {id: 1}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with only is_selected', async function () { + const res = await common.put(endpoint, {is_selected: false}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with only service_type_name', async function () { + const res = await common.put(endpoint, {service_type_name: "MEDIA"}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with only permission_name', async function () { + const res = await common.put(endpoint, {permission_name: "ButtonPress"}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.put(endpoint, {}); + expect(res).to.have.status(400); +}); -common.put( - 'should remove the application service permission info from the app_service_type_permissions table', - endpoint, - {id: 1, is_selected: false, service_type_name: "MEDIA", permission_name: "ButtonPress"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); - -common.put( - 'should return 400 using an invalid id', - endpoint, - {id: -1, is_selected: false, service_type_name: "MEDIA", permission_name: "ButtonPress"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with only id', - endpoint, - {id: 1}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with only is_selected', - endpoint, - {is_selected: false}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with only service_type_name', - endpoint, - {service_type_name: "MEDIA"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with only permission_name', - endpoint, - {permission_name: "ButtonPress"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); - -common.put( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); diff --git a/test/api/v1/applications/rpcencryption.js b/test/api/v1/applications/rpcencryption.js index 3126747f..20acab93 100644 --- a/test/api/v1/applications/rpcencryption.js +++ b/test/api/v1/applications/rpcencryption.js @@ -2,79 +2,38 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/applications/rpcencryption'; -common.put( - 'should change the apps encryption required status to true', - endpoint, - {id: 1, encryption_required: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should change the apps encryption required status to true', async function () { + const res = await common.put(endpoint, {id: 1, encryption_required: true}); + expect(res).to.have.status(200); +}); -common.put( - 'should change the apps encryption required status to false', - endpoint, - {id: 1, encryption_required: false}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should change the apps encryption required status to false', async function () { + const res = await common.put(endpoint, {id: 1, encryption_required: false}); + expect(res).to.have.status(200); +}); -common.put( - 'should return 400 with only id specified', - endpoint, - {id: 1}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only id specified', async function () { + const res = await common.put(endpoint, {id: 1}); + expect(res).to.have.status(400); +}); -common.put( - 'should return 400 with only encryption_required specified', - endpoint, - {encryption_required: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with only encryption_required specified', async function () { + const res = await common.put(endpoint, {encryption_required: true}); + expect(res).to.have.status(400); +}); -common.put( - 'should not succeed with an invalid id', - endpoint, - {id: -1, encryption_required: true}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(500); - done(); - } -); +common.startTest('should not succeed with an invalid id', async function () { + const res = await common.put(endpoint, {id: -1, encryption_required: true}); + expect(res).to.have.status(500); +}); -common.put( - 'should not succeed with an invalid encryption_required', - endpoint, - {id: -1, encryption_required: "nope"}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should not succeed with an invalid encryption_required', async function () { + const res = await common.put(endpoint, {id: -1, encryption_required: "nope"}); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.put(endpoint, {}); + expect(res).to.have.status(400); +}); -common.put( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); diff --git a/test/api/v1/applications/store.js b/test/api/v1/applications/store.js new file mode 100644 index 00000000..bcd2a9c9 --- /dev/null +++ b/test/api/v1/applications/store.js @@ -0,0 +1,77 @@ +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/applications/store'; +const endpointStaging = '/api/v1/applications/store/staging'; + +common.startTest('should retrieve all embedded staging applications', async function () { + const res = await common.get('/api/v1/applications', {}); + const webengineApps = res.body.data.applications.filter(app => app.platform === 'EMBEDDED'); + + // put all webengine apps on STAGING. these should then be viewable in the staging route + for (let app of webengineApps) { + await common.post('/api/v1/applications/action', {id: app.id, approval_status: 'STAGING'}); + } + + const res2 = await common.get(endpointStaging, {}); + expect(res2).to.have.status(200); + + let webengineNames = webengineApps.map(app => app.name); + + for (let app of res2.body.data.applications) { + expect(webengineNames.includes(app.name)).to.equal(true); + } +}); + +common.startTest('should retrieve one embedded staging application', async function () { + const res = await common.get(endpointStaging, {}); + const apps = res.body.data.applications; + + + const res2 = await common.get(endpointStaging, {uuid: apps[0].policyAppID}); + expect(res2).to.have.status(200); + expect(res2.body.data.applications).to.have.lengthOf(1); +}); + +common.startTest('should succeed in retrieving staging applications with transport_type data', async function () { + const res = await common.get(endpointStaging, { + transport_type: 'websocket' + }); + + expect(res).to.have.status(200); +}); + +common.startTest('should retrieve all embedded production applications', async function () { + const res = await common.get('/api/v1/applications', {}); + const webengineApps = res.body.data.applications.filter(app => app.platform === 'EMBEDDED'); + + // put all webengine apps on PRODUCTION. these should then be viewable in the staging route + for (let app of webengineApps) { + await common.post('/api/v1/applications/action', {id: app.id, approval_status: 'ACCEPTED'}); + } + + const res2 = await common.get(endpoint, {}); + expect(res2).to.have.status(200); + + let webengineNames = webengineApps.map(app => app.name); + + for (let app of res2.body.data.applications) { + expect(webengineNames.includes(app.name)).to.equal(true); + } +}); + +common.startTest('should retrieve one embedded production application', async function () { + const res = await common.get(endpoint, {}); + const apps = res.body.data.applications; + + const res2 = await common.get(endpoint, {uuid: apps[0].policyAppID}); + expect(res2).to.have.status(200); + expect(res2.body.data.applications).to.have.lengthOf(1); +}); + +common.startTest('should succeed in retrieving production applications with transport_type data', async function () { + const res = await common.get(endpoint, { + transport_type: 'websocket' + }); + + expect(res).to.have.status(200); +}); diff --git a/test/api/v1/groups/groups.js b/test/api/v1/groups/groups.js index 08bd3418..9282ba9e 100644 --- a/test/api/v1/groups/groups.js +++ b/test/api/v1/groups/groups.js @@ -1,104 +1,57 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/groups'; - -common.get( - 'should get all groups', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.groups).to.have.lengthOf.above(0); - done(); - } -); - -common.get( - 'should get group with given id', - endpoint, - {id: 1}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.groups).to.have.lengthOf(1); - done(); - } -); - -common.get( - 'should not get any groups with invalid id', - endpoint, - {id: 1000}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.groups).to.have.lengthOf(0); - done(); - } -); - -common.post( - 'should add new group', - endpoint, - { +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/groups'; + +common.startTest('should get all groups', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.groups).to.have.lengthOf.above(0); +}); + +common.startTest('should get group with given id', async function () { + const res = await common.get(endpoint, {id: 1}); + expect(res).to.have.status(200); + expect(res.body.data.groups).to.have.lengthOf(1); +}); + +common.startTest('should not get any groups with invalid id', async function () { + const res = await common.get(endpoint, {id: 1000}); + expect(res).to.have.status(200); + expect(res.body.data.groups).to.have.lengthOf(0); +}); + +common.startTest('should add new group', async function () { + const res = await common.post(endpoint, { name: 'Blarg', is_default: false, - rpcs: [ - - ], + rpcs: [], user_consent_prompt: '' - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with invalid name type', - endpoint, - { +common.startTest('should return 400 with invalid name type', async function () { + const res = await common.post(endpoint, { name: 7, is_default: false, - rpcs: [ - - ], + rpcs: [], user_consent_prompt: '' - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with invalid is_default type', - endpoint, - { +common.startTest('should return 400 with invalid is_default type', async function () { + const res = await common.post(endpoint, { name: 'Blarg', is_default: 7, - rpcs: [ - - ], + rpcs: [], user_consent_prompt: '' - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); diff --git a/test/api/v1/groups/names.js b/test/api/v1/groups/names.js index 861eecbd..25d1c329 100644 --- a/test/api/v1/groups/names.js +++ b/test/api/v1/groups/names.js @@ -1,15 +1,17 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/groups/names'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/groups/names'; -// TODO: check that info is correct -common.get( - 'get with no parameters', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); +common.startTest('get with no parameters', async function () { + const groups = (await common.get('/api/v1/groups', {environment: 'staging'})).body.data.groups; + const groupNames = groups.map(group => group.name); + + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.names).to.have.lengthOf.above(0); + + // check that the data returned from the group names has a corresponding functional group name on staging + for (let name of res.body.data.names) { + expect(groupNames.includes(name)).to.equal(true); } -); +}); \ No newline at end of file diff --git a/test/api/v1/groups/promote.js b/test/api/v1/groups/promote.js index 1f0e91f5..c93d075a 100644 --- a/test/api/v1/groups/promote.js +++ b/test/api/v1/groups/promote.js @@ -1,47 +1,27 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/groups/promote'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/groups/promote'; -common.post( - 'should promote group to production', - endpoint, - {id: [ 1 ]}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should promote group to production', async function () { + const res = await common.post(endpoint, {id: [ 1 ]}); + expect(res).to.have.status(200); +}); -common.post( - 'should promote groups to production', - endpoint, - {id: [ 2, 3, 4 ]}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should promote groups to production', async function () { + const res = await common.post(endpoint, {id: [ 2, 3, 4 ]}); + expect(res).to.have.status(200); +}); -common.post( - 'should not promote group with invalid id', - endpoint, - {id: [ 1000 ]}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should not promote group with invalid id', async function () { + const res = await common.post(endpoint, {id: [ 1000 ]}); + expect(res).to.have.status(200); -common.post( - 'should return 400 with no body', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + const res2 = await common.get('/api/v1/groups', {id: 1000}); + expect(res2).to.have.status(200); + expect(res2.body.data.groups).to.have.lengthOf(0); +}); + +common.startTest('should return 400 with no body', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/login/login.js b/test/api/v1/login/login.js index c2c68b45..803cd378 100644 --- a/test/api/v1/login/login.js +++ b/test/api/v1/login/login.js @@ -7,36 +7,21 @@ const oldPassword = common.config.basicAuthPassword; common.config.authType = 'basic'; common.config.basicAuthPassword = 'testing'; -common.post( - 'return a 401 when trying to login with the wrong password', - endpoint, - { +common.startTest('return a 401 when trying to login with the wrong password', async function () { + const res = await common.post(endpoint, { password: 'nope' - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(401); - done(); - } -); + }); + expect(res).to.have.status(401); +}); -common.post( - 'return a 200 when trying to login with the right password', - endpoint, - { +common.startTest('return a 200 when trying to login with the right password', async function () { + const res = await common.post(endpoint, { password: 'testing' - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - - //reset - common.config.authType = undefined; - common.config.basicAuthPassword = oldPassword; - - done(); - } -); - + }); + expect(res).to.have.status(200); + //reset + common.config.authType = undefined; + common.config.basicAuthPassword = oldPassword; +}); diff --git a/test/api/v1/messages/messages.js b/test/api/v1/messages/messages.js index 5a41b0e8..8d2d3dbe 100644 --- a/test/api/v1/messages/messages.js +++ b/test/api/v1/messages/messages.js @@ -1,98 +1,57 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/messages'; - -common.get( - 'should get all messages', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.messages).to.have.lengthOf.above(0); - done(); - } -); - -common.get( - 'should get message with the given id', - endpoint, - {id: 1}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.messages).to.have.lengthOf(1); - done(); - } -); - -common.get( - 'should not get any message with invalid id', - endpoint, - {id: 1000}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.messages).to.have.lengthOf(0); - done(); - } -); - -common.post( - 'should create new message', - endpoint, - { +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/messages'; + +common.startTest('should get all messages', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.messages).to.have.lengthOf.above(0); +}); + +common.startTest('should get message with the given id', async function () { + const res = await common.get(endpoint, {id: 1}); + expect(res).to.have.status(200); + expect(res.body.data.messages).to.have.lengthOf(1); +}); + +common.startTest('should not get any message with invalid id', async function () { + const res = await common.get(endpoint, {id: 1000}); + expect(res).to.have.status(200); + expect(res.body.data.messages).to.have.lengthOf(0); +}); + +common.startTest('should create new message', async function () { + const res = await common.post(endpoint, { messages: [ { message_category: 'Blarg', is_deleted: false, - languages: [ - - ] + languages: [] } ] - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with invalid messages', - endpoint, - { +common.startTest('should return 400 with invalid messages', async function () { + const res = await common.post(endpoint, { messages: [ { message_category: 'Blarg', - languages: [ - - ] + languages: [] }, { message_category: 'Blarg2', is_deleted: false, - languages: [ - - ] + languages: [] } ] - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); diff --git a/test/api/v1/messages/names.js b/test/api/v1/messages/names.js index 905405a2..a8021a75 100644 --- a/test/api/v1/messages/names.js +++ b/test/api/v1/messages/names.js @@ -1,15 +1,17 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/messages/names'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/messages/names'; -// TODO: check that info is correct -common.get( - 'get with no parameters', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); +common.startTest('get with no parameters', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + const names = res.body.data.names; + + const messages = (await common.get('/api/v1/messages', {environment: 'staging'})).body.data.messages + const messageNames = messages.map(message => message.message_category); + + // check that the data returned from the message names has a corresponding consumer message group name on staging + for (let name of names) { + expect(messageNames.includes(name)).to.equal(true); } -); +}); diff --git a/test/api/v1/messages/promote.js b/test/api/v1/messages/promote.js index 2bca8717..b4a5b254 100644 --- a/test/api/v1/messages/promote.js +++ b/test/api/v1/messages/promote.js @@ -1,47 +1,27 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/messages/promote'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/messages/promote'; -common.post( - 'should promote the message with the given id', - endpoint, - {id: [ 1 ]}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should promote the message with the given id', async function () { + const res = await common.post(endpoint, {id: [ 1 ]}); + expect(res).to.have.status(200); +}); -common.post( - 'should promote the messages with the given ids', - endpoint, - {id: [ 2, 3, 4 ]}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should promote the messages with the given ids', async function () { + const res = await common.post(endpoint, {id: [ 2, 3, 4 ]}); + expect(res).to.have.status(200); +}); -common.post( - 'should not promote message with invalid id', - endpoint, - {id: [ 1000 ]}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should not promote message with invalid id', async function () { + const res = await common.post(endpoint, {id: [ 1000 ]}); + expect(res).to.have.status(200); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + const res2 = await common.get('/api/v1/messages', {id: 1000}); + expect(res2).to.have.status(200); + expect(res2.body.data.messages).to.have.lengthOf(0); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/messages/update.js b/test/api/v1/messages/update.js index bfa8febf..e4050304 100644 --- a/test/api/v1/messages/update.js +++ b/test/api/v1/messages/update.js @@ -1,14 +1,8 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/messages/update'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/messages/update'; -common.post( - 'should update the list of languages', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should update the list of languages', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(200); +}); diff --git a/test/api/v1/module/module.js b/test/api/v1/module/module.js index 2cfca8f5..b9cc19c2 100644 --- a/test/api/v1/module/module.js +++ b/test/api/v1/module/module.js @@ -1,47 +1,27 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/module'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/module'; -common.get( - 'should get module config with given id', - endpoint, - {id: 1}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.module_configs).to.have.lengthOf(1); - done(); - } -); +common.startTest('should get module config with given id', async function () { + const res = await common.get(endpoint, {id: 1}); + expect(res).to.have.status(200); + expect(res.body.data.module_configs).to.have.lengthOf(1); +}); -common.get( - 'should not return any module config with invalid id', - endpoint, - {id: 1000}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.module_configs).to.have.lengthOf(0); - done(); - } -); +common.startTest('should not return any module config with invalid id', async function () { + const res = await common.get(endpoint, {id: 1000}); + expect(res).to.have.status(200); + expect(res.body.data.module_configs).to.have.lengthOf(0); +}); -common.get( - 'should get the most recent module config', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.module_configs).to.have.lengthOf(1); - done(); - } -); +common.startTest('should get the most recent module config', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.module_configs).to.have.lengthOf(1); +}); -common.post( - 'should create a new staging module config', - endpoint, - { +common.startTest('should create a new staging module config', async function () { + const res = await common.post(endpoint, { preloaded_pt: true, exchange_after_x_ignition_cycles: 20, exchange_after_x_kilometers: 200, @@ -78,21 +58,12 @@ common.post( PROJECTION: 10 }, lock_screen_dismissal_enabled: true - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + expect(res).to.have.status(200); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/module/promote.js b/test/api/v1/module/promote.js index dde94c89..e028d156 100644 --- a/test/api/v1/module/promote.js +++ b/test/api/v1/module/promote.js @@ -1,11 +1,9 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/module/promote'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/module/promote'; -common.post( - 'should create new production module config', - endpoint, - { +common.startTest('should create new production module config', async function () { + const res = await common.get(endpoint, { preloaded_pt: true, exchange_after_x_ignition_cycles: 20, exchange_after_x_kilometers: 200, @@ -42,21 +40,11 @@ common.post( PROJECTION: 10 }, lock_screen_dismissal_enabled: true - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); \ No newline at end of file diff --git a/test/api/v1/permissions/unmapped.js b/test/api/v1/permissions/unmapped.js index c452e0f2..f1efa8e0 100644 --- a/test/api/v1/permissions/unmapped.js +++ b/test/api/v1/permissions/unmapped.js @@ -1,36 +1,18 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/permissions/unmapped'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/permissions/unmapped'; -common.get( - 'should get unmapped permissions in staging', - endpoint, - {environment: 'staging'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should get unmapped permissions in staging', async function () { + const res = await common.post(endpoint, {environment: 'staging'}); + expect(res).to.have.status(200); +}); -common.get( - 'should get unmapped permissions in production', - endpoint, - {environment: 'production'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should get unmapped permissions in production', async function () { + const res = await common.post(endpoint, {environment: 'production'}); + expect(res).to.have.status(200); +}); -common.get( - 'should get unmapped production permissions when no environment is specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should get unmapped production permissions when no environment is specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(200); +}); diff --git a/test/api/v1/permissions/update.js b/test/api/v1/permissions/update.js index a9b0b6b6..ea5c848d 100644 --- a/test/api/v1/permissions/update.js +++ b/test/api/v1/permissions/update.js @@ -1,14 +1,8 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/permissions/update'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/permissions/update'; -common.post( - 'should update permissions', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should update permissions', async function () { + const res = await common.post(endpoint); + expect(res).to.have.status(200); +}); diff --git a/test/api/v1/policy/apps.js b/test/api/v1/policy/apps.js index f6843b35..7b9048d0 100644 --- a/test/api/v1/policy/apps.js +++ b/test/api/v1/policy/apps.js @@ -1,89 +1,68 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/policy/apps'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/policy/apps'; -common.post( - 'should get staging policy objects', - endpoint, - { +common.startTest('should get staging policy objects', async function () { + const apps = (await common.get('/api/v1/applications', {})).body.data.applications; + const first3Uuids = apps.map(app => app.uuid).slice(0, 3); + const appObj = {}; + for (let uuid of first3Uuids) { + appObj[uuid] = {}; + } + + const res = await common.post(endpoint, { policy_table: { - app_policies: { - "pancakes": 1, - "ac0a3e87-a45a-4c29-af4c-a3a4955a5ad1": 1, - "dfda5c35-700e-487e-87d2-ea4b2c572802": 2 - } + app_policies: appObj }, environment: "staging" - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(Object.keys(res.body.data[0].policy_table.app_policies).length).to.equal(6); - done(); + }); + + expect(res).to.have.status(200); + expect(Object.keys(res.body.data[0].policy_table.app_policies).length).to.equal(6); +}); + +common.startTest('should get production policy objects', async function () { + const apps = (await common.get('/api/v1/applications', {})).body.data.applications; + const first3Uuids = apps.map(app => app.uuid).slice(0, 3); + const appObj = {}; + for (let uuid of first3Uuids) { + appObj[uuid] = {}; } -); -common.post( - 'should get production policy objects', - endpoint, - { + const res = await common.post(endpoint, { policy_table: { - app_policies: { - "pancakes": 1, - "ac0a3e87-a45a-4c29-af4c-a3a4955a5ad1": 1, - "dfda5c35-700e-487e-87d2-ea4b2c572802": 2 - } + app_policies: appObj }, environment: "production" - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(Object.keys(res.body.data[0].policy_table.app_policies).length).to.equal(6); - done(); - } -); + }); -common.post( - 'should return 400 with no app policies specified', - endpoint, - { - policy_table: { + expect(res).to.have.status(200); + expect(Object.keys(res.body.data[0].policy_table.app_policies).length).to.equal(6); +}); - } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with no app policies specified', async function () { + const res = await common.post(endpoint, { + policy_table: {}, + environment: "production" + }); -common.post( - 'should get default permissions for invalid app uuid', - endpoint, - { + expect(res).to.have.status(400); +}); + +common.startTest('should get default permissions for invalid app uuid', async function () { + const res = await common.post(endpoint, { policy_table: { app_policies: { - "INVALID_APP": 1 + "INVALID_APP": {} } } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(Object.keys(res.body.data[0].policy_table.app_policies).length).to.equal(4); - done(); - } -); + }); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + expect(res).to.have.status(200); + expect(Object.keys(res.body.data[0].policy_table.app_policies).length).to.equal(4); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/policy/preview.js b/test/api/v1/policy/preview.js index 10523799..32b4e3c4 100644 --- a/test/api/v1/policy/preview.js +++ b/test/api/v1/policy/preview.js @@ -1,25 +1,13 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/policy/preview'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/policy/preview'; -common.get( - 'should get production policy table by default', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should get production policy table by default', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); +}); -common.get( - 'should get policy table for given environment', - endpoint, - {environment: 'staging'}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should get policy table for given environment', async function () { + const res = await common.get(endpoint, {environment: 'staging'}); + expect(res).to.have.status(200); +}); diff --git a/test/api/v1/policy/production.js b/test/api/v1/policy/production.js index 09973dcc..c6607277 100644 --- a/test/api/v1/policy/production.js +++ b/test/api/v1/policy/production.js @@ -1,11 +1,9 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/production/policy'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/production/policy'; -common.post( - 'should return production policy table', - endpoint, - { +common.startTest('should return staging policy table', async function () { + const res = await common.post(endpoint, { policy_table: { app_policies: {}, consumer_friendly_messages: {}, @@ -14,18 +12,12 @@ common.post( module_config: {}, usage_and_error_counts: {} } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with invalid policy_table', - endpoint, - { +common.startTest('should return 400 with invalid policy_table', async function () { + const res = await common.post(endpoint, { policy_table: { app_policies: {}, consumer_friendly_messages: {}, @@ -33,21 +25,12 @@ common.post( module_config: {}, usage_and_error_counts: {} } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); + +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); diff --git a/test/api/v1/policy/staging.js b/test/api/v1/policy/staging.js index 08907f97..0716d281 100644 --- a/test/api/v1/policy/staging.js +++ b/test/api/v1/policy/staging.js @@ -1,11 +1,9 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/staging/policy'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/staging/policy'; -common.post( - 'should return staging policy table', - endpoint, - { +common.startTest('should return staging policy table', async function () { + const res = await common.post(endpoint, { policy_table: { app_policies: {}, consumer_friendly_messages: {}, @@ -14,18 +12,12 @@ common.post( module_config: {}, usage_and_error_counts: {} } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); + expect(res).to.have.status(200); +}); -common.post( - 'should return 400 with invalid policy_table', - endpoint, - { +common.startTest('should return 400 with invalid policy_table', async function () { + const res = await common.post(endpoint, { policy_table: { app_policies: {}, consumer_friendly_messages: {}, @@ -33,21 +25,11 @@ common.post( module_config: {}, usage_and_error_counts: {} } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/security/certificate.js b/test/api/v1/security/certificate.js index 41f24863..d61466b2 100644 --- a/test/api/v1/security/certificate.js +++ b/test/api/v1/security/certificate.js @@ -3,22 +3,14 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/security/certificate'; -common.post( - 'should return a new certificate even with no data provided', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.certificate).to.be.a('string'); - done(); - } -); +common.startTest('should return a new certificate even with no data provided', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.certificate).to.be.a('string'); +}); -common.post( - 'should return a new certificate with optional data provided', - endpoint, - { +common.startTest('should return a new certificate with optional data provided', async function () { + const res = await common.post(endpoint, { options: { country: "US", state: "test", @@ -29,45 +21,25 @@ common.post( emailAddress: "test", days: 4, } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.certificate).to.be.a('string'); - done(); - } -); + }); + expect(res).to.have.status(200); + expect(res.body.data.certificate).to.be.a('string'); +}); -it('should return a new certificate with the same private key if it was passed in as an argument', (done) => { - chai.request(common.BASE_URL) - .post('/api/v1/security/private') - .set('Accept', 'application/json') - .set('Content-Type', 'application/json') - .set('BASIC-AUTH-PASSWORD', common.config.basicAuthPassword) - .send({}) - .end((err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data).to.be.a('string'); +common.startTest('should return a new certificate with the same private key if it was passed in as an argument', async function () { + const res = await common.post('/api/v1/security/private', {}); + expect(res).to.have.status(200); + expect(res.body.data).to.be.a('string'); - const privateKey = res.body.data; + const privateKey = res.body.data; - chai.request(common.BASE_URL) - .post(endpoint) - .set('Accept', 'application/json') - .set('Content-Type', 'application/json') - .set('BASIC-AUTH-PASSWORD', common.config.basicAuthPassword) - .send({ - options: { - clientKey: privateKey, - } - }) - .end((err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.certificate).to.be.a('string'); - expect(res.body.data.clientKey).to.equal(privateKey); - done(); - }); - }); -}); + const res2 = await common.post(endpoint, { + options: { + clientKey: privateKey, + } + }); + + expect(res2).to.have.status(200); + expect(res2.body.data.certificate).to.be.a('string'); + expect(res2.body.data.clientKey).to.equal(privateKey); +}); \ No newline at end of file diff --git a/test/api/v1/security/private.js b/test/api/v1/security/private.js index 0a11dc86..66b60ed6 100644 --- a/test/api/v1/security/private.js +++ b/test/api/v1/security/private.js @@ -2,31 +2,19 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/security/private'; -common.post( - 'should return a new private key even with no data provided', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data).to.be.a('string'); - done(); - } -); +common.startTest('should return a new private key even with no data provided', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data).to.be.a('string'); +}); -common.post( - 'should return a new private key with optional data provided', - endpoint, - { +common.startTest('should return a new private key with optional data provided', async function () { + const res = await common.post(endpoint, { options: { keyBitsize: "l", cipher: "sha-256", } - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data).to.be.a('string'); - done(); - } -); \ No newline at end of file + }); + expect(res).to.have.status(200); + expect(res.body.data).to.be.a('string'); +}); diff --git a/test/api/v1/vehicle-data/type.js b/test/api/v1/vehicle-data/type.js index a4c2210d..54847bb5 100644 --- a/test/api/v1/vehicle-data/type.js +++ b/test/api/v1/vehicle-data/type.js @@ -1,15 +1,9 @@ -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/vehicle-data/type'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/vehicle-data/type'; -common.get( - 'should get all valid types', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.type).to.have.lengthOf.above(0); - done(); - } -); +common.startTest('should get all valid types', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.type).to.have.lengthOf.above(0); +}); diff --git a/test/api/v1/vehicle-data/vehicle-data.js b/test/api/v1/vehicle-data/vehicle-data.js index ea26e655..32b6984b 100644 --- a/test/api/v1/vehicle-data/vehicle-data.js +++ b/test/api/v1/vehicle-data/vehicle-data.js @@ -1,25 +1,17 @@ const chai = require('chai'); -var common = require('../../../common'); -var expect = common.expect; -var endpoint = '/api/v1/vehicle-data'; -var promoteEndpoint = '/api/v1/vehicle-data/promote'; +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/vehicle-data'; +const promoteEndpoint = '/api/v1/vehicle-data/promote'; -common.get( - 'should get vehicle data template', - endpoint, - { template: 'true' }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.custom_vehicle_data.length).to.equal(1); - done(); - } -); +common.startTest('should get vehicle data template', async function () { + const res = await common.get(endpoint, { template: 'true' }); + expect(res).to.have.status(200); + expect(res.body.data.custom_vehicle_data.length).to.equal(1); +}); -common.post( - 'should create a new STAGING vehicle data item', - endpoint, - { +common.startTest('should create a new STAGING vehicle data item', async function () { + const res = await common.post(endpoint, { name: 'Struct 1', key: 'Struct 1', type: 'Struct', @@ -56,174 +48,92 @@ common.post( ] } ] - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); + expect(res).to.have.status(200); +}); -common.post( - 'should create a new STAGING vehicle data item with only the mandatory fields filled out', - endpoint, - { +common.startTest('should create a new STAGING vehicle data item with only the mandatory fields filled out', async function () { + const res = await common.post(endpoint, { name: 'example-data', key: 'example-data', type: 'Integer', params: [] - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); + }); + expect(res).to.have.status(200); +}); -common.post( - 'should fail creating vehicle data item when name field is missing', - endpoint, - { +common.startTest('should fail creating vehicle data item when name field is missing', async function () { + const res = await common.post(endpoint, { key: 'Struct 1', type: 'Struct', params: [] - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); -common.post( - 'should fail creating vehicle data item when key field is missing', - endpoint, - { +common.startTest('should fail creating vehicle data item when key field is missing', async function () { + const res = await common.post(endpoint, { name: 'Struct 1', type: 'Struct', params: [] - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); -common.post( - 'should fail creating vehicle data item when type field is missing', - endpoint, - { +common.startTest('should fail creating vehicle data item when type field is missing', async function () { + const res = await common.post(endpoint, { name: 'Struct 1', key: 'Struct 1', params: [] - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); -common.get( - 'should get all STAGING vehicle data', - endpoint, - { environment: 'STAGING' }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.custom_vehicle_data).to.have.lengthOf.above(0); - done(); - } -); +common.startTest('should get all STAGING vehicle data', async function () { + const res = await common.get(endpoint, { environment: 'STAGING' }); + expect(res).to.have.status(200); + expect(res.body.data.custom_vehicle_data).to.have.lengthOf.above(0); +}); -common.post( - 'should promote all STAGING vehicle data', - promoteEndpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); - } -); +common.startTest('should promote all STAGING vehicle data', async function () { + const res = await common.post(promoteEndpoint, {}); + expect(res).to.have.status(200); +}); -common.get( - 'should get all PRODUCTION vehicle data', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.custom_vehicle_data).to.have.lengthOf.above(0); - done(); - } -); +common.startTest('should get all PRODUCTION vehicle data', async function () { + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + expect(res.body.data.custom_vehicle_data).to.have.lengthOf.above(0); +}); -it('should get vehicle data with the given id', (done) => { +common.startTest('should get vehicle data with the given id', async function () { //get production data first - chai.request(common.BASE_URL) - .get(endpoint) - .set('Accept', 'application/json') - .set('Content-Type', 'application/json') - .set('BASIC-AUTH-PASSWORD', common.config.basicAuthPassword) - .send() - .end((err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(200); + const res = await common.get(endpoint, {}); + expect(res).to.have.status(200); + const id = res.body.data.custom_vehicle_data[0].id; - const id = res.body.data.custom_vehicle_data[0].id; - //query a specific vehicle data item - chai.request(common.BASE_URL) - .get(endpoint) - .set('Accept', 'application/json') - .set('Content-Type', 'application/json') - .set('BASIC-AUTH-PASSWORD', common.config.basicAuthPassword) - .query({ id: id }) - .send() - .end((err, res) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.custom_vehicle_data).to.have.lengthOf(1); - done(); - }); - }); + //query a specific vehicle data item + const res2 = await common.get(endpoint, { id: id }); + expect(res2).to.have.status(200); + expect(res2.body.data.custom_vehicle_data).to.have.lengthOf(1); }); -common.get( - 'should not get any vehicle data with invalid id', - endpoint, - { id: -10 }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(200); - expect(res.body.data.custom_vehicle_data).to.have.lengthOf(0); - done(); - } -); +common.startTest('should not get any vehicle data with invalid id', async function () { + const res = await common.get(endpoint, { id: -10 }); + expect(res).to.have.status(200); + expect(res.body.data.custom_vehicle_data).to.have.lengthOf(0); +}); -common.post( - 'should return 400 with invalid vehicle data', - endpoint, - { +common.startTest('should return 400 with invalid vehicle data', async function () { + const res = await common.post(endpoint, { name: 'String 1', key: 'String 1', //type: 'String' //name, key, and type are required. - }, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); + }); + expect(res).to.have.status(400); +}); -common.post( - 'should return 400 with no body specified', - endpoint, - {}, - (err, res, done) => { - expect(err).to.be.null; - expect(res).to.have.status(400); - done(); - } -); +common.startTest('should return 400 with no body specified', async function () { + const res = await common.post(endpoint, {}); + expect(res).to.have.status(400); +}); diff --git a/test/api/v1/webhook/webhook.js b/test/api/v1/webhook/webhook.js new file mode 100644 index 00000000..771ea5a9 --- /dev/null +++ b/test/api/v1/webhook/webhook.js @@ -0,0 +1,58 @@ +const common = require('../../../common'); +const expect = common.expect; +const endpoint = '/api/v1/webhook'; + +common.startTest('should fail when not including the public_key property', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.post(endpoint, { + uuid: uuid, + entity: "application", + action: "UPSERT" + }); + + expect(res).to.have.status(401); +}); + +common.startTest('should fail when using the wrong public_key value', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.postWebhook(endpoint, { + uuid: uuid, + entity: "application", + action: "UPSERT" + }, 'nope'); + + expect(res).to.have.status(401); +}); + +common.startTest('should query SHAID for an update to an application', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.postWebhook(endpoint, { + uuid: uuid, + entity: "application", + action: "UPSERT" + }, process.env.SHAID_PUBLIC_KEY); + + expect(res).to.have.status(200); +}); + +common.startTest('should query SHAID and blacklist an application', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.postWebhook(endpoint, { + uuid: uuid, + entity: "application", + action: "BLACKLIST" + }, process.env.SHAID_PUBLIC_KEY); + + expect(res).to.have.status(200); +}); + +common.startTest('should query SHAID and delete an application', async function () { + const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; + const res = await common.postWebhook(endpoint, { + uuid: uuid, + entity: "application", + action: "DELETE" + }, process.env.SHAID_PUBLIC_KEY); + + expect(res).to.have.status(200); +}); \ No newline at end of file diff --git a/test/basicAuth/basicAuth.js b/test/basicAuth/basicAuth.js index db8dfa7d..feb5a8a6 100644 --- a/test/basicAuth/basicAuth.js +++ b/test/basicAuth/basicAuth.js @@ -1,8 +1,8 @@ -var common = require('../common'); -var chai = common.chai; -var BASE_URL = common.BASE_URL; -var expect = common.expect; -var config = common.config; +const common = require('../common'); +const chai = common.chai; +const BASE_URL = common.BASE_URL; +const expect = common.expect; +const config = common.config; it('should return 401 error when basic auth is enabled and no password header is set', (done) => { config.authType = 'basic'; diff --git a/test/cache/cache.js b/test/cache/cache.js index d9e1cd9e..cfd2cbe3 100644 --- a/test/cache/cache.js +++ b/test/cache/cache.js @@ -1,6 +1,6 @@ -var common = require('../common'); -var expect = common.expect; -var cache = require('../../custom/cache'); +const common = require('../common'); +const expect = common.expect; +const cache = require('../../custom/cache'); it('should be enabled', (done) => { expect(common.config.cacheModule).to.not.be.null; diff --git a/test/common.js b/test/common.js index af9081eb..a97c647d 100644 --- a/test/common.js +++ b/test/common.js @@ -7,8 +7,14 @@ const BASE_URL = 'http://' + config.policyServerHost + ':' + config.policyServer chai.use(chaiHttp); chai.use(chaiJsonSchema); -exports.get = (testName, endpoint, queryParams, endFunction) => { - it(testName, (done) => { +exports.startTest = (testName, endFunction) => { + it(testName, async () => { + await endFunction(); + }); +} + +exports.get = (endpoint, queryParams, endFunction) => { + return new Promise((resolve, reject) => { chai.request(BASE_URL) .get(endpoint) .set('Accept', 'application/json') @@ -16,13 +22,36 @@ exports.get = (testName, endpoint, queryParams, endFunction) => { .query(queryParams) .send() .end( (err, res) => { - endFunction(err, res, done); + expect(err).to.be.null; + if (err) { + return reject(err); + } + resolve(res); + }); + }); +} + +exports.postWebhook = (endpoint, body, publicKey, endFunction) => { + return new Promise((resolve, reject) => { + chai.request(BASE_URL) + .post(endpoint) + .set('Accept', 'application/json') + .set('Content-Type', 'application/json') + .set('BASIC-AUTH-PASSWORD', config.basicAuthPassword) + .set('public_key', publicKey) + .send(body) + .end( (err, res) => { + expect(err).to.be.null; + if (err) { + return reject(err); + } + resolve(res); }); }); }; -exports.post = (testName, endpoint, body, endFunction) => { - it(testName, (done) => { +exports.post = (endpoint, body, endFunction) => { + return new Promise((resolve, reject) => { chai.request(BASE_URL) .post(endpoint) .set('Accept', 'application/json') @@ -30,13 +59,17 @@ exports.post = (testName, endpoint, body, endFunction) => { .set('BASIC-AUTH-PASSWORD', config.basicAuthPassword) .send(body) .end( (err, res) => { - endFunction(err, res, done); - }) + expect(err).to.be.null; + if (err) { + return reject(err); + } + resolve(res); + }); }); }; -exports.put = (testName, endpoint, body, endFunction) => { - it(testName, (done) => { +exports.put = (endpoint, body, endFunction) => { + return new Promise((resolve, reject) => { chai.request(BASE_URL) .put(endpoint) .set('Accept', 'application/json') @@ -44,8 +77,12 @@ exports.put = (testName, endpoint, body, endFunction) => { .set('BASIC-AUTH-PASSWORD', config.basicAuthPassword) .send(body) .end( (err, res) => { - endFunction(err, res, done); - }) + expect(err).to.be.null; + if (err) { + return reject(err); + } + resolve(res); + }); }); }; diff --git a/test/test.js b/test/test.js index 995569d6..03febae1 100644 --- a/test/test.js +++ b/test/test.js @@ -1,6 +1,6 @@ "use strict"; -var sdlServer = require('../index.js'); +const sdlServer = require('../index.js'); function importTest(name, path) { describe(name, function() { @@ -11,8 +11,8 @@ function importTest(name, path) { describe('SDL SERVER TESTS', function () { before(function(done) { - this.timeout(16000); - setTimeout(done, 15000); + this.timeout(21000); + setTimeout(done, 20000); }); describe('api', function() { @@ -20,7 +20,6 @@ describe('SDL SERVER TESTS', function () { importTest('/applications', './api/v1/applications/applications'); importTest('/applications/action', './api/v1/applications/action'); importTest('/applications/auto', './api/v1/applications/auto'); - importTest('/applications/groups', './api/v1/applications/groups'); importTest('/staging/policy', './api/v1/policy/staging'); importTest('/production/policy', './api/v1/policy/production'); importTest('/policy/preview', './api/v1/policy/preview'); @@ -31,14 +30,11 @@ describe('SDL SERVER TESTS', function () { importTest('/groups/names', './api/v1/groups/names'); importTest('/groups/promote', './api/v1/groups/promote'); importTest('/messages', './api/v1/messages/messages'); + importTest('/messages/names', './api/v1/messages/names'); importTest('/messages/promote', './api/v1/messages/promote'); importTest('/messages/update', './api/v1/messages/update'); - importTest('/messages/names', './api/v1/messages/names'); importTest('/module', './api/v1/module/module'); importTest('/module/promote', './api/v1/module/promote'); - importTest('/vehicle-data', './api/v1/vehicle-data/vehicle-data'); - importTest('/vehicle-data/type', './api/v1/vehicle-data/type'); - importTest('/applications/auto', './api/v1/applications/auto'); importTest('/applications/administrator', './api/v1/applications/administrator'); importTest('/applications/passthrough', './api/v1/applications/passthrough'); importTest('/applications/rpcencryption', './api/v1/applications/rpcencryption'); @@ -46,10 +42,15 @@ describe('SDL SERVER TESTS', function () { importTest('/applications/permission', './api/v1/applications/permission'); importTest('/applications/certificate-get', './api/v1/applications/certificate-get'); importTest('/applications/certificate', './api/v1/applications/certificate'); + importTest('/applications/groups', './api/v1/applications/groups'); importTest('/about', './api/v1/about/about'); importTest('/security/certificate', './api/v1/security/certificate'); importTest('/security/private', './api/v1/security/private'); + importTest('/vehicle-data', './api/v1/vehicle-data/vehicle-data'); + importTest('/vehicle-data/type', './api/v1/vehicle-data/type'); importTest('/login', './api/v1/login/login'); + importTest('/webhook', './api/v1/webhook/webhook'); + importTest('/store', './api/v1/applications/store'); }); }); From fad5a4a66221f1c79e76cbb885d52a2465b9bf05 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Thu, 20 Jan 2022 15:18:39 -0500 Subject: [PATCH 09/18] Start the server directly when using start-server --- entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entry.js b/entry.js index a77d757d..7c9bf0fe 100644 --- a/entry.js +++ b/entry.js @@ -48,7 +48,7 @@ async function reset (environment) { await executeCommand('db-migrate', ['reset', '-e', environment], { env: mainEnvs }); } async function startServer () { - await executeCommand('npm', ['start'], { env: { ...process.env }}); + await executeCommand('node', ['index.js'], { env: { ...process.env }}); } async function startDev () { await executeCommand('./node_modules/.bin/vue-cli-service', ['serve'], { env: { ...process.env }}); From b5f5e1701126285a74e360a49c1e874acd54e22d Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Fri, 21 Jan 2022 10:01:07 -0500 Subject: [PATCH 10/18] Add polyfills and lower package versions so that node v8+ can be used --- app/v1/applications/helper.js | 6 +- custom/databases/postgres/index.js | 5 +- entry.js | 7 - lib/allSettled/index.js | 15 + package-lock.json | 787 ++++++++++------------------- package.json | 4 +- test/api/v1/applications/hybrid.js | 4 +- 7 files changed, 298 insertions(+), 530 deletions(-) create mode 100644 lib/allSettled/index.js diff --git a/app/v1/applications/helper.js b/app/v1/applications/helper.js index 4aeef7cb..8f6ba586 100644 --- a/app/v1/applications/helper.js +++ b/app/v1/applications/helper.js @@ -8,6 +8,7 @@ const db = app.locals.db; const config = app.locals.config; const certificates = require('../certificates/controller.js'); const certUtil = require('../helpers/certificates.js'); +const allSettled = require('../../../lib/allSettled'); //validation functions function checkIdIntegerBody (req, res) { @@ -44,7 +45,8 @@ function validateFunctionalGroupPut (req, res) { } function validateHybridPost (req, res) { - if (!check.string(req.body.uuid) || !check.includes(["CLOUD","MOBILE","BOTH"], req.body.hybrid_preference)) { + // Do not use check.includes!! functionality differs between node version installs! + if (!check.string(req.body.uuid) || !["CLOUD","MOBILE","BOTH"].includes(req.body.hybrid_preference)) { res.parcel.setStatus(400).setMessage("uuid and a valid hybrid_preference are required"); } return; @@ -143,7 +145,7 @@ async function storeApps (includeApprovalStatus, notifyOEM, apps, callback) { appObjs = await Promise.all(appObjs.map(autoApprovalModifier)); appObjs = await Promise.all(appObjs.map(autoBlacklistModifier)); - const succeededAppIds = (await Promise.allSettled(appObjs.map(model.storeApp.bind(null, notifyOEM)))).map(result => result.value); + const succeededAppIds = (await allSettled(appObjs.map(model.storeApp.bind(null, notifyOEM)))).map(result => result.value); // return all failed apps to try inserts again later return appObjs.filter((appObj, index) => succeededAppIds[index] === undefined).map(appObj => appObj.uuid); } diff --git a/custom/databases/postgres/index.js b/custom/databases/postgres/index.js index 3c4a5a0b..7a1764ea 100644 --- a/custom/databases/postgres/index.js +++ b/custom/databases/postgres/index.js @@ -3,6 +3,7 @@ const pg = require('pg'); //handles connections to the postgres database const sqlBrick = require('sql-bricks-postgres'); const promisify = require('util').promisify; const config = require('../../../settings.js'); +const allSettled = require('../../../lib/allSettled'); //get configurations from environment variables // extend the Postgres client to easily fetch a single expected result as an object @@ -103,8 +104,8 @@ module.exports = function (log) { if (!Array.isArray(sqlStringArray)) { //if its just a single sql statement, make it into an array sqlStringArray = [sqlStringArray]; } - const promiseMethod = propagateErrors ? 'all' : 'allSettled'; - return Promise[promiseMethod](sqlStringArray.map(sql => self.asyncSql(sql))); + const promiseMethod = propagateErrors ? Promise.all : allSettled; + return promiseMethod(sqlStringArray.map(sql => self.asyncSql(sql))); }, getClient: function (callback){ // reserve a client connection ("client") and its associated release callback ("done") diff --git a/entry.js b/entry.js index 7c9bf0fe..7b75249c 100644 --- a/entry.js +++ b/entry.js @@ -8,13 +8,6 @@ let mainEnvs = { DB_DATABASE: process.env.DB_DATABASE, DB_PORT: process.env.DB_PORT, } -let testEnvs = { - TEST_PG_USER: process.env.TEST_PG_USER, - TEST_PG_PASSWORD: process.env.TEST_PG_PASSWORD, - TEST_PG_HOST: process.env.TEST_PG_HOST, - TEST_PG_DATABASE: process.env.TEST_PG_DATABASE, - TEST_PG_PORT: process.env.TEST_PG_PORT, -} main(); async function main () { diff --git a/lib/allSettled/index.js b/lib/allSettled/index.js new file mode 100644 index 00000000..3b2d78df --- /dev/null +++ b/lib/allSettled/index.js @@ -0,0 +1,15 @@ +function allSettledPolyfill (promises) { + return Promise.all(promises.map(promise => { + return promise + .then(value => ({ + status: "fulfilled", + value: value, + })) + .catch(reason => ({ + status: "rejected", + reason: reason + })); + })); +} + +module.exports = allSettledPolyfill; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 83eb9fc2..6fb75258 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1804,16 +1804,6 @@ "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", @@ -1860,34 +1850,6 @@ } } }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, "cssnano": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", @@ -1927,25 +1889,6 @@ "path-exists": "^4.0.0" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2032,16 +1975,6 @@ "minipass": "^3.1.1" } }, - "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, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "terser-webpack-plugin": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", @@ -2058,18 +1991,6 @@ "terser": "^4.6.12", "webpack-sources": "^1.4.3" } - }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.8.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", - "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - } } } }, @@ -2588,39 +2509,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "array.prototype.map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", - "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.4" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -3238,9 +3126,9 @@ "dev": true }, "buffer-writer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz", - "integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" }, "buffer-xor": { "version": "1.0.3", @@ -3552,6 +3440,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", "dev": true, + "optional": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -3568,6 +3457,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "optional": true, "requires": { "fill-range": "^7.0.1" } @@ -3577,6 +3467,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, + "optional": true, "requires": { "to-regex-range": "^5.0.1" } @@ -3585,13 +3476,15 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "dev": true, + "optional": true }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "optional": true, "requires": { "is-number": "^7.0.0" } @@ -4978,9 +4871,9 @@ "dev": true }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "diffie-hellman": { @@ -5301,54 +5194,6 @@ "string.prototype.trimstart": "^1.0.1" } }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "dev": true, - "requires": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -6133,18 +5978,18 @@ } }, "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", "dev": true, "requires": { "is-buffer": "~2.0.3" }, "dependencies": { "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true } } @@ -7385,12 +7230,6 @@ "ip-regex": "^2.0.0" } }, - "is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", - "dev": true - }, "is-negative-zero": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", @@ -7486,23 +7325,11 @@ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" }, - "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", - "dev": true - }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", @@ -7569,22 +7396,6 @@ "is-object": "^1.0.1" } }, - "iterate-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", - "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", - "dev": true - }, - "iterate-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", - "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", - "dev": true, - "requires": { - "es-get-iterator": "^1.0.2", - "iterate-iterator": "^1.0.1" - } - }, "javascript-stringify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", @@ -7638,11 +7449,6 @@ "easy-stack": "^1.0.0" } }, - "js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8349,52 +8155,50 @@ } }, "mocha": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.1.3.tgz", - "integrity": "sha512-ZbaYib4hT4PpF4bdSO2DohooKXIn4lDeiYqB+vTmCdr6l2woW0b6H3pf5x4sM5nwQMru9RvjjHYWVGltR50ZBw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", "dev": true, "requires": { - "ansi-colors": "4.1.1", + "ansi-colors": "3.2.3", "browser-stdout": "1.3.1", - "chokidar": "3.4.2", - "debug": "4.1.1", - "diff": "4.0.2", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.14.0", - "log-symbols": "4.0.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", "object.assign": "4.1.0", - "promise.allsettled": "1.0.2", - "serialize-javascript": "4.0.0", - "strip-json-comments": "3.0.1", - "supports-color": "7.1.0", - "which": "2.0.2", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", "wide-align": "1.1.3", - "workerpool": "6.0.0", "yargs": "13.3.2", "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.1" + "yargs-unparser": "1.6.0" }, "dependencies": { "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "fill-range": "^7.0.1" } }, "camelcase": { @@ -8404,13 +8208,41 @@ "dev": true }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" } }, "cliui": { @@ -8424,25 +8256,10 @@ "wrap-ansi": "^5.1.0" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { "ms": "^2.1.1" @@ -8454,27 +8271,28 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "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==", - "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==", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "to-regex-range": "^5.0.1" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } }, "is-fullwidth-code-point": { "version": "2.0.0", @@ -8482,24 +8300,37 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "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==", + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { - "p-locate": "^5.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, "requires": { - "chalk": "^4.0.0" + "chalk": "^2.4.2" } }, + "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==", + "dev": true + }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", @@ -8512,30 +8343,15 @@ "object-keys": "^1.0.11" } }, - "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", - "dev": true, - "requires": { - "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==", + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", "dev": true, "requires": { - "p-limit": "^3.0.2" + "picomatch": "^2.0.4" } }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -8557,27 +8373,27 @@ } }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "isexe": "^2.0.0" + "is-number": "^7.0.0" } }, "wrap-ansi": { @@ -8589,32 +8405,6 @@ "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" - }, - "dependencies": { - "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, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - } } }, "yargs": { @@ -8633,51 +8423,6 @@ "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.2" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "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", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "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 - } } }, "yargs-parser": { @@ -8841,6 +8586,16 @@ "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", @@ -9587,52 +9342,30 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pg": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/pg/-/pg-6.4.2.tgz", - "integrity": "sha1-w2QBEGDqx6UHoq4GPrhX7OkQ4n8=", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz", + "integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==", "requires": { - "buffer-writer": "1.0.1", - "js-string-escape": "1.0.1", - "packet-reader": "0.3.1", - "pg-connection-string": "0.1.3", - "pg-pool": "1.*", - "pg-types": "1.*", - "pgpass": "1.*", - "semver": "4.3.2" + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.4.1", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" }, "dependencies": { - "packet-reader": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz", - "integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc=" - }, - "pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", - "requires": { - "split": "^1.0.0" - } - }, - "semver": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", - "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { - "through": "2" - } + "pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" } } }, "pg-connection-string": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", - "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" }, "pg-int8": { "version": "1.0.1", @@ -9640,25 +9373,9 @@ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" }, "pg-pool": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-1.8.0.tgz", - "integrity": "sha1-9+xzgkw3oD8Hb1G/33DjQBR8Tzc=", - "requires": { - "generic-pool": "2.4.3", - "object-assign": "4.1.0" - }, - "dependencies": { - "generic-pool": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.4.3.tgz", - "integrity": "sha1-eAw29p360FpaBF3Te+etyhGk9v8=" - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" - } - } + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz", + "integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ==" }, "pg-protocol": { "version": "1.4.0", @@ -9666,14 +9383,14 @@ "integrity": "sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==" }, "pg-types": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.13.0.tgz", - "integrity": "sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", "requires": { "pg-int8": "1.0.1", - "postgres-array": "~1.0.0", + "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.0", + "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, @@ -10389,9 +10106,9 @@ "dev": true }, "postgres-array": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", - "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" }, "postgres-bytea": { "version": "1.0.0", @@ -10463,40 +10180,6 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, - "promise.allsettled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", - "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", - "dev": true, - "requires": { - "array.prototype.map": "^1.0.1", - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "iterate-value": "^1.0.0" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, "prompt": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prompt/-/prompt-1.0.0.tgz", @@ -10794,6 +10477,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", "dev": true, + "optional": true, "requires": { "picomatch": "^2.2.1" } @@ -12405,7 +12089,8 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true }, "through2": { "version": "2.0.5", @@ -13098,6 +12783,87 @@ } } }, + "vue-loader-v16": { + "version": "npm:vue-loader-v16@16.8.3", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", + "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "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, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "vue-resource": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/vue-resource/-/vue-resource-1.3.4.tgz", @@ -14392,12 +14158,6 @@ "errno": "~0.1.7" } }, - "workerpool": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", - "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", - "dev": true - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -14557,16 +14317,14 @@ } }, "yargs-unparser": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", - "integrity": "sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "decamelize": "^1.2.0", "flat": "^4.1.0", - "is-plain-obj": "^1.1.0", - "yargs": "^14.2.3" + "lodash": "^4.17.15", + "yargs": "^13.3.0" }, "dependencies": { "camelcase": { @@ -14630,13 +14388,12 @@ } }, "yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", - "decamelize": "^1.2.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -14645,13 +14402,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index a1b0fa5b..5c61778f 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "mustache": "^3.0.1", "nodemailer": "^6.6.1", "pem": "^1.14.2", - "pg": "6.4.2", + "pg": "8.7.1", "portal-vue": "^2.1.7", "portfinder": "1.0.13", "redis": "^3.1.2", @@ -76,7 +76,7 @@ "eventsource-polyfill": "0.9.6", "express": "4.16.0", "http-proxy-middleware": "^0.19.1", - "mocha": "^8.1.3", + "mocha": "^7.1.1", "mocha-steps": "^1.3.0", "opn": "5.1.0", "ora": "1.2.0", diff --git a/test/api/v1/applications/hybrid.js b/test/api/v1/applications/hybrid.js index 2d5d64a8..8fc5d320 100644 --- a/test/api/v1/applications/hybrid.js +++ b/test/api/v1/applications/hybrid.js @@ -20,10 +20,10 @@ common.startTest('should add the given uuid to the app_hybrid_preference table w expect(res).to.have.status(200); }); -common.startTest('should return 500 with only uuid specified', async function () { +common.startTest('should return 400 with only uuid specified', async function () { const uuid = (await common.get('/api/v1/applications', {id: 1})).body.data.applications[0].uuid; const res = await common.post(endpoint, {uuid: uuid}); - expect(res).to.have.status(500); + expect(res).to.have.status(400); }); common.startTest('should return 400 with only hybrid_preference specified', async function () { From 0814f9d8679a0111333f56e744529e013e4913a3 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Fri, 28 Jan 2022 16:37:31 -0500 Subject: [PATCH 11/18] Create ability to run the server through docker compose --- docker/Dockerfile | 29 ++++++ docker/README.md | 34 +++++++ docker/docker-compose.yml | 30 ++++++ docker/keys/.gitignore | 2 + docker/wait-for-it.sh | 182 +++++++++++++++++++++++++++++++++++++ docker/webengine-bundle.js | 132 +++++++++++++++++++++++++++ 6 files changed, 409 insertions(+) create mode 100644 docker/Dockerfile create mode 100644 docker/README.md create mode 100644 docker/docker-compose.yml create mode 100644 docker/keys/.gitignore create mode 100755 docker/wait-for-it.sh create mode 100644 docker/webengine-bundle.js diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..885f2412 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,29 @@ +# Copyright (c) 2022, Livio, Inc. +FROM node:12 + +ARG VERSION=master + +RUN apt-get update && apt-get install -y --no-install-recommends \ + openssl \ + curl \ + git + +# Download SDL Core from github +WORKDIR /usr + +RUN mkdir /usr/policy +RUN git clone https://github.com/smartdevicelink/sdl_server.git /usr/policy -b $VERSION --depth=1 + +WORKDIR /usr/policy + +RUN npm install +RUN npm install aws-sdk node-stream-zip --save + +COPY .env .env +COPY wait-for-it.sh wait-for-it.sh +COPY keys customizable/ca +COPY webengine-bundle.js customizable/webengine-bundle/index.js + +EXPOSE 3000 + +CMD ["npm", "start"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..fb4cc24d --- /dev/null +++ b/docker/README.md @@ -0,0 +1,34 @@ +### Docker Compose Installation + +[Docker Engine is required to be installed.](https://docs.docker.com/engine/install/) This folder contains all the files needed to set up the policy server through docker images. The `docker-compose.yml` file will spin up the server, the Postgres database, and the Redis database and automatically connect them all (if redis is enabled). The policy server is made available on `http://localhost:3000`. + +### Environment Variables +An `.env` file is expected in this directory, and the Dockerfile will pull in all environment variables from that file, just like how the policy server uses the `.env` file in the root directory. The Dockerfile uses the remote sdl_server repository instead of the local installation. The branch can be changed by changing the `docker-compose.yml` file's arg VERSION value: its default is the master branch. + +The following are notable `.env` variables to the docker environment. They are not a comprehensive list. The usual variables such as `SHAID_PUBLIC_KEY` and `SHAID_SECRET_KEY` are still required for usage. + +| Name | Type | Usage | Description | +|--------------------|--------|------------------|---------------------------------------------------------------------------| +| DB_PASSWORD | String | Postgres | Required to use the Postgres database container | +| DB_HOST | String | Postgres | Please set this value to "postgres" in your `.env` file. Only "postgres" will allow the policy server to connect to Postgres.| +| DB_USER | String | Postgres | Required to use the Postgres database container | +| DB_DATABASE | String | Postgres | Required to use the Postgres database container | +| CACHE_HOST | String | Redis | Please set this value to "redis" in your `.env` file. Only "redis" will allow the policy server to connect to Redis.| +| BUCKET_NAME | String | WebEngine app support | The name of the S3 bucket to store app bundles | +| AWS_REGION | String | WebEngine app support | The region of the S3 bucket | +| AWS_ACCESS_KEY_ID | String | WebEngine app support | [AWS credentials to allow S3 usage](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html). These are exclusive to the docker install of the policy server! | +| AWS_SECRET_ACCESS_KEY | String | WebEngine app support | [AWS credentials to allow S3 usage](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html). These are exclusive to the docker install of the policy server! | + +Note the nearly empty `keys` subfolder. Insert your own key and pem files meant for the certificate generation feature in there, and the contents will be copied into the docker container policy server's `customizable/ca` folder. You will still need the necessary environment variables to activate certificate generation. + +### Commands +To start a new or existing cluster, remembering to rebuild the policy server image in case of .env changes: +`docker compose up --build` +Use Ctrl+C once to stop all the docker containers. + +To tear down a cluster without removing the volume (this will delete the database contents!): +`docker compose down` + +To tear down a cluster and remove the volume (this will delete the database contents!): +`docker compose down -v` + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 00000000..3d415be6 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,30 @@ +version: "3.9" +services: + server: + build: + context: . + args: + - VERSION=master + ports: + - "3000:3000" + volumes: + - data:/usr/policy + env_file: + - .env + links: + - redis + - postgres + depends_on: + - redis + - postgres + command: ["./wait-for-it.sh", "postgres:5432", "--", "npm", "start"] + redis: + image: redis + postgres: + image: postgres:10.19-bullseye + environment: + POSTGRES_PASSWORD: "${DB_PASSWORD}" + POSTGRES_USER: "${DB_USER}" + POSTGRES_DB: "${DB_DATABASE}" +volumes: + data: \ No newline at end of file diff --git a/docker/keys/.gitignore b/docker/keys/.gitignore new file mode 100644 index 00000000..c96a04f0 --- /dev/null +++ b/docker/keys/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/docker/wait-for-it.sh b/docker/wait-for-it.sh new file mode 100755 index 00000000..d990e0d3 --- /dev/null +++ b/docker/wait-for-it.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash +# Use this script to test if a given TCP host/port are available + +WAITFORIT_cmdname=${0##*/} + +echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + else + echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" + fi + WAITFORIT_start_ts=$(date +%s) + while : + do + if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then + nc -z $WAITFORIT_HOST $WAITFORIT_PORT + WAITFORIT_result=$? + else + (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 + WAITFORIT_result=$? + fi + if [[ $WAITFORIT_result -eq 0 ]]; then + WAITFORIT_end_ts=$(date +%s) + echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" + break + fi + sleep 1 + done + return $WAITFORIT_result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $WAITFORIT_QUIET -eq 1 ]]; then + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + else + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + fi + WAITFORIT_PID=$! + trap "kill -INT -$WAITFORIT_PID" INT + wait $WAITFORIT_PID + WAITFORIT_RESULT=$? + if [[ $WAITFORIT_RESULT -ne 0 ]]; then + echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + fi + return $WAITFORIT_RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + WAITFORIT_hostport=(${1//:/ }) + WAITFORIT_HOST=${WAITFORIT_hostport[0]} + WAITFORIT_PORT=${WAITFORIT_hostport[1]} + shift 1 + ;; + --child) + WAITFORIT_CHILD=1 + shift 1 + ;; + -q | --quiet) + WAITFORIT_QUIET=1 + shift 1 + ;; + -s | --strict) + WAITFORIT_STRICT=1 + shift 1 + ;; + -h) + WAITFORIT_HOST="$2" + if [[ $WAITFORIT_HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + WAITFORIT_HOST="${1#*=}" + shift 1 + ;; + -p) + WAITFORIT_PORT="$2" + if [[ $WAITFORIT_PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + WAITFORIT_PORT="${1#*=}" + shift 1 + ;; + -t) + WAITFORIT_TIMEOUT="$2" + if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + WAITFORIT_TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + WAITFORIT_CLI=("$@") + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} +WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} +WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} +WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} + +# Check to see if timeout is from busybox? +WAITFORIT_TIMEOUT_PATH=$(type -p timeout) +WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) + +WAITFORIT_BUSYTIMEFLAG="" +if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then + WAITFORIT_ISBUSY=1 + # Check if busybox timeout uses -t flag + # (recent Alpine versions don't support -t anymore) + if timeout &>/dev/stdout | grep -q -e '-t '; then + WAITFORIT_BUSYTIMEFLAG="-t" + fi +else + WAITFORIT_ISBUSY=0 +fi + +if [[ $WAITFORIT_CHILD -gt 0 ]]; then + wait_for + WAITFORIT_RESULT=$? + exit $WAITFORIT_RESULT +else + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + wait_for_wrapper + WAITFORIT_RESULT=$? + else + wait_for + WAITFORIT_RESULT=$? + fi +fi + +if [[ $WAITFORIT_CLI != "" ]]; then + if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then + echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" + exit $WAITFORIT_RESULT + fi + exec "${WAITFORIT_CLI[@]}" +else + exit $WAITFORIT_RESULT +fi diff --git a/docker/webengine-bundle.js b/docker/webengine-bundle.js new file mode 100644 index 00000000..e22a8bab --- /dev/null +++ b/docker/webengine-bundle.js @@ -0,0 +1,132 @@ +// skeleton function for customized downloading and extracting of package information +const request = require('request'); +const fs = require('fs'); +const UUID = require('uuid'); +const AWS = require('aws-sdk'); +const StreamZip = require('node-stream-zip'); +const BUCKET_NAME = process.env.BUCKET_NAME; + +if (process.env.AWS_REGION !== undefined && BUCKET_NAME !== undefined) { + AWS.config.update({region: process.env.AWS_REGION}); +} + +/** + * asynchronous function for downloading the bundle from the given url and extracting its size information + * @param package_url - a publicly accessible external url that's used to download the bundle onto the Policy Server + * @param cb - a callback function that expects two arguments + * if there was a failure in the process, it should be sent as the first argument. the Policy Server will log it + * the second argument to return must follow the formatted object below + * { + * url: the Policy Server should save a copy of the app bundle somewhere publicly accessible + * this url must be a full resolved url + * size_compressed_bytes: the number of bytes of the compressed downloaded bundle + * size_decompressed_bytes: the number of bytes of the extracted downloaded bundle + * } + */ +exports.handleBundle = function (package_url, cb) { + if (BUCKET_NAME === undefined || process.env.AWS_REGION === undefined) { + return cb(); + } + + let compressedSize = 0; + let bucketUrl = ''; + const TMP_FILE_NAME = `${UUID.v4()}.zip`; + + // create a new bucket if it doesn't already exist + new AWS.S3().createBucket({Bucket: BUCKET_NAME, ACL: 'public-read'}, err => { + + // OperationAborted errors are expected, as we are potentially + // calling this API multiple times simultaneously + if (err && err.code !== 'OperationAborted') { + console.log(err); + return cb(err); + } + // read the URL and save it to a buffer variable + readUrlToBuffer(package_url) + .then(zipBuffer => { // submit the file contents to S3 + compressedSize = zipBuffer.length; + const randomString = UUID.v4(); + const fileName = `${randomString}.zip`; + bucketUrl = `https://${BUCKET_NAME}.s3.amazonaws.com/${fileName}`; + // make the bundle publicly accessible + const objectParams = {Bucket: BUCKET_NAME, ACL: 'public-read', Key: fileName, Body: zipBuffer}; + // Create object upload promise + return new AWS.S3().putObject(objectParams).promise(); + }) + .then(() => { // unzip the contents of the bundle to get its uncompressed data information + return streamUrlToTmpFile(bucketUrl, TMP_FILE_NAME); + }) + .then(() => { + return unzipAndGetUncompressedSize(TMP_FILE_NAME); + }) + .then(uncompressedSize => { + // delete the tmp zip file + fs.unlink(TMP_FILE_NAME, () => { + // all the information has been collected + cb(null, { + url: bucketUrl, + size_compressed_bytes: compressedSize, + size_decompressed_bytes: uncompressedSize + }); + }); + }) + .catch(err => { + console.log(err); + // delete the tmp zip file + fs.unlink(TMP_FILE_NAME, () => { + cb(err); + }); + }); + }); +} + +function unzipAndGetUncompressedSize (fileName) { + let uncompressedSize = 0; + + return new Promise((resolve, reject) => { + const zip = new StreamZip({ + file: fileName, + skipEntryNameValidation: true + }); + zip.on('ready', () => { + // iterate through every unzipped entry and count up the file sizes + for (const entry of Object.values(zip.entries())) { + if (!entry.isDirectory) { + uncompressedSize += entry.size; + } + } + // close the file once you're done + zip.close() + resolve(uncompressedSize); + }); + + // Handle errors + zip.on('error', err => { + console.log(err); + reject(err) + }); + }); +} + +function streamUrlToTmpFile (url, fileName) { + return new Promise((resolve, reject) => { + request(url) + .pipe(fs.createWriteStream(fileName)) + .on('close', resolve); + }); +} + +function readUrlToBuffer (url) { + return new Promise((resolve, reject) => { + let zipBuffer = []; + + request(url) + .on('data', data => { + zipBuffer.push(data); + }) + .on('close', function () { // file fully downloaded + // put the zip contents to a buffer + resolve(Buffer.concat(zipBuffer)); + }); + }) +} From f601ad0ddb59411ebbf940935820506119c8d0bf Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Mon, 31 Jan 2022 12:35:40 -0500 Subject: [PATCH 12/18] Address PR feedback --- test/api/v1/policy/production.js | 2 +- test/common.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/api/v1/policy/production.js b/test/api/v1/policy/production.js index c6607277..98831ea4 100644 --- a/test/api/v1/policy/production.js +++ b/test/api/v1/policy/production.js @@ -2,7 +2,7 @@ const common = require('../../../common'); const expect = common.expect; const endpoint = '/api/v1/production/policy'; -common.startTest('should return staging policy table', async function () { +common.startTest('should return production policy table', async function () { const res = await common.post(endpoint, { policy_table: { app_policies: {}, diff --git a/test/common.js b/test/common.js index a97c647d..a0cb6606 100644 --- a/test/common.js +++ b/test/common.js @@ -13,7 +13,7 @@ exports.startTest = (testName, endFunction) => { }); } -exports.get = (endpoint, queryParams, endFunction) => { +exports.get = (endpoint, queryParams) => { return new Promise((resolve, reject) => { chai.request(BASE_URL) .get(endpoint) @@ -31,7 +31,7 @@ exports.get = (endpoint, queryParams, endFunction) => { }); } -exports.postWebhook = (endpoint, body, publicKey, endFunction) => { +exports.postWebhook = (endpoint, body, publicKey) => { return new Promise((resolve, reject) => { chai.request(BASE_URL) .post(endpoint) @@ -50,7 +50,7 @@ exports.postWebhook = (endpoint, body, publicKey, endFunction) => { }); }; -exports.post = (endpoint, body, endFunction) => { +exports.post = (endpoint, body) => { return new Promise((resolve, reject) => { chai.request(BASE_URL) .post(endpoint) @@ -68,7 +68,7 @@ exports.post = (endpoint, body, endFunction) => { }); }; -exports.put = (endpoint, body, endFunction) => { +exports.put = (endpoint, body) => { return new Promise((resolve, reject) => { chai.request(BASE_URL) .put(endpoint) From 65ca32ea0312f733d5a0836a8bcde926a2e6c461 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 4 Feb 2022 13:05:32 -0500 Subject: [PATCH 13/18] Update docker/Dockerfile Co-authored-by: renonick87 --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 885f2412..10584873 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -8,7 +8,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ git -# Download SDL Core from github +# Download SDL Server from github WORKDIR /usr RUN mkdir /usr/policy From 1589026b5d3547e44d76df5adc8e5475764cd46d Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Tue, 8 Feb 2022 17:28:23 -0500 Subject: [PATCH 14/18] Apply feedback --- docker/Dockerfile | 4 ++-- docker/README.md | 18 ++++++++++-------- docker/docker-compose.yml | 17 +++++++++++++---- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 10584873..192667c1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -19,11 +19,11 @@ WORKDIR /usr/policy RUN npm install RUN npm install aws-sdk node-stream-zip --save -COPY .env .env COPY wait-for-it.sh wait-for-it.sh COPY keys customizable/ca +COPY keys customizable/ssl COPY webengine-bundle.js customizable/webengine-bundle/index.js -EXPOSE 3000 +EXPOSE 3000 443 CMD ["npm", "start"] diff --git a/docker/README.md b/docker/README.md index fb4cc24d..08618ec2 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,27 +1,29 @@ ### Docker Compose Installation -[Docker Engine is required to be installed.](https://docs.docker.com/engine/install/) This folder contains all the files needed to set up the policy server through docker images. The `docker-compose.yml` file will spin up the server, the Postgres database, and the Redis database and automatically connect them all (if redis is enabled). The policy server is made available on `http://localhost:3000`. +[Docker Engine is required to be installed.](https://docs.docker.com/engine/install/) This folder contains all the files needed to set up the policy server through docker images. The `docker-compose.yml` file will spin up the server, the Postgres database, and the Redis database and automatically connect them all. The policy server is made available on `http://localhost:3000`. ### Environment Variables An `.env` file is expected in this directory, and the Dockerfile will pull in all environment variables from that file, just like how the policy server uses the `.env` file in the root directory. The Dockerfile uses the remote sdl_server repository instead of the local installation. The branch can be changed by changing the `docker-compose.yml` file's arg VERSION value: its default is the master branch. -The following are notable `.env` variables to the docker environment. They are not a comprehensive list. The usual variables such as `SHAID_PUBLIC_KEY` and `SHAID_SECRET_KEY` are still required for usage. +The following are notable `.env` variables to the docker environment. They are not a comprehensive list. The usual variables such as `SHAID_PUBLIC_KEY` and `SHAID_SECRET_KEY` are still required for usage. Connection to postgres and redis is automatic and no further configuration is required for them, such as setting environment variables. | Name | Type | Usage | Description | |--------------------|--------|------------------|---------------------------------------------------------------------------| -| DB_PASSWORD | String | Postgres | Required to use the Postgres database container | -| DB_HOST | String | Postgres | Please set this value to "postgres" in your `.env` file. Only "postgres" will allow the policy server to connect to Postgres.| -| DB_USER | String | Postgres | Required to use the Postgres database container | -| DB_DATABASE | String | Postgres | Required to use the Postgres database container | -| CACHE_HOST | String | Redis | Please set this value to "redis" in your `.env` file. Only "redis" will allow the policy server to connect to Redis.| +| DB_HOST | String | Postgres | Please do not use this value. It is predefined to work with Docker Compose| +| DB_PASSWORD | String | Postgres | Not required to be set. Defaults to "postgres" | +| DB_USER | String | Postgres | Not required to be set. Defaults to "postgres" | +| DB_DATABASE | String | Postgres | Not required to be set. Defaults to "postgres" | +| CACHE_HOST | String | Redis | Please do not set this value. It is predefined to work with Docker Compose| | BUCKET_NAME | String | WebEngine app support | The name of the S3 bucket to store app bundles | | AWS_REGION | String | WebEngine app support | The region of the S3 bucket | | AWS_ACCESS_KEY_ID | String | WebEngine app support | [AWS credentials to allow S3 usage](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html). These are exclusive to the docker install of the policy server! | | AWS_SECRET_ACCESS_KEY | String | WebEngine app support | [AWS credentials to allow S3 usage](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html). These are exclusive to the docker install of the policy server! | -Note the nearly empty `keys` subfolder. Insert your own key and pem files meant for the certificate generation feature in there, and the contents will be copied into the docker container policy server's `customizable/ca` folder. You will still need the necessary environment variables to activate certificate generation. +Note the nearly empty `keys` subfolder. Insert your own key and pem files meant for the certificate generation feature and SSL connections in there, and the contents will be copied into the docker container policy server's `customizable/ca` folder and `customizable/ssl` folder. You will still need the necessary environment variables to activate certificate generation and SSL connections respectively. ### Commands +You need to run the following commands in this directory (the docker directory of the project). + To start a new or existing cluster, remembering to rebuild the policy server image in case of .env changes: `docker compose up --build` Use Ctrl+C once to stop all the docker containers. diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 3d415be6..7369c2a0 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -6,11 +6,20 @@ services: args: - VERSION=master ports: - - "3000:3000" + - "${POLICY_SERVER_PORT:-3000}:${POLICY_SERVER_PORT:-3000}" + - "${POLICY_SERVER_PORT_SSL:-443}:${POLICY_SERVER_PORT_SSL:-443}" volumes: - data:/usr/policy env_file: - .env + environment: + DB_HOST: "postgres" + DB_PASSWORD: "${DB_PASSWORD:-postgres}" + DB_USER: "${DB_USER:-postgres}" + DB_DATABASE: "${DB_DATABASE:-postgres}" + CACHE_HOST: "${CACHE_HOST:-redis}" + CACHE_MODULE: "${CACHE_MODULE:-redis}" + CACHE_PORT: "${CACHE_PORT:-6379}" links: - redis - postgres @@ -23,8 +32,8 @@ services: postgres: image: postgres:10.19-bullseye environment: - POSTGRES_PASSWORD: "${DB_PASSWORD}" - POSTGRES_USER: "${DB_USER}" - POSTGRES_DB: "${DB_DATABASE}" + POSTGRES_PASSWORD: "${DB_PASSWORD:-postgres}" + POSTGRES_USER: "${DB_USER:-postgres}" + POSTGRES_DB: "${DB_DATABASE:-postgres}" volumes: data: \ No newline at end of file From f5ac3226a1155768f0497335011085c9639e550e Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Tue, 15 Feb 2022 10:46:05 -0500 Subject: [PATCH 15/18] Hardcode redis env variables for docker. No reason to allow configuration --- docker/docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 7369c2a0..00516520 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -17,9 +17,9 @@ services: DB_PASSWORD: "${DB_PASSWORD:-postgres}" DB_USER: "${DB_USER:-postgres}" DB_DATABASE: "${DB_DATABASE:-postgres}" - CACHE_HOST: "${CACHE_HOST:-redis}" - CACHE_MODULE: "${CACHE_MODULE:-redis}" - CACHE_PORT: "${CACHE_PORT:-6379}" + CACHE_HOST: "redis" + CACHE_MODULE: "redis" + CACHE_PORT: "6379" links: - redis - postgres From 55c2060ed9104a66f2e3256db787b174a729849c Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Wed, 23 Feb 2022 16:11:11 -0500 Subject: [PATCH 16/18] Update version and dependencies --- package-lock.json | 7025 +++++++++++++++++++++++++++++---------------- package.json | 8 +- 2 files changed, 4502 insertions(+), 2531 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6fb75258..e6cc8ef6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,18 @@ { "name": "sdl_policy_server", - "version": "2.12.0", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, "@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", @@ -14,38 +23,151 @@ } }, "@babel/compat-data": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", - "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", + "dev": true }, "@babel/core": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz", - "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.6", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.5", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.5", - "@babel/types": "^7.11.5", + "version": "7.17.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", + "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.3", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "semver": "^6.3.0" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@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.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.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/generator": { @@ -60,80 +182,395 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "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, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "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, "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-compilation-targets": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", - "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "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.10.4", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "browserslist": { + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", + "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001312", + "electron-to-chromium": "^1.4.71", + "escalade": "^3.1.1", + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "dev": true + }, + "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/helper-create-class-features-plugin": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", - "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", + "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", + "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-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" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", + "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.5", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4" + "@babel/helper-annotate-as-pure": "^7.16.7", + "regexpu-core": "^5.0.1" } }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", - "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "@babel/helper-define-polyfill-provider": { + "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, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-regex": "^7.10.4", - "regexpu-core": "^4.7.0" + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@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.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.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/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", + "@babel/helper-environment-visitor": { + "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/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-explode-assignable-expression": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz", - "integrity": "sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==", + "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, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-function-name": { @@ -157,112 +594,455 @@ } }, "@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "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.10.4" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "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, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "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.10.4" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", - "lodash": "^4.17.19" + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.6.tgz", + "integrity": "sha512-2ULmRdqoOMpdvkbT8jONrZML/XALfzxlb052bldftkicAUy8AxSCkD5trDPQcwHNmolcl7wP6ehNqMlyUw6AaA==", + "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.17.3", + "@babel/types": "^7.17.0" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@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.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "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, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "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-regex": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", - "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, "@babel/helper-remap-async-to-generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz", - "integrity": "sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA==", + "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, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "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, "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@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" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@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.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "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/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", - "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "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, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.16.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-split-export-declaration": { @@ -280,27 +1060,259 @@ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, + "@babel/helper-validator-option": { + "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.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", - "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "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, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@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.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@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.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/highlight": { @@ -320,148 +1332,195 @@ "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", "dev": true }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "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, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "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, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.7" + } + }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", - "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4", - "@babel/plugin-syntax-async-generators": "^7.8.0" + "@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.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", - "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "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, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz", + "integrity": "sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.17.6", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz", - "integrity": "sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.2.tgz", + "integrity": "sha512-WH8Z95CwTq/W8rFbMqb9p3hicpt4RX4f0K659ax2VHxgOyT6qQmUaEVEjIh4WR9Eh9NymkVn5vwsrE68fAQNUw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-decorators": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.17.1", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/plugin-syntax-decorators": "^7.17.0", + "charcodes": "^0.2.0" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", - "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", - "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", - "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.0" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", - "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", - "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", - "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", - "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", + "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.4" + "@babel/compat-data": "^7.17.0", + "@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.7" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", - "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", - "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "@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.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", - "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", + "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.16.10", + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "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, + "requires": { + "@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.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", - "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "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, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-async-generators": { @@ -474,21 +1533,30 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", - "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-decorators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz", - "integrity": "sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.0.tgz", + "integrity": "sha512-qWe85yCXsvDEluNP0OyeQjH63DlhAR3W7K9BxxU1MvbDb48tgBG+Ao6IJJ6smPDrrVzSQZrbF6donpkFBMcs3A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-dynamic-import": { @@ -519,12 +1587,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", - "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -581,422 +1649,637 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "@babel/plugin-syntax-top-level-await": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", - "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", - "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", - "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "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, "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4" + "@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.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", - "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", - "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-classes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", - "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", + "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" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-split-export-declaration": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", - "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-destructuring": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", - "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz", + "integrity": "sha512-dDFzegDYKlPqa72xIlbmSkly5MluLoaC1JswABGktyt6NTXSBcUuse/kWE/wvKFWJHPETpi158qJZFS3JmykJg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", - "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "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, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", - "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", - "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "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, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-for-of": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", - "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", - "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "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, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "dependencies": { + "@babel/code-frame": { + "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.7" + } + }, + "@babel/helper-function-name": { + "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.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "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.7" + } + }, + "@babel/helper-validator-identifier": { + "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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "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.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", - "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", - "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", - "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", + "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, "requires": { - "@babel/helper-module-transforms": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", + "@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.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "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, "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@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.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", - "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "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, "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", + "@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" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "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, "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", - "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "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, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.16.7" } }, "@babel/plugin-transform-new-target": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", - "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-object-super": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", - "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" } }, "@babel/plugin-transform-parameters": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", - "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", + "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, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-property-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", - "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-regenerator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", - "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "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, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", - "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-runtime": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.5.tgz", - "integrity": "sha512-9aIoee+EhjySZ6vY5hnLjigHzunBlscx9ANKutkeWTJTx6m5Rbq6Ic01tLvO54lSusR+BxV7u4UDdCmXv5aagg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz", + "integrity": "sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "resolve": "^1.8.1", - "semver": "^5.5.1" + "@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.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "semver": "^6.3.0" + }, + "dependencies": { + "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-transform-shorthand-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", - "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", - "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", - "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-regex": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-template-literals": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", - "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", + "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, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", - "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", - "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", - "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "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, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/preset-env": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.5.tgz", - "integrity": "sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.11.0", - "@babel/helper-compilation-targets": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-proposal-async-generator-functions": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-dynamic-import": "^7.10.4", - "@babel/plugin-proposal-export-namespace-from": "^7.10.4", - "@babel/plugin-proposal-json-strings": "^7.10.4", - "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", - "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@babel/plugin-proposal-private-methods": "^7.10.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", + "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "dev": 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.11", + "@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", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.10.4", - "@babel/plugin-transform-classes": "^7.10.4", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-dotall-regex": "^7.10.4", - "@babel/plugin-transform-duplicate-keys": "^7.10.4", - "@babel/plugin-transform-exponentiation-operator": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-function-name": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-member-expression-literals": "^7.10.4", - "@babel/plugin-transform-modules-amd": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-modules-systemjs": "^7.10.4", - "@babel/plugin-transform-modules-umd": "^7.10.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", - "@babel/plugin-transform-new-target": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.4", - "@babel/plugin-transform-property-literals": "^7.10.4", - "@babel/plugin-transform-regenerator": "^7.10.4", - "@babel/plugin-transform-reserved-words": "^7.10.4", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-sticky-regex": "^7.10.4", - "@babel/plugin-transform-template-literals": "^7.10.4", - "@babel/plugin-transform-typeof-symbol": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.4", - "@babel/plugin-transform-unicode-regex": "^7.10.4", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.5", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@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.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.8", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.20.2", + "semver": "^6.3.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "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/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.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/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1007,9 +2290,9 @@ } }, "@babel/runtime": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", - "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", + "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -1105,19 +2388,96 @@ }, "dependencies": { "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", "dev": true, "requires": { "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", + "cssnano-preset-default": "^4.0.8", "is-resolvable": "^1.0.0", "postcss": "^7.0.0" } + }, + "cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + } + }, + "postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true } } }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -1170,88 +2530,91 @@ "integrity": "sha512-VVOiO4HSzITdcRxUNopcDmI6kE3gNRGq+1Kna1djqx7uCWhaRWpkSl7QxK/i1X3+S5F3dlEQ50qhmBB/JNWubQ==" }, "@soda/friendly-errors-webpack-plugin": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz", - "integrity": "sha512-cWKrGaFX+rfbMrAxVv56DzhPNqOJPZuNIS2HGMELtgGzb+vsMzyig9mml5gZ/hr2BGtSLV+dP2LUEuAL8aG2mQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz", + "integrity": "sha512-h2ooWqP8XuFqTXT+NyAFbrArzfQA7R6HTezADrvD9Re8fxMLTPPniLdqVTdDaO0eIoLaAwKT+d6w+5GeTk7Vbg==", "dev": true, "requires": { - "chalk": "^1.1.3", - "error-stack-parser": "^2.0.0", - "string-width": "^2.0.0" + "chalk": "^3.0.0", + "error-stack-parser": "^2.0.6", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "dependencies": { "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "is-fullwidth-code-point": { - "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=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "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": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.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 - }, - "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" - } - } + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.1" } }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "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" + } } } }, @@ -1261,16 +2624,16 @@ "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==", "dev": true }, - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "dev": true }, "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dev": true, "requires": { "@types/connect": "*", @@ -1289,18 +2652,18 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, "@types/connect": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", - "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "dev": true, "requires": { "@types/node": "*" } }, "@types/connect-history-api-fallback": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz", - "integrity": "sha512-7SxFCd+FLlxCfwVwbyPxbR4khL9aNikJhrorw8nUIOqeuooc9gifBuDQOJw5kzN7i6i3vLn9G8Wde/4QDihpYw==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", "dev": true, "requires": { "@types/express-serve-static-core": "*", @@ -1314,21 +2677,21 @@ "dev": true }, "@types/express": { - "version": "4.17.8", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.8.tgz", - "integrity": "sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ==", + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", "dev": true, "requires": { "@types/body-parser": "*", - "@types/express-serve-static-core": "*", + "@types/express-serve-static-core": "^4.17.18", "@types/qs": "*", "@types/serve-static": "*" } }, "@types/express-serve-static-core": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz", - "integrity": "sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA==", + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", "dev": true, "requires": { "@types/node": "*", @@ -1337,9 +2700,9 @@ } }, "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "requires": { "@types/minimatch": "*", @@ -1347,47 +2710,36 @@ } }, "@types/http-proxy": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz", - "integrity": "sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/http-proxy-middleware": { - "version": "0.19.3", - "resolved": "https://registry.npmjs.org/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz", - "integrity": "sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA==", + "version": "1.17.8", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", + "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", "dev": true, "requires": { - "@types/connect": "*", - "@types/http-proxy": "*", "@types/node": "*" } }, "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "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/mime": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", - "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, "@types/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, "@types/node": { @@ -1397,37 +2749,37 @@ "dev": true }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==", "dev": true }, "@types/qs": { - "version": "6.9.5", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", - "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", "dev": true }, "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, "@types/serve-static": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.5.tgz", - "integrity": "sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ==", + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", "dev": true, "requires": { - "@types/express-serve-static-core": "*", - "@types/mime": "*" + "@types/mime": "^1", + "@types/node": "*" } }, "@types/source-list-map": { @@ -1447,15 +2799,15 @@ } }, "@types/tapable": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz", - "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", + "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==", "dev": true }, "@types/uglify-js": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.3.tgz", - "integrity": "sha512-KswB5C7Kwduwjj04Ykz+AjvPcfgv/37Za24O2EDzYNbwyzOo8+ydtvzUfZ5UMguiVu29Gx44l1A6VsPPcmYu9w==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", + "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", "dev": true, "requires": { "source-map": "^0.6.1" @@ -1470,16 +2822,16 @@ } }, "@types/webpack": { - "version": "4.41.22", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.22.tgz", - "integrity": "sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ==", + "version": "4.41.32", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz", + "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", "dev": true, "requires": { - "@types/anymatch": "*", "@types/node": "*", - "@types/tapable": "*", + "@types/tapable": "^1", "@types/uglify-js": "*", "@types/webpack-sources": "*", + "anymatch": "^3.0.0", "source-map": "^0.6.0" }, "dependencies": { @@ -1492,22 +2844,92 @@ } }, "@types/webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-3+86AgSzl18n5P1iUP9/lz3G3GMztCp+wxdDvVuNhx1sr1jE79GpYfKHL8k+Vht3N74K2n98CuAEw4YPJCYtDA==", + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.6.tgz", + "integrity": "sha512-XCph0RiiqFGetukCTC3KVnY1jwLcZ84illFRMbyFzCcWl90B/76ew0tSqF46oBhnLC4obNDG7dMO0JfTN0MgMQ==", "dev": true, "requires": { "@types/connect-history-api-fallback": "*", "@types/express": "*", - "@types/http-proxy-middleware": "*", "@types/serve-static": "*", - "@types/webpack": "*" + "@types/webpack": "^4", + "http-proxy-middleware": "^1.0.0" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "http-proxy-middleware": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", + "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } } }, "@types/webpack-sources": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.2.tgz", - "integrity": "sha512-77T++JyKow4BQB/m9O96n9d/UUHWLQHlcqXb9Vsf4F1+wKNrrlWNFPDLKNT92RJnCSL6CieTc+NDXtCVZswdTw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.0.tgz", + "integrity": "sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==", "dev": true, "requires": { "@types/node": "*", @@ -1523,43 +2945,50 @@ } } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz", - "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", + "integrity": "sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==", "dev": true }, "@vue/babel-helper-vue-transform-on": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.0-rc.2.tgz", - "integrity": "sha512-1+7CwjQ0Kasml6rHoNQUmbISwqLNNfFVBUcZl6QBremUl296ZmLrVQPqJP5pyAAWjZke5bpI1hlj+LVVuT7Jcg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==", "dev": true }, "@vue/babel-plugin-jsx": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.0-rc.3.tgz", - "integrity": "sha512-/Ibq0hoKsidnHWPhgRpjcjYhYcHpqEm2fiKVAPO88OXZNHGwaGgS4yXkC6TDEvlZep4mBDo+2S5T81wpbVh90Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", + "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", - "@vue/babel-helper-vue-transform-on": "^1.0.0-rc.2", + "@vue/babel-helper-vue-transform-on": "^1.0.2", "camelcase": "^6.0.0", "html-tags": "^3.1.0", "svg-tags": "^1.0.0" } }, "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz", - "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz", + "integrity": "sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", "html-tags": "^2.0.0", "lodash.kebabcase": "^4.1.1", "svg-tags": "^1.0.0" @@ -1574,9 +3003,9 @@ } }, "@vue/babel-preset-app": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.5.6.tgz", - "integrity": "sha512-Eps83UNiBJeqlbpR9afYnhvjVLElVtA4fDLNuVUr1r3RbepoxWuq+mUTr3TBArPQebnAaDcrZaNHBWTLRbfo3A==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.5.15.tgz", + "integrity": "sha512-J+YttzvwRfV1BPczf8r3qCevznYk+jh531agVF+5EYlHF4Sgh/cGXTz9qkkiux3LQgvhEGXgmCteg1n38WuuKg==", "dev": true, "requires": { "@babel/core": "^7.11.0", @@ -1589,8 +3018,8 @@ "@babel/plugin-transform-runtime": "^7.11.0", "@babel/preset-env": "^7.11.0", "@babel/runtime": "^7.11.0", - "@vue/babel-plugin-jsx": "^1.0.0-0", - "@vue/babel-preset-jsx": "^1.1.2", + "@vue/babel-plugin-jsx": "^1.0.3", + "@vue/babel-preset-jsx": "^1.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", "core-js": "^3.6.5", "core-js-compat": "^3.6.5", @@ -1606,46 +3035,66 @@ } }, "@vue/babel-preset-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz", - "integrity": "sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz", + "integrity": "sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w==", + "dev": true, + "requires": { + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", + "@vue/babel-sugar-composition-api-inject-h": "^1.2.1", + "@vue/babel-sugar-composition-api-render-instance": "^1.2.4", + "@vue/babel-sugar-functional-vue": "^1.2.2", + "@vue/babel-sugar-inject-h": "^1.2.2", + "@vue/babel-sugar-v-model": "^1.2.3", + "@vue/babel-sugar-v-on": "^1.2.3" + } + }, + "@vue/babel-sugar-composition-api-inject-h": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz", + "integrity": "sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@vue/babel-sugar-composition-api-render-instance": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz", + "integrity": "sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q==", "dev": true, "requires": { - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "@vue/babel-sugar-functional-vue": "^1.1.2", - "@vue/babel-sugar-inject-h": "^1.1.2", - "@vue/babel-sugar-v-model": "^1.1.2", - "@vue/babel-sugar-v-on": "^1.1.2" + "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-functional-vue": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz", - "integrity": "sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz", + "integrity": "sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-inject-h": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz", - "integrity": "sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz", + "integrity": "sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-v-model": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz", - "integrity": "sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz", + "integrity": "sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", "camelcase": "^5.0.0", "html-tags": "^2.0.0", "svg-tags": "^1.0.0" @@ -1666,13 +3115,13 @@ } }, "@vue/babel-sugar-v-on": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz", - "integrity": "sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz", + "integrity": "sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw==", "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", "camelcase": "^5.0.0" }, "dependencies": { @@ -1685,20 +3134,20 @@ } }, "@vue/cli-overlay": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.5.6.tgz", - "integrity": "sha512-8kFIdiErtGRlvKWJV0AcF6SXakQDxeuqqcMhWt3qIJxRH6aD33RTC37Q3KWuMsYryBZpEY3tNWGhS1d4spQu0g==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.5.15.tgz", + "integrity": "sha512-0zI0kANAVmjFO2LWGUIzdGPMeE3+9k+KeRDXsUqB30YfRF7abjfiiRPq5BU9pOzlJbVdpRkisschBrvdJqDuDg==", "dev": true }, "@vue/cli-plugin-babel": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-4.5.6.tgz", - "integrity": "sha512-jkeXIpvxg2Og+6igsck6qBMFwFN5poqbgDL7JEQP94DPRMAGt+AOoEz6Ultwvykd9lRDD/xLmzZ2MTeXvrpq4A==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-4.5.15.tgz", + "integrity": "sha512-hBLrwYfFkHldEe34op/YNgPhpOWI5n5DB2Qt9I/1Epeif4M4iFaayrgjvOR9AVM6WbD3Yx7WCFszYpWrQZpBzQ==", "dev": true, "requires": { "@babel/core": "^7.11.0", - "@vue/babel-preset-app": "^4.5.6", - "@vue/cli-shared-utils": "^4.5.6", + "@vue/babel-preset-app": "^4.5.15", + "@vue/cli-shared-utils": "^4.5.15", "babel-loader": "^8.1.0", "cache-loader": "^4.1.0", "thread-loader": "^2.1.3", @@ -1706,12 +3155,12 @@ } }, "@vue/cli-plugin-eslint": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.5.6.tgz", - "integrity": "sha512-maG3dy64pGVT9mMQq7KvP6kbBK6TeVgcj1aa1QwzT5yrw65E2So8bKMrEMEjy53b88bgR9jZ7gshOks00jrYsg==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.5.15.tgz", + "integrity": "sha512-/2Fl6wY/5bz3HD035oSnFRMsKNxDxU396KqBdpCQdwdvqk4mm6JAbXqihpcBRTNPeTO6w+LwGe6FE56PVbJdbg==", "dev": true, "requires": { - "@vue/cli-shared-utils": "^4.5.6", + "@vue/cli-shared-utils": "^4.5.15", "eslint-loader": "^2.2.1", "globby": "^9.2.0", "inquirer": "^7.1.0", @@ -1720,24 +3169,24 @@ } }, "@vue/cli-plugin-router": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.6.tgz", - "integrity": "sha512-QEqOGglg0JEKddZPuyiSnAzAVK7IzLrdTPCUegigzGSbUXDW4gQiltY3/2nij2q538YvdIM7JXtW1sUfy4MgHQ==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.15.tgz", + "integrity": "sha512-q7Y6kP9b3k55Ca2j59xJ7XPA6x+iSRB+N4ac0ZbcL1TbInVQ4j5wCzyE+uqid40hLy4fUdlpl4X9fHJEwuVxPA==", "dev": true, "requires": { - "@vue/cli-shared-utils": "^4.5.6" + "@vue/cli-shared-utils": "^4.5.15" } }, "@vue/cli-plugin-vuex": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.6.tgz", - "integrity": "sha512-cWxj0jIhhupU+oFl0mc1St3ig9iF5F01XKwAhKEbvvuHR97zHxLd29My/vvcRwojZMy4aY320oJ+0ljoCIbueQ==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.15.tgz", + "integrity": "sha512-fqap+4HN+w+InDxlA3hZTOGE0tzBTgXhKLoDydhywqgmhQ1D9JA6Feh94ze6tG8DsWX58/ujYUqA8jAz17FJtg==", "dev": true }, "@vue/cli-service": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.5.6.tgz", - "integrity": "sha512-wl0rhjHSpy2Mc2zNU6sfhaUVNNaRzgXNfZMIpTZMO3wJalPMLuvGC3KLMaXcpvuI01zeQBmkEocAdhzay4lQ0w==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.5.15.tgz", + "integrity": "sha512-sFWnLYVCn4zRfu45IcsIE9eXM0YpDV3S11vlM2/DVbIPAGoYo5ySpSof6aHcIvkeGsIsrHFpPHzNvDZ/efs7jA==", "dev": true, "requires": { "@intervolga/optimize-cssnano-plugin": "^1.0.5", @@ -1746,10 +3195,10 @@ "@types/minimist": "^1.2.0", "@types/webpack": "^4.0.0", "@types/webpack-dev-server": "^3.11.0", - "@vue/cli-overlay": "^4.5.6", - "@vue/cli-plugin-router": "^4.5.6", - "@vue/cli-plugin-vuex": "^4.5.6", - "@vue/cli-shared-utils": "^4.5.6", + "@vue/cli-overlay": "^4.5.15", + "@vue/cli-plugin-router": "^4.5.15", + "@vue/cli-plugin-vuex": "^4.5.15", + "@vue/cli-shared-utils": "^4.5.15", "@vue/component-compiler-utils": "^3.1.2", "@vue/preload-webpack-plugin": "^1.1.0", "@vue/web-component-wrapper": "^1.2.0", @@ -1784,12 +3233,12 @@ "pnp-webpack-plugin": "^1.6.4", "portfinder": "^1.0.26", "postcss-loader": "^3.0.0", - "ssri": "^7.1.0", - "terser-webpack-plugin": "^2.3.6", + "ssri": "^8.0.1", + "terser-webpack-plugin": "^1.4.4", "thread-loader": "^2.1.3", "url-loader": "^2.2.0", "vue-loader": "^15.9.2", - "vue-loader-v16": "npm:vue-loader@^16.0.0-beta.7", + "vue-loader-v16": "npm:vue-loader@^16.1.0", "vue-style-loader": "^4.1.2", "webpack": "^4.0.0", "webpack-bundle-analyzer": "^3.8.0", @@ -1799,136 +3248,122 @@ }, "dependencies": { "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", - "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, - "requires": { - "lodash": "^4.17.14" - } + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true }, - "cacache": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", - "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "optional": true, "requires": { - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.2", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "minipass": "^3.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "p-map": "^3.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^2.7.1", - "ssri": "^7.0.0", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "color-convert": "^2.0.1" } }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "optional": true, "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", - "dev": true - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "optional": true, "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "color-name": "~1.1.4" } }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } + "optional": true }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" } }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", "dev": true, "requires": { - "semver": "^6.0.0" + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" } }, - "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" - } + "dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true }, - "path-exists": { + "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true }, - "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==", + "loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", "dev": true, + "optional": true, "requires": { - "find-up": "^4.0.0" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } }, "portfinder": { @@ -1943,9 +3378,9 @@ }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" @@ -1953,51 +3388,60 @@ } } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, "ssri": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.1.tgz", - "integrity": "sha512-w+daCzXN89PseTL99MkA+fxJEcU3wfaE/ah0i0lnOlpG1CYLJ2ZjzEry68YBKfLs4JfoTShrTEsJkAZuNZ/stw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", "dev": true, "requires": { - "figgy-pudding": "^3.5.1", "minipass": "^3.1.1" } }, - "terser-webpack-plugin": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", - "integrity": "sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==", + "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, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.8.3", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", + "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", "dev": true, + "optional": true, "requires": { - "cacache": "^13.0.1", - "find-cache-dir": "^3.3.1", - "jest-worker": "^25.4.0", - "p-limit": "^2.3.0", - "schema-utils": "^2.6.6", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.6.12", - "webpack-sources": "^1.4.3" + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" } } } }, "@vue/cli-shared-utils": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.5.6.tgz", - "integrity": "sha512-p6ePDlEa7Xc0GEt99KDOCwPZtR7UnoEaZLMfwPYU5LAWkdCmtAw8HPAY/WWcjtoiaAkY4k9tz7ZehQasZ9mJxg==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.5.15.tgz", + "integrity": "sha512-SKaej9hHzzjKSOw1NlFmc6BSE0vcqUQMQiv1cxQ2DhVyy4QxZXBmzmiLBUBe+hYZZs1neXW7n//udeN9bCAY+Q==", "dev": true, "requires": { "@hapi/joi": "^15.0.1", @@ -2068,18 +3512,18 @@ } }, "@vue/component-compiler-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz", - "integrity": "sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", + "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==", "dev": true, "requires": { "consolidate": "^0.15.1", "hash-sum": "^1.0.2", "lru-cache": "^4.1.2", "merge-source-map": "^1.1.0", - "postcss": "^7.0.14", + "postcss": "^7.0.36", "postcss-selector-parser": "^6.0.2", - "prettier": "^1.18.2", + "prettier": "^1.18.2 || ^2.0.0", "source-map": "~0.6.1", "vue-template-es2015-compiler": "^1.9.0" }, @@ -2121,9 +3565,9 @@ "dev": true }, "@vue/web-component-wrapper": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz", - "integrity": "sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz", + "integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==", "dev": true }, "@webassemblyjs/ast": { @@ -2323,9 +3767,9 @@ } }, "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true }, "acorn-jsx": { @@ -2346,16 +3790,6 @@ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "dev": true }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, "ajv": { "version": "6.12.5", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", @@ -2392,26 +3826,26 @@ "dev": true }, "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "type-fest": "^0.11.0" + "type-fest": "^0.21.3" }, "dependencies": { "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "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-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "dev": true }, "ansi-regex": { @@ -2435,9 +3869,9 @@ "dev": true }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -2451,9 +3885,9 @@ "dev": true }, "arch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz", - "integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true }, "argparse": { @@ -2530,9 +3964,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -2587,6 +4021,15 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "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, + "requires": { + "lodash": "^4.17.14" + } + }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -2611,18 +4054,26 @@ "dev": true }, "autoprefixer": { - "version": "9.8.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", - "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", "dev": true, "requires": { "browserslist": "^4.12.0", "caniuse-lite": "^1.0.30001109", - "colorette": "^1.2.1", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", "postcss": "^7.0.32", "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + } } }, "aws-sign2": { @@ -2650,15 +4101,14 @@ } }, "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz", + "integrity": "sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==", "dev": true, "requires": { - "find-cache-dir": "^2.1.0", + "find-cache-dir": "^3.3.1", "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", + "make-dir": "^3.1.0", "schema-utils": "^2.6.5" } }, @@ -2671,6 +4121,44 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-polyfill-corejs2": { + "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, + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.3.1", + "semver": "^6.1.1" + }, + "dependencies": { + "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-polyfill-corejs3": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", + "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.21.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "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, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.1" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2732,9 +4220,9 @@ } }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, "batch": { @@ -2804,9 +4292,9 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", "dev": true }, "body-parser": { @@ -2989,21 +4477,13 @@ } }, "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "requires": { - "bn.js": "^4.1.0", + "bn.js": "^5.0.0", "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } } }, "browserify-sign": { @@ -3108,9 +4588,9 @@ } }, "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 }, "buffer-indexof": { @@ -3197,90 +4677,29 @@ "union-value": "^1.0.0", "unset-value": "^1.0.0" } - }, - "cache-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz", - "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==", - "dev": true, - "requires": { - "buffer-json": "^2.0.0", - "find-cache-dir": "^3.0.0", - "loader-utils": "^1.2.3", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "schema-utils": "^2.0.0" - }, - "dependencies": { - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.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, - "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" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.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" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "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" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + }, + "cache-loader": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz", + "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==", + "dev": true, + "requires": { + "buffer-json": "^2.0.0", + "find-cache-dir": "^3.0.0", + "loader-utils": "^1.2.3", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "schema-utils": "^2.0.0" + } + }, + "call-bind": { + "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" } }, "call-me-maybe": { @@ -3353,9 +4772,9 @@ "dev": true }, "case-sensitive-paths-webpack-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", - "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", "dev": true }, "caseless": { @@ -3413,6 +4832,12 @@ "supports-color": "^4.0.0" } }, + "charcodes": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz", + "integrity": "sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==", + "dev": true + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -3436,20 +4861,20 @@ "integrity": "sha1-Ro9XGkQ1wkJI9f0MsOjYfDw0Hn0=" }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "optional": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.2", - "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.4.0" + "readdirp": "~3.6.0" }, "dependencies": { "braces": { @@ -3498,13 +4923,10 @@ "dev": true }, "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true }, "ci-info": { "version": "1.6.0", @@ -3546,9 +4968,9 @@ } }, "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", "dev": true, "requires": { "source-map": "~0.6.0" @@ -3562,12 +4984,6 @@ } } }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -3578,39 +4994,49 @@ } }, "cli-highlight": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.4.tgz", - "integrity": "sha512-s7Zofobm20qriqDoU9sXptQx0t2R9PEgac92mENNm7xaEe1hn71IIMsXMK+6encA6WRCWWxIGQbipr3q998tlQ==", + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", "dev": true, "requires": { - "chalk": "^3.0.0", - "highlight.js": "^9.6.0", + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^5.1.1", - "yargs": "^15.0.0" + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "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" } }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3640,13 +5066,51 @@ "requires": { "has-flag": "^4.0.0" } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true } } }, "cli-spinners": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz", - "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==", + "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 }, "cli-width": { @@ -3737,13 +5201,13 @@ } }, "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "dev": true, "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, "color-convert": { @@ -3760,19 +5224,19 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", + "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", "dev": true, "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, - "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "colord": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", + "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", "dev": true }, "colors": { @@ -3830,12 +5294,6 @@ "vary": "~1.1.2" }, "dependencies": { - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3918,9 +5376,9 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -3982,6 +5440,26 @@ "webpack-log": "^2.0.0" }, "dependencies": { + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -4015,6 +5493,14 @@ "ignore": "^3.3.5", "pify": "^3.0.0", "slash": "^1.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } } }, "ignore": { @@ -4023,12 +5509,50 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, - "pify": { + "locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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": "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, + "requires": { + "find-up": "^3.0.0" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -4054,15 +5578,34 @@ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" }, "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", + "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", "dev": true, "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.19.1", "semver": "7.0.0" }, "dependencies": { + "browserslist": { + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", + "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001312", + "electron-to-chromium": "^1.4.71", + "escalade": "^3.1.1", + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "dev": true + }, "semver": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", @@ -4109,6 +5652,15 @@ } } }, + "cpu-features": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.2.tgz", + "integrity": "sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==", + "optional": true, + "requires": { + "nan": "^2.14.1" + } + }, "create-ecdh": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", @@ -4120,9 +5672,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -4286,68 +5838,344 @@ } } }, - "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", - "dev": true, - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", - "postcss-unique-selectors": "^4.0.1" - } - }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "cssnano": { + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.17.tgz", + "integrity": "sha512-fmjLP7k8kL18xSspeXTzRhaFtRI7DL9b8IcXR80JgtnWBpvAzHT7sCR/6qdn0tnxIaINUN6OEQu83wF57Gs3Xw==", + "dev": true, + "requires": { + "cssnano-preset-default": "^5.1.12", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + } + }, + "cssnano-preset-default": { + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.12.tgz", + "integrity": "sha512-rO/JZYyjW1QNkWBxMGV28DW7d98UDLaF759frhli58QFehZ+D/LSmwQ2z/ylBAe2hUlsIWTq6NYGfQPq65EF9w==", + "dev": true, + "requires": { + "css-declaration-sorter": "^6.0.3", + "cssnano-utils": "^3.0.2", + "postcss-calc": "^8.2.0", + "postcss-colormin": "^5.2.5", + "postcss-convert-values": "^5.0.4", + "postcss-discard-comments": "^5.0.3", + "postcss-discard-duplicates": "^5.0.3", + "postcss-discard-empty": "^5.0.3", + "postcss-discard-overridden": "^5.0.4", + "postcss-merge-longhand": "^5.0.6", + "postcss-merge-rules": "^5.0.6", + "postcss-minify-font-values": "^5.0.4", + "postcss-minify-gradients": "^5.0.6", + "postcss-minify-params": "^5.0.5", + "postcss-minify-selectors": "^5.1.3", + "postcss-normalize-charset": "^5.0.3", + "postcss-normalize-display-values": "^5.0.3", + "postcss-normalize-positions": "^5.0.4", + "postcss-normalize-repeat-style": "^5.0.4", + "postcss-normalize-string": "^5.0.4", + "postcss-normalize-timing-functions": "^5.0.3", + "postcss-normalize-unicode": "^5.0.4", + "postcss-normalize-url": "^5.0.5", + "postcss-normalize-whitespace": "^5.0.4", + "postcss-ordered-values": "^5.0.5", + "postcss-reduce-initial": "^5.0.3", + "postcss-reduce-transforms": "^5.0.4", + "postcss-svgo": "^5.0.4", + "postcss-unique-selectors": "^5.0.4" + }, + "dependencies": { + "css-declaration-sorter": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.1.4.tgz", + "integrity": "sha512-lpfkqS0fctcmZotJGhnxkIyJWvBXgpyi2wsFd4J8VB7wzyrT6Ch/3Q+FMNJpjK4gu1+GN5khOnpU2ZVKrLbhCw==", + "dev": true, + "requires": { + "timsort": "^0.3.0" + } + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.5.tgz", + "integrity": "sha512-+X30aDaGYq81mFqwyPpnYInsZQnNpdxMX0ajlY7AExCexEFkPVV+KrO7kXwayqEWL2xwEbNQ4nUO0ZsRWGnevg==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.4.tgz", + "integrity": "sha512-bugzSAyjIexdObovsPZu/sBCTHccImJxLyFgeV0MmNBm/Lw5h5XnjfML6gzEmJ3A6nyfCW7hb1JXzcsA4Zfbdw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-discard-comments": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.3.tgz", + "integrity": "sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q==", + "dev": true + }, + "postcss-discard-duplicates": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.3.tgz", + "integrity": "sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw==", + "dev": true + }, + "postcss-discard-empty": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.3.tgz", + "integrity": "sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA==", + "dev": true + }, + "postcss-discard-overridden": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.4.tgz", + "integrity": "sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg==", + "dev": true + }, + "postcss-merge-longhand": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.6.tgz", + "integrity": "sha512-rkmoPwQO6ymJSmWsX6l2hHeEBQa7C4kJb9jyi5fZB1sE8nSCv7sqchoYPixRwX/yvLoZP2y6FA5kcjiByeJqDg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.0.3" + } + }, + "postcss-merge-rules": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.6.tgz", + "integrity": "sha512-nzJWJ9yXWp8AOEpn/HFAW72WKVGD2bsLiAmgw4hDchSij27bt6TF+sIK0cJUBAYT3SGcjtGGsOR89bwkkMuMgQ==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.0.2", + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-minify-font-values": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.4.tgz", + "integrity": "sha512-RN6q3tyuEesvyCYYFCRGJ41J1XFvgV+dvYGHr0CeHv8F00yILlN8Slf4t8XW4IghlfZYCeyRrANO6HpJ948ieA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.6.tgz", + "integrity": "sha512-E/dT6oVxB9nLGUTiY/rG5dX9taugv9cbLNTFad3dKxOO+BQg25Q/xo2z2ddG+ZB1CbkZYaVwx5blY8VC7R/43A==", + "dev": true, + "requires": { + "colord": "^2.9.1", + "cssnano-utils": "^3.0.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.5.tgz", + "integrity": "sha512-YBNuq3Rz5LfLFNHb9wrvm6t859b8qIqfXsWeK7wROm3jSKNpO1Y5e8cOyBv6Acji15TgSrAwb3JkVNCqNyLvBg==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "cssnano-utils": "^3.0.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.3.tgz", + "integrity": "sha512-9RJfTiQEKA/kZhMaEXND893nBqmYQ8qYa/G+uPdVnXF6D/FzpfI6kwBtWEcHx5FqDbA79O9n6fQJfrIj6M8jvQ==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-normalize-charset": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.3.tgz", + "integrity": "sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA==", + "dev": true + }, + "postcss-normalize-display-values": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.3.tgz", + "integrity": "sha512-FIV5FY/qs4Ja32jiDb5mVj5iWBlS3N8tFcw2yg98+8MkRgyhtnBgSC0lxU+16AMHbjX5fbSJgw5AXLMolonuRQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.4.tgz", + "integrity": "sha512-qynirjBX0Lc73ROomZE3lzzmXXTu48/QiEzKgMeqh28+MfuHLsuqC9po4kj84igZqqFGovz8F8hf44hA3dPYmQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.4.tgz", + "integrity": "sha512-Innt+wctD7YpfeDR7r5Ik6krdyppyAg2HBRpX88fo5AYzC1Ut/l3xaxACG0KsbX49cO2n5EB13clPwuYVt8cMA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.4.tgz", + "integrity": "sha512-Dfk42l0+A1CDnVpgE606ENvdmksttLynEqTQf5FL3XGQOyqxjbo25+pglCUvziicTxjtI2NLUR6KkxyUWEVubQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.3.tgz", + "integrity": "sha512-QRfjvFh11moN4PYnJ7hia4uJXeFotyK3t2jjg8lM9mswleGsNw2Lm3I5wO+l4k1FzK96EFwEVn8X8Ojrp2gP4g==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.4.tgz", + "integrity": "sha512-W79Regn+a+eXTzB+oV/8XJ33s3pDyFTND2yDuUCo0Xa3QSy1HtNIfRVPXNubHxjhlqmMFADr3FSCHT84ITW3ig==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.5.tgz", + "integrity": "sha512-Ws3tX+PcekYlXh+ycAt0wyzqGthkvVtZ9SZLutMVvHARxcpu4o7vvXcNoiNKyjKuWecnjS6HDI3fjBuDr5MQxQ==", + "dev": true, + "requires": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.4.tgz", + "integrity": "sha512-wsnuHolYZjMwWZJoTC9jeI2AcjA67v4UuidDrPN9RnX8KIZfE+r2Nd6XZRwHVwUiHmRvKQtxiqo64K+h8/imaw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-ordered-values": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.5.tgz", + "integrity": "sha512-mfY7lXpq+8bDEHfP+muqibDPhZ5eP9zgBEF9XRvoQgXcQe2Db3G1wcvjbnfjXG6wYsl+0UIjikqq4ym1V2jGMQ==", + "dev": true, + "requires": { + "cssnano-utils": "^3.0.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reduce-initial": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.3.tgz", + "integrity": "sha512-c88TkSnQ/Dnwgb4OZbKPOBbCaauwEjbECP5uAuFPOzQ+XdjNjRH7SG0dteXrpp1LlIFEKK76iUGgmw2V0xeieA==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.4.tgz", + "integrity": "sha512-VIJB9SFSaL8B/B7AXb7KHL6/GNNbbCHslgdzS9UDfBZYIA2nx8NLY7iD/BXFSO/1sRUILzBTfHCoW5inP37C5g==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", + "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-unique-selectors": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.4.tgz", + "integrity": "sha512-5ampwoSDJCxDPoANBIlMgoBcYUHnhaiuLYJR5pj1DLnYQvMRVyFuTA5C3Bvt+aHtiqWpJkD/lXT50Vo1D0ZsAQ==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "stylehacks": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.3.tgz", + "integrity": "sha512-ENcUdpf4yO0E1rubu8rkxI+JGQk4CgjchynZ4bDBJDfqdy+uhTRSWb8/F3Jtu+Bw5MW45Po3/aQGeIyyxgQtxg==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" + } + } + } + }, "cssnano-util-get-arguments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", @@ -4375,29 +6203,35 @@ "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", "dev": true }, + "cssnano-utils": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.2.tgz", + "integrity": "sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==", + "dev": true + }, "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "dev": true, "requires": { - "css-tree": "1.0.0-alpha.39" + "css-tree": "^1.1.2" }, "dependencies": { "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "dev": true, "requires": { - "mdn-data": "2.0.6", + "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, "source-map": { @@ -4596,9 +6430,9 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "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": { @@ -4655,9 +6489,9 @@ } }, "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 }, "mimic-fn": { @@ -4817,12 +6651,6 @@ } } }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -4865,15 +6693,15 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "diffie-hellman": { @@ -4888,9 +6716,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -4958,9 +6786,9 @@ }, "dependencies": { "domelementtype": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.2.tgz", - "integrity": "sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true } } @@ -4978,12 +6806,20 @@ "dev": true }, "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "^2.2.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + } } }, "domutils": { @@ -5045,9 +6881,9 @@ } }, "easy-stack": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz", - "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz", + "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==", "dev": true }, "ecc-jsbn": { @@ -5070,6 +6906,12 @@ "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", "dev": true }, + "electron-to-chromium": { + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", + "dev": true + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -5119,9 +6961,9 @@ } }, "enhanced-resolve": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", - "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -5148,9 +6990,9 @@ "dev": true }, "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, "requires": { "prr": "~1.0.1" @@ -5166,32 +7008,40 @@ } }, "error-stack-parser": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", - "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", + "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", "dev": true, "requires": { "stackframe": "^1.1.1" } }, "es-abstract": { - "version": "1.18.0-next.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.0.tgz", - "integrity": "sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ==", + "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.1", - "is-callable": "^1.2.0", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "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.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -5210,6 +7060,12 @@ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.1.1.tgz", "integrity": "sha512-HBL8I3mIki5C1Cc9QjKUenHtnG0A5/xA8Q/AllRcfiwl2CZFXGK7ddBiCoRwAix4i2KxcQfjtIVcrVbB3vbmwg==" }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -5296,9 +7152,9 @@ } }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "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", @@ -5492,15 +7348,15 @@ "dev": true }, "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", + "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", "dev": true, "requires": { "original": "^1.0.0" @@ -5831,9 +7687,9 @@ "dev": true }, "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -5958,41 +7814,31 @@ } }, "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" } }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "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": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - } - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true }, "flat-cache": { "version": "2.0.1", @@ -6033,9 +7879,9 @@ } }, "follow-redirects": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", - "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", "dev": true }, "for-in": { @@ -6105,15 +7951,6 @@ "universalify": "^0.1.0" } }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -6132,9 +7969,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -6151,9 +7988,9 @@ "dev": true }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -6167,6 +8004,17 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-intrinsic": { + "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", + "has-symbols": "^1.0.1" + } + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -6176,6 +8024,16 @@ "pump": "^3.0.0" } }, + "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", @@ -6204,9 +8062,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -6269,9 +8127,9 @@ } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "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": { @@ -6336,6 +8194,12 @@ } } }, + "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 + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -6347,9 +8211,9 @@ "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "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 }, "has-to-string-tag-x": { @@ -6360,6 +8224,15 @@ "has-symbol-support-x": "^1.4.1" } }, + "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", @@ -6497,9 +8370,9 @@ "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" }, "highlight.js": { - "version": "9.18.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.3.tgz", - "integrity": "sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "dev": true }, "hmac-drbg": { @@ -6569,16 +8442,10 @@ } } }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true - }, "html-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", "dev": true }, "html-minifier": { @@ -6668,34 +8535,43 @@ } }, "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "dev": true, "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" }, "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" } } } @@ -6724,6 +8600,12 @@ } } }, + "http-parser-js": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", + "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==", + "dev": true + }, "http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", @@ -6770,9 +8652,9 @@ "dev": true }, "i": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", - "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=" + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz", + "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==" }, "iconv-lite": { "version": "0.4.24", @@ -6793,9 +8675,9 @@ } }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, "iferr": { @@ -6846,6 +8728,51 @@ "requires": { "pkg-dir": "^3.0.0", "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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": "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, + "requires": { + "find-up": "^3.0.0" + } + } } }, "imurmurhash": { @@ -6854,12 +8781,6 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", @@ -6918,19 +8839,18 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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", @@ -7025,21 +8945,23 @@ } } }, + "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", + "side-channel": "^1.0.4" + } + }, "interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -7084,10 +9006,14 @@ } }, "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true + "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", @@ -7095,6 +9021,15 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bigint": { + "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", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -7104,15 +9039,25 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "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" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "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": { @@ -7159,10 +9104,13 @@ } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "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": "0.1.6", @@ -7190,9 +9138,9 @@ "dev": true }, "is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true }, "is-extendable": { @@ -7231,9 +9179,9 @@ } }, "is-negative-zero": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", - "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "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": { @@ -7256,6 +9204,15 @@ } } }, + "is-number-object": { + "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-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -7306,12 +9263,13 @@ } }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "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": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-resolvable": { @@ -7325,27 +9283,33 @@ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" }, + "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": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, "requires": { - "html-comment-regex": "^1.1.0" + "has-tostringtag": "^1.0.0" } }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "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.1" + "has-symbols": "^1.0.2" } }, "is-typedarray": { @@ -7353,6 +9317,21 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "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", @@ -7397,56 +9376,29 @@ } }, "javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", "dev": true }, - "jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": 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, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "jquery": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" }, "js-message": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz", - "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz", + "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==", "dev": true }, "js-queue": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz", - "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz", + "integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==", "dev": true, "requires": { - "easy-stack": "^1.0.0" + "easy-stack": "^1.0.1" } }, "js-tokens": { @@ -7456,9 +9408,9 @@ "dev": true }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "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", @@ -7488,11 +9440,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -7516,9 +9463,9 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "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" @@ -7540,14 +9487,21 @@ "dev": true }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" + }, + "dependencies": { + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + } } }, "killable": { @@ -7571,59 +9525,22 @@ } }, "launch-editor": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz", - "integrity": "sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.3.0.tgz", + "integrity": "sha512-3QrsCXejlWYHjBPFXTyGNhPj4rrQdB+5+r5r3wArpLH201aR+nWUgw/zKKkTmilCfY/sv6u8qo98pNvtg8LUTA==", "dev": true, "requires": { - "chalk": "^2.3.0", + "picocolors": "^1.0.0", "shell-quote": "^1.6.1" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "launch-editor-middleware": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz", - "integrity": "sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==", - "dev": true, - "requires": { - "launch-editor": "^2.2.1" - } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.3.0.tgz", + "integrity": "sha512-GJR64trLdFFwCoL9DMn/d1SZX0OzTDPixu4mcfWTShQ4tIqCHCGvlg9fOEYQXyBlrSMQwylsJfUWncheShfV2w==", "dev": true, "requires": { - "leven": "^3.1.0" + "launch-editor": "^2.3.0" } }, "levn": { @@ -7636,10 +9553,16 @@ "type-check": "~0.3.2" } }, + "lilconfig": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", + "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", + "dev": true + }, "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, "loader-fs-cache": { @@ -7722,13 +9645,12 @@ } }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "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": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -7736,6 +9658,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -7792,20 +9720,11 @@ } }, "loglevel": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", - "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "lower-case": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", @@ -7827,13 +9746,20 @@ } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "map-cache": { @@ -7964,17 +9890,17 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } }, "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true }, "mime-db": { @@ -8064,9 +9990,9 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -8080,33 +10006,6 @@ } } }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -8155,41 +10054,66 @@ } }, "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz", + "integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==", "dev": true, "requires": { - "ansi-colors": "3.2.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "ms": "2.1.3", + "nanoid": "3.2.0", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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 }, "braces": { @@ -8201,74 +10125,90 @@ "fill-range": "^7.0.1" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "dependencies": { "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "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": "^3.0.0" + "has-flag": "^4.0.0" } } } }, "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.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.2.0" + "readdirp": "~3.6.0" } }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "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.1" + "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 + } } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "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 }, "fill-range": { @@ -8280,10 +10220,27 @@ "to-regex-range": "^5.0.1" } }, + "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" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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", @@ -8294,10 +10251,10 @@ "path-is-absolute": "^1.0.0" } }, - "is-fullwidth-code-point": { - "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=", + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "is-number": { @@ -8307,84 +10264,88 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "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": "^1.0.7", - "esprima": "^4.0.0" + "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" } }, "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "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": "^2.4.2" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" } }, "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 }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "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": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "yocto-queue": "^0.1.0" } }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "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": { - "picomatch": "^2.0.4" + "p-limit": "^3.0.2" } }, - "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==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "picomatch": "^2.2.1" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "serialize-javascript": { + "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": { - "ansi-regex": "^4.1.0" + "randombytes": "^2.1.0" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "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": "^3.0.0" + "has-flag": "^4.0.0" } }, "to-regex-range": { @@ -8396,44 +10357,52 @@ "is-number": "^7.0.0" } }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } }, @@ -8522,9 +10491,14 @@ "version": "2.14.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, "optional": true }, + "nanoid": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "dev": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -8586,21 +10560,14 @@ "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" + "whatwg-url": "^5.0.0" } }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, "node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", @@ -8613,14 +10580,14 @@ "integrity": "sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs=" }, "node-ipc": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz", - "integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.2.1.tgz", + "integrity": "sha512-mJzaM6O3xHf9VT8BULvJSbdVbmHUKRNOH7zDDkCrA1/T+CVjq2WVIDfLt0azZRXpgArJtl3rtmEozrbXPZ9GaQ==", "dev": true, "requires": { "event-pubsub": "4.3.0", - "js-message": "1.0.5", - "js-queue": "2.0.0" + "js-message": "1.0.7", + "js-queue": "2.0.2" } }, "node-libs-browser": { @@ -8662,6 +10629,12 @@ } } }, + "node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, "nodemailer": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.1.tgz", @@ -8769,40 +10742,19 @@ "dev": true }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "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-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "object-keys": { @@ -8821,46 +10773,26 @@ } }, "object.assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", - "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "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", - "es-abstract": "^1.18.0-next.0", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" } }, "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", + "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "es-abstract": "^1.19.1" } }, "object.pick": { @@ -8873,36 +10805,14 @@ } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "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.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "es-abstract": "^1.19.1" } }, "obuf": { @@ -9088,22 +10998,19 @@ } }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "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.0.0" + "p-limit": "^2.2.0" } }, "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true }, "p-retry": { "version": "3.0.1", @@ -9197,9 +11104,9 @@ } }, "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -9215,12 +11122,20 @@ "dev": true }, "parse5-htmlparser2-tree-adapter": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.1.1.tgz", - "integrity": "sha512-CF+TKjXqoqyDwHqBhFQ+3l5t83xYi6fVT1tQNg+Ye0JRLnTxWvIroCjEp1A0k4lneHNBGnICUf0cfYVYGEazqw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, "requires": { - "parse5": "^5.1.1" + "parse5": "^6.0.1" + }, + "dependencies": { + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + } } }, "parseurl": { @@ -9247,9 +11162,9 @@ "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=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { @@ -9270,9 +11185,9 @@ "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==" }, "path-to-regexp": { "version": "0.1.7", @@ -9297,15 +11212,15 @@ } }, "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -9402,6 +11317,12 @@ "split2": "^3.1.1" } }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -9430,12 +11351,12 @@ } }, "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==", + "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": "^3.0.0" + "find-up": "^4.0.0" } }, "pkginfo": { @@ -9444,9 +11365,9 @@ "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=" }, "pnp-webpack-plugin": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", - "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz", + "integrity": "sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==", "dev": true, "requires": { "ts-pnp": "^1.1.6" @@ -9499,59 +11420,33 @@ "dev": true }, "postcss": { - "version": "7.0.34", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.34.tgz", - "integrity": "sha512-H/7V2VeNScX9KE83GDrDZNiGT1m2H+UTnlinIzhjlLX9hfMUn1mHNnGeX81a1c8JSBdBvqk7c2ZOG6ZPn5itGw==", + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "picocolors": "^0.2.1", + "source-map": "^0.6.1" }, "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, "postcss-calc": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.4.tgz", - "integrity": "sha512-0I79VRAd1UTkaHzY9w83P39YGO/M3bG7/tNLrHGEunBolfoGM0hSjrGvjoeaj0JE/zIw5GsI2KZ0UwDJqv5hjw==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", "dev": true, "requires": { "postcss": "^7.0.27", @@ -9635,9 +11530,9 @@ } }, "postcss-load-config": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.1.tgz", - "integrity": "sha512-D2ENobdoZsW0+BHy4x1CAkXtbXtYWYRIxL/JbtRBqrRGOPtJ2zoga/bEZWhV/ShWB5saVxJMzbMdSyA/vv4tXw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", "dev": true, "requires": { "cosmiconfig": "^5.0.0", @@ -10057,34 +11952,147 @@ } }, "postcss-selector-parser": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.3.tgz", - "integrity": "sha512-0ClFaY4X1ra21LRqbW6y3rUbWcxnSVkDFG57R7Nxus9J9myPFlv+jYDMohzpkBx0RrjjiqjtycpchQ+PLGmZ9w==", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", + "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", "dev": true, "requires": { "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1", "util-deprecate": "^1.0.2" } }, "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.4.tgz", + "integrity": "sha512-yDKHvULbnZtIrRqhZoA+rxreWpee28JSRH/gy9727u0UCgtpv1M/9WEWY3xySlFa0zQJcqf6oCBJPR5NwkmYpg==", "dev": true, "requires": { - "is-svg": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" }, "dependencies": { + "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 + }, + "css-select": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", + "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "dev": true + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + } + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "domhandler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + } } } }, @@ -10100,9 +12108,9 @@ } }, "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, "postgres-array": { @@ -10140,20 +12148,20 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true, "optional": true }, "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "dev": true, "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" + "lodash": "^4.17.20", + "renderkid": "^2.0.4" } }, "process": { @@ -10267,9 +12275,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -10473,9 +12481,9 @@ } }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "optional": true, "requires": { @@ -10526,24 +12534,24 @@ "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" }, "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "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 }, "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", "dev": true, "requires": { - "regenerate": "^1.4.0" + "regenerate": "^1.4.2" } }, "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "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 }, "regenerator-transform": { @@ -10566,34 +12574,13 @@ } }, "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "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": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "regexpp": { @@ -10603,29 +12590,29 @@ "dev": true }, "regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", + "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", "dev": true, "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" } }, "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", "dev": true }, "regjsparser": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -10652,16 +12639,16 @@ "dev": true }, "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", "dev": true, "requires": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { @@ -10671,31 +12658,59 @@ "dev": true }, "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", + "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", "dev": true, "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" + "boolbase": "^1.0.0", + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" } }, "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "dev": true + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true }, "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "boolbase": "^1.0.0" } }, "strip-ansi": { @@ -10873,9 +12888,9 @@ } }, "rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -10923,9 +12938,9 @@ "dev": true }, "selfsigned": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", - "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", + "version": "1.10.14", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz", + "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==", "dev": true, "requires": { "node-forge": "^0.10.0" @@ -11014,35 +13029,11 @@ "ms": "2.0.0" } }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true } } }, @@ -11131,15 +13122,15 @@ "dev": true }, "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, "shelljs": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.6.tgz", - "integrity": "sha1-N5zM+1a5HIYB5HkzVutTgpJN6a0=", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, "requires": { "glob": "^7.0.0", @@ -11147,6 +13138,17 @@ "rechoir": "^0.6.2" } }, + "side-channel": { + "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", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -11318,55 +13320,46 @@ } }, "sockjs": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", - "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.4.0", - "websocket-driver": "0.6.5" + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" }, "dependencies": { "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true } } }, "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz", + "integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==", "dev": true, "requires": { - "debug": "^3.2.5", + "debug": "^3.2.6", "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.5.3" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } } } }, @@ -11405,9 +13398,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", @@ -11455,9 +13448,9 @@ } }, "spdx-license-ids": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", - "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "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 }, "spdy": { @@ -11564,24 +13557,6 @@ "underscore": "^1.4.x" } }, - "ssh2": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.4.tgz", - "integrity": "sha1-G/a2soyW6u8mf01sRqWiUXpZnic=", - "requires": { - "ssh2-streams": "~0.1.15" - } - }, - "ssh2-streams": { - "version": "0.1.20", - "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.1.20.tgz", - "integrity": "sha1-URGNFUVV31Rp7h9n4M8efoosDjo=", - "requires": { - "asn1": "~0.2.0", - "semver": "^5.1.0", - "streamsearch": "~0.1.2" - } - }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -11599,9 +13574,9 @@ } }, "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", "dev": true, "requires": { "figgy-pudding": "^3.5.1" @@ -11619,9 +13594,9 @@ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, "stackframe": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", - "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.1.tgz", + "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==", "dev": true }, "static-extend": { @@ -11689,11 +13664,6 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" - }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -11711,65 +13681,23 @@ } }, "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "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": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "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": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "string_decoder": { @@ -11789,9 +13717,9 @@ }, "dependencies": { "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" } } }, @@ -12032,6 +13960,70 @@ "worker-farm": "^1.7.0" }, "dependencies": { + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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": "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, + "requires": { + "find-up": "^3.0.0" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -12114,9 +14106,9 @@ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "dev": true, "requires": { "setimmediate": "^1.0.4" @@ -12201,9 +14193,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 }, "toposort": { @@ -12221,6 +14213,11 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -12234,9 +14231,9 @@ "dev": true }, "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tty-browserify": { @@ -12254,13 +14251,13 @@ } }, "tunnel-ssh": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tunnel-ssh/-/tunnel-ssh-4.1.4.tgz", - "integrity": "sha512-CjBqboGvAbM7iXSX2F95kzoI+c2J81YkrHbyyo4SWNKCzU6w5LfEvXBCHu6PPriYaNvfhMKzD8bFf5Vl14YTtg==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/tunnel-ssh/-/tunnel-ssh-4.1.6.tgz", + "integrity": "sha512-y7+x+T3F3rkx2Zov5Tk9DGfeEBVAdWU3A/91E0Dk5rrZ/VFIlpV2uhhRuaISJUdyG0N+Lcp1fXZMXz+ovPt5vA==", "requires": { "debug": "2.6.9", "lodash.defaults": "^4.1.0", - "ssh2": "0.5.4" + "ssh2": "1.4.0" }, "dependencies": { "debug": { @@ -12275,6 +14272,23 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "optional": true + }, + "ssh2": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.4.0.tgz", + "integrity": "sha512-XvXwcXKvS452DyQvCa6Ct+chpucwc/UyxgliYz+rWXJ3jDHdtBb9xgmxJdMmnIn5bpgGAEV3KaEsH98ZGPHqwg==", + "requires": { + "asn1": "^0.2.4", + "bcrypt-pbkdf": "^1.0.2", + "cpu-features": "0.0.2", + "nan": "^2.15.0" + } } } }, @@ -12349,37 +14363,49 @@ } } }, + "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", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "underscore": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" }, "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "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 }, "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "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, "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" } }, "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "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 }, "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "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 }, "union-value": { @@ -12537,9 +14563,9 @@ } }, "url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, "requires": { "querystringify": "^2.1.1", @@ -12597,27 +14623,6 @@ "es-abstract": "^1.17.2", "has-symbols": "^1.0.1", "object.getownpropertydescriptors": "^2.1.0" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "utila": { @@ -12662,9 +14667,9 @@ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" }, "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "validate-npm-package-license": { @@ -12763,9 +14768,9 @@ } }, "vue-loader": { - "version": "15.9.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz", - "integrity": "sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA==", + "version": "15.9.8", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.8.tgz", + "integrity": "sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==", "dev": true, "requires": { "@vue/component-compiler-utils": "^3.1.0", @@ -12776,91 +14781,10 @@ }, "dependencies": { "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true - } - } - }, - "vue-loader-v16": { - "version": "npm:vue-loader-v16@16.8.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", - "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "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, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true } } }, @@ -12891,9 +14815,9 @@ "integrity": "sha1-C/Wi3E5uZCFlHqCu+mj69uvD/rw=" }, "vue-style-loader": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", - "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", + "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", "dev": true, "requires": { "hash-sum": "^1.0.2", @@ -12925,21 +14849,21 @@ "dev": true }, "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dev": true, "requires": { "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" + "watchpack-chokidar2": "^2.0.1" } }, "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", "dev": true, "optional": true, "requires": { @@ -13073,10 +14997,15 @@ "defaults": "^1.0.3" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, "webpack": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", - "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -13087,7 +15016,7 @@ "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.3.0", + "enhanced-resolve": "^4.5.0", "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", "loader-runner": "^2.4.0", @@ -13138,34 +15067,44 @@ "ws": "^6.0.0" }, "dependencies": { + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "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.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "dev": true, "requires": { - "bytes": "3.1.0", + "bytes": "3.1.2", "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.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" } }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, "chalk": { @@ -13180,18 +15119,18 @@ } }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" } }, "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true }, "debug": { @@ -13204,17 +15143,17 @@ } }, "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "dev": true, "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", @@ -13228,13 +15167,13 @@ "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", @@ -13256,59 +15195,96 @@ "unpipe": "~1.0.0" } }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "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" + "toidentifier": "1.0.1" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, + "mime-db": { + "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.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.51.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, "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.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", "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.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, + "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 + }, "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, "requires": { "debug": "2.6.9", @@ -13318,38 +15294,38 @@ "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" }, "dependencies": { "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 } } }, "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, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.17.2" } }, "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 }, "supports-color": { @@ -13374,9 +15350,9 @@ } }, "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", "dev": true, "requires": { "memory-fs": "^0.4.1", @@ -13387,12 +15363,12 @@ } }, "webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz", + "integrity": "sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==", "dev": true, "requires": { - "ansi-html": "0.0.7", + "ansi-html-community": "0.0.8", "bonjour": "^3.5.0", "chokidar": "^2.1.8", "compression": "^1.7.4", @@ -13412,11 +15388,11 @@ "p-retry": "^3.0.1", "portfinder": "^1.0.26", "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", + "selfsigned": "^1.10.8", "semver": "^6.3.0", "serve-index": "^1.9.1", - "sockjs": "0.3.20", - "sockjs-client": "1.4.0", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", "spdy": "^4.0.2", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", @@ -13427,6 +15403,16 @@ "yargs": "^13.3.2" }, "dependencies": { + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -13454,15 +15440,6 @@ } } }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -13470,21 +15447,21 @@ "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.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", "dev": true, "requires": { - "bytes": "3.1.0", + "bytes": "3.1.2", "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.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" }, "dependencies": { "debug": { @@ -13499,9 +15476,9 @@ } }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, "camelcase": { @@ -13565,18 +15542,18 @@ "dev": true }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" } }, "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true }, "emoji-regex": { @@ -13586,17 +15563,17 @@ "dev": true }, "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", "dev": true, "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.4.2", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", @@ -13610,13 +15587,13 @@ "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", @@ -13660,6 +15637,21 @@ } } }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, "fsevents": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", @@ -13693,24 +15685,16 @@ } }, "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" } }, "is-absolute-url": { @@ -13734,18 +15718,49 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, + "mime-db": { + "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.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.51.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", @@ -13755,6 +15770,21 @@ "is-wsl": "^1.1.0" } }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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 + }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -13767,36 +15797,46 @@ }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, "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.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", "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.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -13812,6 +15852,12 @@ "readable-stream": "^2.0.2" } }, + "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 + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -13830,9 +15876,9 @@ "dev": true }, "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, "requires": { "debug": "2.6.9", @@ -13842,9 +15888,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" @@ -13868,29 +15914,29 @@ } }, "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 } } }, "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, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.17.2" } }, "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 }, "string-width": { @@ -14043,11 +16089,13 @@ } }, "websocket-driver": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -14057,6 +16105,15 @@ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "when": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/when/-/when-2.0.1.tgz", @@ -14071,53 +16128,24 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "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", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, - "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 - }, - "is-fullwidth-code-point": { - "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 - }, - "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" - } - } - } - }, "winston": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/winston/-/winston-2.3.1.tgz", @@ -14158,6 +16186,12 @@ "errno": "~0.1.7" } }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -14207,9 +16241,9 @@ } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "dev": true, "requires": { "async-limiter": "~1.0.0" @@ -14250,6 +16284,12 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", @@ -14317,106 +16357,37 @@ } }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.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 - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, - "is-fullwidth-code-point": { - "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=", + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true - }, - "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==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "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" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, "yorkie": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz", diff --git a/package.json b/package.json index 5c61778f..589b6e7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sdl_policy_server", - "version": "2.12.0", + "version": "3.0.0", "license": "BSD-3-Clause", "description": "Integrates with SHAID to allow managing app permissions through policy tables", "author": "Livio", @@ -70,19 +70,19 @@ "chai-json-schema": "^1.5.0", "chalk": "2.0.1", "connect-history-api-fallback": "1.3.0", - "cssnano": "^4.1.10", + "cssnano": "^5.0.17", "eslint": "^6.7.2", "eslint-plugin-vue": "^6.2.2", "eventsource-polyfill": "0.9.6", "express": "4.16.0", "http-proxy-middleware": "^0.19.1", - "mocha": "^7.1.1", + "mocha": "^9.2.1", "mocha-steps": "^1.3.0", "opn": "5.1.0", "ora": "1.2.0", "rimraf": "2.6.0", "semver": "^5.3.0", - "shelljs": "0.7.6", + "shelljs": "^0.8.5", "vue-template-compiler": "^2.6.11" }, "engines": { From 84a0a0577a3e1011bf46928edff0cb9e5f30e890 Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Fri, 25 Feb 2022 09:48:45 -0500 Subject: [PATCH 17/18] Use deployed version of server to avoid dev server issues --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 00516520..87cfeae7 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -26,7 +26,7 @@ services: depends_on: - redis - postgres - command: ["./wait-for-it.sh", "postgres:5432", "--", "npm", "start"] + command: ["./wait-for-it.sh", "postgres:5432", "--", "npm", "run", "start-server"] redis: image: redis postgres: From d1aedde472d238cc1f9763caaf6807661f44c1d2 Mon Sep 17 00:00:00 2001 From: renonick87 Date: Wed, 9 Mar 2022 11:40:11 -0500 Subject: [PATCH 18/18] Fix Safari still showing save button for messages and groups with an empty name field --- src/components/ConsumerMessageDetails.vue | 14 +++++--------- src/components/FunctionalGroupDetails.vue | 14 +++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/components/ConsumerMessageDetails.vue b/src/components/ConsumerMessageDetails.vue index 5fd97e96..f3c9d79f 100644 --- a/src/components/ConsumerMessageDetails.vue +++ b/src/components/ConsumerMessageDetails.vue @@ -41,7 +41,7 @@
-
+

-
+