diff --git a/.github/workflows/deploy-canary.yml b/.github/workflows/deploy-canary.yml index 75e32ca7f2..43d5f6f57d 100644 --- a/.github/workflows/deploy-canary.yml +++ b/.github/workflows/deploy-canary.yml @@ -33,6 +33,12 @@ jobs: # Version of the underlying sfw to use (no `v` prefix): https://github.com/SocketDev/sfw-free/releases firewall-version: 1.12.0 + # Lunaria needs the full git history, but `vercel deploy` uploads the source without `.git`, + # so generate `dist/lunaria/status.json` here and upload it with the source instead. + # https://github.com/npmx-dev/npmx.dev/issues/2785 + - run: sfw vp install --filter . --ignore-scripts + - run: vp run build:lunaria + - run: sfw vp i -g vercel@54.12.2 - run: vercel deploy --target=canary env: diff --git a/.github/workflows/enforce-release-source.yml b/.github/workflows/enforce-release-source.yml index 6d90c30374..d631c32dd5 100644 --- a/.github/workflows/enforce-release-source.yml +++ b/.github/workflows/enforce-release-source.yml @@ -10,10 +10,6 @@ on: - synchronize - edited -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: false - permissions: {} jobs: diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 8a706714bf..de28fe2da1 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -5,6 +5,12 @@ rules: ignore: # lunariajs/action has no tag refs; keep the branch commit hash-pinned. - lunaria.yml:40 + concurrency-limits: + ignore: + # Stateless, idempotent check. Concurrency groups cancel superseded pending + # runs even with `cancel-in-progress: false`, which would leave a failed + # check on the release PR's head commit (`main`). + - enforce-release-source.yml dangerous-triggers: ignore: - enforce-release-source.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f60c45b03..282108089b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -689,7 +689,7 @@ Use vue-i18n's built-in formatters for locale-aware formatting: Write unit tests for core functionality using Vitest: ```typescript -import { describe, it, expect } from 'vitest' +import { describe, it, expect } from 'vite-plus/test' describe('featureName', () => { it('should handle expected case', () => { diff --git a/app/assets/main.css b/app/assets/main.css index bb6b830399..bce110f018 100644 --- a/app/assets/main.css +++ b/app/assets/main.css @@ -395,3 +395,9 @@ html:has(dialog:modal) { overflow: hidden; scrollbar-gutter: stable; } + +/* Match main annotator toolbar backdrop when group buttons are disabled + Override the background color set by vue-data-ui */ +.vue-ui-pen-and-paper-group-actions { + background-color: transparent !important; +} diff --git a/app/components/Changelog/ErrorMsg.vue b/app/components/Changelog/ErrorMsg.vue index 901e846696..f7a54aade2 100644 --- a/app/components/Changelog/ErrorMsg.vue +++ b/app/components/Changelog/ErrorMsg.vue @@ -1,16 +1,31 @@ diff --git a/app/components/Changelog/Releases.vue b/app/components/Changelog/Releases.vue index 0d0388ccd1..e865f98700 100644 --- a/app/components/Changelog/Releases.vue +++ b/app/components/Changelog/Releases.vue @@ -96,5 +96,5 @@ prefetchComponents('ChangelogCard') :host="info.host" /> - + diff --git a/app/components/Chart/AnnotatorIcon.vue b/app/components/Chart/AnnotatorIcon.vue new file mode 100644 index 0000000000..84ce04d38a --- /dev/null +++ b/app/components/Chart/AnnotatorIcon.vue @@ -0,0 +1,21 @@ + + + diff --git a/app/components/Chart/FullscreenIcon.vue b/app/components/Chart/FullscreenIcon.vue new file mode 100644 index 0000000000..49a1ce9287 --- /dev/null +++ b/app/components/Chart/FullscreenIcon.vue @@ -0,0 +1,13 @@ + + + diff --git a/app/components/CollapsibleSection.vue b/app/components/CollapsibleSection.vue index c267d6a80b..67f11bf6e4 100644 --- a/app/components/CollapsibleSection.vue +++ b/app/components/CollapsibleSection.vue @@ -1,6 +1,5 @@ - + {{ pkg }} { id="package-search" v-model="inputValue" type="text" + :aria-describedby="versionHintId" :placeholder=" packages.length === 0 ? $t('compare.selector.search_first') @@ -314,6 +324,23 @@ onClickOutside(containerRef, () => { + + + + + +

{{ $t('compare.selector.packages_selected', { diff --git a/app/components/Package/DailyDownloadsHeatmap.vue b/app/components/Package/DailyDownloadsHeatmap.vue index 719fdac178..ab4bdef01b 100644 --- a/app/components/Package/DailyDownloadsHeatmap.vue +++ b/app/components/Package/DailyDownloadsHeatmap.vue @@ -15,13 +15,7 @@ import { applyBlocklistCorrection } from '~/utils/download-anomalies' import { downloadFileLink } from '~/utils/download' import { useCopyChartPng } from '~/composables/useCopyChartPng' import { useElementSize } from '@vueuse/core' -import { - sanitise, - copyAltTextFromDownloadsHeatmap, - CHART_ANNOTATOR_SLOTS, - getAnnotatorIcon, - getAnnotatorStyle, -} from '~/utils/charts' +import { sanitise, copyAltTextFromDownloadsHeatmap, CHART_ANNOTATOR_SLOTS } from '~/utils/charts' type DailyDataPoint = { day: string @@ -298,13 +292,14 @@ const config = computed(() => ({ useCursorPointer: true, buttons: { pdf: false, - fullscreen: false, + fullscreen: true, table: false, tooltip: false, altCopy: true, annotator: !isMobile.value, }, buttonTitles: { + fullscreen: $t('package.trends.toggle_fullscreen'), csv: $t('package.trends.download_file', { fileType: 'CSV' }), img: $t('package.trends.download_file', { fileType: 'PNG' }), svg: $t('package.trends.download_file', { fileType: 'SVG' }), @@ -750,6 +745,9 @@ function getLegendContent(svg: VueUiHeatmapSvgSlotProps['svg']) { @click="copyChartPng" /> + @@ -769,16 +767,7 @@ function getLegendContent(svg: VueUiHeatmapSvgSlotProps['svg']) { diff --git a/app/components/Package/Install/Dropdown.vue b/app/components/Package/Install/Dropdown.vue index d93eb784a8..d5ebca4aef 100644 --- a/app/components/Package/Install/Dropdown.vue +++ b/app/components/Package/Install/Dropdown.vue @@ -77,6 +77,7 @@ onPrehydrate(el => {

{{ $t('package.get_started.title') }}

diff --git a/app/components/Package/SecurityDowngradeAlert.vue b/app/components/Package/SecurityDowngradeAlert.vue index 7bd2ddf91a..c0aca05692 100644 --- a/app/components/Package/SecurityDowngradeAlert.vue +++ b/app/components/Package/SecurityDowngradeAlert.vue @@ -2,6 +2,7 @@ import type { PublishSecurityDowngrade } from '~/utils/publish-security' defineProps<{ + packageName: string downgrade: PublishSecurityDowngrade | null fallbackInstallText?: string | null }>() @@ -119,5 +120,15 @@ defineProps<{ {{ fallbackInstallText }}

+ + {{ $t('compare.file_changes') }} + diff --git a/app/components/Package/TimelineChart.vue b/app/components/Package/TimelineChart.vue index 645b7687f8..89f27934ed 100644 --- a/app/components/Package/TimelineChart.vue +++ b/app/components/Package/TimelineChart.vue @@ -23,8 +23,6 @@ import { type TimelineSizeCacheValue, CHART_ANNOTATOR_SLOTS, E18E_GRADIENT_COLORS, - getAnnotatorIcon, - getAnnotatorStyle, type TimelineChartMetric, type StackbarTooltipPoint, type TimelinePlotItem, @@ -430,6 +428,7 @@ const commonConfig = computed(() => ({ }, }, buttonTitles: { + fullscreen: $t('package.trends.toggle_fullscreen'), csv: $t('package.trends.download_file', { fileType: 'CSV' }), img: $t('package.trends.download_file', { fileType: 'PNG' }), svg: $t('package.trends.download_file', { fileType: 'SVG' }), @@ -535,7 +534,7 @@ const config = computed(() => { buttons: { pdf: false, labels: false, - fullscreen: false, + fullscreen: true, table: false, tooltip: false, altCopy: true, @@ -729,7 +728,7 @@ const stackbarConfig = computed(() => ({ buttons: { pdf: false, labels: false, - fullscreen: false, + fullscreen: true, table: false, tooltip: false, annotator: !isMobile.value, @@ -851,6 +850,9 @@ const sort = usePermalink<'time' | 'semver'>('sort', 'semver') // "Stable only" filter shared with the page + list via the query string. const stableOnly = useTimelineStableOnly() +// "Frozen history" toggle for the size metrics +const frozenHistory = useTimelineFrozenHistory() + const timelineSortOptions = computed(() => [ { value: 'time' as const, label: $t('package.timeline.chart.sort_time') }, { value: 'semver' as const, label: $t('package.timeline.chart.sort_semver') }, @@ -934,6 +936,10 @@ const timelineMetricTabs = computed(() => [ v-model="stableOnly" :label="$t('package.timeline.chart.ordered_versions')" /> + diff --git a/app/components/Package/TrendsChart.vue b/app/components/Package/TrendsChart.vue index 3cffb9e4b0..09acdd2877 100644 --- a/app/components/Package/TrendsChart.vue +++ b/app/components/Package/TrendsChart.vue @@ -16,7 +16,12 @@ import type { import { DATE_INPUT_MAX } from '~/utils/input' import { endDateOnlyToUtcMs } from '~/utils/chart-data-prediction' import { applyBlocklistCorrection, getAnomaliesForPackages } from '~/utils/download-anomalies' -import { copyAltTextForTrendLineChart, sanitise, applyEllipsis } from '~/utils/charts' +import { + CHART_ANNOTATOR_SLOTS, + copyAltTextForTrendLineChart, + sanitise, + applyEllipsis, +} from '~/utils/charts' import { buildNormalisedTrendsDataset, buildTrendsChartConfig, @@ -2146,6 +2151,9 @@ const copyEmbedUrl = () => copyEmbed(embedUrl.value) @click="copyChartPng" /> + @@ -2165,72 +2173,8 @@ const copyEmbedUrl = () => copyEmbed(embedUrl.value) /> - - - - - - - - - - - - - - - - - - - - -