Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions app/composables/usePackageAnalysis.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ModuleFormat, TypesStatus, CreatePackageInfo } from '#shared/utils/package-analysis'
import type { ChangelogInfo } from '#shared/types'

export interface PackageAnalysisResponse {
package: string
Expand All @@ -10,6 +11,7 @@ export interface PackageAnalysisResponse {
npm?: string
}
createPackage?: CreatePackageInfo
changelog?: ChangelogInfo
}

/**
Expand Down
20 changes: 20 additions & 0 deletions app/pages/package/[...package].vue
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,26 @@ defineOgImageComponent('Package', {
{{ $t('package.links.issues') }}
</a>
</li>
<li v-if="packageAnalysis?.changelog">
<NuxtLink
v-if="packageAnalysis.changelog.source === 'file'"
:to="packageAnalysis.changelog.url"
class="link-subtle font-mono text-sm inline-flex items-center gap-1.5"
>
<span class="i-carbon:catalog w-4 h-4" aria-hidden="true" />
{{ $t('package.links.changelog') }}
</NuxtLink>
<a
v-else
:href="packageAnalysis.changelog.url"
target="_blank"
rel="noopener noreferrer"
class="link-subtle font-mono text-sm inline-flex items-center gap-1.5"
>
<span class="i-carbon:catalog w-4 h-4" aria-hidden="true" />
{{ $t('package.links.changelog') }}
</a>
</li>
<li>
<a
:href="`https://www.npmjs.com/package/${pkg.name}`"
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"repo": "repo",
"homepage": "homepage",
"issues": "issues",
"changelog": "changelog",
"jsr": "jsr",
"code": "code",
"docs": "docs",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/ar-EG.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"repo": "المستودع",
"homepage": "الصفحة الرئيسية",
"issues": "المشكلات",
"changelog": "سجل التغييرات",
"jsr": "jsr",
"code": "الكود",
"docs": "التوثيق",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/az.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"repo": "repo",
"homepage": "ana səhifə",
"issues": "xətalar",
"changelog": "changelog",
"jsr": "jsr",
"code": "kod",
"docs": "sənədlər",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/cs-CZ.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@
"repo": "repozitář",
"homepage": "domovská stránka",
"issues": "úkoly",
"changelog": "changelog",
"jsr": "jsr",
"code": "kód",
"docs": "dokumentace",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
"repo": "Repo",
"homepage": "Homepage",
"issues": "Issues",
"changelog": "Changelog",
"jsr": "JSR",
"code": "Code",
"docs": "Doku",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"repo": "repo",
"homepage": "homepage",
"issues": "issues",
"changelog": "changelog",
"jsr": "jsr",
"code": "code",
"docs": "docs",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/es-419.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
"repo": "repo",
"homepage": "página de inicio",
"issues": "problemas",
"changelog": "historial de cambios",
"jsr": "jsr",
"code": "código",
"docs": "documentación",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
"repo": "repo",
"homepage": "página de inicio",
"issues": "problemas",
"changelog": "historial de cambios",
"jsr": "jsr",
"code": "código",
"docs": "documentación",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"repo": "dépôt",
"homepage": "site web",
"issues": "issues",
"changelog": "changelog",
"jsr": "jsr",
"code": "code",
"docs": "docs",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/hi-IN.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@
"repo": "रिपो",
"homepage": "मुखपृष्ठ",
"issues": "मसले",
"changelog": "परिवर्तन लॉग",
"jsr": "jsr",
"code": "कोड",
"docs": "दस्तावेज़",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/hu-HU.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"repo": "repo",
"homepage": "honlap",
"issues": "hibák",
"changelog": "changelog",
"jsr": "jsr",
"code": "kód",
"docs": "dokumentáció",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/id-ID.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
"repo": "repo",
"homepage": "beranda",
"issues": "kendala",
"changelog": "changelog",
"jsr": "jsr",
"code": "kode",
"docs": "dokumen",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/it-IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
"repo": "repo",
"homepage": "homepage",
"issues": "issues",
"changelog": "changelog",
"jsr": "jsr",
"code": "codice",
"docs": "documenti",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
"repo": "リポジトリ",
"homepage": "ホームページ",
"issues": "issues",
"changelog": "変更履歴",
"jsr": "jsr",
"code": "コード",
"docs": "ドキュメント",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/ne-NP.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
"repo": "रिपो",
"homepage": "होमपेज",
"issues": "इश्यूहरू",
"changelog": "changelog",
"jsr": "jsr",
"code": "कोड",
"docs": "डकुमेन्टेसन",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/pl-PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@
"repo": "repozytorium",
"homepage": "strona",
"issues": "zgłoszenia",
"changelog": "changelog",
"jsr": "jsr",
"code": "kod źródłowy",
"docs": "dokumentacja",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
"repo": "repositório",
"homepage": "página inicial",
"issues": "problemas",
"changelog": "changelog",
"jsr": "jsr",
"code": "código",
"docs": "documentação",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
"repo": "репозиторий",
"homepage": "сайт",
"issues": "issues",
"changelog": "changelog",
"jsr": "jsr",
"code": "код",
"docs": "доки",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/uk-UA.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"repo": "репозиторій",
"homepage": "головна сторінка",
"issues": "проблеми",
"changelog": "changelog",
"jsr": "jsr",
"code": "код",
"docs": "документація",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"repo": "仓库",
"homepage": "主页",
"issues": "议题",
"changelog": "更新日志",
"jsr": "jsr",
"code": "代码",
"docs": "文档",
Expand Down
59 changes: 57 additions & 2 deletions server/api/registry/analysis/[...pkg].get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import {
} from '#shared/utils/constants'
import { parseRepoUrl } from '#shared/utils/git-providers'
import { getLatestVersion, getLatestVersionBatch } from 'fast-npm-meta'
import type { ChangelogInfo } from '#shared/types'
import { findChangelogFile } from '#shared/utils/changelog'
import { fetchFileTree } from '../../../utils/file-tree'
import { checkReleaseTag } from '../../../utils/release-tag'

export default defineCachedEventHandler(
async event => {
Expand Down Expand Up @@ -52,12 +56,17 @@ export default defineCachedEventHandler(
// Only show if the packages are actually associated (same maintainers or same org)
const createPackage = await findAssociatedCreatePackage(packageName, pkg)

// Detect changelog: check release tag first (faster), then fall back to file tree
const resolvedVersion = pkg.version ?? version ?? 'latest'
const changelog = await detectChangelog(pkg, packageName, resolvedVersion)

const analysis = analyzePackage(pkg, { typesPackage, createPackage })

return {
package: packageName,
version: pkg.version ?? version ?? 'latest',
version: resolvedVersion,
...analysis,
changelog,
} satisfies PackageAnalysisResponse
} catch (error: unknown) {
handleApiError(error, {
Expand All @@ -71,7 +80,7 @@ export default defineCachedEventHandler(
swr: true,
getKey: event => {
const pkg = getRouterParam(event, 'pkg') ?? ''
return `analysis:v1:${pkg.replace(/\/+$/, '').trim()}`
return `analysis:v2:${pkg.replace(/\/+$/, '').trim()}`
},
},
)
Expand Down Expand Up @@ -216,3 +225,49 @@ export interface PackageAnalysisResponse extends PackageAnalysis {
package: string
version: string
}

/**
* Detect changelog for a package version.
* Priority: release tag (faster) > changelog file in tarball
*/
async function detectChangelog(
pkg: ExtendedPackageJson,
packageName: string,
version: string,
): Promise<ChangelogInfo | undefined> {
// Step 1: Check for release tag (faster - single API call per tag format)
if (pkg.repository?.url) {
const repoRef = parseRepoUrl(pkg.repository.url)
if (repoRef) {
try {
const releaseInfo = await checkReleaseTag(repoRef, version, packageName)
if (releaseInfo.exists && releaseInfo.url) {
return {
source: 'releases',
url: releaseInfo.url,
}
}
} catch {
// Release tag check failed, continue to file tree check
}
}
}

// Step 2: Check for changelog file in tarball (fallback)
try {
const fileTreeResult = await fetchFileTree(packageName, version)
const changelogFile = findChangelogFile(fileTreeResult.files)
if (changelogFile) {
return {
source: 'file',
url: `/package-code/${packageName}/v/${version}/${changelogFile}`,
filename: changelogFile,
}
}
} catch {
// File tree fetch failed, no changelog available
}

// Neither release tag nor changelog file found
return undefined
}
Loading
Loading