Skip to content

Commit 56eadf1

Browse files
committed
chore: patch starlight-links-validator to warn on relative links only
Upstream treats same-site absolute URLs like /.well-known/... as relative-link errors and always fails the build when any validation issue exists. Split out ValidationErrorType.RelativeLink results: log them with logger.warn and allow the Astro build to succeed; other link issues still fail the build.
1 parent b5a9e0e commit 56eadf1

File tree

3 files changed

+137
-3
lines changed

3 files changed

+137
-3
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@
135135
"starlight-openapi": "patches/starlight-openapi.patch",
136136
"astro": "patches/astro.patch",
137137
"@astrojs/vercel": "patches/@astrojs__vercel.patch",
138-
"vite-plugin-monaco-editor@1.1.0": "patches/vite-plugin-monaco-editor@1.1.0.patch"
138+
"vite-plugin-monaco-editor@1.1.0": "patches/vite-plugin-monaco-editor@1.1.0.patch",
139+
"starlight-links-validator@0.19.2": "patches/starlight-links-validator@0.19.2.patch"
139140
},
140141
"overrides": {
141142
"h3": "^1.15.6",
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
diff --git a/index.ts b/index.ts
2+
index f8277dc78db878b6a54da7ef7a92596c91b77528..53c6b514f8c8f48a0d563f186041da5bb201ded0 100644
3+
--- a/index.ts
4+
+++ b/index.ts
5+
@@ -1,12 +1,13 @@
6+
import type { StarlightPlugin } from '@astrojs/starlight/types'
7+
import type { IntegrationResolvedRoute } from 'astro'
8+
import { AstroError } from 'astro/errors'
9+
+import { green } from 'kleur/colors'
10+
11+
import { clearContentLayerCache } from './libs/astro'
12+
import { StarlightLinksValidatorOptionsSchema, type StarlightLinksValidatorUserOptions } from './libs/config'
13+
import { pathnameToSlug, stripTrailingSlash } from './libs/path'
14+
import { remarkStarlightLinksValidator, type RemarkStarlightLinksValidatorConfig } from './libs/remark'
15+
-import { logErrors, validateLinks } from './libs/validation'
16+
+import { logErrors, logRelativeLinkWarnings, splitRelativeLinkErrors, validateLinks } from './libs/validation'
17+
18+
export type { StarlightLinksValidatorOptions } from './libs/config'
19+
20+
@@ -69,9 +70,11 @@ export default function starlightLinksValidatorPlugin(
21+
22+
const errors = validateLinks(pages, customPages, dir, astroConfig, starlightConfig, options.data)
23+
24+
- const hasInvalidLinkToCustomPage = logErrors(logger, errors, site)
25+
+ const { fatalErrors, relativeErrors } = splitRelativeLinkErrors(errors)
26+
+ logRelativeLinkWarnings(logger, relativeErrors, site)
27+
28+
- if (errors.size > 0) {
29+
+ if (fatalErrors.size > 0) {
30+
+ const hasInvalidLinkToCustomPage = logErrors(logger, fatalErrors, site)
31+
throwPluginError(
32+
'Links validation failed.',
33+
hasInvalidLinkToCustomPage
34+
@@ -79,6 +82,16 @@ export default function starlightLinksValidatorPlugin(
35+
: undefined,
36+
)
37+
}
38+
+
39+
+ if (relativeErrors.size > 0) {
40+
+ logger.info(
41+
+ green(
42+
+ '✓ Link validation passed (relative-link issues above are warnings only).\n',
43+
+ ),
44+
+ )
45+
+ } else {
46+
+ logErrors(logger, fatalErrors, site)
47+
+ }
48+
},
49+
},
50+
})
51+
diff --git a/libs/validation.ts b/libs/validation.ts
52+
index d5436cdab642e018f97d81834045c115b1e4a974..7e3b263884b0b59e31370228abb66efa265590f2 100644
53+
--- a/libs/validation.ts
54+
+++ b/libs/validation.ts
55+
@@ -4,7 +4,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url'
56+
57+
import type { StarlightUserConfig as StarlightUserConfigWithPlugins } from '@astrojs/starlight/types'
58+
import type { AstroConfig, AstroIntegrationLogger } from 'astro'
59+
-import { bgGreen, black, blue, dim, green, red } from 'kleur/colors'
60+
+import { bgGreen, black, blue, dim, green, red, yellow } from 'kleur/colors'
61+
import picomatch from 'picomatch'
62+
import terminalLink from 'terminal-link'
63+
64+
@@ -327,3 +327,66 @@ interface ValidationContext {
65+
}
66+
67+
export type StarlightUserConfig = Omit<StarlightUserConfigWithPlugins, 'plugins'>
68+
+
69+
+/**
70+
+ * Splits validation results so "relative link" policy violations can be logged as warnings
71+
+ * without failing the production build (aptos-docs).
72+
+ */
73+
+export function splitRelativeLinkErrors(errors: ValidationErrors): {
74+
+ fatalErrors: ValidationErrors
75+
+ relativeErrors: ValidationErrors
76+
+} {
77+
+ const fatalErrors: ValidationErrors = new Map()
78+
+ const relativeErrors: ValidationErrors = new Map()
79+
+
80+
+ for (const [id, { errors: validationErrors, file }] of errors) {
81+
+ const relativeOnly = validationErrors.filter((e) => e.type === ValidationErrorType.RelativeLink)
82+
+ const fatalOnly = validationErrors.filter((e) => e.type !== ValidationErrorType.RelativeLink)
83+
+
84+
+ if (fatalOnly.length > 0) {
85+
+ fatalErrors.set(id, { errors: fatalOnly, file })
86+
+ }
87+
+ if (relativeOnly.length > 0) {
88+
+ relativeErrors.set(id, { errors: relativeOnly, file })
89+
+ }
90+
+ }
91+
+
92+
+ return { fatalErrors, relativeErrors }
93+
+}
94+
+
95+
+export function logRelativeLinkWarnings(
96+
+ pluginLogger: AstroIntegrationLogger,
97+
+ errors: ValidationErrors,
98+
+ site: AstroConfig['site'],
99+
+): void {
100+
+ if (errors.size === 0) {
101+
+ return
102+
+ }
103+
+
104+
+ const logger = pluginLogger.fork('')
105+
+
106+
+ const warnCount = [...errors.values()].reduce(
107+
+ (acc, { errors: validationErrors }) => acc + validationErrors.length,
108+
+ 0,
109+
+ )
110+
+
111+
+ logger.warn(
112+
+ yellow(
113+
+ `⚠ Found ${warnCount} ${pluralize(warnCount, 'relative link issue')} in ${errors.size} ${pluralize(errors.size, 'file')} (warning only; build continues).`,
114+
+ ),
115+
+ )
116+
+
117+
+ for (const [id, { errors: validationErrors, file }] of errors) {
118+
+ logger.warn(`${yellow('▶')} ${blue(terminalLink(id, pathToFileURL(file).toString(), { fallback: false }))}`)
119+
+
120+
+ for (const [index, validationError] of validationErrors.entries()) {
121+
+ logger.warn(
122+
+ ` ${blue(`${index < validationErrors.length - 1 ? '├' : '└'}─`)} ${validationError.link}${dim(
123+
+ ` - ${formatValidationError(validationError, site)}`,
124+
+ )}`,
125+
+ )
126+
+ }
127+
+ }
128+
+
129+
+ process.stdout.write('\n')
130+
+}

pnpm-lock.yaml

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)