@@ -6,6 +6,7 @@ import YAML from 'yaml'
66import { siteSections } from './lib/config.js'
77
88interface GitbookConfig {
9+ root ?: string
910 redirects ?: Record < string , string >
1011}
1112
@@ -16,102 +17,81 @@ interface BrokenRedirect {
1617 reason : string
1718}
1819
20+ function findForeignSection (
21+ path : string ,
22+ ownRoot : string ,
23+ ) : string | undefined {
24+ for ( const other of siteSections ) {
25+ if ( other . root === ownRoot ) continue
26+ const prefix = other . urlPrefix . replace ( / ^ \/ / , '' ) + '/'
27+ if ( prefix !== '/' && path . startsWith ( prefix ) ) return other . name
28+ }
29+ return undefined
30+ }
31+
1932const broken : BrokenRedirect [ ] = [ ]
2033
34+ interface ConfigToValidate {
35+ configPath : string
36+ root : string
37+ redirects : Record < string , string >
38+ }
39+
40+ const configs : ConfigToValidate [ ] = [ ]
41+
2142for ( const section of siteSections ) {
2243 const configPath = join ( section . root , '.gitbook.yaml' )
2344 if ( ! existsSync ( configPath ) ) continue
24-
2545 const config = YAML . parse ( readFileSync ( configPath , 'utf-8' ) ) as GitbookConfig
26- const redirects = config . redirects ?? { }
27- for ( const [ source , target ] of Object . entries ( redirects ) ) {
28- // Source must not start with another section's URL prefix
29- for ( const other of siteSections ) {
30- if ( other . root === section . root ) continue
31- const otherPrefix = other . urlPrefix . replace ( / ^ \/ / , '' ) + '/'
32- if ( otherPrefix !== '/' && source . startsWith ( otherPrefix ) ) {
33- broken . push ( {
34- configPath,
35- source,
36- target,
37- reason : `Source belongs to the "${ other . name } " section, not "${ section . name } ". Move this redirect to ${ join ( other . root , '.gitbook.yaml' ) } ` ,
38- } )
39- }
40- }
41-
42- // Target must not start with another section's URL prefix
43- for ( const other of siteSections ) {
44- if ( other . root === section . root ) continue
45- const otherPrefix = other . urlPrefix . replace ( / ^ \/ / , '' ) + '/'
46- if ( otherPrefix !== '/' && target . startsWith ( otherPrefix ) ) {
47- broken . push ( {
48- configPath,
49- source,
50- target,
51- reason : `Target points to the "${ other . name } " section. Move this redirect to ${ join ( other . root , '.gitbook.yaml' ) } ` ,
52- } )
53- }
54- }
55-
56- // Target must resolve to an existing file within this section
57- const fullPath = join ( section . root , target )
58- if ( ! existsSync ( fullPath ) || ! statSync ( fullPath ) . isFile ( ) ) {
59- broken . push ( {
60- configPath,
61- source,
62- target,
63- reason : `File not found: ${ fullPath } ` ,
64- } )
65- }
66- }
46+ configs . push ( {
47+ configPath,
48+ root : section . root ,
49+ redirects : config . redirects ?? { } ,
50+ } )
6751}
6852
69- // Also check the root .gitbook.yaml if it's not already a section config
7053const rootConfigPath = '.gitbook.yaml'
71- const rootIsSection = siteSections . some (
72- ( s ) => join ( s . root , '.gitbook.yaml' ) === rootConfigPath ,
73- )
74-
54+ const rootIsSection = configs . some ( ( c ) => c . configPath === rootConfigPath )
7555if ( ! rootIsSection && existsSync ( rootConfigPath ) ) {
7656 const config = YAML . parse (
7757 readFileSync ( rootConfigPath , 'utf-8' ) ,
78- ) as GitbookConfig & { root ?: string }
79- const redirects = config . redirects ?? { }
58+ ) as GitbookConfig
8059 const root = ( config . root ?? './' ) . replace ( / ^ \. \/ / , '' ) . replace ( / \/ $ / , '' )
60+ configs . push ( {
61+ configPath : rootConfigPath ,
62+ root,
63+ redirects : config . redirects ?? { } ,
64+ } )
65+ }
8166
82- const section = siteSections . find ( ( s ) => s . root === root )
83-
67+ for ( const { configPath, root, redirects } of configs ) {
8468 for ( const [ source , target ] of Object . entries ( redirects ) ) {
85- for ( const other of siteSections ) {
86- if ( section != null && other . root === section . root ) continue
87- const otherPrefix = other . urlPrefix . replace ( / ^ \/ / , '' ) + '/'
88- if ( otherPrefix !== '/' && source . startsWith ( otherPrefix ) ) {
89- broken . push ( {
90- configPath : rootConfigPath ,
91- source,
92- target,
93- reason : `Source belongs to the "${ other . name } " section. Move this redirect to ${ join ( other . root , '.gitbook.yaml' ) } ` ,
94- } )
95- }
69+ const foreignSource = findForeignSection ( source , root )
70+ if ( foreignSource != null ) {
71+ broken . push ( {
72+ configPath,
73+ source,
74+ target,
75+ reason : `Source belongs to the "${ foreignSource } " section. Move this redirect to that section's .gitbook.yaml` ,
76+ } )
77+ continue
9678 }
9779
98- for ( const other of siteSections ) {
99- if ( section != null && other . root === section . root ) continue
100- const otherPrefix = other . urlPrefix . replace ( / ^ \/ / , '' ) + '/'
101- if ( otherPrefix !== '/' && target . startsWith ( otherPrefix ) ) {
102- broken . push ( {
103- configPath : rootConfigPath ,
104- source,
105- target,
106- reason : `Target points to the "${ other . name } " section. Move this redirect to ${ join ( other . root , '.gitbook.yaml' ) } ` ,
107- } )
108- }
80+ const foreignTarget = findForeignSection ( target , root )
81+ if ( foreignTarget != null ) {
82+ broken . push ( {
83+ configPath,
84+ source,
85+ target,
86+ reason : `Target points to the "${ foreignTarget } " section. Move this redirect to that section's .gitbook.yaml` ,
87+ } )
88+ continue
10989 }
11090
11191 const fullPath = join ( root , target )
11292 if ( ! existsSync ( fullPath ) || ! statSync ( fullPath ) . isFile ( ) ) {
11393 broken . push ( {
114- configPath : rootConfigPath ,
94+ configPath,
11595 source,
11696 target,
11797 reason : `File not found: ${ fullPath } ` ,
0 commit comments