@@ -8,6 +8,7 @@ import type { ExtendedPackageJson } from '~~/shared/utils/package-analysis'
88import { ERROR_CHANGELOG_NOT_FOUND } from '~~/shared/utils/constants'
99import * as v from 'valibot'
1010import { GithubReleaseSchama } from '~~/shared/schemas/changelog/release'
11+ import { resolveURL } from 'ufo'
1112
1213/**
1314 * Detect whether changelogs/releases are available for this package
@@ -28,7 +29,9 @@ export async function detectChangelog(
2829 return false
2930 }
3031
31- const changelog = ( await checkReleases ( repoRef ) ) || ( await checkChangelogFile ( repoRef ) )
32+ const changelog =
33+ ( await checkReleases ( repoRef , pkg . repository . directory ) ) ||
34+ ( await checkChangelogFile ( repoRef , pkg . repository . directory ) )
3235
3336 if ( changelog ) {
3437 return changelog
@@ -44,41 +47,25 @@ export async function detectChangelog(
4447 * check whether releases are being used with this repo
4548 * @returns true if in use
4649 */
47- async function checkReleases ( ref : RepoRef ) : Promise < ChangelogInfo | false > {
50+ async function checkReleases ( ref : RepoRef , directory ?: string ) : Promise < ChangelogInfo | false > {
4851 switch ( ref . provider ) {
4952 case 'github' : {
50- return checkLatestGithubRelease ( ref )
53+ return checkLatestGithubRelease ( ref , directory )
5154 }
5255 }
5356
54- // const checkUrls = getLatestReleaseUrl(ref)
55-
56- // for (const checkUrl of checkUrls ?? []) {
57- // const exists = await fetch(checkUrl, {
58- // headers: {
59- // // GitHub API requires User-Agent
60- // 'User-Agent': 'npmx.dev',
61- // },
62- // method: 'HEAD', // we just need to know if it exists or not
63- // })
64- // .then(r => r.ok)
65- // .catch(() => false)
66- // if (exists) {
67- // return {
68- // provider: ref.provider,
69- // type: 'release',
70- // repo: `${ref.owner}/${ref.repo}`,
71- // }
72- // }
73- // }
7457 return false
7558}
7659
7760/// releases
7861
7962const MD_REGEX = / (?< = \[ .* ?( c h a n g e l o g | r e l e a s e s | c h a n g e s | h i s t o r y | n e w s ) \. m d .* ?\] \( ) ( .* ?) (? = \) ) / i
63+ const ROOT_ONLY_REGEX = / ^ \/ [ ^ / ] + $ /
8064
81- function checkLatestGithubRelease ( ref : RepoRef ) : Promise < ChangelogInfo | false > {
65+ function checkLatestGithubRelease (
66+ ref : RepoRef ,
67+ directory ?: string ,
68+ ) : Promise < ChangelogInfo | false > {
8269 return $fetch ( `https://ungh.cc/repos/${ ref . owner } /${ ref . repo } /releases/latest` )
8370 . then ( r => {
8471 const { release } = v . parse ( v . object ( { release : GithubReleaseSchama } ) , r )
@@ -96,6 +83,10 @@ function checkLatestGithubRelease(ref: RepoRef): Promise<ChangelogInfo | false>
9683 }
9784
9885 const path = matchedChangelog . replace ( / ^ .* \/ b l o b \/ [ ^ / ] + \/ / i, '' )
86+
87+ if ( directory && ! ( path . startsWith ( directory ) || ROOT_ONLY_REGEX . test ( path ) ) ) {
88+ return false as const
89+ }
9990 return {
10091 provider : ref . provider ,
10192 type : 'md' ,
@@ -105,7 +96,7 @@ function checkLatestGithubRelease(ref: RepoRef): Promise<ChangelogInfo | false>
10596 } satisfies ChangelogMarkdownInfo
10697 } )
10798 . catch ( ( ) => {
108- return false
99+ return false as const
109100 } )
110101}
111102
@@ -120,14 +111,27 @@ const CHANGELOG_FILENAMES = ['changelog', 'releases', 'changes', 'history', 'new
120111 } )
121112 . flat ( 3 )
122113
123- async function checkChangelogFile ( ref : RepoRef ) : Promise < ChangelogMarkdownInfo | false > {
114+ async function checkChangelogFile (
115+ ref : RepoRef ,
116+ directory ?: string ,
117+ ) : Promise < ChangelogMarkdownInfo | false > {
124118 const baseUrl = getBaseFileUrl ( ref )
125119 if ( ! baseUrl ) {
126120 return false
127121 }
128122
123+ if ( directory ) {
124+ const inDir = await checkFiles ( ref , baseUrl , directory )
125+ if ( inDir ) {
126+ return inDir
127+ }
128+ }
129+ return checkFiles ( ref , baseUrl )
130+ }
131+
132+ async function checkFiles ( ref : RepoRef , baseUrl : RepoFileUrl , dir ?: string ) {
129133 for ( const fileName of CHANGELOG_FILENAMES ) {
130- const exists = await fetch ( ` ${ baseUrl . raw } / ${ fileName } ` , {
134+ const exists = await fetch ( resolveURL ( baseUrl . raw , dir ?? '' , fileName ) , {
131135 headers : {
132136 // GitHub API requires User-Agent
133137 'User-Agent' : 'npmx.dev' ,
@@ -140,9 +144,9 @@ async function checkChangelogFile(ref: RepoRef): Promise<ChangelogMarkdownInfo |
140144 return {
141145 type : 'md' ,
142146 provider : ref . provider ,
143- path : fileName ,
147+ path : resolveURL ( dir ?? '' , fileName ) ,
144148 repo : `${ ref . owner } /${ ref . repo } ` ,
145- link : ` ${ baseUrl . blob } / ${ fileName } ` ,
149+ link : resolveURL ( baseUrl . blob , dir ?? '' , fileName ) ,
146150 } satisfies ChangelogMarkdownInfo
147151 }
148152 }
0 commit comments