1+ const path = require ( 'path' ) ;
2+ const fs = require ( 'node:fs' ) ;
3+ const { pathPrefix } = require ( './gatsby-config.js' ) ;
4+ const {
5+ readRedirectionsFile,
6+ writeRedirectionsFile,
7+ getRedirectionsFilePath,
8+ getMarkdownFiles,
9+ getFindPatternForMarkdownFiles,
10+ getReplacePatternForMarkdownFiles,
11+ replaceLinksInFile
12+ } = require ( './scriptUtils.js' ) ;
13+
14+ function toKebabCase ( str ) {
15+ const isScreamingSnakeCase = new RegExp ( / ^ [ A - Z 0 - 9 _ ] * $ / gm) . test ( str ) ;
16+ str = isScreamingSnakeCase ? str . toLowerCase ( ) : str ;
17+ return str
18+ . match ( / [ A - Z ] { 2 , } (? = [ A - Z ] [ a - z ] + [ 0 - 9 ] * | \b ) | [ A - Z ] ? [ a - z ] + [ 0 - 9 ] * | [ A - Z ] | [ 0 - 9 ] + / g)
19+ . map ( x => x . toLowerCase ( ) )
20+ . join ( '-' ) ;
21+ }
22+
23+ function toEdsCase ( str ) {
24+ const isValid = Boolean ( ( / ^ ( [ a - z 0 - 9 - ] * ) $ / . test ( str ) ) ) ;
25+ return isValid ? str : toKebabCase ( str ) ;
26+ }
27+
28+ function toUrl ( file , renameBaseWithoutExt = name => name ) {
29+ const base = path . basename ( file ) ;
30+ const ext = path . extname ( file ) ;
31+ const end = file . length - base . length ;
32+ const baseWithoutExt = base . substring ( 0 , base . length - ext . length ) ;
33+ const newBaseWithoutExt = renameBaseWithoutExt ( baseWithoutExt ) ;
34+ return `${ file . substring ( 0 , end ) } ${ newBaseWithoutExt } `
35+ }
36+
37+ function renameFile ( file , renameBaseWithoutExt ) {
38+ const url = toUrl ( file , renameBaseWithoutExt ) ;
39+ const ext = path . extname ( file ) ;
40+ return `${ url } ${ ext } `
41+ }
42+
43+ function getFileMap ( files ) {
44+ const map = new Map ( ) ;
45+ files . forEach ( from => {
46+ const to = renameFile ( from , toEdsCase )
47+ if ( to !== from ) {
48+ map . set ( from , to )
49+ }
50+ } ) ;
51+ return map ;
52+ }
53+
54+ function getLinkMap ( fileMap , relativeToDir ) {
55+ const linkMap = new Map ( ) ;
56+ fileMap . forEach ( ( toFile , fromFile ) => {
57+ const fromRelFile = path . relative ( relativeToDir , fromFile ) ;
58+ const toRelFile = path . relative ( relativeToDir , toFile ) ;
59+ linkMap . set ( fromRelFile , toRelFile ) ;
60+ } ) ;
61+ return linkMap ;
62+ }
63+
64+ function renameLinksInMarkdownFile ( fileMap , file ) {
65+ const dir = path . dirname ( file ) ;
66+ replaceLinksInFile ( {
67+ file,
68+ linkMap : getLinkMap ( fileMap , dir ) ,
69+ getFindPattern : getFindPatternForMarkdownFiles ,
70+ getReplacePattern : getReplacePatternForMarkdownFiles ,
71+ } ) ;
72+ }
73+
74+ function renameLinksInRedirectsFile ( fileMap ) {
75+ const file = getRedirectionsFilePath ( ) ;
76+ const dir = path . dirname ( file ) ;
77+ replaceLinksInFile ( {
78+ file,
79+ linkMap : getLinkMap ( fileMap , dir ) ,
80+ getFindPattern : ( from ) => `(['"]?)(Source|Destination)(['"]?\\s*:\\s*['"])(${ pathPrefix } ${ toUrl ( from ) } )(/?)(#[^'"]*)?(['"])` ,
81+ getReplacePattern : ( to ) => `$1$2$3${ pathPrefix } ${ toUrl ( to ) } $5$6$7` ,
82+ } ) ;
83+ }
84+
85+ function renameLinksInGatsbyConfigFile ( fileMap , file ) {
86+ const dir = 'src/pages' ;
87+ replaceLinksInFile ( {
88+ file,
89+ linkMap : getLinkMap ( fileMap , dir ) ,
90+ getFindPattern : ( from ) => `(['"]?path['"]?\\s*:\\s*['"])(/|./)?(${ from } )(#[^'"]*)?(['"])` ,
91+ getReplacePattern : ( to ) => `$1$2${ to } $4$5` ,
92+ } ) ;
93+ }
94+
95+ function appendRedirects ( fileMap ) {
96+ const file = getRedirectionsFilePath ( ) ;
97+ const dir = path . dirname ( file ) ;
98+ const linkMap = getLinkMap ( fileMap , dir ) ;
99+ const newData = [ ] ;
100+ linkMap . forEach ( ( to , from ) => {
101+ newData . push ( {
102+ Source : `${ pathPrefix } ${ toUrl ( from ) } ` ,
103+ Destination : `${ pathPrefix } ${ toUrl ( to ) } ` ,
104+ } )
105+ } ) ;
106+ const currData = readRedirectionsFile ( ) ;
107+ const data = [ ...currData , ...newData ] ;
108+ writeRedirectionsFile ( data ) ;
109+ }
110+
111+ function renameFiles ( map ) {
112+ map . forEach ( ( to , from ) => {
113+ fs . renameSync ( from , to ) ;
114+ } ) ;
115+ }
116+
117+ try {
118+ const markdownFiles = getMarkdownFiles ( ) ;
119+ const fileMap = getFileMap ( markdownFiles ) ;
120+ markdownFiles . forEach ( file => {
121+ renameLinksInMarkdownFile ( fileMap , file ) ;
122+ } ) ;
123+ renameFiles ( fileMap ) ;
124+
125+ const redirectsFile = getRedirectionsFilePath ( ) ;
126+ if ( fs . existsSync ( redirectsFile ) ) {
127+ renameLinksInRedirectsFile ( fileMap ) ;
128+ appendRedirects ( fileMap ) ;
129+ }
130+
131+ const gatsbyConfigFile = 'gatsby-config.js' ;
132+ if ( fs . existsSync ( gatsbyConfigFile ) ) {
133+ renameLinksInGatsbyConfigFile ( fileMap , gatsbyConfigFile ) ;
134+ }
135+
136+ } catch ( err ) {
137+ console . error ( err ) ;
138+ }
0 commit comments