@@ -10,6 +10,7 @@ const PUBLIC_DIR = path.join(__dirname, '../public');
1010const fileCache = new Map ( ) ;
1111const anchorMap = new Map ( ) ; // Map<filepath, Set<anchorId>>
1212const contributorMap = new Map ( ) ; // Map<anchorId, URL>
13+ const redirectMap = new Map ( ) ; // Map<source, destination>
1314let errorCodes = new Set ( ) ;
1415
1516async function readFileWithCache ( filePath ) {
@@ -162,6 +163,22 @@ async function validateLink(link) {
162163 return { valid : true } ;
163164 }
164165
166+ // Check for redirects
167+ if ( redirectMap . has ( urlWithoutAnchor ) ) {
168+ const redirectDestination = redirectMap . get ( urlWithoutAnchor ) ;
169+ if (
170+ redirectDestination . startsWith ( 'http://' ) ||
171+ redirectDestination . startsWith ( 'https://' )
172+ ) {
173+ return { valid : true } ;
174+ }
175+ const redirectedLink = {
176+ ...link ,
177+ url : redirectDestination + ( anchorMatch ? anchorMatch [ 0 ] : '' ) ,
178+ } ;
179+ return validateLink ( redirectedLink ) ;
180+ }
181+
165182 // Check if it's an error code link
166183 const errorCodeMatch = urlWithoutAnchor . match ( / ^ \/ e r r o r s \/ ( \d + ) $ / ) ;
167184 if ( errorCodeMatch ) {
@@ -295,17 +312,42 @@ async function fetchErrorCodes() {
295312 }
296313 const codes = await response . json ( ) ;
297314 errorCodes = new Set ( Object . keys ( codes ) ) ;
298- console . log ( chalk . gray ( `Fetched ${ errorCodes . size } React error codes\n ` ) ) ;
315+ console . log ( chalk . gray ( `Fetched ${ errorCodes . size } React error codes` ) ) ;
299316 } catch ( error ) {
300317 throw new Error ( `Failed to fetch error codes: ${ error . message } ` ) ;
301318 }
302319}
303320
321+ async function buildRedirectsMap ( ) {
322+ try {
323+ const vercelConfigPath = path . join ( __dirname , '../vercel.json' ) ;
324+ const vercelConfig = JSON . parse (
325+ await fs . promises . readFile ( vercelConfigPath , 'utf8' )
326+ ) ;
327+
328+ if ( vercelConfig . redirects ) {
329+ for ( const redirect of vercelConfig . redirects ) {
330+ redirectMap . set ( redirect . source , redirect . destination ) ;
331+ }
332+ console . log (
333+ chalk . gray ( `Loaded ${ redirectMap . size } redirects from vercel.json` )
334+ ) ;
335+ }
336+ } catch ( error ) {
337+ console . log (
338+ chalk . yellow (
339+ `Warning: Could not load redirects from vercel.json: ${ error . message } \n`
340+ )
341+ ) ;
342+ }
343+ }
344+
304345async function main ( ) {
305346 const files = getMarkdownFiles ( ) ;
306347 console . log ( chalk . gray ( `Checking ${ files . length } markdown files...` ) ) ;
307348
308349 await fetchErrorCodes ( ) ;
350+ await buildRedirectsMap ( ) ;
309351 await buildContributorMap ( ) ;
310352 await buildAnchorMap ( files ) ;
311353
@@ -315,6 +357,7 @@ async function main() {
315357 const totalLinks = results . reduce ( ( sum , r ) => sum + r . totalLinks , 0 ) ;
316358
317359 if ( deadLinks . length > 0 ) {
360+ console . log ( '\n' ) ;
318361 for ( const link of deadLinks ) {
319362 console . log ( chalk . yellow ( `${ link . file } :${ link . line } :${ link . column } ` ) ) ;
320363 console . log ( chalk . reset ( ` Link text: ${ link . text } ` ) ) ;
0 commit comments