From f9ed7e57d4bc9c910966964b14c5302ff4b9cc8f Mon Sep 17 00:00:00 2001 From: akash1810 Date: Tue, 19 Mar 2024 19:05:32 +0000 Subject: [PATCH] Add linting rule to prefer `.flatMap(...)` over `.map(...).flat()` Using `.flatMap` is terser than mapping then flattening. See https://github.com/sindresorhus/eslint-plugin-unicorn. --- package-lock.json | 205 +++++++++++++++++- package.json | 7 +- packages/repocop/src/evaluation/repository.ts | 6 +- packages/repocop/src/index.ts | 2 +- .../remediation/vuln-digest/vuln-digest.ts | 2 +- 5 files changed, 204 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index d2334e8cd..ddf6a8b82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "esbuild-jest": "^0.5.0", "eslint": "^8.57.0", "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-unicorn": "^51.0.1", "jest": "^29.7.0", "npm-run-all": "^4.1.5", "tsx": "^4.7.1", @@ -5601,7 +5602,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.2", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -5617,10 +5620,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -5665,6 +5667,18 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cache-base": { "version": "1.0.1", "dev": true, @@ -5713,7 +5727,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001572", + "version": "1.0.30001599", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz", + "integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==", "dev": true, "funding": [ { @@ -5728,8 +5744,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/capture-exit": { "version": "2.0.0", @@ -5838,6 +5853,27 @@ "node": ">= 0.4" } }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/clean-stack": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", @@ -6027,6 +6063,19 @@ "node": ">=0.10.0" } }, + "node_modules/core-js-compat": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/create-jest": { "version": "29.7.0", "dev": true, @@ -6283,9 +6332,10 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.616", - "dev": true, - "license": "ISC" + "version": "1.4.710", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.710.tgz", + "integrity": "sha512-w+9yAVHoHhysCa+gln7AzbO9CdjFcL/wN/5dd+XW/Msl2d/4+WisEaCF1nty0xbAKaxdaJfgLB2296U7zZB7BA==", + "dev": true }, "node_modules/emittery": { "version": "0.13.1", @@ -6911,6 +6961,66 @@ } } }, + "node_modules/eslint-plugin-unicorn": { + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "@eslint-community/eslint-utils": "^4.4.0", + "@eslint/eslintrc": "^2.1.4", + "ci-info": "^4.0.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.34.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.5.4", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=8.56.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "dev": true, @@ -8007,6 +8117,21 @@ "dev": true, "license": "MIT" }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "license": "MIT", @@ -9361,6 +9486,15 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.2", "dev": true, @@ -10184,6 +10318,15 @@ "node": ">=8" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/posix-character-classes": { "version": "0.1.1", "dev": true, @@ -10460,6 +10603,15 @@ "node": ">=0.10.0" } }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "dev": true, @@ -10476,6 +10628,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regjsparser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "dev": true, @@ -11527,6 +11700,18 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "dev": true, diff --git a/package.json b/package.json index 88caeef9b..94996f095 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "esbuild-jest": "^0.5.0", "eslint": "^8.57.0", "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-unicorn": "^51.0.1", "jest": "^29.7.0", "npm-run-all": "^4.1.5", "tsx": "^4.7.1", @@ -33,11 +34,13 @@ "eslintConfig": { "extends": "@guardian/eslint-config-typescript", "plugins": [ - "prettier" + "prettier", + "unicorn" ], "rules": { "prettier/prettier": "error", - "@typescript-eslint/no-non-null-assertion": "error" + "@typescript-eslint/no-non-null-assertion": "error", + "unicorn/prefer-array-flat-map": "error" } }, "eslintIgnore": [ diff --git a/packages/repocop/src/evaluation/repository.ts b/packages/repocop/src/evaluation/repository.ts index af58ba392..56ed593b4 100644 --- a/packages/repocop/src/evaluation/repository.ts +++ b/packages/repocop/src/evaluation/repository.ts @@ -320,8 +320,7 @@ export function collectAndFormatUrgentSnykAlerts( .map((project) => project.id); const snykIssuesForRepo: SnykIssue[] = snykProjectIdsForRepo - .map((projectId) => getIssuesForProject(projectId, snykIssues)) - .flat() + .flatMap((projectId) => getIssuesForProject(projectId, snykIssues)) .filter((i) => !i.attributes.ignored); const processedVulns = snykIssuesForRepo.map((v) => @@ -470,8 +469,7 @@ export function snykAlertToRepocopVulnerability( projects: SnykProject[], ): RepocopVulnerability { const packages = (issue.attributes.coordinates ?? []) - .map((c) => c.representations) - .flat() + .flatMap((c) => c.representations) .filter((r) => r !== null) as Dependency[]; const projectIdFromIssue = issue.relationships.scan_item.data.id; diff --git a/packages/repocop/src/index.ts b/packages/repocop/src/index.ts index d1e30972f..70fbdec74 100644 --- a/packages/repocop/src/index.ts +++ b/packages/repocop/src/index.ts @@ -82,7 +82,7 @@ export async function main() { const repocopRules = evaluationResults.map((r) => r.repocopRules); const severityPredicate = (x: RepocopVulnerability) => x.severity === 'high'; const [high, critical] = partition( - evaluationResults.map((r) => r.vulnerabilities).flat(), + evaluationResults.flatMap((r) => r.vulnerabilities), severityPredicate, ); diff --git a/packages/repocop/src/remediation/vuln-digest/vuln-digest.ts b/packages/repocop/src/remediation/vuln-digest/vuln-digest.ts index 7683cbc6e..0530321aa 100644 --- a/packages/repocop/src/remediation/vuln-digest/vuln-digest.ts +++ b/packages/repocop/src/remediation/vuln-digest/vuln-digest.ts @@ -56,7 +56,7 @@ export function createDigest( results: EvaluationResult[], ): VulnerabilityDigest | undefined { const resultsForTeam = getOwningRepos(team, repoOwners, results); - const vulns = resultsForTeam.map((r) => r.vulnerabilities).flat(); + const vulns = resultsForTeam.flatMap((r) => r.vulnerabilities); const totalVulnsCount = vulns.length;