docs: address fragment review feedback
This commit is contained in:
@@ -607,7 +607,7 @@ function docSyncLeafGates(options: {
|
||||
pnpmScript('translation-pairing', 'verify-translation-pairing', { label: 'translation pairing' }),
|
||||
pnpmScript('doc-budgets', 'verify-doc-budgets', { label: 'doc budgets' }),
|
||||
pnpmExec('docs-site-projection', ['vitest', 'run', 'scripts/project-doc-site.spec.ts', 'scripts/verify-doc-site-fragments.spec.ts'], {
|
||||
label: 'documentation projection',
|
||||
label: 'documentation site checks',
|
||||
}),
|
||||
// Keep the VitePress build itself in one gate because projection rewrites website/.generated.
|
||||
pnpmScript('docs-site-build', options.docsBuildScript ?? 'docs:build', { label: 'documentation build' }),
|
||||
|
||||
@@ -38,9 +38,29 @@ describe('inspectSiteFragments', () => {
|
||||
|
||||
it('resolves clean, encoded, and same-page routes', () => {
|
||||
const root = fixture()
|
||||
writeFileSync(join(root, 'guide/encoded.html'), '<h1 id="a b">Encoded</h1><a href="./encoded#a%20b">self</a>')
|
||||
writeFileSync(
|
||||
join(root, 'guide/encoded.html'),
|
||||
'<h1 id="a b">Encoded</h1><h2 id="%">Literal</h2><a href="./encoded#a%20b">encoded</a><a href="#%">literal</a>',
|
||||
)
|
||||
|
||||
expect(inspectSiteFragments(root)).toEqual({ checked: 5, broken: [] })
|
||||
expect(inspectSiteFragments(root)).toEqual({ checked: 6, broken: [] })
|
||||
})
|
||||
|
||||
it('rejects ambiguous built routes', () => {
|
||||
const root = fixture()
|
||||
writeFileSync(join(root, 'guide.html'), '<h1 id="flat">Flat</h1>')
|
||||
writeFileSync(join(root, 'guide/index.html'), '<h1 id="index">Index</h1>')
|
||||
|
||||
expect(() => inspectSiteFragments(root)).toThrow('share route "/guide"')
|
||||
})
|
||||
|
||||
it('rejects malformed fragment hrefs', () => {
|
||||
const root = fixture()
|
||||
writeFileSync(join(root, 'guide/invalid.html'), '<a href="http://[invalid]#fragment">invalid</a>')
|
||||
|
||||
expect(() => inspectSiteFragments(root)).toThrow(
|
||||
'guide/invalid.html has invalid fragment href "http://[invalid]#fragment"',
|
||||
)
|
||||
})
|
||||
|
||||
it('reports missing ids and missing built routes', () => {
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* VitePress use different heading-slug algorithms, so source-link validation
|
||||
* alone cannot prove that a published fragment exists.
|
||||
*
|
||||
* Run with `tsx scripts/verify-doc-site-fragments.ts` after `docs:build`.
|
||||
* This runs as part of `docs:build` and can also run directly after a build
|
||||
* with `tsx scripts/verify-doc-site-fragments.ts`.
|
||||
*/
|
||||
|
||||
import { globSync, readFileSync } from 'node:fs'
|
||||
@@ -61,7 +62,9 @@ function aliasesFor(page: BuiltPage): string[] {
|
||||
function decodedFragment(hash: string): string {
|
||||
try {
|
||||
return decodeURIComponent(hash.slice(1))
|
||||
} catch {
|
||||
} catch (error) {
|
||||
if (!(error instanceof URIError)) throw error
|
||||
// URIError means malformed percent encoding; preserve the literal id for comparison.
|
||||
return hash.slice(1)
|
||||
}
|
||||
}
|
||||
@@ -90,7 +93,15 @@ export function inspectSiteFragments(distRoot: string): SiteFragmentReport {
|
||||
|
||||
const byRoute = new Map<string, BuiltPage>()
|
||||
for (const page of pages) {
|
||||
for (const alias of aliasesFor(page)) byRoute.set(alias, page)
|
||||
for (const alias of aliasesFor(page)) {
|
||||
const existing = byRoute.get(alias)
|
||||
if (existing !== undefined && existing !== page) {
|
||||
throw new Error(
|
||||
`verify-doc-site-fragments: built pages ${existing.file} and ${page.file} share route ${JSON.stringify(alias)}.`,
|
||||
)
|
||||
}
|
||||
byRoute.set(alias, page)
|
||||
}
|
||||
}
|
||||
|
||||
const origin = 'https://dsh-docs.invalid'
|
||||
@@ -103,8 +114,11 @@ export function inspectSiteFragments(distRoot: string): SiteFragmentReport {
|
||||
let targetUrl: URL
|
||||
try {
|
||||
targetUrl = new URL(href, `${origin}${page.route}`)
|
||||
} catch {
|
||||
continue
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`verify-doc-site-fragments: ${page.file} has invalid fragment href ${JSON.stringify(href)}.`,
|
||||
{ cause: error },
|
||||
)
|
||||
}
|
||||
if (targetUrl.origin !== origin || targetUrl.hash === '') continue
|
||||
const fragment = decodedFragment(targetUrl.hash)
|
||||
|
||||
Reference in New Issue
Block a user