diff --git a/app/components/BaseCard.vue b/app/components/BaseCard.vue index 2eb7f348bd..8bb4e95b7c 100644 --- a/app/components/BaseCard.vue +++ b/app/components/BaseCard.vue @@ -8,7 +8,7 @@ defineProps<{ diff --git a/app/components/Package/Dependencies.vue b/app/components/Package/Dependencies.vue deleted file mode 100644 index 649bfb34a5..0000000000 --- a/app/components/Package/Dependencies.vue +++ /dev/null @@ -1,334 +0,0 @@ - - - diff --git a/app/components/Package/Header.vue b/app/components/Package/Header.vue index e01e0dc03b..04707471a3 100644 --- a/app/components/Package/Header.vue +++ b/app/components/Package/Header.vue @@ -10,7 +10,7 @@ const props = defineProps<{ latestVersion?: SlimVersion | null provenanceData?: ProvenanceDetails | null provenanceStatus?: string | null - page: 'main' | 'docs' | 'code' | 'diff' | 'changelog' | 'timeline' | 'stats' + page: 'main' | 'docs' | 'code' | 'dependencies' | 'diff' | 'changelog' | 'timeline' | 'stats' versionUrlPattern: string }>() @@ -154,6 +154,13 @@ const codeLink = computed((): RouteLocationRaw | null => { } }) +const dependenciesLink = computed((): RouteLocationRaw | null => { + if (props.pkg == null || props.resolvedVersion == null) { + return null + } + return dependenciesRoute(props.pkg.name, props.resolvedVersion) +}) + const mainLink = computed((): RouteLocationRaw | null => { if (props.pkg == null || props.resolvedVersion == null) { return null @@ -209,6 +216,7 @@ useShortcuts({ '-': () => changelogLink.value, 't': () => timelineLink.value, 's': () => statsLink.value, + 'y': () => dependenciesLink.value, }) @@ -372,6 +380,15 @@ useShortcuts({ > {{ $t('package.links.code') }} + + {{ $t('package.links.dependencies') }} + -import { getOutdatedTooltip, getVersionClass } from '~/utils/npm/outdated-dependencies' +import { getOutdatedTooltip, getVersionClass } from '~/utils/npm/problematic-dependencies' +import { normalizeDependencies } from '~/utils/npm/package-dependency-sections' import type { RouteLocationRaw } from 'vue-router' const props = defineProps<{ @@ -48,12 +49,25 @@ const scriptParts = computed(() => { return parts }) -const outdatedNpxDeps = useOutdatedDependencies(() => props.installScripts.npxDependencies) +const { data: outdatedNpxDeps } = useOutdatedDependencies(() => + normalizeDependencies(props.installScripts.npxDependencies), +) +// const { data: replacementNpxDeps } = useReplacementDependencies( +// () => props.installScripts.npxDependencies, +// ) +const replacementNpxDeps = Object.create(null) + const hasNpxDeps = computed(() => Object.keys(props.installScripts.npxDependencies).length > 0) const sortedNpxDeps = computed(() => { return Object.entries(props.installScripts.npxDependencies).sort(([a], [b]) => a.localeCompare(b)) }) +const versionClass = (dep: string) => + getVersionClass(dep, { + outdatedDeps: ref(outdatedNpxDeps), + replacementDeps: ref(replacementNpxDeps), + }) + const isExpanded = shallowRef(false) @@ -135,7 +149,7 @@ const isExpanded = shallowRef(false) outdatedNpxDeps[dep].resolved !== outdatedNpxDeps[dep].latest " class="shrink-0 p-2 -m-2" - :class="getVersionClass(outdatedNpxDeps[dep])" + :class="versionClass(dep)" aria-hidden="true" :text="getOutdatedTooltip(outdatedNpxDeps[dep], $t)" > @@ -143,7 +157,7 @@ const isExpanded = shallowRef(false) +import type { PackageDependencyInsights } from '~/composables/usePackageDependencyInsights' import { WindowVirtualizer } from 'virtua/vue' /** Number of items to render statically during SSR */ @@ -7,6 +8,8 @@ const SSR_COUNT = 20 const props = defineProps<{ /** List of search results to display */ results: NpmSearchResult[] + /** Optional pre-computed insights to avoid duplicate fetching/processing */ + insights?: PackageDependencyInsights /** Filters to apply to the results */ filters?: StructuredFilters /** Heading level for package names */ @@ -138,6 +141,13 @@ watch( }, ) +/** + * Preserves the optional pre-computed `props.insights` override. + * When `props.insights` is undefined, child components (`PackageCard` and `PackageTableRow`) + * fall back to computing dependency insights scoped to their own result's package name and version. + */ +const insights = computed(() => props.insights) + function scrollToIndex(index: number, smooth = true) { listRef.value?.scrollToIndex(index, { align: 'center', smooth }) } @@ -157,6 +167,7 @@ defineExpose({ :columns="columns" v-model:sort-option="sortOption" :is-loading="isLoading" + :insights="insights" @click-keyword="emit('clickKeyword', $event)" /> @@ -193,6 +204,7 @@ defineExpose({ : {} " :filters="filters" + :insights="insights" @click-keyword="emit('clickKeyword', $event)" /> @@ -211,6 +223,7 @@ defineExpose({ :index="index" :search-query="searchQuery" :filters="filters" + :insights="insights" @click-keyword="emit('clickKeyword', $event)" /> @@ -252,6 +265,7 @@ defineExpose({ : {} " :filters="filters" + :insights="insights" @click-keyword="emit('clickKeyword', $event)" /> diff --git a/app/components/Package/Table.vue b/app/components/Package/Table.vue index 9bba226cee..9aac1c55e3 100644 --- a/app/components/Package/Table.vue +++ b/app/components/Package/Table.vue @@ -9,11 +9,14 @@ import type { } from '#shared/types/preferences' import { buildSortOption, parseSortOption, toggleDirection } from '#shared/types/preferences' +import type { PackageDependencyInsights } from '~/composables/usePackageDependencyInsights' + const props = defineProps<{ results: NpmSearchResult[] columns: ColumnConfig[] filters?: StructuredFilters isLoading?: boolean + insights?: PackageDependencyInsights }>() const { t } = useI18n() @@ -101,7 +104,7 @@ const { selectable } = usePackageSelectionContext() diff --git a/app/components/Package/TableRow.vue b/app/components/Package/TableRow.vue index 42fe4b62b0..2727ffa890 100644 --- a/app/components/Package/TableRow.vue +++ b/app/components/Package/TableRow.vue @@ -1,12 +1,21 @@ + + diff --git a/app/pages/package-stats/[[org]]/[packageName].vue b/app/pages/package-stats/[[org]]/[packageName].vue index d9fa54ef1f..ba91bfeaa8 100644 --- a/app/pages/package-stats/[[org]]/[packageName].vue +++ b/app/pages/package-stats/[[org]]/[packageName].vue @@ -1,4 +1,9 @@