■ ■ ■ ■ ■ ■
packages/web/src/store/selectors/websiteResults.ts
skipped 6 lines 7 7 import { SeverityWeightMap } from '../../components/ui/Vulnerability/Vulnerability'; 8 8 import type { ClientApi } from '../../services/apiClient'; 9 9 10 - const getFlags = (state: RootState) => ({ 11 - isLoading: state.webpageResults.isLoading, 12 - isFailed: state.webpageResults.isFailed, 13 - }); 14 - const getScanStatus = (state: RootState) => state.webpageResults.detectionResult?.status; 15 - const getPackages = (state: RootState) => 16 - state.webpageResults.detectionResult?.scanResult?.packages; 17 - const getVulnerabilities = (state: RootState) => 18 - state.webpageResults.detectionResult?.scanResult?.vulnerabilities; 19 - const getSorting = (state: RootState) => state.webpageResults.filters.sort; 20 - const getFilter = (state: RootState) => state.webpageResults.filters.filter; 21 - const getPackageNameFilter = (state: RootState) => state.webpageResults.filters.filterPackageName; 10 + const makeSelectScanResultByUrl = () => 11 + createSelector( 12 + [(state: RootState) => state.scans, (state: RootState, url: string | undefined) => url], 13 + (scans, url) => (url ? scans[url] : undefined) 14 + ); 22 15 23 16 const compareByPopularity = ( 24 17 left: ClientApi.ScanResultPackageResponse, skipped 69 lines 94 87 }; 95 88 96 89 export const selectors = { 97 - default: createSelector([getScanStatus, getVulnerabilities], (scanStatus, vulnerabilities) => ({ 98 - status: scanStatus, 99 - vulnerabilities, 90 + scanState: createSelector([makeSelectScanResultByUrl()], (scanResult) => ({ 91 + isLoading: scanResult?.isLoading ?? true, 92 + isFailed: !!scanResult?.error, 93 + isPending: scanResult?.scan?.status === 'pending', 94 + isProtected: scanResult?.scan?.status === 'protected', 95 + isInvalid: scanResult?.scan?.scanResult?.identifiedPackages.length === 0, 100 96 })), 101 - stateFlags: createSelector( 102 - [getScanStatus, getPackages, getFlags], 103 - (scanStatus, packages, flags) => ({ 104 - ...flags, 105 - isInvalid: packages && packages.length === 0, 106 - isPending: !scanStatus || scanStatus === 'pending', 107 - isProtected: scanStatus === 'protected', 108 - }) 109 - ), 110 - packagesStats: createSelector( 111 - [getPackages, getVulnerabilities], 112 - (packages = [], vulnerabilities = {}) => ({ 97 + packagesStats: createSelector([makeSelectScanResultByUrl()], (scanResult) => { 98 + const packages = scanResult?.scan?.scanResult?.identifiedPackages ?? []; 99 + const vulnerabilities = scanResult?.scan?.scanResult?.vulnerabilities ?? {}; 100 + 101 + return { 113 102 total: packages.length, 114 103 vulnerable: packages.filter((pkg) => (vulnerabilities[pkg.name]?.length ?? 0) > 0).length, 115 104 outdated: packages.filter( 116 105 (pkg) => 117 106 pkg.registryMetadata && semver.gtr(pkg.registryMetadata.latestVersion, pkg.versionRange) 118 107 ).length, 119 - }) 120 - ), 121 - packagesSortedAndFiltered: createSelector( 122 - [getPackages, getVulnerabilities, getSorting, getFilter, getPackageNameFilter], 123 - (packages, vulnerabilities, sorting, filter, packageNameFilter) => 124 - packages && 125 - vulnerabilities && 126 - filterModes[filter]( 127 - sortingModes[sorting](packages, vulnerabilities), 128 - vulnerabilities, 129 - packageNameFilter 130 - ) 131 - ), 108 + }; 109 + } ), 110 + packagesSortedAndFiltered: createSelector([ makeSelectScanResultByUrl ( ) ] , ( scanResult ) = > { 111 + const packages = scanResult?.scan?.scanResult?.identifiedPackages ?? []; 112 + const vulnerabilities = scanResult?.scan?.scanResult?.vulnerabilities ?? {}; 113 + 114 + const filters = scanResult?.filters; 115 + 116 + if (!filters) { 117 + return []; 118 + } 119 + 120 + return filterModes[filters.filter]( 121 + sortingModes[filters.sort](packages, vulnerabilities), 122 + vulnerabilities, 123 + filters.filterPackageName 124 + ); 125 + }), 132 126 }; 133 127 128 + export { makeSelectScanResultByUrl }; 129 +