From ae9b82d2cca04ed1e3586813b1ceb93c8e0d5f6d Mon Sep 17 00:00:00 2001 From: hayaofr Date: Tue, 21 Dec 2021 16:55:32 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20Changement=20de=20la=20m=C3=A9thode=20d?= =?UTF-8?q?'analyse=20en=20recr=C3=A9ant=20le=20DOM=20de=20la=20page=20en?= =?UTF-8?q?=20m=C3=A9moire.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cela évite de charge le code de l'analyseur dans la page elle même. Cela permet d'analyser des sites ayant des Content Security Policy de configurés. Ces modifications sont issues de la proposition de @hayaofr (via #16), j'ai simplement ici réduit au maximum le nombre de modification pour faciliter la relecture de la PR Fix: #19 --- cli-core/analysis.js | 33 +- cli-core/reportHtml.js | 4 +- greenit | 0 greenit-core/analyseFrameCore.js | 34 +- greenit-core/chrome.js | 16 + greenit-core/ecoIndex.js | 7 + greenit-core/greenpanel.js | 102 ++- .../rules/AddExpiresOrCacheControlHeaders.js | 59 +- greenit-core/rules/CompressHttp.js | 59 +- greenit-core/rules/DomainsNumber.js | 51 +- .../rules/DontResizeImageInBrowser.js | 87 ++- greenit-core/rules/EmptySrcTag.js | 30 +- greenit-core/rules/ExternalizeCss.js | 30 +- greenit-core/rules/ExternalizeJs.js | 30 +- greenit-core/rules/HttpError.js | 46 +- greenit-core/rules/HttpRequests.js | 36 +- .../rules/ImageDownloadedNotDisplayed.js | 66 +- greenit-core/rules/JsValidate.js | 45 +- greenit-core/rules/MaxCookiesLength.js | 61 +- greenit-core/rules/MinifiedCss.js | 47 +- greenit-core/rules/MinifiedJs.js | 47 +- .../rules/NoCookieForStaticRessources.js | 55 +- greenit-core/rules/NoRedirect.js | 47 +- greenit-core/rules/OptimizeBitmapImages.js | 87 ++- greenit-core/rules/OptimizeSvg.js | 55 +- greenit-core/rules/Plugins.js | 34 +- greenit-core/rules/PrintStyleSheet.js | 34 +- greenit-core/rules/SocialNetworkButton.js | 51 +- greenit-core/rules/StyleSheets.js | 53 +- greenit-core/rules/UseETags.js | 71 +- greenit-core/rules/UseStandardTypefaces.js | 61 +- greenit-core/rulesManager.js | 6 +- greenit-core/utils.js | 24 + package-lock.json | 665 ++++++++++++------ package.json | 1 + 35 files changed, 1325 insertions(+), 809 deletions(-) mode change 100644 => 100755 greenit create mode 100644 greenit-core/chrome.js diff --git a/cli-core/analysis.js b/cli-core/analysis.js index 7e231ce..d335194 100644 --- a/cli-core/analysis.js +++ b/cli-core/analysis.js @@ -3,7 +3,9 @@ const fs = require('fs') const path = require('path'); const ProgressBar = require('progress'); const sizes = require('../sizes.js'); -const translator = require('./translator.js').translator; +const jsdom = require("jsdom"); +const {JSDOM} = jsdom; +const launchAnalyse = require('../greenit-core/greenpanel.js').launchAnalyse; //Path to the url file const SUBRESULTS_DIRECTORY = path.join(__dirname,'../results'); @@ -65,26 +67,15 @@ async function analyseURL(browser, pageInformations, options) { const client = await page.target().createCDPSession(); let ressourceTree = await client.send('Page.getResourceTree'); await client.detach() - - // replace chrome.i18n.getMessage call by i18n custom implementation working in page - // fr is default catalog - await page.evaluate(language_array =>(chrome = { "i18n" : {"getMessage" : function (message, parameters = []) { - return language_array[message].replace(/%s/g, function() { - // parameters is string or array - return Array.isArray(parameters) ? parameters.shift() : parameters; - }); - }}}), translator.getCatalog()); - - //add script, get run, then remove it to not interfere with the analysis - let script = await page.addScriptTag({ path: path.join(__dirname,'../dist/bundle.js')}); - await script.evaluate(x=>(x.remove())); - - //pass node object to browser - await page.evaluate(x=>(har = x), harObj.log); - await page.evaluate(x=>(resources = x), ressourceTree.frameTree.resources); - + + //retrieve page content + const pageContent = await page.content(); + + // Building in memory Page DOM + const dom = new JSDOM(pageContent); + //launch analyse - result = await page.evaluate(()=>(launchAnalyse())); + result = await launchAnalyse(dom.window.document, harObj.log, ressourceTree.frameTree.resources); page.close(); result.success = true; @@ -323,4 +314,4 @@ async function createJsonReports(browser, pagesInformations, options, proxy, hea module.exports = { createJsonReports, login -} \ No newline at end of file +}; diff --git a/cli-core/reportHtml.js b/cli-core/reportHtml.js index a2e8400..545fc50 100644 --- a/cli-core/reportHtml.js +++ b/cli-core/reportHtml.js @@ -162,7 +162,7 @@ function extractBestPractices(bestPracticesFromReport) { } function writeGlobalReport(templateEngine, globalReportVariables, outputFile) { - templateEngine.processFile('cli-core/template/global.html', globalReportVariables) + templateEngine.processFile(__dirname + '/template/global.html', globalReportVariables) .then(globalReportHtml => { fs.writeFileSync(outputFile, globalReportHtml); }) @@ -173,7 +173,7 @@ function writeGlobalReport(templateEngine, globalReportVariables, outputFile) { function writeAllReports(templateEngine, allReportsVariables, outputFolder) { allReportsVariables.forEach(reportVariables => { - templateEngine.processFile('cli-core/template/page.html', reportVariables) + templateEngine.processFile(__dirname + '/template/page.html', reportVariables) .then(singleReportHtml => { fs.writeFileSync(`${outputFolder}/${reportVariables.filename}`, singleReportHtml); }) diff --git a/greenit b/greenit old mode 100644 new mode 100755 diff --git a/greenit-core/analyseFrameCore.js b/greenit-core/analyseFrameCore.js index 061b5e1..0a639c2 100644 --- a/greenit-core/analyseFrameCore.js +++ b/greenit-core/analyseFrameCore.js @@ -16,20 +16,20 @@ * along with this program. If not, see . */ -function start_analyse_core() { +function start_analyse_core(document, analyseBestPractices) { const analyseStartingTime = Date.now(); const dom_size = document.getElementsByTagName("*").length; let pageAnalysis; if (analyseBestPractices) { // test with http://www.wickham43.net/flashvideo.php - const pluginsNumber = getPluginsNumber(); - const printStyleSheetsNumber = getPrintStyleSheetsNumber(); - const inlineStyleSheetsNumber = getInlineStyleSheetsNumber(); - const emptySrcTagNumber = getEmptySrcTagNumber(); - const inlineJsScript = getInlineJsScript(); - const inlineJsScriptsNumber = getInlineJsScriptsNumber(); - const imagesResizedInBrowser = getImagesResizedInBrowser(); + const pluginsNumber = getPluginsNumber(document); + const printStyleSheetsNumber = getPrintStyleSheetsNumber(document); + const inlineStyleSheetsNumber = getInlineStyleSheetsNumber(document); + const emptySrcTagNumber = getEmptySrcTagNumber(document); + const inlineJsScript = getInlineJsScript(document); + const inlineJsScriptsNumber = getInlineJsScriptsNumber(document); + const imagesResizedInBrowser = getImagesResizedInBrowser(document); pageAnalysis = { @@ -55,26 +55,26 @@ function start_analyse_core() { } -function getPluginsNumber() { +function getPluginsNumber(document) { const plugins = document.querySelectorAll('object,embed'); return (plugins === undefined) ? 0 : plugins.length; } -function getEmptySrcTagNumber() { +function getEmptySrcTagNumber(document) { return document.querySelectorAll('img[src=""]').length + document.querySelectorAll('script[src=""]').length + document.querySelectorAll('link[rel=stylesheet][href=""]').length; } -function getPrintStyleSheetsNumber() { +function getPrintStyleSheetsNumber(document) { return document.querySelectorAll('link[rel=stylesheet][media~=print]').length + document.querySelectorAll('style[media~=print]').length; } -function getInlineStyleSheetsNumber() { +function getInlineStyleSheetsNumber(document) { let styleSheetsArray = Array.from(document.styleSheets); let inlineStyleSheetsNumber = 0; styleSheetsArray.forEach(styleSheet => { @@ -90,7 +90,7 @@ return inlineStyleSheetsNumber; } -function getInlineJsScript() { +function getInlineJsScript(document) { let scriptArray = Array.from(document.scripts); let scriptText = ""; scriptArray.forEach(script => { @@ -100,7 +100,7 @@ function getInlineJsScript() { return scriptText; } -function getInlineJsScriptsNumber() { +function getInlineJsScriptsNumber(document) { let scriptArray = Array.from(document.scripts); let inlineScriptNumber = 0; scriptArray.forEach(script => { @@ -111,7 +111,7 @@ function getInlineJsScriptsNumber() { } -function getImagesResizedInBrowser() { +function getImagesResizedInBrowser(document) { const imgArray = Array.from(document.querySelectorAll('img')); let imagesResized = []; imgArray.forEach(img => { @@ -132,3 +132,7 @@ function getImagesResizedInBrowser() { }); return imagesResized; } + +module.exports = { + start_analyse_core +}; diff --git a/greenit-core/chrome.js b/greenit-core/chrome.js new file mode 100644 index 0000000..9f9fe16 --- /dev/null +++ b/greenit-core/chrome.js @@ -0,0 +1,16 @@ +const {translator} = require("../cli-core/translator"); + +chrome = { + "i18n": { + "getMessage": function (message, parameters = []) { + return translator.getCatalog()[message].replace(/%s/g, function () { + // parameters is string or array + return Array.isArray(parameters) ? parameters.shift() : parameters; + }); + } + } +}; + +module.exports = { + chrome +}; diff --git a/greenit-core/ecoIndex.js b/greenit-core/ecoIndex.js index 5ff3ab7..83bcb35 100644 --- a/greenit-core/ecoIndex.js +++ b/greenit-core/ecoIndex.js @@ -65,3 +65,10 @@ function computeWaterConsumptionfromEcoIndex(ecoIndex) return (Math.round(100 * (3 + 3 * (50 - ecoIndex) / 100)) / 100); } +module.exports = { + computeEcoIndex, + computeWaterConsumptionfromEcoIndex, + computeGreenhouseGasesEmissionfromEcoIndex, + computeQuantile, + getEcoIndexGrade +}; diff --git a/greenit-core/greenpanel.js b/greenit-core/greenpanel.js index 28b088a..536b876 100644 --- a/greenit-core/greenpanel.js +++ b/greenit-core/greenpanel.js @@ -16,17 +16,48 @@ * along with this program. If not, see . */ +const utils = require('./utils.js'); +const {start_analyse_core} = require("./analyseFrameCore"); +const { + computeEcoIndex, computeWaterConsumptionfromEcoIndex, computeGreenhouseGasesEmissionfromEcoIndex, + getEcoIndexGrade +} = require("./ecoIndex"); +const {isNetworkResource, isDataResource} = require("./utils"); +const {registerAddExpiresOrCacheControlHeaders} = require("./rules/AddExpiresOrCacheControlHeaders"); +const {registerCompressHttp} = require("./rules/CompressHttp"); +const {registerDontResizeImageInBrowser} = require("./rules/DontResizeImageInBrowser"); +const {registerDomainsNumber} = require("./rules/DomainsNumber"); +const {registerEmptySrcTag} = require("./rules/EmptySrcTag"); +const {registerExternalizeCss} = require("./rules/ExternalizeCss"); +const {registerExternalizeJs} = require("./rules/ExternalizeJs"); +const {registerHttpError} = require("./rules/HttpError"); +const {registerHttpRequests} = require("./rules/HttpRequests"); +const {registerImageDownloadedNotDisplayed} = require("./rules/ImageDownloadedNotDisplayed"); +const {registerJsValidate} = require("./rules/JsValidate"); +const {registerMaxCookiesLength} = require("./rules/MaxCookiesLength"); +const {registerMinifiedCss} = require("./rules/MinifiedCss"); +const {registerMinifiedJs} = require("./rules/MinifiedJs"); +const {registerNoCookieForStaticRessources} = require("./rules/NoCookieForStaticRessources"); +const {registerNoRedirect} = require("./rules/NoRedirect"); +const {registerOptimizeBitmapImages} = require("./rules/OptimizeBitmapImages"); +const {registerOptimizeSvg} = require("./rules/OptimizeSvg"); +const {registerPlugins} = require("./rules/Plugins"); +const {registerPrintStyleSheet} = require("./rules/PrintStyleSheet"); +const {registerSocialNetworkButton} = require("./rules/SocialNetworkButton"); +const {registerStyleSheets} = require("./rules/StyleSheets"); +const {registerUseETags} = require("./rules/UseETags"); +const {registerUseStandardTypefaces} = require("./rules/UseStandardTypefaces"); +const RulesManager = require('./rulesManager.js').RulesManager + let backgroundPageConnection; let currentRulesChecker; let lastAnalyseStartingTime = 0; let measuresAcquisition; let analyseBestPractices = true; -let har; -let resources; function handleResponseFromBackground(frameMeasures) { if (isOldAnalyse(frameMeasures.analyseStartingTime)) { - debug(() => `Analyse is too old for url ${frameMeasures.url} , time = ${frameMeasures.analyseStartingTime}`); + utils.debug(() => `Analyse is too old for url ${frameMeasures.url} , time = ${frameMeasures.analyseStartingTime}`); return; } measuresAcquisition.aggregateFrameMeasures(frameMeasures); @@ -41,21 +72,42 @@ function computeEcoIndexMeasures(measures) { measures.grade = getEcoIndexGrade(measures.ecoIndex); } +function registerRules(rulesManager) { + registerAddExpiresOrCacheControlHeaders(rulesManager) + registerCompressHttp(rulesManager) + registerDontResizeImageInBrowser(rulesManager) + registerDomainsNumber(rulesManager) + registerEmptySrcTag(rulesManager) + registerExternalizeCss(rulesManager) + registerExternalizeJs(rulesManager) + registerHttpError(rulesManager) + registerHttpRequests(rulesManager) + registerImageDownloadedNotDisplayed(rulesManager) + registerJsValidate(rulesManager) + registerMaxCookiesLength(rulesManager) + registerMinifiedCss(rulesManager) + registerMinifiedJs(rulesManager) + registerNoCookieForStaticRessources(rulesManager) + registerNoRedirect(rulesManager) + registerOptimizeBitmapImages(rulesManager) + registerOptimizeSvg(rulesManager) + registerPlugins(rulesManager) + registerPrintStyleSheet(rulesManager) + registerSocialNetworkButton(rulesManager) + registerStyleSheets(rulesManager) + registerUseETags(rulesManager) + registerUseStandardTypefaces(rulesManager) +} -function launchAnalyse() { - let now = Date.now(); - - // To avoid parallel analyse , force 1 secondes between analysis - if (now - lastAnalyseStartingTime < 1000) { - debug(() => "Ignore click"); - return; - } - lastAnalyseStartingTime = now; +async function launchAnalyse(document, har, resources) { + lastAnalyseStartingTime = Date.now(); + let rulesManager = new RulesManager() + registerRules(rulesManager); currentRulesChecker = rulesManager.getNewRulesChecker(); measuresAcquisition = new MeasuresAcquisition(currentRulesChecker); measuresAcquisition.initializeMeasures(); - measuresAcquisition.aggregateFrameMeasures(start_analyse_core()) - measuresAcquisition.startMeasuring(); + measuresAcquisition.aggregateFrameMeasures(start_analyse_core(document, analyseBestPractices)) + measuresAcquisition.startMeasuring(har, resources); let returnObj = measuresAcquisition.getMeasures(); returnObj.bestPractices = measuresAcquisition.getBestPractices() return returnObj; @@ -88,9 +140,9 @@ function MeasuresAcquisition(rules) { }; } - this.startMeasuring = function () { - getNetworkMeasure(); - if (analyseBestPractices) getResourcesMeasure(); + this.startMeasuring = function (har, resources) { + getNetworkMeasure(har); + if (analyseBestPractices) getResourcesMeasure(resources); } this.getMeasures = () => measures; @@ -126,18 +178,18 @@ function MeasuresAcquisition(rules) { - const getNetworkMeasure = () => { - + const getNetworkMeasure = (har) => { + console.log("Start network measure..."); // only account for network traffic, filtering resources embedded through data urls let entries = har.entries.filter(entry => isNetworkResource(entry)); - // Get the "mother" url + // Get the "mother" url if (entries.length > 0) measures.url = entries[0].request.url; else { - // Bug with firefox when we first get har.entries when starting the plugin , we need to ask again to have it + // Bug with firefox when we first get har.entries when starting the plugin , we need to ask again to have it if (nbGetHarTry < 1) { - debug(() => 'No entries, try again to get HAR in 1s'); + utils.debug(() => 'No entries, try again to get HAR in 1s'); nbGetHarTry++; setTimeout(getNetworkMeasure, 1000); } @@ -170,7 +222,7 @@ function MeasuresAcquisition(rules) { } } - function getResourcesMeasure() { + function getResourcesMeasure(resources) { resources.forEach(resource => { if (resource.url.startsWith("file") || resource.url.startsWith("http")) { if ((resource.type === 'script') || (resource.type === 'stylesheet') || (resource.type === 'image')) { @@ -234,3 +286,7 @@ function storeAnalysisInHistory() { localStorage.setItem("analyse_history", JSON.stringify(analyse_history)); } + +module.exports = { + launchAnalyse +}; diff --git a/greenit-core/rules/AddExpiresOrCacheControlHeaders.js b/greenit-core/rules/AddExpiresOrCacheControlHeaders.js index 4ecef10..2e03240 100644 --- a/greenit-core/rules/AddExpiresOrCacheControlHeaders.js +++ b/greenit-core/rules/AddExpiresOrCacheControlHeaders.js @@ -1,31 +1,40 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "AddExpiresOrCacheControlHeaders", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); +const {isStaticRessource, hasValidCacheHeaders} = require("../utils"); - check: function (measures) { - let staticResourcesSize = 0; - let staticResourcesWithCache = 0; +function registerAddExpiresOrCacheControlHeaders(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "AddExpiresOrCacheControlHeaders", + comment: "", + detailComment: "", - if (measures.entries.length) measures.entries.forEach(entry => { - if (isStaticRessource(entry)) { - staticResourcesSize += entry.response.content.size; - if (hasValidCacheHeaders(entry)) { - staticResourcesWithCache += entry.response.content.size; + check: function (measures) { + let staticResourcesSize = 0; + let staticResourcesWithCache = 0; + + if (measures.entries.length) measures.entries.forEach(entry => { + if (isStaticRessource(entry)) { + staticResourcesSize += entry.response.content.size; + if (hasValidCacheHeaders(entry)) { + staticResourcesWithCache += entry.response.content.size; + } + else this.detailComment += chrome.i18n.getMessage("rule_AddExpiresOrCacheControlHeaders_DetailComment", `${entry.request.url} ${Math.round(entry.response.content.size / 100) / 10}`) + '
'; } - else this.detailComment += chrome.i18n.getMessage("rule_AddExpiresOrCacheControlHeaders_DetailComment",`${entry.request.url} ${Math.round(entry.response.content.size / 100) / 10}`) + '
'; - } - }); + }); - if (staticResourcesSize > 0) { - const cacheHeaderRatio = staticResourcesWithCache / staticResourcesSize * 100; - if (cacheHeaderRatio < 95) { - if (cacheHeaderRatio < 90) this.complianceLevel = 'C' - else this.complianceLevel = 'B'; + if (staticResourcesSize > 0) { + const cacheHeaderRatio = staticResourcesWithCache / staticResourcesSize * 100; + if (cacheHeaderRatio < 95) { + if (cacheHeaderRatio < 90) this.complianceLevel = 'C' + else this.complianceLevel = 'B'; + } + else this.complianceLevel = 'A'; + this.comment = chrome.i18n.getMessage("rule_AddExpiresOrCacheControlHeaders_Comment", String(Math.round(cacheHeaderRatio * 10) / 10) + "%"); } - else this.complianceLevel = 'A'; - this.comment = chrome.i18n.getMessage("rule_AddExpiresOrCacheControlHeaders_Comment", String(Math.round(cacheHeaderRatio * 10) / 10) + "%"); } - } -}, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerAddExpiresOrCacheControlHeaders +}; diff --git a/greenit-core/rules/CompressHttp.js b/greenit-core/rules/CompressHttp.js index 57964da..c7183ed 100644 --- a/greenit-core/rules/CompressHttp.js +++ b/greenit-core/rules/CompressHttp.js @@ -1,29 +1,38 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "CompressHttp", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); +const {isResourceCompressed, isCompressibleResource} = require("../utils"); - check: function (measures) { - let compressibleResourcesSize = 0; - let compressibleResourcesCompressedSize = 0; - if (measures.entries.length) measures.entries.forEach(entry => { - if (isCompressibleResource(entry)) { - compressibleResourcesSize += entry.response.content.size; - if (isResourceCompressed(entry)) { - compressibleResourcesCompressedSize += entry.response.content.size; +function registerCompressHttp(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "CompressHttp", + comment: "", + detailComment: "", + + check: function (measures) { + let compressibleResourcesSize = 0; + let compressibleResourcesCompressedSize = 0; + if (measures.entries.length) measures.entries.forEach(entry => { + if (isCompressibleResource(entry)) { + compressibleResourcesSize += entry.response.content.size; + if (isResourceCompressed(entry)) { + compressibleResourcesCompressedSize += entry.response.content.size; + } + else this.detailComment += chrome.i18n.getMessage("rule_CompressHttp_DetailComment", `${entry.request.url} ${Math.round(entry.response.content.size / 100) / 10}`) + '
'; } - else this.detailComment += chrome.i18n.getMessage("rule_CompressHttp_DetailComment",`${entry.request.url} ${Math.round(entry.response.content.size / 100) / 10}`) + '
'; - } - }); - if (compressibleResourcesSize > 0) { - const compressRatio = compressibleResourcesCompressedSize / compressibleResourcesSize * 100; - if (compressRatio < 95) { - if (compressRatio < 90) this.complianceLevel = 'C' - else this.complianceLevel = 'B'; + }); + if (compressibleResourcesSize > 0) { + const compressRatio = compressibleResourcesCompressedSize / compressibleResourcesSize * 100; + if (compressRatio < 95) { + if (compressRatio < 90) this.complianceLevel = 'C' + else this.complianceLevel = 'B'; + } + else this.complianceLevel = 'A'; + this.comment = chrome.i18n.getMessage("rule_CompressHttp_Comment", String(Math.round(compressRatio * 10) / 10) + "%"); } - else this.complianceLevel = 'A'; - this.comment = chrome.i18n.getMessage("rule_CompressHttp_Comment", String(Math.round(compressRatio * 10) / 10) + "%"); } - } -}, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerCompressHttp +}; diff --git a/greenit-core/rules/DomainsNumber.js b/greenit-core/rules/DomainsNumber.js index 494ba6b..fa3c361 100644 --- a/greenit-core/rules/DomainsNumber.js +++ b/greenit-core/rules/DomainsNumber.js @@ -1,25 +1,34 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "DomainsNumber", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); +const {getDomainFromUrl} = require("../utils"); - check: function (measures) { - let domains = []; - if (measures.entries.length) measures.entries.forEach(entry => { - let domain = getDomainFromUrl(entry.request.url); - if (domains.indexOf(domain) === -1) { - domains.push(domain); +function registerDomainsNumber(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "DomainsNumber", + comment: "", + detailComment: "", + + check: function (measures) { + let domains = []; + if (measures.entries.length) measures.entries.forEach(entry => { + let domain = getDomainFromUrl(entry.request.url); + if (domains.indexOf(domain) === -1) { + domains.push(domain); + } + }); + if (domains.length > 2) { + if (domains.length === 3) this.complianceLevel = 'B'; + else this.complianceLevel = 'C'; } - }); - if (domains.length > 2) { - if (domains.length === 3) this.complianceLevel = 'B'; - else this.complianceLevel = 'C'; + domains.forEach(domain => { + this.detailComment += domain + "
"; + }); + + this.comment = chrome.i18n.getMessage("rule_DomainsNumber_Comment", String(domains.length)); } - domains.forEach(domain => { - this.detailComment += domain + "
"; - }); + }, "harReceived"); +} - this.comment = chrome.i18n.getMessage("rule_DomainsNumber_Comment", String(domains.length)); - } -}, "harReceived"); \ No newline at end of file +module.exports = { + registerDomainsNumber +}; diff --git a/greenit-core/rules/DontResizeImageInBrowser.js b/greenit-core/rules/DontResizeImageInBrowser.js index 239c3e3..6f08dc1 100644 --- a/greenit-core/rules/DontResizeImageInBrowser.js +++ b/greenit-core/rules/DontResizeImageInBrowser.js @@ -1,39 +1,48 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "DontResizeImageInBrowser", - comment: "", - detailComment: "", - imagesResizedInBrowserNumber: 0, - imgAnalysed: new Map(), - - // need to get a new map , otherwise it's share between instance - initialize: function () { - this.imgAnalysed = new Map(); - }, - - isRevelant: function (entry) { - // exclude svg - if (isSvgUrl(entry.src)) return false; - - // difference of 1 pixel is not relevant - if (entry.naturalWidth - entry.clientWidth < 2) return false; - if (entry.naturalHeight - entry.clientHeight < 2) return false; - - // If picture is 0x0 it meens it's not visible on the ui , see imageDownloadedNotDisplayed - if (entry.clientWidth === 0) return false; - - return true; - }, - - check: function (measures) { - measures.imagesResizedInBrowser.forEach(entry => { - if (!this.imgAnalysed.has(entry.src) && this.isRevelant(entry)) { // Do not count two times the same picture - this.detailComment += chrome.i18n.getMessage("rule_DontResizeImageInBrowser_DetailComment",[entry.src,`${entry.naturalWidth}x${entry.naturalHeight}`,`${entry.clientWidth}x${entry.clientHeight}`]) + '
'; - this.imgAnalysed.set(entry.src); - this.imagesResizedInBrowserNumber += 1; - } - }); - if (this.imagesResizedInBrowserNumber > 0) this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_DontResizeImageInBrowser_Comment", String(this.imagesResizedInBrowserNumber)); - } -}, "frameMeasuresReceived"); \ No newline at end of file +const { chrome } = require("../chrome"); +const {isSvgUrl} = require("../utils"); + +function registerDontResizeImageInBrowser(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "DontResizeImageInBrowser", + comment: "", + detailComment: "", + imagesResizedInBrowserNumber: 0, + imgAnalysed: new Map(), + + // need to get a new map , otherwise it's share between instance + initialize: function () { + this.imgAnalysed = new Map(); + }, + + isRevelant: function (entry) { + // exclude svg + if (isSvgUrl(entry.src)) return false; + + // difference of 1 pixel is not relevant + if (entry.naturalWidth - entry.clientWidth < 2) return false; + if (entry.naturalHeight - entry.clientHeight < 2) return false; + + // If picture is 0x0 it meens it's not visible on the ui , see imageDownloadedNotDisplayed + if (entry.clientWidth === 0) return false; + + return true; + }, + + check: function (measures) { + measures.imagesResizedInBrowser.forEach(entry => { + if (!this.imgAnalysed.has(entry.src) && this.isRevelant(entry)) { // Do not count two times the same picture + this.detailComment += chrome.i18n.getMessage("rule_DontResizeImageInBrowser_DetailComment", [entry.src, `${entry.naturalWidth}x${entry.naturalHeight}`, `${entry.clientWidth}x${entry.clientHeight}`]) + '
'; + this.imgAnalysed.set(entry.src); + this.imagesResizedInBrowserNumber += 1; + } + }); + if (this.imagesResizedInBrowserNumber > 0) this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_DontResizeImageInBrowser_Comment", String(this.imagesResizedInBrowserNumber)); + } + }, "frameMeasuresReceived"); +} + +module.exports = { + registerDontResizeImageInBrowser +}; diff --git a/greenit-core/rules/EmptySrcTag.js b/greenit-core/rules/EmptySrcTag.js index 544caf3..65f2d6b 100644 --- a/greenit-core/rules/EmptySrcTag.js +++ b/greenit-core/rules/EmptySrcTag.js @@ -1,13 +1,21 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "EmptySrcTag", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); - check: function (measures) { - if (measures.emptySrcTagNumber > 0) { - this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_EmptySrcTag_Comment", String(measures.emptySrcTagNumber)); +function registerEmptySrcTag(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "EmptySrcTag", + comment: "", + detailComment: "", + + check: function (measures) { + if (measures.emptySrcTagNumber > 0) { + this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_EmptySrcTag_Comment", String(measures.emptySrcTagNumber)); + } } - } -}, "frameMeasuresReceived"); \ No newline at end of file + }, "frameMeasuresReceived"); +} + +module.exports = { + registerEmptySrcTag +}; diff --git a/greenit-core/rules/ExternalizeCss.js b/greenit-core/rules/ExternalizeCss.js index 87bf726..9c0ae8f 100644 --- a/greenit-core/rules/ExternalizeCss.js +++ b/greenit-core/rules/ExternalizeCss.js @@ -1,13 +1,21 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "ExternalizeCss", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); - check: function (measures) { - if (measures.inlineStyleSheetsNumber > 0) { - this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_ExternalizeCss_Comment", String(measures.inlineStyleSheetsNumber)); +function registerExternalizeCss(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "ExternalizeCss", + comment: "", + detailComment: "", + + check: function (measures) { + if (measures.inlineStyleSheetsNumber > 0) { + this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_ExternalizeCss_Comment", String(measures.inlineStyleSheetsNumber)); + } } - } -}, "frameMeasuresReceived"); \ No newline at end of file + }, "frameMeasuresReceived"); +} + +module.exports = { + registerExternalizeCss +}; diff --git a/greenit-core/rules/ExternalizeJs.js b/greenit-core/rules/ExternalizeJs.js index 65b5115..47bfa3d 100644 --- a/greenit-core/rules/ExternalizeJs.js +++ b/greenit-core/rules/ExternalizeJs.js @@ -1,14 +1,22 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "ExternalizeJs", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); - check: function (measures) { - if (measures.inlineJsScriptsNumber > 0) { - if (measures.inlineJsScriptsNumber > 1) this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_ExternalizeJs_Comment", String(measures.inlineJsScriptsNumber)); +function registerExternalizeJs(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "ExternalizeJs", + comment: "", + detailComment: "", + check: function (measures) { + if (measures.inlineJsScriptsNumber > 0) { + if (measures.inlineJsScriptsNumber > 1) this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_ExternalizeJs_Comment", String(measures.inlineJsScriptsNumber)); + + } } - } -}, "frameMeasuresReceived"); \ No newline at end of file + }, "frameMeasuresReceived"); +} + +module.exports = { + registerExternalizeJs +}; diff --git a/greenit-core/rules/HttpError.js b/greenit-core/rules/HttpError.js index 017eb30..6b35b7e 100644 --- a/greenit-core/rules/HttpError.js +++ b/greenit-core/rules/HttpError.js @@ -1,20 +1,28 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "HttpError", - comment: "", - detailComment: "", - - check: function (measures) { - let errorNumber = 0; - if (measures.entries.length) measures.entries.forEach(entry => { - if (entry.response) { - if (entry.response.status >=400 ) { - this.detailComment += entry.response.status + " " + entry.request.url + "
"; - errorNumber++; - } +const { chrome } = require("../chrome"); + +function registerHttpError(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "HttpError", + comment: "", + detailComment: "", + + check: function (measures) { + let errorNumber = 0; + if (measures.entries.length) measures.entries.forEach(entry => { + if (entry.response) { + if (entry.response.status >= 400) { + this.detailComment += entry.response.status + " " + entry.request.url + "
"; + errorNumber++; + } + } + }); + if (errorNumber > 0) this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_HttpError_Comment", String(errorNumber)); } - }); - if (errorNumber > 0) this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_HttpError_Comment", String(errorNumber)); - } - }, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerHttpError +}; diff --git a/greenit-core/rules/HttpRequests.js b/greenit-core/rules/HttpRequests.js index 27d390b..5a1aeb5 100644 --- a/greenit-core/rules/HttpRequests.js +++ b/greenit-core/rules/HttpRequests.js @@ -1,15 +1,23 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "HttpRequests", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); - check: function (measures) { - if (measures.entries.length) measures.entries.forEach(entry => { - this.detailComment += entry.request.url + "
"; - }); - if (measures.nbRequest > 40) this.complianceLevel = 'C'; - else if (measures.nbRequest > 26) this.complianceLevel = 'B'; - this.comment = chrome.i18n.getMessage("rule_HttpRequests_Comment", String(measures.nbRequest)); - } -}, "harReceived"); \ No newline at end of file +function registerHttpRequests(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "HttpRequests", + comment: "", + detailComment: "", + + check: function (measures) { + if (measures.entries.length) measures.entries.forEach(entry => { + this.detailComment += entry.request.url + "
"; + }); + if (measures.nbRequest > 40) this.complianceLevel = 'C'; + else if (measures.nbRequest > 26) this.complianceLevel = 'B'; + this.comment = chrome.i18n.getMessage("rule_HttpRequests_Comment", String(measures.nbRequest)); + } + }, "harReceived"); +} + +module.exports = { + registerHttpRequests +}; diff --git a/greenit-core/rules/ImageDownloadedNotDisplayed.js b/greenit-core/rules/ImageDownloadedNotDisplayed.js index e5d1529..8998a12 100644 --- a/greenit-core/rules/ImageDownloadedNotDisplayed.js +++ b/greenit-core/rules/ImageDownloadedNotDisplayed.js @@ -1,32 +1,40 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "ImageDownloadedNotDisplayed", - comment: "", - detailComment: "", - imageDownloadedNotDisplayedNumber: 0, - imgAnalysed: new Map(), +const { chrome } = require("../chrome"); - // need to get a new map , otherwise it's share between instance - initialize: function () { - this.imgAnalysed = new Map(); - }, +function registerImageDownloadedNotDisplayed(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "ImageDownloadedNotDisplayed", + comment: "", + detailComment: "", + imageDownloadedNotDisplayedNumber: 0, + imgAnalysed: new Map(), - isRevelant: function (entry) { - // Very small images could be download even if not display as it may be icons - if (entry.naturalWidth * entry.naturalHeight < 10000) return false; - if (entry.clientWidth === 0 && entry.clientHeight === 0) return true; - return false; - }, + // need to get a new map , otherwise it's share between instance + initialize: function () { + this.imgAnalysed = new Map(); + }, - check: function (measures) { - measures.imagesResizedInBrowser.forEach(entry => { - if (!this.imgAnalysed.has(entry.src) && this.isRevelant(entry)) { // Do not count two times the same picture - this.detailComment += chrome.i18n.getMessage("rule_ImageDownloadedNotDisplayed_DetailComment",[entry.src,`${entry.naturalWidth}x${entry.naturalHeight}`]) + '
'; - this.imgAnalysed.set(entry.src); - this.imageDownloadedNotDisplayedNumber += 1; - } - }); - if (this.imageDownloadedNotDisplayedNumber > 0) this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_ImageDownloadedNotDisplayed_Comment", String(this.imageDownloadedNotDisplayedNumber)); - } -}, "frameMeasuresReceived"); \ No newline at end of file + isRevelant: function (entry) { + // Very small images could be download even if not display as it may be icons + if (entry.naturalWidth * entry.naturalHeight < 10000) return false; + if (entry.clientWidth === 0 && entry.clientHeight === 0) return true; + return false; + }, + + check: function (measures) { + measures.imagesResizedInBrowser.forEach(entry => { + if (!this.imgAnalysed.has(entry.src) && this.isRevelant(entry)) { // Do not count two times the same picture + this.detailComment += chrome.i18n.getMessage("rule_ImageDownloadedNotDisplayed_DetailComment", [entry.src, `${entry.naturalWidth}x${entry.naturalHeight}`]) + '
'; + this.imgAnalysed.set(entry.src); + this.imageDownloadedNotDisplayedNumber += 1; + } + }); + if (this.imageDownloadedNotDisplayedNumber > 0) this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_ImageDownloadedNotDisplayed_Comment", String(this.imageDownloadedNotDisplayedNumber)); + } + }, "frameMeasuresReceived"); +} + +module.exports = { + registerImageDownloadedNotDisplayed +}; diff --git a/greenit-core/rules/JsValidate.js b/greenit-core/rules/JsValidate.js index 6f869e9..ce9fd6d 100644 --- a/greenit-core/rules/JsValidate.js +++ b/greenit-core/rules/JsValidate.js @@ -1,21 +1,30 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "JsValidate", - comment: "", - detailComment: "", - errors: 0, - totalJsSize: 0, +const { chrome } = require("../chrome"); +const {computeNumberOfErrorsInJSCode} = require("../utils"); - check: function (measures, resourceContent) { - if (resourceContent.type === "script") { - this.totalJsSize += resourceContent.content.length; - let errorNumber = computeNumberOfErrorsInJSCode(resourceContent.content, resourceContent.url); - if (errorNumber > 0) { - this.detailComment += (`URL ${resourceContent.url} has ${errorNumber} error(s)
`); - this.errors += errorNumber; - this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_JsValidate_Comment", String(this.errors)); +function registerJsValidate(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "JsValidate", + comment: "", + detailComment: "", + errors: 0, + totalJsSize: 0, + + check: function (measures, resourceContent) { + if (resourceContent.type === "script") { + this.totalJsSize += resourceContent.content.length; + let errorNumber = computeNumberOfErrorsInJSCode(resourceContent.content, resourceContent.url); + if (errorNumber > 0) { + this.detailComment += (`URL ${resourceContent.url} has ${errorNumber} error(s)
`); + this.errors += errorNumber; + this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_JsValidate_Comment", String(this.errors)); + } } } - } -}, "resourceContentReceived"); \ No newline at end of file + }, "resourceContentReceived"); +} + +module.exports = { + registerJsValidate +}; diff --git a/greenit-core/rules/MaxCookiesLength.js b/greenit-core/rules/MaxCookiesLength.js index 91215ff..1a1b8c8 100644 --- a/greenit-core/rules/MaxCookiesLength.js +++ b/greenit-core/rules/MaxCookiesLength.js @@ -1,30 +1,39 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "MaxCookiesLength", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); +const {getCookiesLength, getDomainFromUrl} = require("../utils"); - check: function (measures) { - let maxCookiesLength = 0; - let domains = new Map(); - if (measures.entries.length) measures.entries.forEach(entry => { - const cookiesLength = getCookiesLength(entry); - if (cookiesLength !== 0) { - let domain = getDomainFromUrl(entry.request.url); - if (domains.has(domain)) { - if (domains.get(domain) < cookiesLength) domains.set(domain, cookiesLength); +function registerMaxCookiesLength(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "MaxCookiesLength", + comment: "", + detailComment: "", + + check: function (measures) { + let maxCookiesLength = 0; + let domains = new Map(); + if (measures.entries.length) measures.entries.forEach(entry => { + const cookiesLength = getCookiesLength(entry); + if (cookiesLength !== 0) { + let domain = getDomainFromUrl(entry.request.url); + if (domains.has(domain)) { + if (domains.get(domain) < cookiesLength) domains.set(domain, cookiesLength); + } + else domains.set(domain, cookiesLength); + if (cookiesLength > maxCookiesLength) maxCookiesLength = cookiesLength; } - else domains.set(domain, cookiesLength); - if (cookiesLength > maxCookiesLength) maxCookiesLength = cookiesLength; + }); + domains.forEach((value, key) => { + this.detailComment += chrome.i18n.getMessage("rule_MaxCookiesLength_DetailComment", [value, key]) + '
'; + }); + if (maxCookiesLength !== 0) { + this.comment = chrome.i18n.getMessage("rule_MaxCookiesLength_Comment", String(maxCookiesLength)); + if (maxCookiesLength > 512) this.complianceLevel = 'B'; + if (maxCookiesLength > 1024) this.complianceLevel = 'C'; } - }); - domains.forEach((value, key) => { - this.detailComment += chrome.i18n.getMessage("rule_MaxCookiesLength_DetailComment",[value,key]) + '
' ; - }); - if (maxCookiesLength !== 0) { - this.comment = chrome.i18n.getMessage("rule_MaxCookiesLength_Comment", String(maxCookiesLength)); - if (maxCookiesLength > 512) this.complianceLevel = 'B'; - if (maxCookiesLength > 1024) this.complianceLevel = 'C'; } - } -}, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerMaxCookiesLength +}; diff --git a/greenit-core/rules/MinifiedCss.js b/greenit-core/rules/MinifiedCss.js index 5c5a189..20af8ee 100644 --- a/greenit-core/rules/MinifiedCss.js +++ b/greenit-core/rules/MinifiedCss.js @@ -1,21 +1,30 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "MinifiedCss", - comment: "", - detailComment: "", - totalCssSize: 0, - minifiedCssSize: 0, +const { chrome } = require("../chrome"); +const {isMinified} = require("../utils"); - check: function (measures, resourceContent) { - if (resourceContent.type === "stylesheet") { - this.totalCssSize += resourceContent.content.length; - if (!isMinified(resourceContent.content)) this.detailComment += chrome.i18n.getMessage("rule_MinifiedCss_DetailComment",resourceContent.url) + '
'; - else this.minifiedCssSize += resourceContent.content.length; - const percentMinifiedCss = this.minifiedCssSize / this.totalCssSize * 100; - this.complianceLevel = 'A'; - if (percentMinifiedCss < 90) this.complianceLevel = 'C'; - else if (percentMinifiedCss < 95) this.complianceLevel = 'B'; - this.comment = chrome.i18n.getMessage("rule_MinifiedCss_Comment", String(Math.round(percentMinifiedCss * 10) / 10)); +function registerMinifiedCss(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "MinifiedCss", + comment: "", + detailComment: "", + totalCssSize: 0, + minifiedCssSize: 0, + + check: function (measures, resourceContent) { + if (resourceContent.type === "stylesheet") { + this.totalCssSize += resourceContent.content.length; + if (!isMinified(resourceContent.content)) this.detailComment += chrome.i18n.getMessage("rule_MinifiedCss_DetailComment", resourceContent.url) + '
'; + else this.minifiedCssSize += resourceContent.content.length; + const percentMinifiedCss = this.minifiedCssSize / this.totalCssSize * 100; + this.complianceLevel = 'A'; + if (percentMinifiedCss < 90) this.complianceLevel = 'C'; + else if (percentMinifiedCss < 95) this.complianceLevel = 'B'; + this.comment = chrome.i18n.getMessage("rule_MinifiedCss_Comment", String(Math.round(percentMinifiedCss * 10) / 10)); + } } - } -}, "resourceContentReceived"); + }, "resourceContentReceived"); +} + +module.exports = { + registerMinifiedCss +}; diff --git a/greenit-core/rules/MinifiedJs.js b/greenit-core/rules/MinifiedJs.js index 47708d4..39eb556 100644 --- a/greenit-core/rules/MinifiedJs.js +++ b/greenit-core/rules/MinifiedJs.js @@ -1,21 +1,30 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "MinifiedJs", - comment: "", - detailComment: "", - totalJsSize: 0, - minifiedJsSize: 0, +const { chrome } = require("../chrome"); +const {isMinified} = require("../utils"); - check: function (measures, resourceContent) { - if (resourceContent.type === "script") { - this.totalJsSize += resourceContent.content.length; - if (!isMinified(resourceContent.content)) this.detailComment += chrome.i18n.getMessage("rule_MinifiedJs_DetailComment",resourceContent.url) + '
'; - else this.minifiedJsSize += resourceContent.content.length; - const percentMinifiedJs = this.minifiedJsSize / this.totalJsSize * 100; - this.complianceLevel = 'A'; - if (percentMinifiedJs < 90) this.complianceLevel = 'C'; - else if (percentMinifiedJs < 95) this.complianceLevel = 'B'; - this.comment = chrome.i18n.getMessage("rule_MinifiedJs_Comment", String(Math.round(percentMinifiedJs * 10) / 10)); +function registerMinifiedJs(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "MinifiedJs", + comment: "", + detailComment: "", + totalJsSize: 0, + minifiedJsSize: 0, + + check: function (measures, resourceContent) { + if (resourceContent.type === "script") { + this.totalJsSize += resourceContent.content.length; + if (!isMinified(resourceContent.content)) this.detailComment += chrome.i18n.getMessage("rule_MinifiedJs_DetailComment", resourceContent.url) + '
'; + else this.minifiedJsSize += resourceContent.content.length; + const percentMinifiedJs = this.minifiedJsSize / this.totalJsSize * 100; + this.complianceLevel = 'A'; + if (percentMinifiedJs < 90) this.complianceLevel = 'C'; + else if (percentMinifiedJs < 95) this.complianceLevel = 'B'; + this.comment = chrome.i18n.getMessage("rule_MinifiedJs_Comment", String(Math.round(percentMinifiedJs * 10) / 10)); + } } - } -}, "resourceContentReceived"); + }, "resourceContentReceived"); +} + +module.exports = { + registerMinifiedJs +}; diff --git a/greenit-core/rules/NoCookieForStaticRessources.js b/greenit-core/rules/NoCookieForStaticRessources.js index e7abe45..7bc2de7 100644 --- a/greenit-core/rules/NoCookieForStaticRessources.js +++ b/greenit-core/rules/NoCookieForStaticRessources.js @@ -1,24 +1,33 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "NoCookieForStaticRessources", - comment: "", - detailComment: "", - - check: function (measures) { - let nbRessourcesStaticWithCookie = 0; - let totalCookiesSize = 0; - if (measures.entries.length) measures.entries.forEach(entry => { - const cookiesLength = getCookiesLength(entry); - if (isStaticRessource(entry) && (cookiesLength > 0)) { - nbRessourcesStaticWithCookie++; - totalCookiesSize += cookiesLength + 7; // 7 is size for the header name "cookie:" - this.detailComment += chrome.i18n.getMessage("rule_NoCookieForStaticRessources_DetailComment",entry.request.url) + "
"; +const { chrome } = require("../chrome"); +const {getCookiesLength, isStaticRessource} = require("../utils"); + +function registerNoCookieForStaticRessources(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "NoCookieForStaticRessources", + comment: "", + detailComment: "", + + check: function (measures) { + let nbRessourcesStaticWithCookie = 0; + let totalCookiesSize = 0; + if (measures.entries.length) measures.entries.forEach(entry => { + const cookiesLength = getCookiesLength(entry); + if (isStaticRessource(entry) && (cookiesLength > 0)) { + nbRessourcesStaticWithCookie++; + totalCookiesSize += cookiesLength + 7; // 7 is size for the header name "cookie:" + this.detailComment += chrome.i18n.getMessage("rule_NoCookieForStaticRessources_DetailComment", entry.request.url) + "
"; + } + }); + if (nbRessourcesStaticWithCookie > 0) { + if (totalCookiesSize > 2000) this.complianceLevel = 'C'; + else this.complianceLevel = 'B'; + this.comment = chrome.i18n.getMessage("rule_NoCookieForStaticRessources_Comment", [String(nbRessourcesStaticWithCookie), String(Math.round(totalCookiesSize / 100) / 10)]); + } } - }); - if (nbRessourcesStaticWithCookie > 0) { - if (totalCookiesSize > 2000) this.complianceLevel = 'C'; - else this.complianceLevel = 'B'; - this.comment = chrome.i18n.getMessage("rule_NoCookieForStaticRessources_Comment", [String(nbRessourcesStaticWithCookie), String(Math.round(totalCookiesSize / 100) / 10)]); - } - } - }, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerNoCookieForStaticRessources +}; diff --git a/greenit-core/rules/NoRedirect.js b/greenit-core/rules/NoRedirect.js index 66c4c96..b9fee05 100644 --- a/greenit-core/rules/NoRedirect.js +++ b/greenit-core/rules/NoRedirect.js @@ -1,20 +1,29 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "NoRedirect", - comment: "", - detailComment: "", - - check: function (measures) { - let redirectNumber = 0; - if (measures.entries.length) measures.entries.forEach(entry => { - if (entry.response) { - if (isHttpRedirectCode(entry.response.status)) { - this.detailComment += entry.response.status + " " + entry.request.url + "
"; - redirectNumber++; - } +const { chrome } = require("../chrome"); +const {isHttpRedirectCode} = require("../utils"); + +function registerNoRedirect(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "NoRedirect", + comment: "", + detailComment: "", + + check: function (measures) { + let redirectNumber = 0; + if (measures.entries.length) measures.entries.forEach(entry => { + if (entry.response) { + if (isHttpRedirectCode(entry.response.status)) { + this.detailComment += entry.response.status + " " + entry.request.url + "
"; + redirectNumber++; + } + } + }); + if (redirectNumber > 0) this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_NoRedirect_Comment", String(redirectNumber)); } - }); - if (redirectNumber > 0) this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_NoRedirect_Comment", String(redirectNumber)); - } - }, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerNoRedirect +}; diff --git a/greenit-core/rules/OptimizeBitmapImages.js b/greenit-core/rules/OptimizeBitmapImages.js index 87b7c40..954b61c 100644 --- a/greenit-core/rules/OptimizeBitmapImages.js +++ b/greenit-core/rules/OptimizeBitmapImages.js @@ -1,39 +1,50 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "OptimizeBitmapImages", - comment: "", - detailComment: "", - - check: function (measures) { - let nbImagesToOptimize = 0; - let totalMinGains = 0; - if (measures.entries) measures.entries.forEach(entry => { - if (entry.response) { - const imageType = getImageTypeFromResource(entry); - if (imageType !== "") { - var myImage = new Image(); - myImage.src = entry.request.url; - // needed to access object in the function after - myImage.rule = this; - - myImage.size = entry.response.content.size; - myImage.onload = function () { - - const minGains = getMinOptimisationGainsForImage(this.width * this.height, this.size, imageType); - if (minGains > 500) { // exclude small gain - nbImagesToOptimize++; - totalMinGains += minGains; - this.rule.detailComment += chrome.i18n.getMessage("rule_OptimizeBitmapImages_DetailComment", [this.src + " , " + Math.round(this.size / 1000),this.width + "x" + this.height,String(Math.round(minGains / 1000))]) + "
"; - } - if (nbImagesToOptimize > 0) { - if (totalMinGains < 50000) this.rule.complianceLevel = 'B'; - else this.rule.complianceLevel = 'C'; - this.rule.comment = chrome.i18n.getMessage("rule_OptimizeBitmapImages_Comment", [String(nbImagesToOptimize), String(Math.round(totalMinGains / 1000))]); - showEcoRuleOnUI(this.rule); - } - } - } +const { chrome } = require("../chrome"); +const {getImageTypeFromResource, getMinOptimisationGainsForImage} = require("../utils"); +const {JSDOM} = require("jsdom"); + +function registerOptimizeBitmapImages(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "OptimizeBitmapImages", + comment: "", + detailComment: "", + + check: function (measures) { + let nbImagesToOptimize = 0; + let totalMinGains = 0; + + if (measures.entries) measures.entries.forEach(entry => { + if (entry.response) { + const imageType = getImageTypeFromResource(entry); + if (imageType !== "") { + const dom = new JSDOM(); + var myImage = new dom.window.Image(); + myImage.src = entry.request.url; + // needed to access object in the function after + myImage.rule = this; + + myImage.size = entry.response.content.size; + myImage.onload = function () { + + const minGains = getMinOptimisationGainsForImage(this.width * this.height, this.size, imageType); + if (minGains > 500) { // exclude small gain + nbImagesToOptimize++; + totalMinGains += minGains; + this.rule.detailComment += chrome.i18n.getMessage("rule_OptimizeBitmapImages_DetailComment", [this.src + " , " + Math.round(this.size / 1000), this.width + "x" + this.height, String(Math.round(minGains / 1000))]) + "
"; + } + if (nbImagesToOptimize > 0) { + if (totalMinGains < 50000) this.rule.complianceLevel = 'B'; + else this.rule.complianceLevel = 'C'; + this.rule.comment = chrome.i18n.getMessage("rule_OptimizeBitmapImages_Comment", [String(nbImagesToOptimize), String(Math.round(totalMinGains / 1000))]); + } + } + } + } + }); } - }); - } - }, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerOptimizeBitmapImages +}; diff --git a/greenit-core/rules/OptimizeSvg.js b/greenit-core/rules/OptimizeSvg.js index 3b94feb..9ed1f07 100644 --- a/greenit-core/rules/OptimizeSvg.js +++ b/greenit-core/rules/OptimizeSvg.js @@ -1,24 +1,33 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "OptimizeSvg", - comment: "", - detailComment: "", - totalSizeToOptimize: 0, - totalResourcesToOptimize: 0, - - check: function (measures, resourceContent) { - if ((resourceContent.type === 'image') && isSvgUrl(resourceContent.url)) { - if (!isSvgOptimized(window.atob(resourceContent.content))) // code is in base64 , decode base64 data with atob - { - this.detailComment += chrome.i18n.getMessage("rule_OptimizeSvg_detailComment",[resourceContent.url,String(Math.round(resourceContent.content.length / 100) / 10)]) + '
'; - this.totalSizeToOptimize += resourceContent.content.length; - this.totalResourcesToOptimize++; +const { chrome } = require("../chrome"); +const {isSvgOptimized, isSvgUrl} = require("../utils"); + +function registerOptimizeSvg(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "OptimizeSvg", + comment: "", + detailComment: "", + totalSizeToOptimize: 0, + totalResourcesToOptimize: 0, + + check: function (measures, resourceContent) { + if ((resourceContent.type === 'image') && isSvgUrl(resourceContent.url)) { + if (!isSvgOptimized(window.atob(resourceContent.content))) // code is in base64 , decode base64 data with atob + { + this.detailComment += chrome.i18n.getMessage("rule_OptimizeSvg_detailComment", [resourceContent.url, String(Math.round(resourceContent.content.length / 100) / 10)]) + '
'; + this.totalSizeToOptimize += resourceContent.content.length; + this.totalResourcesToOptimize++; + } + if (this.totalSizeToOptimize > 0) { + if (this.totalSizeToOptimize < 20000) this.complianceLevel = 'B'; + else this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_OptimizeSvg_Comment", String(this.totalResourcesToOptimize)); + } + } } - if (this.totalSizeToOptimize > 0) { - if (this.totalSizeToOptimize < 20000) this.complianceLevel = 'B'; - else this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_OptimizeSvg_Comment", String(this.totalResourcesToOptimize)); - } - } - } - }, "resourceContentReceived"); \ No newline at end of file + }, "resourceContentReceived"); +} + +module.exports = { + registerOptimizeSvg +}; diff --git a/greenit-core/rules/Plugins.js b/greenit-core/rules/Plugins.js index d2442dc..060b033 100644 --- a/greenit-core/rules/Plugins.js +++ b/greenit-core/rules/Plugins.js @@ -1,13 +1,21 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "Plugins", - comment: "", - detailComment: "", - - check: function (measures) { - if (measures.pluginsNumber > 0) { - this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_Plugins_Comment", String(measures.pluginsNumber)); - } - } - }, "frameMeasuresReceived"); \ No newline at end of file +const { chrome } = require("../chrome"); + +function registerPlugins(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "Plugins", + comment: "", + detailComment: "", + + check: function (measures) { + if (measures.pluginsNumber > 0) { + this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_Plugins_Comment", String(measures.pluginsNumber)); + } + } + }, "frameMeasuresReceived"); +} + +module.exports = { + registerPlugins +}; diff --git a/greenit-core/rules/PrintStyleSheet.js b/greenit-core/rules/PrintStyleSheet.js index 590c45a..f9a3291 100644 --- a/greenit-core/rules/PrintStyleSheet.js +++ b/greenit-core/rules/PrintStyleSheet.js @@ -1,13 +1,21 @@ -rulesManager.registerRule({ - complianceLevel: 'C', - id: "PrintStyleSheet", - comment: "", - detailComment: "", - - check: function (measures) { - if (measures.printStyleSheetsNumber > 0) { - this.complianceLevel = 'A'; - this.comment = chrome.i18n.getMessage("rule_PrintStyleSheet_Comment", String(measures.printStyleSheetsNumber)); - } - } - }, "frameMeasuresReceived"); \ No newline at end of file +const { chrome } = require("../chrome"); + +function registerPrintStyleSheet(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'C', + id: "PrintStyleSheet", + comment: "", + detailComment: "", + + check: function (measures) { + if (measures.printStyleSheetsNumber > 0) { + this.complianceLevel = 'A'; + this.comment = chrome.i18n.getMessage("rule_PrintStyleSheet_Comment", String(measures.printStyleSheetsNumber)); + } + } + }, "frameMeasuresReceived"); +} + +module.exports = { + registerPrintStyleSheet +}; diff --git a/greenit-core/rules/SocialNetworkButton.js b/greenit-core/rules/SocialNetworkButton.js index 7fa8b86..e08c6cd 100644 --- a/greenit-core/rules/SocialNetworkButton.js +++ b/greenit-core/rules/SocialNetworkButton.js @@ -1,25 +1,34 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "SocialNetworkButton", - comment: "", - detailComment: "", +const { chrome } = require("../chrome"); +const {getOfficialSocialButtonFormUrl} = require("../utils"); - check: function (measures) { - let nbSocialNetworkButton = 0; - let socialNetworks = []; - if (measures.entries.length) measures.entries.forEach(entry => { - const officalSocialButton = getOfficialSocialButtonFormUrl(entry.request.url); - if (officalSocialButton.length > 0) { - if (socialNetworks.indexOf(officalSocialButton) === -1) { - socialNetworks.push(officalSocialButton); - this.detailComment += chrome.i18n.getMessage("rule_SocialNetworkButton_detailComment", officalSocialButton) + "
"; - nbSocialNetworkButton++; +function registerSocialNetworkButton(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "SocialNetworkButton", + comment: "", + detailComment: "", + + check: function (measures) { + let nbSocialNetworkButton = 0; + let socialNetworks = []; + if (measures.entries.length) measures.entries.forEach(entry => { + const officalSocialButton = getOfficialSocialButtonFormUrl(entry.request.url); + if (officalSocialButton.length > 0) { + if (socialNetworks.indexOf(officalSocialButton) === -1) { + socialNetworks.push(officalSocialButton); + this.detailComment += chrome.i18n.getMessage("rule_SocialNetworkButton_detailComment", officalSocialButton) + "
"; + nbSocialNetworkButton++; + } } + }); + if (nbSocialNetworkButton > 0) { + this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_SocialNetworkButton_Comment", String(nbSocialNetworkButton)); } - }); - if (nbSocialNetworkButton > 0) { - this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_SocialNetworkButton_Comment", String(nbSocialNetworkButton)); } - } -}, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerSocialNetworkButton +}; diff --git a/greenit-core/rules/StyleSheets.js b/greenit-core/rules/StyleSheets.js index 38244e8..bb6025f 100644 --- a/greenit-core/rules/StyleSheets.js +++ b/greenit-core/rules/StyleSheets.js @@ -1,23 +1,32 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "StyleSheets", - comment: "", - detailComment: "", - - check: function (measures) { - let styleSheets = []; - if (measures.entries.length) measures.entries.forEach(entry => { - if (getResponseHeaderFromResource(entry, "content-type").toLowerCase().includes('text/css')) { - if (styleSheets.indexOf(entry.request.url) === -1) { - styleSheets.push(entry.request.url); - this.detailComment += entry.request.url + "
"; - } +const { chrome } = require("../chrome"); +const {getResponseHeaderFromResource} = require("../utils"); + +function registerStyleSheets(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "StyleSheets", + comment: "", + detailComment: "", + + check: function (measures) { + let styleSheets = []; + if (measures.entries.length) measures.entries.forEach(entry => { + if (getResponseHeaderFromResource(entry, "content-type").toLowerCase().includes('text/css')) { + if (styleSheets.indexOf(entry.request.url) === -1) { + styleSheets.push(entry.request.url); + this.detailComment += entry.request.url + "
"; + } + } + }); + if (styleSheets.length > 2) { + if (styleSheets.length === 3) this.complianceLevel = 'B'; + else this.complianceLevel = 'C'; + this.comment = chrome.i18n.getMessage("rule_StyleSheets_Comment", String(styleSheets.length)); + } } - }); - if (styleSheets.length > 2) { - if (styleSheets.length === 3) this.complianceLevel = 'B'; - else this.complianceLevel = 'C'; - this.comment = chrome.i18n.getMessage("rule_StyleSheets_Comment", String(styleSheets.length)); - } - } - }, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerStyleSheets +}; diff --git a/greenit-core/rules/UseETags.js b/greenit-core/rules/UseETags.js index a48164d..bee45a7 100644 --- a/greenit-core/rules/UseETags.js +++ b/greenit-core/rules/UseETags.js @@ -1,32 +1,41 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "UseETags", - comment: "", - detailComment: "", - - check: function (measures) { - - let staticResourcesSize = 0; - let staticResourcesWithETagsSize = 0; - - if (measures.entries.length) measures.entries.forEach(entry => { - if (isStaticRessource(entry)) { - staticResourcesSize += entry.response.content.size; - if (isRessourceUsingETag(entry)) { - staticResourcesWithETagsSize += entry.response.content.size; - } - else this.detailComment +=chrome.i18n.getMessage("rule_UseETags_DetailComment",`${entry.request.url} ${Math.round(entry.response.content.size / 100) / 10}`) + '
'; +const { chrome } = require("../chrome"); +const {isRessourceUsingETag, isStaticRessource} = require("../utils"); + +function registerUseETags(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "UseETags", + comment: "", + detailComment: "", + + check: function (measures) { + + let staticResourcesSize = 0; + let staticResourcesWithETagsSize = 0; + + if (measures.entries.length) measures.entries.forEach(entry => { + if (isStaticRessource(entry)) { + staticResourcesSize += entry.response.content.size; + if (isRessourceUsingETag(entry)) { + staticResourcesWithETagsSize += entry.response.content.size; + } + else this.detailComment += chrome.i18n.getMessage("rule_UseETags_DetailComment", `${entry.request.url} ${Math.round(entry.response.content.size / 100) / 10}`) + '
'; + } + }); + if (staticResourcesSize > 0) { + const eTagsRatio = staticResourcesWithETagsSize / staticResourcesSize * 100; + if (eTagsRatio < 95) { + if (eTagsRatio < 90) this.complianceLevel = 'C' + else this.complianceLevel = 'B'; + } + else this.complianceLevel = 'A'; + this.comment = chrome.i18n.getMessage("rule_UseETags_Comment", + Math.round(eTagsRatio * 10) / 10 + "%"); + } } - }); - if (staticResourcesSize > 0) { - const eTagsRatio = staticResourcesWithETagsSize / staticResourcesSize * 100; - if (eTagsRatio < 95) { - if (eTagsRatio < 90) this.complianceLevel = 'C' - else this.complianceLevel = 'B'; - } - else this.complianceLevel = 'A'; - this.comment = chrome.i18n.getMessage("rule_UseETags_Comment", - Math.round(eTagsRatio * 10) / 10 + "%"); - } - } - }, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerUseETags +}; diff --git a/greenit-core/rules/UseStandardTypefaces.js b/greenit-core/rules/UseStandardTypefaces.js index b9ffb69..ae9de85 100644 --- a/greenit-core/rules/UseStandardTypefaces.js +++ b/greenit-core/rules/UseStandardTypefaces.js @@ -1,27 +1,36 @@ -rulesManager.registerRule({ - complianceLevel: 'A', - id: "UseStandardTypefaces", - comment: "", - detailComment: "", - - check: function (measures) { - let totalFontsSize = 0; - if (measures.entries.length) measures.entries.forEach(entry => { - if (isFontResource(entry) && (entry.response.content.size > 0)) { - totalFontsSize += entry.response.content.size; - this.detailComment += entry.request.url + " " + Math.round(entry.response.content.size / 1000) + "KB
"; +const { chrome } = require("../chrome"); +const {isFontResource} = require("../utils"); + +function registerUseStandardTypefaces(rulesManager) { + rulesManager.registerRule({ + complianceLevel: 'A', + id: "UseStandardTypefaces", + comment: "", + detailComment: "", + + check: function (measures) { + let totalFontsSize = 0; + if (measures.entries.length) measures.entries.forEach(entry => { + if (isFontResource(entry) && (entry.response.content.size > 0)) { + totalFontsSize += entry.response.content.size; + this.detailComment += entry.request.url + " " + Math.round(entry.response.content.size / 1000) + "KB
"; + } + }); + if (measures.dataEntries.length) measures.dataEntries.forEach(entry => { + if (isFontResource(entry) && (entry.response.content.size > 0)) { + totalFontsSize += entry.response.content.size; + let url_toshow = entry.request.url; + if (url_toshow.length > 80) url_toshow = url_toshow.substring(0, 80) + "..."; + this.detailComment += url_toshow + " " + Math.round(entry.response.content.size / 1000) + "KB
"; + } + }); + if (totalFontsSize > 10000) this.complianceLevel = 'C'; + else if (totalFontsSize > 0) this.complianceLevel = 'B'; + if (totalFontsSize > 0) this.comment = chrome.i18n.getMessage("rule_UseStandardTypefaces_Comment", String(Math.round(totalFontsSize / 1000))); } - }); - if (measures.dataEntries.length) measures.dataEntries.forEach(entry => { - if (isFontResource(entry) && (entry.response.content.size > 0)) { - totalFontsSize += entry.response.content.size; - url_toshow = entry.request.url; - if (url_toshow.length > 80) url_toshow = url_toshow.substring(0, 80) + "..."; - this.detailComment += url_toshow + " " + Math.round(entry.response.content.size / 1000) + "KB
"; - } - }); - if (totalFontsSize > 10000) this.complianceLevel = 'C'; - else if (totalFontsSize > 0) this.complianceLevel = 'B'; - if (totalFontsSize > 0) this.comment = chrome.i18n.getMessage("rule_UseStandardTypefaces_Comment", String(Math.round(totalFontsSize / 1000))); - } - }, "harReceived"); \ No newline at end of file + }, "harReceived"); +} + +module.exports = { + registerUseStandardTypefaces +}; diff --git a/greenit-core/rulesManager.js b/greenit-core/rulesManager.js index 89538ae..e94c957 100644 --- a/greenit-core/rulesManager.js +++ b/greenit-core/rulesManager.js @@ -15,8 +15,6 @@ * along with this program. If not, see . */ -rulesManager = new RulesManager(); - function RulesManager() { let rulesId = []; @@ -79,3 +77,7 @@ function RulesManager() { } } } + +module.exports = { + RulesManager +}; diff --git a/greenit-core/utils.js b/greenit-core/utils.js index d63097b..e593dd9 100644 --- a/greenit-core/utils.js +++ b/greenit-core/utils.js @@ -364,3 +364,27 @@ function debug(lazyString) { const message = typeof lazyString === 'function' ? lazyString() : lazyString; console.log(`GreenIT-Analysis [DEBUG] ${message}\n`); } + +module.exports = { + debug, + isFontResource, + isMinified, + isDataResource, + isNetworkResource, + isHttpRedirectCode, + isResourceCompressed, + isRessourceUsingETag, + isStaticRessource, + isSvgUrl, + isSvgOptimized, + getOfficialSocialButtonFormUrl, + getMinOptimisationGainsForImage, + getImageTypeFromResource, + getCookiesLength, + getResponseHeaderFromResource, + getHeaderWithName, + getDomainFromUrl, + hasValidCacheHeaders, + computeNumberOfErrorsInJSCode, + isCompressibleResource +}; diff --git a/package-lock.json b/package-lock.json index 50d7e3e..dd9ab59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,27 +40,27 @@ } }, "@sindresorhus/is": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz", - "integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz", + "integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==" }, "@szmarczak/http-timer": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", - "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "requires": { "defer-to-connect": "^2.0.0" } }, "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" }, "@types/cacheable-request": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", - "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", "requires": { "@types/http-cache-semantics": "*", "@types/keyv": "*", @@ -69,14 +69,14 @@ } }, "@types/http-cache-semantics": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", - "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "@types/keyv": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", - "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", + "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", "requires": { "@types/node": "*" } @@ -95,9 +95,9 @@ } }, "@types/yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", "optional": true, "requires": { "@types/node": "*" @@ -124,9 +124,9 @@ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" }, "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==" + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", + "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==" }, "acorn-globals": { "version": "6.0.0", @@ -155,9 +155,9 @@ "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" }, "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==" }, "ansi-styles": { "version": "4.3.0", @@ -168,23 +168,23 @@ } }, "archiver": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.2.0.tgz", - "integrity": "sha512-QEAKlgQuAtUxKeZB9w5/ggKXh21bZS+dzzuQ0RPBC20qtDCbTyzqmisoeJP46MP39fg4B4IcyvR+yeyEBdblsQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", + "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", "requires": { "archiver-utils": "^2.1.0", "async": "^3.2.0", "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", "readdir-glob": "^1.0.0", - "tar-stream": "^2.1.4", - "zip-stream": "^4.0.4" + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" }, "dependencies": { "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", + "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" } } }, @@ -245,17 +245,17 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base64-js": { "version": "1.5.1", @@ -263,9 +263,9 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "big-integer": { - "version": "1.6.48", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==" }, "binary": { "version": "0.3.0", @@ -335,16 +335,16 @@ "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" }, "cacheable-request": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", - "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", + "normalize-url": "^6.0.1", "responselike": "^2.0.0" } }, @@ -422,12 +422,12 @@ } }, "compress-commons": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.0.2.tgz", - "integrity": "sha512-qhd32a9xgzmpfoga1VQEiLEwdKZ6Plnpx5UCgIsf89FSolyJ7WnifY4Gtjgv5WR6hWAyRaHxC5MiEhU/38U70A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "requires": { "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.1", + "crc32-stream": "^4.0.2", "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" } @@ -446,9 +446,9 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "crc-32": { "version": "1.2.0", @@ -460,18 +460,18 @@ } }, "crc32-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.1.tgz", - "integrity": "sha512-FN5V+weeO/8JaXsamelVYO1PHyeCsuL3HcG4cqsj0ceARcocxalaShCsohZMSAF+db7UYFwBy1rARK/0oFItUw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", + "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", "requires": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" } }, "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" }, "cssstyle": { "version": "2.3.0", @@ -489,13 +489,13 @@ } }, "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz", + "integrity": "sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==", "requires": { "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^10.0.0" } }, "dayjs": { @@ -512,9 +512,9 @@ } }, "decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" }, "decompress-response": { "version": "6.0.0", @@ -532,14 +532,14 @@ } }, "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==" }, "defer-to-connect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", - "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, "delayed-stream": { "version": "1.0.0", @@ -552,18 +552,11 @@ "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==" }, "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" - } + "webidl-conversions": "^7.0.0" } }, "dumb-query-selector": { @@ -644,9 +637,9 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" }, "esutils": { "version": "2.0.3", @@ -654,9 +647,9 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "exceljs": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.2.0.tgz", - "integrity": "sha512-r0/ClXRs3cQmMGJOQY6/ymnZSBSzeJL/LjAlKjY75ev1iQgf0LcmeFfTqFTFK0fADLAWieOMXe7abPoGYWI6hA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.3.0.tgz", + "integrity": "sha512-hTAeo5b5TPvf8Z02I2sKIT4kSfCnOO2bCxYX8ABqODCdAjppI3gI9VYiGCQQYVcBaBSKlFDMKlAQRqC+kV9O8w==", "requires": { "archiver": "^5.0.0", "dayjs": "^1.8.34", @@ -670,9 +663,9 @@ }, "dependencies": { "dayjs": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz", - "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==" + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" }, "uuid": { "version": "8.3.2", @@ -729,14 +722,14 @@ } }, "follow-redirects": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", - "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==" + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", + "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==" }, "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -788,9 +781,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -801,16 +794,16 @@ } }, "got": { - "version": "11.8.1", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.1.tgz", - "integrity": "sha512-9aYdZL+6nHmvJwHALLwKSUZ0hMwGaJGYv3hoPLPgnT8BoBXm1SjnZeky+91tfwJaDzun2s4RsBRy48IEYv2q2Q==", + "version": "11.8.3", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", + "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", "requires": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.1", + "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", @@ -819,16 +812,16 @@ } }, "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.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", "requires": { - "whatwg-encoding": "^1.0.5" + "whatwg-encoding": "^2.0.0" } }, "http-cache-semantics": { @@ -837,11 +830,11 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "requires": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" }, @@ -857,9 +850,9 @@ } }, "http2-wrapper": { - "version": "1.0.0-beta.5.2", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", - "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "requires": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" @@ -875,11 +868,11 @@ } }, "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "ieee754": { @@ -922,22 +915,22 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-18.1.1.tgz", + "integrity": "sha512-NmJQbjQ/gpS/1at/ce3nCx89HbXL/f5OcenBe8wU1Eik0ROhyUc3LtmG3567dEHAGXkN8rmILW/qtCOPxPHQJw==", "requires": { "abab": "^2.0.5", - "acorn": "^8.2.4", + "acorn": "^8.5.0", "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", + "cssom": "^0.5.0", "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", + "data-urls": "^3.0.1", + "decimal.js": "^10.3.1", + "domexception": "^4.0.0", "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.0", @@ -946,13 +939,13 @@ "symbol-tree": "^3.2.4", "tough-cookie": "^4.0.0", "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.5", - "xml-name-validator": "^3.0.0" + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^10.0.0", + "ws": "^8.2.3", + "xml-name-validator": "^4.0.0" }, "dependencies": { "agent-base": { @@ -973,9 +966,9 @@ } }, "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz", + "integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==" } } }, @@ -985,9 +978,9 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "jszip": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz", - "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", + "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", "requires": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -1025,17 +1018,17 @@ } }, "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.4.tgz", + "integrity": "sha512-vqNHbAc8BBsxk+7QBYLW0Y219rWcClspR6WSeoHYKG5mnsSoOH+BL1pWq02DDCVdvvuUny5rkBlzMRzoqc+GIg==", "requires": { "json-buffer": "3.0.1" } }, "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "requires": { "readable-stream": "^2.0.5" }, @@ -1175,16 +1168,16 @@ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" }, "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "requires": { - "mime-db": "1.47.0" + "mime-db": "1.51.0" } }, "mimic-response": { @@ -1224,9 +1217,33 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "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" + } + } + } }, "normalize-path": { "version": "3.0.0", @@ -1234,9 +1251,9 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, "nwsapi": { "version": "2.2.0", @@ -1265,9 +1282,9 @@ } }, "p-cancelable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", - "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" }, "p-limit": { "version": "2.3.0", @@ -1428,9 +1445,9 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "resolve-alpn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", - "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" }, "responselike": { "version": "2.0.0", @@ -1482,12 +1499,23 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "sitemapper": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/sitemapper/-/sitemapper-3.1.12.tgz", - "integrity": "sha512-0BOXAhIfjQll1rrUkkFkpAhYy7MTs887H7Zpc4eAxLPPJJRFXNDdrryTadFWubGMn62bqGr3KdKBKhVdtt/HWg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/sitemapper/-/sitemapper-3.2.0.tgz", + "integrity": "sha512-UgWo5bX59IxCSJMnXPGF8euBRQL9JjE61F2Wv0WXGb21TmTaFeXVTV0VkNqaLW1uNbpM2d0MMkgH9VmkMsXoUw==", "requires": { "got": "^11.8.0", + "p-limit": "^3.1.0", "xml2js": "^0.4.23" + }, + "dependencies": { + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + } } }, "source-map": { @@ -1497,13 +1525,13 @@ "optional": true }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" } }, "string_decoder": { @@ -1515,11 +1543,11 @@ } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "symbol-tree": { @@ -1566,6 +1594,179 @@ "@ultraq/string-utils": "^2.1.0", "dumb-query-selector": "^3.3.0", "jsdom": "^16.3.0" + }, + "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "requires": { + "punycode": "^2.1.1" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + } } }, "tmp": { @@ -1587,9 +1788,9 @@ } }, "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", "requires": { "punycode": "^2.1.1" } @@ -1686,39 +1887,38 @@ } }, "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", "requires": { - "xml-name-validator": "^3.0.0" + "xml-name-validator": "^4.0.0" } }, "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" }, "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", "requires": { - "iconv-lite": "0.4.24" + "iconv-lite": "0.6.3" } }, "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" }, "whatwg-url": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", - "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", + "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==", "requires": { - "lodash": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^6.1.0" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" } }, "word-wrap": { @@ -1742,14 +1942,14 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", - "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==" }, "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" }, "xml2js": { "version": "0.4.23", @@ -1771,14 +1971,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "yargs": { "version": "16.2.0", @@ -1795,9 +1995,9 @@ } }, "yargs-parser": { - "version": "20.2.5", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", - "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==" + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" }, "yauzl": { "version": "2.10.0", @@ -1808,15 +2008,20 @@ "fd-slicer": "~1.1.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==" + }, "zip-stream": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.0.4.tgz", - "integrity": "sha512-a65wQ3h5gcQ/nQGWV1mSZCEzCML6EK/vyVPcrPNynySP1j3VBbQKh3nhC8CbORb+jfl2vXvh56Ul5odP1bAHqw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", + "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", "requires": { "archiver-utils": "^2.1.0", - "compress-commons": "^4.0.2", + "compress-commons": "^4.1.0", "readable-stream": "^3.6.0" } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index b4b0810..e8aaf19 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "concat-files": "^0.1.1", "exceljs": "^4.2.0", "glob": "^7.1.6", + "jsdom": "^18.1.1", "progress": "^2.0.3", "puppeteer": "^5.5.0", "puppeteer-har": "^1.1.2",