diff --git a/biome.json b/biome.json index b64d31fff..0dcad3dec 100644 --- a/biome.json +++ b/biome.json @@ -1,7 +1,11 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "organizeImports": { - "enabled": true + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "assist": { + "actions": { + "source": { + "organizeImports": "off" + } + } }, "vcs": { "enabled": true, @@ -31,8 +35,12 @@ } }, "files": { - "ignore": [ - "**/src/app/client/*.ts" + "includes": [ + "**", + "!**/dist", + "!**/node_modules", + "!client/coverage", + "!client/src/app/client" ] } } diff --git a/client/package.json b/client/package.json index aa6f46be3..b68ddbe0e 100644 --- a/client/package.json +++ b/client/package.json @@ -60,7 +60,11 @@ "typescript": "^5.7.3" }, "browserslist": { - "production": [">0.2%", "not dead", "not op_mini all"], + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], "development": [ "last 1 chrome version", "last 1 firefox version", diff --git a/client/rsbuild.config.ts b/client/rsbuild.config.ts index af0be5b95..c20457e99 100644 --- a/client/rsbuild.config.ts +++ b/client/rsbuild.config.ts @@ -93,7 +93,7 @@ export default defineConfig({ exclude: [ ({ file = "" }) => /[\\/]node_modules[\\/]/.test(file), ({ file = "" }) => { - return /\/src\/app\/client(?:\/[^\/]+)*\/[^\/]+\.ts$/.test(file); + return /\/src\/app\/client(?:\/[^/]+)*\/[^/]+\.ts$/.test(file); }, ], }, diff --git a/client/src/app/api/model-utils.ts b/client/src/app/api/model-utils.ts index 85e7f0605..472680e4c 100644 --- a/client/src/app/api/model-utils.ts +++ b/client/src/app/api/model-utils.ts @@ -26,7 +26,7 @@ type ListType = { color: { name: string; value: string; var: string }; progressProps: Pick; - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed icon: React.ComponentType; }; }; diff --git a/client/src/app/axios-config/apiInit.ts b/client/src/app/axios-config/apiInit.ts index 42b6a7a34..1f93d68ed 100644 --- a/client/src/app/axios-config/apiInit.ts +++ b/client/src/app/axios-config/apiInit.ts @@ -66,7 +66,7 @@ export const initInterceptors = () => { retryCounter: retryCounter + 1, }); } - } catch (refreshError) { + } catch (_refreshError) { await userManager.signoutRedirect(); } } diff --git a/client/src/app/components/ConfirmDialog.tsx b/client/src/app/components/ConfirmDialog.tsx index 43cc69b8e..0df7995a5 100644 --- a/client/src/app/components/ConfirmDialog.tsx +++ b/client/src/app/components/ConfirmDialog.tsx @@ -18,7 +18,7 @@ export interface ConfirmDialogProps { | "danger" | "warning" | "info" - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed | React.ComponentType; message: string | React.ReactNode; @@ -89,7 +89,7 @@ export const ConfirmDialog: React.FC = ({ {cancelBtn} ) : ( - <>{confirmBtn} + confirmBtn )} diff --git a/client/src/app/components/EditLabelsForm.tsx b/client/src/app/components/EditLabelsForm.tsx index 57cff725c..1df250087 100644 --- a/client/src/app/components/EditLabelsForm.tsx +++ b/client/src/app/components/EditLabelsForm.tsx @@ -62,9 +62,13 @@ export const EditLabelsForm: React.FC = ({ const onSaveForm = () => { const labels = selections .map((e) => splitStringAsKeyValue(getString(e.name))) - .reduce((prev, { key, value }) => { - return Object.assign(prev, { [key]: value }); - }, {}); + .reduce( + (prev, { key, value }) => { + prev[key] = value ?? ""; + return prev; + }, + {} as Record, + ); onSave(labels); }; diff --git a/client/src/app/components/FilterPanel/FilterPanel.tsx b/client/src/app/components/FilterPanel/FilterPanel.tsx index b40cc15d7..ca36bd9e5 100644 --- a/client/src/app/components/FilterPanel/FilterPanel.tsx +++ b/client/src/app/components/FilterPanel/FilterPanel.tsx @@ -40,51 +40,53 @@ export const FilterPanel = ({ ) === undefined ); }) - .reduce((prev, current) => { - return Object.assign(prev, { [current.categoryKey]: undefined }); - }, {}); + .reduce( + (prev, current) => { + prev[current.categoryKey] = undefined; + return prev; + }, + {} as Record, + ); setFilterValues({ ...filterValues, ...filtersToBeCleared }); }; return ( - <> - - - - - {filterCategories - .filter((filterCategory) => { - return ( - omitFilterCategoryKeys.find( - (categoryKey) => categoryKey === filterCategory.categoryKey, - ) === undefined - ); - }) - .map((category) => { - return ( - - - - {category.title} - - - - category={category} - filterValue={filterValues[category.categoryKey]} - setFilterValue={(newValue) => - setFilterValue(category, newValue) - } - isDisabled={isDisabled} - isSidebar - /> - - - - ); - })} - - + + + + + {filterCategories + .filter((filterCategory) => { + return ( + omitFilterCategoryKeys.find( + (categoryKey) => categoryKey === filterCategory.categoryKey, + ) === undefined + ); + }) + .map((category) => { + return ( + + + + {category.title} + + + + category={category} + filterValue={filterValues[category.categoryKey]} + setFilterValue={(newValue) => + setFilterValue(category, newValue) + } + isDisabled={isDisabled} + isSidebar + /> + + + + ); + })} + ); }; diff --git a/client/src/app/components/FilterToolbar/SelectFilterControl.tsx b/client/src/app/components/FilterToolbar/SelectFilterControl.tsx index 884e9b08a..a76cf77b5 100644 --- a/client/src/app/components/FilterToolbar/SelectFilterControl.tsx +++ b/client/src/app/components/FilterToolbar/SelectFilterControl.tsx @@ -51,12 +51,15 @@ export const SelectFilterControl = ({ node: chipLabel ?? label ?? value, }; }) - .reduce((prev, current) => { - if (current) { - prev.push(current); - } - return prev; - }, new Array()); + .reduce( + (prev, current) => { + if (current) { + prev.push(current); + } + return prev; + }, + [] as (string | ToolbarLabel)[], + ); const onFilterSelect = (value: string) => { const option = getOptionFromOptionValue(value); diff --git a/client/src/app/components/HookFormPFFields/HookFormPFSelect.tsx b/client/src/app/components/HookFormPFFields/HookFormPFSelect.tsx index 8243b5b18..f20dafa89 100644 --- a/client/src/app/components/HookFormPFFields/HookFormPFSelect.tsx +++ b/client/src/app/components/HookFormPFFields/HookFormPFSelect.tsx @@ -30,7 +30,7 @@ export const HookFormPFSelect = < HookFormPFSelectProps >(props); const { fieldId, helperText, isRequired, errorsSuppressed } = extractedProps; - const { children, ref, ...rest } = remainingProps; + const { children: _children, ref: _ref, ...rest } = remainingProps; return ( diff --git a/client/src/app/components/IconedStatus.tsx b/client/src/app/components/IconedStatus.tsx index cf7a56554..f581fb794 100644 --- a/client/src/app/components/IconedStatus.tsx +++ b/client/src/app/components/IconedStatus.tsx @@ -98,7 +98,7 @@ export const IconedStatus: React.FC = ({ presetProps?.tooltipMessage ? ( {children} ) : ( - <>{children} + children ); return ( diff --git a/client/src/app/components/OidcProvider.tsx b/client/src/app/components/OidcProvider.tsx index 606d22961..580a9ff88 100644 --- a/client/src/app/components/OidcProvider.tsx +++ b/client/src/app/components/OidcProvider.tsx @@ -21,7 +21,7 @@ interface IOidcProviderProps { export const OidcProvider: React.FC = ({ children }) => { return ENV.AUTH_REQUIRED !== "true" ? ( - <>{children} + children ) : ( { const summary = sboms.reduce( (prev, current) => { const sbomStatus = current.sbomStatus; + // biome-ignore lint/performance/noAccumulatingSpread: allowed return Object.assign(prev, { total: prev.total + 1, sbomStatus: { diff --git a/client/src/app/hooks/domain-controls/useVulnerabilitiesOfPackage.ts b/client/src/app/hooks/domain-controls/useVulnerabilitiesOfPackage.ts index 36fd548da..3da82e888 100644 --- a/client/src/app/hooks/domain-controls/useVulnerabilitiesOfPackage.ts +++ b/client/src/app/hooks/domain-controls/useVulnerabilitiesOfPackage.ts @@ -130,6 +130,7 @@ const advisoryToModels = (advisories: PurlAdvisory[]) => { const prevVulnStatusValue = prev.vulnerabilityStatus[vulnStatus]; + // biome-ignore lint/performance/noAccumulatingSpread: allowed const result: VulnerabilityOfPackageSummary = Object.assign(prev, { vulnerabilityStatus: { ...prev.vulnerabilityStatus, diff --git a/client/src/app/hooks/domain-controls/useVulnerabilitiesOfSbom.ts b/client/src/app/hooks/domain-controls/useVulnerabilitiesOfSbom.ts index 38759b64a..b4354e569 100644 --- a/client/src/app/hooks/domain-controls/useVulnerabilitiesOfSbom.ts +++ b/client/src/app/hooks/domain-controls/useVulnerabilitiesOfSbom.ts @@ -126,6 +126,7 @@ const advisoryToModels = (advisories: SbomAdvisory[]) => { const prevVulnStatusValue = prev.vulnerabilityStatus[vulnStatus]; + // biome-ignore lint/performance/noAccumulatingSpread: allowed const result: VulnerabilityOfSbomSummary = Object.assign(prev, { vulnerabilityStatus: { ...prev.vulnerabilityStatus, diff --git a/client/src/app/hooks/table-controls/expansion/useExpansionState.ts b/client/src/app/hooks/table-controls/expansion/useExpansionState.ts index 955e3f415..e5ba9771a 100644 --- a/client/src/app/hooks/table-controls/expansion/useExpansionState.ts +++ b/client/src/app/hooks/table-controls/expansion/useExpansionState.ts @@ -103,7 +103,7 @@ export const useExpansionState = < deserialize: ({ expandedCells: expandedCellsStr }) => { try { return JSON.parse(expandedCellsStr || "{}"); - } catch (e) { + } catch (_e) { return {}; } }, diff --git a/client/src/app/hooks/table-controls/filtering/getLocalFilterDerivedState.ts b/client/src/app/hooks/table-controls/filtering/getLocalFilterDerivedState.ts index 0cbb2e0c0..278394ddd 100644 --- a/client/src/app/hooks/table-controls/filtering/getLocalFilterDerivedState.ts +++ b/client/src/app/hooks/table-controls/filtering/getLocalFilterDerivedState.ts @@ -52,7 +52,7 @@ export const getLocalFilterDerivedState = < const defaultMatcher = (filterValue: string, item: TItem) => legacyMatcher( filterValue, - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed filterCategory?.getItemValue?.(item) ?? (item as any)[filterKey], ); const matcher = filterCategory?.matcher ?? defaultMatcher; @@ -69,7 +69,7 @@ export const getLocalFilterDerivedState = < * * @returns false for any falsy value (regardless of the filter value), true if (coerced to string) lowercased value contains lowercased filter value. */ -// biome-ignore lint/suspicious/noExplicitAny: +// biome-ignore lint/suspicious/noExplicitAny: allowed const legacyMatcher = (filterValue: string, value: any) => { if (!value) return false; const lowerCaseItemValue = String(value).toLowerCase(); diff --git a/client/src/app/hooks/table-controls/filtering/helpers.ts b/client/src/app/hooks/table-controls/filtering/helpers.ts index 2f92b92fa..ffafadbbc 100644 --- a/client/src/app/hooks/table-controls/filtering/helpers.ts +++ b/client/src/app/hooks/table-controls/filtering/helpers.ts @@ -37,7 +37,7 @@ export const deserializeFilterUrlParams = < }): Partial> => { try { return JSON.parse(serializedParams.filters || "{}"); - } catch (e) { + } catch (_e) { return {}; } }; diff --git a/client/src/app/hooks/useUrlParams.ts b/client/src/app/hooks/useUrlParams.ts index 86d73e9d8..c64ff1394 100644 --- a/client/src/app/hooks/useUrlParams.ts +++ b/client/src/app/hooks/useUrlParams.ts @@ -71,9 +71,8 @@ export const useUrlParams = < persistenceKeyPrefix ? objectKeys(serializedParams).reduce( (obj, key) => { - return Object.assign(obj, { - [withPrefix(key)]: serializedParams[key], - }); + obj[withPrefix(key)] = serializedParams[key]; + return obj; }, {} as TSerializedParams, ) @@ -108,9 +107,8 @@ export const useUrlParams = < if (isEnabled) { const serializedParams = keys.reduce( (obj, key) => { - return Object.assign(obj, { - [key]: urlParams.get(withPrefix(key)), - }); + obj[key] = urlParams.get(withPrefix(key)); + return obj; }, {} as TSerializedParams, ); @@ -118,7 +116,7 @@ export const useUrlParams = < params = allParamsEmpty ? defaultValue : deserialize(serializedParams); } - // biome-ignore lint/correctness/useExhaustiveDependencies: + // biome-ignore lint/correctness/useExhaustiveDependencies: allowed React.useEffect(() => { if (allParamsEmpty) setParams(defaultValue); // Leaving this rule enabled results in a cascade of unnecessary useCallbacks: diff --git a/client/src/app/layout/header.tsx b/client/src/app/layout/header.tsx index e62b8d6cf..a753ee1b5 100644 --- a/client/src/app/layout/header.tsx +++ b/client/src/app/layout/header.tsx @@ -45,6 +45,7 @@ export const HeaderApp: React.FC = () => { masthead: { leftBrand, leftTitle, rightBrand, supportUrl }, } = useBranding(); + // biome-ignore lint/correctness/useHookAtTopLevel: allowed const auth = (isAuthRequired && useAuth()) || undefined; const navigate = useNavigate(); diff --git a/client/src/app/pages/advisory-list/advisory-table.tsx b/client/src/app/pages/advisory-list/advisory-table.tsx index df10feaf5..d863fed87 100644 --- a/client/src/app/pages/advisory-list/advisory-table.tsx +++ b/client/src/app/pages/advisory-list/advisory-table.tsx @@ -98,9 +98,8 @@ export const AdvisoryTable: React.FC = () => { const extendedSeverity = extendedSeverityFromSeverity( current.severity, ); - return Object.assign(prev, { - [extendedSeverity]: prev[extendedSeverity] + 1, - }); + prev[extendedSeverity] = prev[extendedSeverity] + 1; + return prev; }, defaultSeverityGroup); return ( diff --git a/client/src/app/pages/advisory-list/advisory-toolbar.tsx b/client/src/app/pages/advisory-list/advisory-toolbar.tsx index e261ba961..ec2f551c1 100644 --- a/client/src/app/pages/advisory-list/advisory-toolbar.tsx +++ b/client/src/app/pages/advisory-list/advisory-toolbar.tsx @@ -26,19 +26,17 @@ export const AdvisoryToolbar: React.FC = ({ } = tableControls; return ( - <> - - - {showFilters && } - - - - - - + + + {showFilters && } + + + + + ); }; diff --git a/client/src/app/pages/home/components/MonitoringSection.tsx b/client/src/app/pages/home/components/MonitoringSection.tsx index 2475c0267..33f0c31d5 100644 --- a/client/src/app/pages/home/components/MonitoringSection.tsx +++ b/client/src/app/pages/home/components/MonitoringSection.tsx @@ -157,7 +157,7 @@ export const MonitoringSection: React.FC = () => { style={[{ fill: "#0066cc" }]} events={{ onClick: (event) => { - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed const sbomName = (event.target as any) .innerHTML as string | null; const sbom = barchartSboms.find( diff --git a/client/src/app/pages/home/home.tsx b/client/src/app/pages/home/home.tsx index 2e7b5eb88..e119af22a 100644 --- a/client/src/app/pages/home/home.tsx +++ b/client/src/app/pages/home/home.tsx @@ -8,19 +8,17 @@ import { WatchedSbomsProvider } from "./watched-sboms-context"; export const Home: React.FC = () => { return ( - <> - - - - - - - - - - - - - + + + + + + + + + + + + ); }; diff --git a/client/src/app/pages/importer-list/components/importer-form.tsx b/client/src/app/pages/importer-list/components/importer-form.tsx index 405fa5318..adda45b36 100644 --- a/client/src/app/pages/importer-list/components/importer-form.tsx +++ b/client/src/app/pages/importer-list/components/importer-form.tsx @@ -54,7 +54,7 @@ const getPeriodValue = (period?: string) => { return period ? Number.parseInt(period.substring(0, period.length - 1)) : null; - } catch (e) { + } catch (_e) { return null; } }; @@ -64,7 +64,7 @@ const getPeriodUnit = (period?: string): PeriodUnitType | null => { return period ? (period.substring(period.length - 1) as PeriodUnitType) : null; - } catch (e) { + } catch (_e) { return null; } }; @@ -131,7 +131,7 @@ export const ImporterForm: React.FC = ({ )[0] as ImporterType; const importerConfiguration = importer?.configuration - ? // biome-ignore lint/suspicious/noExplicitAny: + ? // biome-ignore lint/suspicious/noExplicitAny: allowed ((importer?.configuration as any)[importerType] as SbomImporter) : undefined; @@ -258,44 +258,149 @@ export const ImporterForm: React.FC = ({ }; return ( - <> -
- - {ALL_IMPORTERS.map((option) => ( - - ))} - + + + {ALL_IMPORTERS.map((option) => ( + + ))} + + + + ( + + { + onChange(checked); + }} + /> + + + + + + + )} + /> + + + Fill demo settings + + } + /> + } + > - + + + + + ( + { + onChange(value - 1); + }} + onChange={onChange} + onPlus={() => { + onChange(value + 1); + }} + inputName="periodValue" + inputAriaLabel="period value" + minusBtnAriaLabel="minus" + plusBtnAriaLabel="plus" + /> + )} + /> + + + ( + + {ALL_PERIOD_UNITS.map((option) => ( + + ))} + + )} + /> + + + + ( { onChange(checked); @@ -303,8 +408,8 @@ export const ImporterForm: React.FC = ({ /> @@ -315,186 +420,79 @@ export const ImporterForm: React.FC = ({ )} /> - - Fill demo settings - - } - /> - } + + + {fieldsKeys.map((field, index) => { + return ( + + + + ( + { + onChange(value); + }} + onBlur={onBlur} + value={value} + /> + )} + /> + + + + + + + ); + })} + + + + + + + + + - - - - ); - })} - - - - - - - - - - - - - + {!importer ? "Create" : "Save"} + + + + ); }; diff --git a/client/src/app/pages/importer-list/importer-list.tsx b/client/src/app/pages/importer-list/importer-list.tsx index 2e4bb3d38..4c6a0a450 100644 --- a/client/src/app/pages/importer-list/importer-list.tsx +++ b/client/src/app/pages/importer-list/importer-list.tsx @@ -69,7 +69,7 @@ type ImporterStatus = "disabled" | "scheduled" | "running"; const getImporterStatus = (importer: Importer): ImporterStatus => { const importerType = Object.keys(importer.configuration ?? {})[0]; - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed const configValues = (importer.configuration as any)[ importerType ] as SbomImporter; @@ -112,7 +112,7 @@ export const ImporterList: React.FC = () => { const execEnableDisableImporter = (row: Importer, enable: boolean) => { const importerType = Object.keys(row.configuration ?? {})[0]; - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed const currentConfigValues = (row.configuration as any)[ importerType ] as SbomImporter; @@ -317,7 +317,7 @@ export const ImporterList: React.FC = () => { > {currentPageItems?.map((item, rowIndex) => { const importerType = Object.keys(item.configuration ?? {})[0]; - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed const configValues = (item.configuration as any)[ importerType ] as SbomImporter; diff --git a/client/src/app/pages/sbom-details/packages-by-sbom.tsx b/client/src/app/pages/sbom-details/packages-by-sbom.tsx index d5850e90c..a5ba714d6 100644 --- a/client/src/app/pages/sbom-details/packages-by-sbom.tsx +++ b/client/src/app/pages/sbom-details/packages-by-sbom.tsx @@ -254,45 +254,39 @@ export const PackagesBySbom: React.FC = ({ sbomId }) => {
{isCellExpanded(item, "licenses") ? ( - <> - - {item.licenses.map((e) => ( - - {renderLicenseWithMappings( - e.license_name, - item.licenses_ref_mapping, - )}{" "} - - - ))} - - + + {item.licenses.map((e) => ( + + {renderLicenseWithMappings( + e.license_name, + item.licenses_ref_mapping, + )}{" "} + + + ))} + ) : null} {isCellExpanded(item, "purls") ? ( - <> - - {item.purl.map((e) => { - return ( - - - {e.purl} - - - ); - })} - - + + {item.purl.map((e) => { + return ( + + + {e.purl} + + + ); + })} + ) : null} {isCellExpanded(item, "cpes") ? ( - <> - - {item.cpe.map((e) => ( - {e} - ))} - - + + {item.cpe.map((e) => ( + {e} + ))} + ) : null}
diff --git a/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx b/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx index d941a4a43..1e7a18a2f 100644 --- a/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx +++ b/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx @@ -179,282 +179,276 @@ export const VulnerabilitiesBySbom: React.FC = ({ } = tableControls; return ( - <> - - - - - - - - - - - - - Name - - {sbom?.name} - - - - Version - - {sbom?.described_by - .map((item) => item.version) - .join(", ")} - - - - Creation date - - {formatDate(sbom?.published)} - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - {currentPageItems?.map((item, rowIndex) => { - return ( - - - + + + + + + + Name + + {sbom?.name} + + + + Version + + {sbom?.described_by + .map((item) => item.version) + .join(", ")} + + + + Creation date + + {formatDate(sbom?.published)} + + + + + + + + + + + + + + + + + + +
- - - - - - -
+ + + + + + + {currentPageItems?.map((item, rowIndex) => { + return ( + + + + + + {(isFocused, setIsFocused) => ( + - - {(isFocused, setIsFocused) => ( - + {item.vulnerability && ( + + )} + + + )} + + - - - - - - {isCellExpanded(item) ? ( - - + + + ); + })} + +
+ + + + + + +
- - + setIsFocused(true)} + onBlur={() => setIsFocused(false)} + tabIndex={0} + {...getTdProps({ columnKey: "description" })} > - {item.vulnerability.identifier} - - setIsFocused(true)} - onBlur={() => setIsFocused(false)} - tabIndex={0} - {...getTdProps({ columnKey: "description" })} + - - {item.vulnerability && ( - - )} - - + - - - - {item.summary.totalPackages} - - {formatDate(item.vulnerability?.published)} - - {formatDate(item.vulnerability?.modified)} -
- - {isCellExpanded(item, "affectedDependencies") ? ( - <> - - - - - - - - - - - - - {item.summary.allPackages - .flatMap((item) => { - // Some packages do not have purl neither ID. So we render only the parent name meanwhile - type EnrichedPurlSummary = { - parentName: string; - purlSummary?: PurlSummary; - }; + score={item.vulnerability.average_score} + showLabel + showScore + /> + + + + + + + {isCellExpanded(item) ? ( + + - - ) : null} - - ); - })} - -
TypeNamespaceNameVersionPathQualifiers
+ {item.summary.totalPackages} + + {formatDate(item.vulnerability?.published)} + + {formatDate(item.vulnerability?.modified)} +
+ + {isCellExpanded(item, "affectedDependencies") ? ( + + + + + + + + + + + + + {item.summary.allPackages + .flatMap((item) => { + // Some packages do not have purl neither ID. So we render only the parent name meanwhile + type EnrichedPurlSummary = { + parentName: string; + purlSummary?: PurlSummary; + }; - const hasNoPurlsButOnlyName = - item.name && item.purl.length === 0; + const hasNoPurlsButOnlyName = + item.name && item.purl.length === 0; - if (hasNoPurlsButOnlyName) { - const result: EnrichedPurlSummary = { - parentName: item.name, - }; - return [result]; - } + if (hasNoPurlsButOnlyName) { + const result: EnrichedPurlSummary = { + parentName: item.name, + }; + return [result]; + } - return item.purl.map((i) => { - const result: EnrichedPurlSummary = { - parentName: item.name, - purlSummary: i, - }; - return result; - }); - }) - .map((purl, index) => { - if (purl.purlSummary) { - const decomposedPurl = decomposePurl( - purl.purlSummary.purl, - ); - return ( - - - - - - - - - ); - } + return item.purl.map((i) => { + const result: EnrichedPurlSummary = { + parentName: item.name, + purlSummary: i, + }; + return result; + }); + }) + .map((purl, index) => { + if (purl.purlSummary) { + const decomposedPurl = decomposePurl( + purl.purlSummary.purl, + ); + return ( + + + + + + + + + ); + } - return ( - - - - ); - })} - -
TypeNamespaceNameVersionPathQualifiers
{decomposedPurl?.type} - {decomposedPurl?.namespace} - - - {decomposedPurl?.name} - - {decomposedPurl?.version}{decomposedPurl?.path} - {decomposedPurl?.qualifiers && ( - - )} -
{decomposedPurl?.type}{decomposedPurl?.namespace} + + {decomposedPurl?.name} + + {decomposedPurl?.version}{decomposedPurl?.path} + {decomposedPurl?.qualifiers && ( + + )} +
- - {purl.parentName} - - -
- - ) : null} -
-
- - - - + return ( +
+ + {purl.parentName} + + +
+ ) : null} + + + + ) : null} + + ); + })} + + + +
+
); }; diff --git a/client/src/app/pages/sbom-list/sbom-toolbar.tsx b/client/src/app/pages/sbom-list/sbom-toolbar.tsx index 279c2a565..7c808ed88 100644 --- a/client/src/app/pages/sbom-list/sbom-toolbar.tsx +++ b/client/src/app/pages/sbom-list/sbom-toolbar.tsx @@ -24,19 +24,17 @@ export const SbomToolbar: React.FC = ({ showFilters }) => { } = tableControls; return ( - <> - - - {showFilters && } - - - - - - + + + {showFilters && } + + + + + ); }; diff --git a/client/src/app/pages/search/search-context.tsx b/client/src/app/pages/search/search-context.tsx index 12fa295c9..422b3d0e7 100644 --- a/client/src/app/pages/search/search-context.tsx +++ b/client/src/app/pages/search/search-context.tsx @@ -9,7 +9,7 @@ interface Provider { props?: Omit; } -// biome-ignore lint/suspicious/noExplicitAny: +// biome-ignore lint/suspicious/noExplicitAny: allowed function composeProviders>>( providers: TProviders, ): React.ComponentType { diff --git a/client/src/app/pages/upload/components/upload-file.tsx b/client/src/app/pages/upload/components/upload-file.tsx index 0150bbe5b..08fa8e49c 100644 --- a/client/src/app/pages/upload/components/upload-file.tsx +++ b/client/src/app/pages/upload/components/upload-file.tsx @@ -90,87 +90,85 @@ export const UploadFiles: React.FC = ({ ).length; return ( - <> - + } + titleText="Drag and drop files here" + titleTextSeparator="or" + infoText="Accepted file types: .json, .bz2" + /> + {showStatus && ( + + {Array.from(uploads.entries()).map(([file, upload], index) => ( + {}} + fileIcon={} + file={file} + key={`${file.name}-${index}`} + onClearClick={() => removeFiles([file])} + progressValue={upload.progress} + progressVariant={ + upload.error + ? "danger" + : upload.response + ? "success" + : undefined + } + progressHelperText={ + upload.error ? ( + + + {extractErrorMessage(upload.error)} + + + ) : upload.progress === 100 && !upload.response ? ( + + + + File uploaded. Waiting for the server to process it. + + + ) : upload.response ? ( + + + {extractSuccessMessage(upload.response)} + + + ) : undefined + } + /> + ))} + + )} + + 0} + aria-label="unsupported file upload attempted" + onClose={() => setRejectedFiles([])} + variant="small" > - } - titleText="Drag and drop files here" - titleTextSeparator="or" - infoText="Accepted file types: .json, .bz2" - /> - {showStatus && ( - - {Array.from(uploads.entries()).map(([file, upload], index) => ( - {}} - fileIcon={} - file={file} - key={`${file.name}-${index}`} - onClearClick={() => removeFiles([file])} - progressValue={upload.progress} - progressVariant={ - upload.error - ? "danger" - : upload.response - ? "success" - : undefined - } - progressHelperText={ - upload.error ? ( - - - {extractErrorMessage(upload.error)} - - - ) : upload.progress === 100 && !upload.response ? ( - - - - File uploaded. Waiting for the server to process it. - - - ) : upload.response ? ( - - - {extractSuccessMessage(upload.response)} - - - ) : undefined - } - /> + + + + {rejectedFiles.map((e) => ( + {e.file.name} ))} - - )} - - 0} - aria-label="unsupported file upload attempted" - onClose={() => setRejectedFiles([])} - variant="small" - > - - - - {rejectedFiles.map((e) => ( - {e.file.name} - ))} - - - - - + + + + ); }; diff --git a/client/src/app/pages/vulnerability-details/overview.tsx b/client/src/app/pages/vulnerability-details/overview.tsx index 60add7cf6..0b80a9b3f 100644 --- a/client/src/app/pages/vulnerability-details/overview.tsx +++ b/client/src/app/pages/vulnerability-details/overview.tsx @@ -23,87 +23,85 @@ interface OverviewProps { export const Overview: React.FC = ({ vulnerability }) => { return ( - <> - - - - - - - - - - - - - - - - + + + + + + - - - The date the Vulnerability identifier was assigned by - CVE Numbering Authority (CNA). - - } - > - - Reserved - - - - {formatDate(vulnerability.reserved)} + - - - The date the Vulnerability went public. - } - > - - Published - - - - - {formatDate(vulnerability.published)} - - - - - - The last date when information for this Vulnerability - was updated in the National Vulnerability Database - (NVD). - - } - > - - Modified - - - - - {formatDate(vulnerability.modified)} - - - - - - - - + + + + + + + + + The date the Vulnerability identifier was assigned by + CVE Numbering Authority (CNA). + + } + > + + Reserved + + + + + {formatDate(vulnerability.reserved)} + + + + + The date the Vulnerability went public. + } + > + + Published + + + + + {formatDate(vulnerability.published)} + + + + + + The last date when information for this Vulnerability + was updated in the National Vulnerability Database + (NVD). + + } + > + + Modified + + + + + {formatDate(vulnerability.modified)} + + + + + + + ); }; diff --git a/client/src/app/pages/vulnerability-details/sboms-by-vulnerability.tsx b/client/src/app/pages/vulnerability-details/sboms-by-vulnerability.tsx index ee58a546d..88cc8540c 100644 --- a/client/src/app/pages/vulnerability-details/sboms-by-vulnerability.tsx +++ b/client/src/app/pages/vulnerability-details/sboms-by-vulnerability.tsx @@ -62,7 +62,7 @@ export const SbomsByVulnerability: React.FC = ({ .reduce((prev, current) => { const existingElement = prev.find((e) => e.uuid === current.uuid); return existingElement ? prev : [...prev.slice(), current]; - }, new Array()) + }, [] as PurlSummary[]) .map((purlSummary) => { const decomposedPurl = decomposePurl(purlSummary.purl); const result: PurlData = { @@ -236,48 +236,46 @@ export const SbomsByVulnerability: React.FC = ({ > {isCellExpanded(item, "dependencies") ? ( - <> - - - - - - - - - - - - - {item.allUniquePackages.map((purl) => { - return ( - - - - - - - - - ); - })} - -
TypeNamespaceNameVersionPathQualifiers
{purl.decomposedPurl?.type}{purl.decomposedPurl?.namespace} - - {purl.decomposedPurl?.name} - - {purl.decomposedPurl?.version}{purl.decomposedPurl?.path} - {purl.decomposedPurl?.qualifiers && ( - - )} -
- + + + + + + + + + + + + + {item.allUniquePackages.map((purl) => { + return ( + + + + + + + + + ); + })} + +
TypeNamespaceNameVersionPathQualifiers
{purl.decomposedPurl?.type}{purl.decomposedPurl?.namespace} + + {purl.decomposedPurl?.name} + + {purl.decomposedPurl?.version}{purl.decomposedPurl?.path} + {purl.decomposedPurl?.qualifiers && ( + + )} +
) : null}
diff --git a/client/src/app/utils/utils.ts b/client/src/app/utils/utils.ts index 717c5be95..143ba7eda 100644 --- a/client/src/app/utils/utils.ts +++ b/client/src/app/utils/utils.ts @@ -8,7 +8,7 @@ import type { ToolbarLabel } from "@patternfly/react-core"; // Axios error -// biome-ignore lint/suspicious/noExplicitAny: +// biome-ignore lint/suspicious/noExplicitAny: allowed export const getAxiosErrorMessage = (axiosError: AxiosError) => { if (axiosError.response?.data?.errorMessage) { return axiosError.response.data.errorMessage; @@ -53,7 +53,7 @@ export const duplicateNameCheck = ( nameValue: T["name"], ) => duplicateFieldCheck("name", itemList, currentItem, nameValue); -// biome-ignore lint/suspicious/noExplicitAny: +// biome-ignore lint/suspicious/noExplicitAny: allowed export const dedupeFunction = (arr: any[]) => arr?.filter( (value, index, self) => @@ -135,9 +135,9 @@ export const getFilenameFromContentDisposition = ( * @param locale to be used by string compareFn */ export const universalComparator = ( - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed a: any, - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed b: any, locale: string, ) => localeNumericCompare(String(a ?? ""), String(b ?? ""), locale); diff --git a/client/types/@hookform_resolvers_2.9.11.d.ts b/client/types/@hookform_resolvers_2.9.11.d.ts index abdf7fa03..06b83d515 100644 --- a/client/types/@hookform_resolvers_2.9.11.d.ts +++ b/client/types/@hookform_resolvers_2.9.11.d.ts @@ -13,11 +13,11 @@ declare module "@hookform/resolvers/yup" { import type * as Yup from "yup"; import type Lazy from "yup/lib/Lazy"; - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed declare type Options> = Parameters< T["validate"] >[1]; - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed export declare type Resolver = >( schema: T, schemaOptions?: Options, diff --git a/client/types/array-filter-Boolean.ts b/client/types/array-filter-Boolean.ts index af9645170..37afb857b 100644 --- a/client/types/array-filter-Boolean.ts +++ b/client/types/array-filter-Boolean.ts @@ -15,6 +15,7 @@ /** See https://stackoverflow.com/a/51390763/1470607 */ type Falsy = false | 0 | "" | null | undefined; +// biome-ignore lint/correctness/noUnusedVariables: allowed interface Array { /** * Returns the elements of an array that meet the condition specified in a callback function. @@ -23,7 +24,7 @@ interface Array { */ filter( predicate: BooleanConstructor, - // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: allowed thisArg?: any, ): Exclude[]; } diff --git a/package-lock.json b/package-lock.json index 54551751e..940394844 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "http-proxy-middleware": "^2.0.6" }, "devDependencies": { - "@biomejs/biome": "^1.9.4", + "@biomejs/biome": "^2.0.6", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.0", @@ -611,11 +611,10 @@ "license": "MIT" }, "node_modules/@biomejs/biome": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", - "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.0.6.tgz", + "integrity": "sha512-RRP+9cdh5qwe2t0gORwXaa27oTOiQRQvrFf49x2PA1tnpsyU7FIHX4ZOFMtBC4QNtyWsN7Dqkf5EDbg4X+9iqA==", "dev": true, - "hasInstallScript": true, "license": "MIT OR Apache-2.0", "bin": { "biome": "bin/biome" @@ -628,20 +627,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.4", - "@biomejs/cli-darwin-x64": "1.9.4", - "@biomejs/cli-linux-arm64": "1.9.4", - "@biomejs/cli-linux-arm64-musl": "1.9.4", - "@biomejs/cli-linux-x64": "1.9.4", - "@biomejs/cli-linux-x64-musl": "1.9.4", - "@biomejs/cli-win32-arm64": "1.9.4", - "@biomejs/cli-win32-x64": "1.9.4" + "@biomejs/cli-darwin-arm64": "2.0.6", + "@biomejs/cli-darwin-x64": "2.0.6", + "@biomejs/cli-linux-arm64": "2.0.6", + "@biomejs/cli-linux-arm64-musl": "2.0.6", + "@biomejs/cli-linux-x64": "2.0.6", + "@biomejs/cli-linux-x64-musl": "2.0.6", + "@biomejs/cli-win32-arm64": "2.0.6", + "@biomejs/cli-win32-x64": "2.0.6" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.0.6.tgz", + "integrity": "sha512-AzdiNNjNzsE6LfqWyBvcL29uWoIuZUkndu+wwlXW13EKcBHbbKjNQEZIJKYDc6IL+p7bmWGx3v9ZtcRyIoIz5A==", "cpu": [ "arm64" ], @@ -656,9 +655,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.0.6.tgz", + "integrity": "sha512-wJjjP4E7bO4WJmiQaLnsdXMa516dbtC6542qeRkyJg0MqMXP0fvs4gdsHhZ7p9XWTAmGIjZHFKXdsjBvKGIJJQ==", "cpu": [ "x64" ], @@ -673,9 +672,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.0.6.tgz", + "integrity": "sha512-ZSVf6TYo5rNMUHIW1tww+rs/krol7U5A1Is/yzWyHVZguuB0lBnIodqyFuwCNqG9aJGyk7xIMS8HG0qGUPz0SA==", "cpu": [ "arm64" ], @@ -690,9 +689,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.6.tgz", + "integrity": "sha512-CVPEMlin3bW49sBqLBg2x016Pws7eUXA27XYDFlEtponD0luYjg2zQaMJ2nOqlkKG9fqzzkamdYxHdMDc2gZFw==", "cpu": [ "arm64" ], @@ -707,9 +706,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", - "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.0.6.tgz", + "integrity": "sha512-geM1MkHTV1Kh2Cs/Xzot9BOF3WBacihw6bkEmxkz4nSga8B9/hWy5BDiOG3gHDGIBa8WxT0nzsJs2f/hPqQIQw==", "cpu": [ "x64" ], @@ -724,9 +723,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", - "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.6.tgz", + "integrity": "sha512-mKHE/e954hR/hSnAcJSjkf4xGqZc/53Kh39HVW1EgO5iFi0JutTN07TSjEMg616julRtfSNJi0KNyxvc30Y4rQ==", "cpu": [ "x64" ], @@ -741,9 +740,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.0.6.tgz", + "integrity": "sha512-290V4oSFoKaprKE1zkYVsDfAdn0An5DowZ+GIABgjoq1ndhvNxkJcpxPsiYtT7slbVe3xmlT0ncdfOsN7KruzA==", "cpu": [ "arm64" ], @@ -758,9 +757,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", - "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.0.6.tgz", + "integrity": "sha512-bfM1Bce0d69Ao7pjTjUS+AWSZ02+5UHdiAP85Th8e9yV5xzw6JrHXbL5YWlcEKQ84FIZMdDc7ncuti1wd2sdbw==", "cpu": [ "x64" ], @@ -2222,9 +2221,9 @@ ] }, "node_modules/@rsbuild/core": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.4.1.tgz", - "integrity": "sha512-zNCfuTtQq3CyO1Hf5AaAHftdD/Py9j3grwGSsA5wUp1DR9GX4D3lCZGvc5xDnSQvEu+BADiN5wZ3HTn1HQNDkQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.4.2.tgz", + "integrity": "sha512-46rcBPYz2kIdDQ1en40yDRT7ZGOKUB0+NqeOAvMAg4DU7TCfgK1qJdmznVasagTWKN9RjjzNpy5encS6W7gUOQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index f9827b457..2658951a5 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "typescript": "~5.7.3" }, "devDependencies": { - "@biomejs/biome": "^1.9.4", + "@biomejs/biome": "^2.0.6", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.0",