diff --git a/package-lock.json b/package-lock.json index c40fcaf..5ca4ecf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.3", "license": "MIT", "dependencies": { - "@projectwallace/css-analyzer": "^5.14.0" + "@projectwallace/css-analyzer": "^6.0.0" }, "devDependencies": { "typescript": "^5.4.5", @@ -31,16 +31,36 @@ } }, "node_modules/@bramus/specificity": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.3.0.tgz", - "integrity": "sha512-up0RtrNYEd3Q5fadLnsG000H/BfbHrRHwENQGZn7BB/36VtusPNAVblbkV+CtKSIOs16Nkss8d9fHYIoKeVN9g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.1.tgz", + "integrity": "sha512-cI7AmySy3FGIC59YRusPWnscNr2/M60HKTvE2h63EMGZPdB1LLT2G7OE3XB8tajjX7hVBR0YXUVvTEr4JHtLsg==", + "license": "MIT", "dependencies": { - "css-tree": "^2.3.1" + "css-tree": "^3.0.0" }, "bin": { "specificity": "bin/cli.js" } }, + "node_modules/@bramus/specificity/node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/@bramus/specificity/node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -495,15 +515,16 @@ } }, "node_modules/@projectwallace/css-analyzer": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@projectwallace/css-analyzer/-/css-analyzer-5.14.0.tgz", - "integrity": "sha512-9SYViJo7UkalvcgppT74eKXrGJbywW0VsiO0kJSVpb6Z2EBVsYaTEPcDnaG83TTip0lbQ233y7hsJ+j+/xsFLQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@projectwallace/css-analyzer/-/css-analyzer-6.0.0.tgz", + "integrity": "sha512-DMg5VHfmVnoscLeMY2trB3rtNmPPOrGEpDDQ3EKxFxpNBy6HAIm+eE7h776j+QWElKNo2KYNW9225YBKzc/bYA==", + "license": "MIT", "dependencies": { - "@bramus/specificity": "^2.3.0", + "@bramus/specificity": "^2.4.1", "css-tree": "^2.3.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@rollup/pluginutils": { @@ -983,6 +1004,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -1272,7 +1294,8 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" }, "node_modules/minimatch": { "version": "3.0.8", @@ -1744,11 +1767,27 @@ "dev": true }, "@bramus/specificity": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.3.0.tgz", - "integrity": "sha512-up0RtrNYEd3Q5fadLnsG000H/BfbHrRHwENQGZn7BB/36VtusPNAVblbkV+CtKSIOs16Nkss8d9fHYIoKeVN9g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.1.tgz", + "integrity": "sha512-cI7AmySy3FGIC59YRusPWnscNr2/M60HKTvE2h63EMGZPdB1LLT2G7OE3XB8tajjX7hVBR0YXUVvTEr4JHtLsg==", "requires": { - "css-tree": "^2.3.1" + "css-tree": "^3.0.0" + }, + "dependencies": { + "css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "requires": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + } + }, + "mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==" + } } }, "@esbuild/aix-ppc64": { @@ -1989,11 +2028,11 @@ } }, "@projectwallace/css-analyzer": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@projectwallace/css-analyzer/-/css-analyzer-5.14.0.tgz", - "integrity": "sha512-9SYViJo7UkalvcgppT74eKXrGJbywW0VsiO0kJSVpb6Z2EBVsYaTEPcDnaG83TTip0lbQ233y7hsJ+j+/xsFLQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@projectwallace/css-analyzer/-/css-analyzer-6.0.0.tgz", + "integrity": "sha512-DMg5VHfmVnoscLeMY2trB3rtNmPPOrGEpDDQ3EKxFxpNBy6HAIm+eE7h776j+QWElKNo2KYNW9225YBKzc/bYA==", "requires": { - "@bramus/specificity": "^2.3.0", + "@bramus/specificity": "^2.4.1", "css-tree": "^2.3.1" } }, diff --git a/package.json b/package.json index 65e5edb..2c983f3 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "check": "tsc --noEmit" }, "dependencies": { - "@projectwallace/css-analyzer": "^5.14.0" + "@projectwallace/css-analyzer": "^6.0.0" }, "devDependencies": { "typescript": "^5.4.5", diff --git a/src/complexity.js b/src/complexity.js index 6833267..4c0bae0 100644 --- a/src/complexity.js +++ b/src/complexity.js @@ -29,8 +29,10 @@ export const guards = [ /** @param {ReturnType} result */ result => { const mode = result.selectors.specificity.mode - const selectorsAboveMode = result.selectors.specificity.items - .filter(c => compareSpecificity(c, mode) < 0) + /** @type {import('@projectwallace/css-analyzer').Specificity[]} */ + // @ts-expect-error css-analyzer type is incorrect + const items = result.selectors.specificity.items + const selectorsAboveMode = items.filter(c => compareSpecificity(c, mode) < 0) .length const outcome = { @@ -52,7 +54,7 @@ export const guards = [ /** @param {ReturnType} result */ result => { const MAX_SELECTOR_COMPLEXITY = 5 - const actual = result.selectors.complexity.max + const actual = result.selectors.complexity.max || 0 const outcome = { id: 'MaxSelectorComplexity', diff --git a/src/core.js b/src/core.js index 038058a..37de2b5 100644 --- a/src/core.js +++ b/src/core.js @@ -29,9 +29,7 @@ function calculateScore(result, guards) { } } -/** - * @param {ReturnType} analysis - */ +/** @param {ReturnType} analysis */ export function calculate(analysis) { const performance = calculateScore(analysis, performanceGuards) const maintainability = calculateScore(analysis, maintainabilityGuards) diff --git a/src/index.test.js b/src/index.test.js index 05f8d7f..b69cc10 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -73,7 +73,6 @@ Index('smoke test', () => { "id": "TooMuchEmbeddedContent", "score": 0, "value": 0, - "actuals": [] }, { "id": "SourceLinesOfCode", @@ -235,7 +234,6 @@ Index('smoke test', () => { "id": "TooMuchEmbeddedContent", "score": 0, "value": 0, - "actuals": [] } ] }, diff --git a/src/maintainability.js b/src/maintainability.js index ab73a42..d3607b1 100644 --- a/src/maintainability.js +++ b/src/maintainability.js @@ -65,17 +65,18 @@ export const guards = [ /** @param {ReturnType} result */ result => { const MAX_SELECTORS_PER_RULESET = 10 + let max = result.rules.selectors.max || 0 const outcome = { id: 'MaxSelectorsPerRule', score: 0, - value: result.rules.selectors.max, + value: max, actuals: result.rules.selectors.items, } // Deduct 0.5 points per selectors over 10 - if (result.rules.selectors.max > MAX_SELECTORS_PER_RULESET) { - const score = Math.ceil((result.rules.selectors.max - MAX_SELECTORS_PER_RULESET) * 0.5) + if (max > MAX_SELECTORS_PER_RULESET) { + const score = Math.ceil((max - MAX_SELECTORS_PER_RULESET) * 0.5) outcome.score = Math.min(score, 15) } @@ -86,17 +87,18 @@ export const guards = [ /** @param {ReturnType} result */ result => { const MAX_DECLARATIONS_PER_RULESET = 10 + const max = result.rules.declarations.max || 0 const outcome = { id: 'MaxDeclarationsPerRule', score: 0, - value: result.rules.declarations.max, + value: max, actuals: result.rules.declarations.items, } // Deduct 0.5 points per declarations over 10 - if (result.rules.declarations.max > MAX_DECLARATIONS_PER_RULESET) { - const score = Math.ceil((result.rules.declarations.max - MAX_DECLARATIONS_PER_RULESET) * 0.5) + if (max > MAX_DECLARATIONS_PER_RULESET) { + const score = Math.ceil((max - MAX_DECLARATIONS_PER_RULESET) * 0.5) outcome.score = Math.min(15, score) } diff --git a/src/performance.js b/src/performance.js index 45705da..58b9c88 100644 --- a/src/performance.js +++ b/src/performance.js @@ -39,11 +39,11 @@ export const guards = [ const outcome = { id: 'DeclarationDuplications', score: 0, - value: 1 - result.declarations.unique.ratio, + value: 1 - result.declarations.uniquenessRatio, } - if (result.declarations.unique.ratio < 0.66) { - outcome.score = Math.floor((1 - result.declarations.unique.ratio) * 10) + if (result.declarations.uniquenessRatio < 0.66) { + outcome.score = Math.floor((1 - result.declarations.uniquenessRatio) * 10) } return outcome @@ -72,13 +72,12 @@ export const guards = [ // Should not contain too much embedded content // Deduct 1 point for every 250 bytes /** @param {ReturnType} result */ - result => { + (result) => { const { size } = result.stylesheet.embeddedContent return { id: 'TooMuchEmbeddedContent', score: Math.min(20, Math.floor(size.total / 250)), value: size.total, - actuals: Object.keys(result.stylesheet.embeddedContent.unique), } }, ] diff --git a/src/performance.test.js b/src/performance.test.js index cc2d3da..a7b987d 100644 --- a/src/performance.test.js +++ b/src/performance.test.js @@ -186,7 +186,6 @@ Performance('deducts points for having embedded content', () => { id: 'TooMuchEmbeddedContent', score: 20, value: 45990, - actuals: Array.from({ length: 100 }).fill('').map((_, index) => generateEmbed(index)), }, ]) })