Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions app/components/compare/FacetSelector.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<script setup lang="ts">
import type { ComparisonFacet } from '#shared/types'
import { FACET_INFO, FACETS_BY_CATEGORY, CATEGORY_ORDER } from '#shared/types/comparison'
import {
FACET_INFO,
FACETS_BY_CATEGORY,
CATEGORY_ORDER,
getFacetDescriptionKey,
getFacetLabelKey,
} from '#shared/types/comparison'

const { isFacetSelected, toggleFacet, selectCategory, deselectCategory } = useFacetSelection()

Expand Down Expand Up @@ -87,10 +93,12 @@ function isCategoryNoneSelected(category: string): boolean {
v-for="{ facet, info } in facetsByCategory[category]"
:key="facet"
type="button"
:title="info.comingSoon ? $t('compare.facets.coming_soon') : info.description"
:title="
info.comingSoon ? $t('compare.facets.coming_soon') : $t(getFacetDescriptionKey(facet))
"
:disabled="info.comingSoon"
:aria-pressed="isFacetSelected(facet)"
:aria-label="info.label"
:aria-label="$t(getFacetLabelKey(facet))"
class="inline-flex items-center gap-1 px-1.5 py-0.5 font-mono text-xs rounded border transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
:class="
info.comingSoon
Expand All @@ -107,7 +115,7 @@ function isCategoryNoneSelected(category: string): boolean {
:class="isFacetSelected(facet) ? 'i-carbon:checkmark' : 'i-carbon:add'"
aria-hidden="true"
/>
{{ info.label }}
{{ $t(getFacetLabelKey(facet)) }}
<span v-if="info.comingSoon" class="text-[9px]"
>({{ $t('compare.facets.coming_soon') }})</span
>
Expand Down
40 changes: 32 additions & 8 deletions app/composables/usePackageComparison.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ export interface PackageComparisonData {
* Composable for fetching and comparing multiple packages.
*
*/
export function usePackageComparison(packageNames: MaybeRefOrGetter<string[]>) {
export function usePackageComparison(
packageNames: MaybeRefOrGetter<string[]>,
t: (key: string, params?: Record<string, unknown>) => string = key => key,
) {
const packages = computed(() => toValue(packageNames))

// Cache of fetched data by package name (source of truth)
Expand Down Expand Up @@ -195,7 +198,7 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter<string[]>) {

return packagesData.value.map(pkg => {
if (!pkg) return null
return computeFacetValue(facet, pkg)
return computeFacetValue(facet, pkg, t)
})
}

Expand Down Expand Up @@ -229,7 +232,11 @@ function encodePackageName(name: string): string {
return encodeURIComponent(name)
}

function computeFacetValue(facet: ComparisonFacet, data: PackageComparisonData): FacetValue | null {
function computeFacetValue(
facet: ComparisonFacet,
data: PackageComparisonData,
t: (key: string, params?: Record<string, unknown>) => string,
): FacetValue | null {
switch (facet) {
case 'downloads':
if (data.downloads === undefined) return null
Expand Down Expand Up @@ -270,13 +277,19 @@ function computeFacetValue(facet: ComparisonFacet, data: PackageComparisonData):
return {
raw: types.kind,
display:
types.kind === 'included' ? 'Included' : types.kind === '@types' ? '@types' : 'None',
types.kind === 'included'
? t('compare.facets.values.types_included')
: types.kind === '@types'
? '@types'
: t('compare.facets.values.types_none'),
status: types.kind === 'included' ? 'good' : types.kind === '@types' ? 'info' : 'bad',
}

case 'engines':
const engines = data.metadata?.engines
if (!engines?.node) return { raw: null, display: 'Any', status: 'neutral' }
if (!engines?.node) {
return { raw: null, display: t('compare.facets.values.any'), status: 'neutral' }
}
return {
raw: engines.node,
display: `Node ${engines.node}`,
Expand All @@ -289,7 +302,14 @@ function computeFacetValue(facet: ComparisonFacet, data: PackageComparisonData):
const sev = data.vulnerabilities.severity
return {
raw: count,
display: count === 0 ? 'None' : `${count} (${sev.critical}C/${sev.high}H)`,
display:
count === 0
? t('compare.facets.values.none')
: t('compare.facets.values.vulnerabilities_summary', {
count,
critical: sev.critical,
high: sev.high,
}),
status: count === 0 ? 'good' : sev.critical > 0 || sev.high > 0 ? 'bad' : 'warning',
}

Expand All @@ -305,7 +325,9 @@ function computeFacetValue(facet: ComparisonFacet, data: PackageComparisonData):

case 'license':
const license = data.metadata?.license
if (!license) return { raw: null, display: 'Unknown', status: 'warning' }
if (!license) {
return { raw: null, display: t('compare.facets.values.unknown'), status: 'warning' }
}
return {
raw: license,
display: license,
Expand All @@ -325,7 +347,9 @@ function computeFacetValue(facet: ComparisonFacet, data: PackageComparisonData):
const isDeprecated = !!data.metadata?.deprecated
return {
raw: isDeprecated,
display: isDeprecated ? 'Deprecated' : 'No',
display: isDeprecated
? t('compare.facets.values.deprecated')
: t('compare.facets.values.not_deprecated'),
status: isDeprecated ? 'bad' : 'good',
}

Expand Down
60 changes: 60 additions & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,66 @@
"health": "Health",
"compatibility": "Compatibility",
"security": "Security & Compliance"
},
"items": {
"packageSize": {
"label": "Package Size",
"description": "Size of the package itself (unpacked)"
},
"installSize": {
"label": "Install Size",
"description": "Total install size including all dependencies"
},
"dependencies": {
"label": "# Direct Deps",
"description": "Number of direct dependencies"
},
"totalDependencies": {
"label": "# Total Deps",
"description": "Total number of dependencies including transitive"
},
"downloads": {
"label": "Downloads/wk",
"description": "Weekly download count"
},
"lastUpdated": {
"label": "Last Updated",
"description": "Most recent publish date"
},
"deprecated": {
"label": "Deprecated?",
"description": "Whether the package is deprecated"
},
"engines": {
"label": "Engines",
"description": "Node.js version requirements"
},
"types": {
"label": "Types",
"description": "TypeScript type definitions"
},
"moduleFormat": {
"label": "Module Format",
"description": "ESM/CJS support"
},
"license": {
"label": "License",
"description": "Package license"
},
"vulnerabilities": {
"label": "Vulnerabilities",
"description": "Known security vulnerabilities"
}
},
"values": {
"any": "Any",
"none": "None",
"unknown": "Unknown",
"deprecated": "Deprecated",
"not_deprecated": "No",
"types_included": "Included",
"types_none": "None",
"vulnerabilities_summary": "{count} ({critical}C/{high}H)"
}
}
}
Expand Down
62 changes: 61 additions & 1 deletion i18n/locales/pl-PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@
"cjs": "Obsługuje CommonJS",
"no_esm": "Brak obsługi ES Modules",
"types_label": "Typy",
"types_included": "Typy w pakiecie",
"types_included": "Typy wbudowane",
"types_available": "Typy dostępne przez {package}",
"no_types": "Brak typów TypeScript"
},
Expand Down Expand Up @@ -837,6 +837,66 @@
"health": "Zdrowie",
"compatibility": "Kompatybilność",
"security": "Bezpieczeństwo i zgodność"
},
"items": {
"packageSize": {
"label": "Rozmiar pakietu",
"description": "Rozmiar samego pakietu (rozpakowany)"
},
"installSize": {
"label": "Rozmiar instalacji",
"description": "Łączny rozmiar instalacji wraz ze wszystkimi zależnościami"
},
"dependencies": {
"label": "Bezpośrednie zależności",
"description": "Liczba bezpośrednich zależności"
},
"totalDependencies": {
"label": "# Wszystkich zależności",
"description": "Łączna liczba zależności, w tym przechodnich"
},
"downloads": {
"label": "Pobrania/tydz.",
"description": "Tygodniowa liczba pobrań"
},
"lastUpdated": {
"label": "Ostatnia aktualizacja",
"description": "Data ostatniego wydania"
},
"deprecated": {
"label": "Wycofany?",
"description": "Czy pakiet jest wycofany"
},
"engines": {
"label": "Silniki",
"description": "Wymagania wersji Node.js"
},
"types": {
"label": "Typy",
"description": "Definicje typów TypeScript"
},
"moduleFormat": {
"label": "Format modułu",
"description": "Obsługa ESM/CJS"
},
"license": {
"label": "Licencja",
"description": "Licencja pakietu"
},
"vulnerabilities": {
"label": "Podatności",
"description": "Znane luki bezpieczeństwa"
}
},
"values": {
"any": "Dowolne",
"none": "Brak",
"unknown": "Nieznana",
"deprecated": "Wycofany",
"not_deprecated": "Nie",
"types_included": "Wbudowane",
"types_none": "Brak",
"vulnerabilities_summary": "{count} ({critical}K/{high}W)"
}
}
}
Expand Down
60 changes: 60 additions & 0 deletions lunaria/files/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,66 @@
"health": "Health",
"compatibility": "Compatibility",
"security": "Security & Compliance"
},
"items": {
"packageSize": {
"label": "Package Size",
"description": "Size of the package itself (unpacked)"
},
"installSize": {
"label": "Install Size",
"description": "Total install size including all dependencies"
},
"dependencies": {
"label": "# Direct Deps",
"description": "Number of direct dependencies"
},
"totalDependencies": {
"label": "# Total Deps",
"description": "Total number of dependencies including transitive"
},
"downloads": {
"label": "Downloads/wk",
"description": "Weekly download count"
},
"lastUpdated": {
"label": "Last Updated",
"description": "Most recent publish date"
},
"deprecated": {
"label": "Deprecated?",
"description": "Whether the package is deprecated"
},
"engines": {
"label": "Engines",
"description": "Node.js version requirements"
},
"types": {
"label": "Types",
"description": "TypeScript type definitions"
},
"moduleFormat": {
"label": "Module Format",
"description": "ESM/CJS support"
},
"license": {
"label": "License",
"description": "Package license"
},
"vulnerabilities": {
"label": "Vulnerabilities",
"description": "Known security vulnerabilities"
}
},
"values": {
"any": "Any",
"none": "None",
"unknown": "Unknown",
"deprecated": "Deprecated",
"not_deprecated": "No",
"types_included": "Included",
"types_none": "None",
"vulnerabilities_summary": "{count} ({critical}C/{high}H)"
}
}
}
Expand Down
Loading
Loading