Skip to content

Commit 483b7b2

Browse files
authored
Merge branch 'main' into lino/add-module-replacements
2 parents 4304d53 + e824aa1 commit 483b7b2

51 files changed

Lines changed: 1191 additions & 253 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ npmx.dev uses [@nuxtjs/i18n](https://i18n.nuxtjs.org/) for internationalization.
242242
### Approach
243243

244244
- All user-facing strings should use translation keys via `$t()` in templates and script
245-
- Translation files live in `i18n/locales/` (e.g., `en-US.json`)
245+
- Translation files live in [`i18n/locales/`](i18n/locales) (e.g., `en-US.json`)
246246
- We use the `no_prefix` strategy (no `/en-US/` or `/fr-FR/` in URLs)
247247
- Locale preference is stored in cookies and respected on subsequent visits
248248

app/assets/main.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ html.light .shiki span {
281281
white-space: pre;
282282
word-break: normal;
283283
overflow-wrap: normal;
284+
/* Makes unicode and ascii art work properly */
285+
line-height: 1.25;
286+
display: inline-block;
284287
}
285288

286289
.readme-content ul,

app/components/AppFooter.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<template>
22
<footer class="border-t border-border mt-auto">
33
<div class="container py-3 sm:py-8 flex flex-col gap-2 sm:gap-4 text-fg-subtle text-sm">
4-
<div class="flex flex-col sm:flex-row items-center justify-start gap-2 sm:gap-4">
5-
<p class="font-mono m-0 hidden sm:block">{{ $t('tagline') }}</p>
4+
<div
5+
class="flex flex-col sm:flex-row items-center sm:items-baseline justify-start gap-2 sm:gap-4"
6+
>
7+
<p class="font-mono text-balance m-0 hidden sm:block">{{ $t('tagline') }}</p>
68
<span aria-hidden="true" class="flex-shrink-1 flex-grow-1" />
79
<div class="flex items-center justify-start gap-3 sm:gap-6">
810
<NuxtLink

app/components/PackageDependencies.vue

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { useVulnerabilityTree } from '~/composables/useVulnerabilityTree'
2+
import { useDependencyAnalysis } from '~/composables/useDependencyAnalysis'
33
import { SEVERITY_TEXT_COLORS, getHighestSeverity } from '#shared/utils/severity'
44
55
const props = defineProps<{
@@ -15,7 +15,7 @@ const props = defineProps<{
1515
const outdatedDeps = useOutdatedDependencies(() => props.dependencies)
1616
1717
// Get vulnerability info from shared cache (already fetched by PackageVulnerabilityTree)
18-
const { data: vulnTree } = useVulnerabilityTree(
18+
const { data: vulnTree } = useDependencyAnalysis(
1919
() => props.packageName,
2020
() => props.version,
2121
)
@@ -26,6 +26,12 @@ function getVulnerableDepInfo(depName: string) {
2626
return vulnTree.value.vulnerablePackages.find(p => p.name === depName && p.depth === 'direct')
2727
}
2828
29+
// Check if a dependency is deprecated (only direct deps)
30+
function getDeprecatedDepInfo(depName: string) {
31+
if (!vulnTree.value) return null
32+
return vulnTree.value.deprecatedPackages.find(p => p.name === depName && p.depth === 'direct')
33+
}
34+
2935
// Expanded state for each section
3036
const depsExpanded = shallowRef(false)
3137
const peerDepsExpanded = shallowRef(false)
@@ -120,6 +126,18 @@ const sortedOptionalDependencies = computed(() => {
120126
<span class="i-carbon-security w-3 h-3 block" aria-hidden="true" />
121127
<span class="sr-only">{{ $t('package.dependencies.view_vulnerabilities') }}</span>
122128
</NuxtLink>
129+
<NuxtLink
130+
v-if="getDeprecatedDepInfo(dep)"
131+
:to="{
132+
name: 'package',
133+
params: { package: [...dep.split('/'), 'v', getDeprecatedDepInfo(dep)!.version] },
134+
}"
135+
class="shrink-0 text-purple-500"
136+
:title="getDeprecatedDepInfo(dep)!.message"
137+
>
138+
<span class="i-carbon-warning-hex w-3 h-3 block" aria-hidden="true" />
139+
<span class="sr-only">{{ $t('package.deprecated.label') }}</span>
140+
</NuxtLink>
123141
<NuxtLink
124142
:to="{ name: 'package', params: { package: [...dep.split('/'), 'v', version] } }"
125143
class="font-mono text-xs text-right truncate"
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<script setup lang="ts">
2+
import type { DependencyDepth } from '#shared/types'
3+
4+
const props = defineProps<{
5+
packageName: string
6+
version: string
7+
}>()
8+
9+
const { data: analysisData, status } = useDependencyAnalysis(
10+
() => props.packageName,
11+
() => props.version,
12+
)
13+
14+
const isExpanded = shallowRef(false)
15+
const showAll = shallowRef(false)
16+
17+
const hasDeprecated = computed(
18+
() => analysisData.value && analysisData.value.deprecatedPackages.length > 0,
19+
)
20+
21+
// Banner color - purple for deprecated
22+
const bannerColor = 'border-purple-600/40 bg-purple-500/10 text-purple-700 dark:text-purple-400'
23+
24+
// Styling for each depth level
25+
const depthStyles = {
26+
root: {
27+
bg: 'bg-purple-500/5 border-l-2 border-l-purple-600',
28+
text: 'text-fg',
29+
},
30+
direct: {
31+
bg: 'bg-purple-500/5 border-l-2 border-l-purple-500',
32+
text: 'text-fg-muted',
33+
},
34+
transitive: {
35+
bg: 'bg-purple-500/5 border-l-2 border-l-purple-400',
36+
text: 'text-fg-muted',
37+
},
38+
} as const
39+
40+
function getDepthStyle(depth: DependencyDepth) {
41+
return depthStyles[depth] || depthStyles.transitive
42+
}
43+
</script>
44+
45+
<template>
46+
<section
47+
v-if="status === 'success' && hasDeprecated"
48+
aria-labelledby="deprecated-tree-heading"
49+
class="relative"
50+
>
51+
<div class="rounded-lg border overflow-hidden" :class="bannerColor">
52+
<!-- Header -->
53+
<button
54+
type="button"
55+
class="w-full flex items-center justify-between gap-3 px-4 py-3 text-left transition-colors duration-200 hover:bg-white/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-fg/50"
56+
:aria-expanded="isExpanded"
57+
aria-controls="deprecated-tree-details"
58+
@click="isExpanded = !isExpanded"
59+
>
60+
<div class="flex items-center gap-2 min-w-0">
61+
<span class="i-carbon-warning-hex w-4 h-4 shrink-0" aria-hidden="true" />
62+
<span class="font-mono text-sm font-medium truncate">
63+
{{ $t('package.deprecated.tree_found', analysisData!.deprecatedPackages.length) }}
64+
</span>
65+
</div>
66+
<span
67+
class="i-carbon-chevron-down w-4 h-4 transition-transform duration-200 shrink-0"
68+
:class="{ 'rotate-180': isExpanded }"
69+
aria-hidden="true"
70+
/>
71+
</button>
72+
73+
<!-- Expandable details -->
74+
<div
75+
v-show="isExpanded"
76+
id="deprecated-tree-details"
77+
class="border-t border-border bg-bg-subtle"
78+
>
79+
<ul class="divide-y divide-border list-none m-0 p-0">
80+
<li
81+
v-for="pkg in analysisData!.deprecatedPackages.slice(0, showAll ? undefined : 5)"
82+
:key="`${pkg.name}@${pkg.version}`"
83+
class="px-4 py-3"
84+
:class="getDepthStyle(pkg.depth).bg"
85+
>
86+
<div class="flex items-center gap-2 mb-1">
87+
<!-- Path badge -->
88+
<DependencyPathPopup v-if="pkg.path && pkg.path.length > 1" :path="pkg.path" />
89+
90+
<NuxtLink
91+
:to="{
92+
name: 'package',
93+
params: { package: [...pkg.name.split('/'), 'v', pkg.version] },
94+
}"
95+
class="font-mono text-sm font-medium hover:underline truncate"
96+
:class="getDepthStyle(pkg.depth).text"
97+
>
98+
{{ pkg.name }}@{{ pkg.version }}
99+
</NuxtLink>
100+
</div>
101+
<p class="text-xs text-fg-muted m-0 line-clamp-2">
102+
{{ pkg.message }}
103+
</p>
104+
</li>
105+
</ul>
106+
107+
<button
108+
v-if="analysisData!.deprecatedPackages.length > 5 && !showAll"
109+
type="button"
110+
class="w-full px-4 py-2 text-xs font-mono text-fg-muted hover:text-fg border-t border-border transition-colors duration-200"
111+
@click="showAll = true"
112+
>
113+
{{
114+
$t('package.deprecated.show_all', { count: analysisData!.deprecatedPackages.length })
115+
}}
116+
</button>
117+
</div>
118+
</div>
119+
</section>
120+
</template>

app/components/PackageDownloadAnalytics.vue

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ const config = computed(() => {
619619
<div
620620
class="flex items-center gap-2 px-2.5 py-1.75 bg-bg-subtle border border-border rounded-md focus-within:(border-border-hover ring-2 ring-accent/30)"
621621
>
622-
<span class="i-carbon-calendar w-4 h-4 text-fg-subtle shrink-0" aria-hidden="true" />
622+
<span class="i-carbon:calendar w-4 h-4 text-fg-subtle shrink-0" aria-hidden="true" />
623623
<input
624624
id="startDate"
625625
v-model="startDate"
@@ -639,7 +639,7 @@ const config = computed(() => {
639639
<div
640640
class="flex items-center gap-2 px-2.5 py-1.75 bg-bg-subtle border border-border rounded-md focus-within:(border-border-hover ring-2 ring-accent/30)"
641641
>
642-
<span class="i-carbon-calendar w-4 h-4 text-fg-subtle shrink-0" aria-hidden="true" />
642+
<span class="i-carbon:calendar w-4 h-4 text-fg-subtle shrink-0" aria-hidden="true" />
643643
<input
644644
id="endDate"
645645
v-model="endDate"
@@ -666,80 +666,80 @@ const config = computed(() => {
666666
}
667667
"
668668
>
669-
<span class="i-carbon-reset w-5 h-5 inline-block" aria-hidden="true" />
669+
<span class="i-carbon:reset w-5 h-5 inline-block" aria-hidden="true" />
670670
</button>
671671
</div>
672672
</div>
673673

674674
<ClientOnly v-if="inModal && chartData.dataset">
675675
<VueUiXy :dataset="chartData.dataset" :config="config">
676676
<template #menuIcon="{ isOpen }">
677-
<span v-if="isOpen" class="i-carbon-close w-6 h-6" aria-hidden="true" />
678-
<span v-else class="i-carbon-overflow-menu-vertical w-6 h-6" aria-hidden="true" />
677+
<span v-if="isOpen" class="i-carbon:close w-6 h-6" aria-hidden="true" />
678+
<span v-else class="i-carbon:overflow-menu-vertical w-6 h-6" aria-hidden="true" />
679679
</template>
680680
<template #optionCsv>
681681
<span
682-
class="i-carbon-csv w-6 h-6 text-fg-subtle"
682+
class="i-carbon:csv w-6 h-6 text-fg-subtle"
683683
style="pointer-events: none"
684684
aria-hidden="true"
685685
/>
686686
</template>
687687
<template #optionImg>
688688
<span
689-
class="i-carbon-png w-6 h-6 text-fg-subtle"
689+
class="i-carbon:png w-6 h-6 text-fg-subtle"
690690
style="pointer-events: none"
691691
aria-hidden="true"
692692
/>
693693
</template>
694694
<template #optionSvg>
695695
<span
696-
class="i-carbon-svg w-6 h-6 text-fg-subtle"
696+
class="i-carbon:svg w-6 h-6 text-fg-subtle"
697697
style="pointer-events: none"
698698
aria-hidden="true"
699699
/>
700700
</template>
701701

702702
<template #annotator-action-close>
703703
<span
704-
class="i-carbon-close w-6 h-6 text-fg-subtle"
704+
class="i-carbon:close w-6 h-6 text-fg-subtle"
705705
style="pointer-events: none"
706706
aria-hidden="true"
707707
/>
708708
</template>
709709
<template #annotator-action-color="{ color }">
710-
<span class="i-carbon-color-palette w-6 h-6" :style="{ color }" aria-hidden="true" />
710+
<span class="i-carbon:color-palette w-6 h-6" :style="{ color }" aria-hidden="true" />
711711
</template>
712712
<template #annotator-action-undo>
713713
<span
714-
class="i-carbon-undo w-6 h-6 text-fg-subtle"
714+
class="i-carbon:undo w-6 h-6 text-fg-subtle"
715715
style="pointer-events: none"
716716
aria-hidden="true"
717717
/>
718718
</template>
719719
<template #annotator-action-redo>
720720
<span
721-
class="i-carbon-redo w-6 h-6 text-fg-subtle"
721+
class="i-carbon:redo w-6 h-6 text-fg-subtle"
722722
style="pointer-events: none"
723723
aria-hidden="true"
724724
/>
725725
</template>
726726
<template #annotator-action-delete>
727727
<span
728-
class="i-carbon-trash-can w-6 h-6 text-fg-subtle"
728+
class="i-carbon:trash-can w-6 h-6 text-fg-subtle"
729729
style="pointer-events: none"
730730
aria-hidden="true"
731731
/>
732732
</template>
733733
<template #optionAnnotator="{ isAnnotator }">
734734
<span
735735
v-if="isAnnotator"
736-
class="i-carbon-edit-off w-6 h-6 text-fg-subtle"
736+
class="i-carbon:edit-off w-6 h-6 text-fg-subtle"
737737
style="pointer-events: none"
738738
aria-hidden="true"
739739
/>
740740
<span
741741
v-else
742-
class="i-carbon-edit w-6 h-6 text-fg-subtle"
742+
class="i-carbon:edit w-6 h-6 text-fg-subtle"
743743
style="pointer-events: none"
744744
aria-hidden="true"
745745
/>
@@ -762,7 +762,7 @@ const config = computed(() => {
762762
v-if="pending"
763763
role="status"
764764
aria-live="polite"
765-
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-xs text-fg-subtle font-mono bg-bg/70 backdrop-blur px-3 py-2 rounded-md border border-border"
765+
class="absolute top-1/2 inset-is-1/2 -translate-x-1/2 -translate-y-1/2 text-xs text-fg-subtle font-mono bg-bg/70 backdrop-blur px-3 py-2 rounded-md border border-border"
766766
>
767767
{{ $t('package.downloads.loading') }}
768768
</div>

app/components/PackageInstallScripts.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const isExpanded = shallowRef(false)
2323
id="install-scripts-heading"
2424
class="text-xs text-fg-subtle uppercase tracking-wider mb-3 flex items-center gap-2"
2525
>
26-
<span class="i-carbon-warning-alt w-3 h-3 text-yellow-500" aria-hidden="true" />
26+
<span class="i-carbon:warning-alt w-3 h-3 text-yellow-500" aria-hidden="true" />
2727
{{ $t('package.install_scripts.title') }}
2828
</h2>
2929

@@ -51,7 +51,7 @@ const isExpanded = shallowRef(false)
5151
@click="isExpanded = !isExpanded"
5252
>
5353
<span
54-
class="i-carbon-chevron-right w-3 h-3 transition-transform duration-200"
54+
class="i-carbon:chevron-right rtl-flip w-3 h-3 transition-transform duration-200"
5555
:class="{ 'rotate-90': isExpanded }"
5656
aria-hidden="true"
5757
/>
@@ -67,7 +67,7 @@ const isExpanded = shallowRef(false)
6767
<ul
6868
v-show="isExpanded"
6969
id="npx-packages-details"
70-
class="mt-2 space-y-1 list-none m-0 p-0 pl-4"
70+
class="mt-2 space-y-1 list-none m-0 p-0 ps-4"
7171
>
7272
<li
7373
v-for="[dep, version] in sortedNpxDeps"
@@ -91,10 +91,10 @@ const isExpanded = shallowRef(false)
9191
:title="getOutdatedTooltip(outdatedNpxDeps[dep])"
9292
aria-hidden="true"
9393
>
94-
<span class="i-carbon-warning-alt w-3 h-3 block" />
94+
<span class="i-carbon:warning-alt w-3 h-3 block" />
9595
</span>
9696
<span
97-
class="font-mono text-xs text-right truncate"
97+
class="font-mono text-xs text-end truncate"
9898
:class="getVersionClass(outdatedNpxDeps[dep])"
9999
:title="
100100
outdatedNpxDeps[dep]

0 commit comments

Comments
 (0)