|
1 | 1 | import { existsSync, readFileSync } from 'node:fs' |
2 | 2 | import { join } from 'node:path' |
3 | 3 |
|
| 4 | +import YAML from 'yaml' |
| 5 | + |
4 | 6 | import { siteSections } from './lib/config.js' |
5 | 7 |
|
6 | | -// Parse the redirects section from .gitbook.yaml. |
7 | | -// Each redirect line is: " source-path: target-path" |
8 | | -const gitbookYaml = readFileSync('.gitbook.yaml', 'utf-8') |
9 | | -const lines = gitbookYaml.split('\n') |
| 8 | +const gitbookConfig = YAML.parse(readFileSync('.gitbook.yaml', 'utf-8')) as { |
| 9 | + redirects?: Record<string, string> |
| 10 | +} |
10 | 11 |
|
11 | 12 | interface Redirect { |
12 | | - line: number |
13 | 13 | source: string |
14 | 14 | target: string |
15 | 15 | } |
16 | 16 |
|
17 | | -const redirects: Redirect[] = [] |
18 | | -let inRedirects = false |
19 | | - |
20 | | -for (let i = 0; i < lines.length; i++) { |
21 | | - const line = lines[i] ?? '' |
22 | | - |
23 | | - if (line === 'redirects:') { |
24 | | - inRedirects = true |
25 | | - continue |
26 | | - } |
27 | | - |
28 | | - // A non-indented, non-empty line ends the redirects section |
29 | | - if (inRedirects && line !== '' && !line.startsWith(' ')) { |
30 | | - break |
31 | | - } |
32 | | - |
33 | | - if (!inRedirects) continue |
34 | | - |
35 | | - const match = line.match(/^\s+(.+?):\s+(.+)$/) |
36 | | - if (match?.[1] != null && match[2] != null) { |
37 | | - redirects.push({ line: i + 1, source: match[1], target: match[2] }) |
38 | | - } |
39 | | -} |
| 17 | +const redirects: Redirect[] = Object.entries( |
| 18 | + gitbookConfig.redirects ?? {}, |
| 19 | +).map(([source, target]) => ({ source, target })) |
40 | 20 |
|
41 | 21 | // Check if a path resolves to a page as a file, URL slug, or directory index. |
42 | 22 | function pageExists(fullPath: string): boolean { |
@@ -77,28 +57,16 @@ function resolveTarget(target: string): boolean { |
77 | 57 | return pageExists(join(guidesSection.root, target)) |
78 | 58 | } |
79 | 59 |
|
80 | | -interface BrokenRedirect { |
81 | | - line: number |
82 | | - source: string |
83 | | - target: string |
84 | | -} |
85 | | - |
86 | | -const broken: BrokenRedirect[] = [] |
87 | | - |
88 | | -for (const redirect of redirects) { |
89 | | - if (!resolveTarget(redirect.target)) { |
90 | | - broken.push(redirect) |
91 | | - } |
92 | | -} |
| 60 | +const broken: Redirect[] = redirects.filter((r) => !resolveTarget(r.target)) |
93 | 61 |
|
94 | 62 | if (broken.length > 0) { |
95 | 63 | // eslint-disable-next-line no-console |
96 | 64 | console.error( |
97 | 65 | `Found ${broken.length} redirect(s) with missing target(s) in .gitbook.yaml:\n`, |
98 | 66 | ) |
99 | | - for (const { line, source, target } of broken) { |
| 67 | + for (const { source, target } of broken) { |
100 | 68 | // eslint-disable-next-line no-console |
101 | | - console.error(` line ${line}: ${source}`) |
| 69 | + console.error(` ${source}`) |
102 | 70 | // eslint-disable-next-line no-console |
103 | 71 | console.error(` target: ${target}\n`) |
104 | 72 | } |
|
0 commit comments