11import { readdir , readFile , rename , writeFile } from 'node:fs/promises'
2- import { basename , extname , join } from 'node:path'
2+ import { join } from 'node:path'
33
44const EXCLUDED_DIRECTORIES = new Set ( [ 'dist' , 'coverage' , 'node_modules' , '.git' , 'tmp' ] )
55
@@ -14,30 +14,18 @@ export async function searchAndReplace(
1414 throw new Error ( 'fromStrings and toStrings arrays must have the same length' )
1515 }
1616
17- // Helper: check if a segment exactly matches any fromString (positional)
18- function findReplacementForSegment ( segment : string ) : string | undefined {
19- for ( const [ i , from ] of fromStrings . entries ( ) ) {
20- if ( segment === from ) {
21- return toStrings [ i ]
22- }
23- }
24- return undefined
25- }
26-
2717 async function processFile ( filePath : string ) : Promise < void > {
2818 try {
2919 const content = await readFile ( filePath , 'utf8' )
3020 let newContent = content
3121
3222 for ( const [ i , fromString ] of fromStrings . entries ( ) ) {
33- // Use a safer word-boundary regex for content replacement
34- const regex = new RegExp ( `\\b${ fromString } \\b` , 'g' )
23+ const regex = new RegExp ( fromString , 'g' )
3524 newContent = newContent . replace ( regex , toStrings [ i ] )
36- }
37-
38- // Preserve trailing newline if it existed
39- if ( content . endsWith ( '\n' ) && ! newContent . endsWith ( '\n' ) ) {
40- newContent += '\n'
25+ // Make sure we maintain the possible newline at the end of the file
26+ if ( content . endsWith ( '\n' ) && ! newContent . endsWith ( '\n' ) ) {
27+ newContent += '\n'
28+ }
4129 }
4230
4331 if ( content !== newContent ) {
@@ -46,11 +34,11 @@ export async function searchAndReplace(
4634 }
4735 if ( isVerbose ) {
4836 console . log ( `${ isDryRun ? '[Dry Run] ' : '' } File modified: ${ filePath } ` )
49- for ( const [ index , fromStr ] of fromStrings . entries ( ) ) {
50- const count = ( newContent . match ( new RegExp ( toStrings [ index ] , 'g' ) ) || [ ] ) . length
51- if ( count > 0 ) {
52- console . log ( ` Replaced " ${ fromStr } " with " ${ toStrings [ index ] } " ${ count } time(s)` )
53- }
37+ }
38+ for ( const [ index , fromStr ] of fromStrings . entries ( ) ) {
39+ const count = ( newContent . match ( new RegExp ( toStrings [ index ] , 'g' ) ) || [ ] ) . length
40+ if ( count > 0 && isVerbose ) {
41+ console . log ( ` Replaced " ${ fromStr } " with " ${ toStrings [ index ] } " ${ count } time(s)` )
5442 }
5543 }
5644 }
@@ -93,45 +81,39 @@ export async function searchAndReplace(
9381 }
9482
9583 async function renamePaths ( directoryPath : string ) : Promise < void > {
96- const entries = await readdir ( directoryPath , { withFileTypes : true } )
84+ try {
85+ const entries = await readdir ( directoryPath , { withFileTypes : true } )
9786
98- for ( const entry of entries ) {
99- if ( EXCLUDED_DIRECTORIES . has ( entry . name ) ) {
100- if ( isVerbose ) {
101- console . log ( `Found in excluded directory: ${ entry . name } ` )
87+ for ( const entry of entries ) {
88+ if ( EXCLUDED_DIRECTORIES . has ( entry . name ) ) {
89+ if ( isVerbose ) {
90+ console . log ( `Skipping excluded directory for renaming: ${ join ( directoryPath , entry . name ) } ` )
91+ }
92+ continue
10293 }
103- continue
104- }
10594
106- const oldPath = join ( directoryPath , entry . name )
95+ const oldPath = join ( directoryPath , entry . name )
96+ let newPath = oldPath
10797
108- // Recurse first
109- if ( entry . isDirectory ( ) ) {
110- await renamePaths ( oldPath )
111- }
112-
113- // Split name and extension
114- const ext = extname ( entry . name )
115- const base = basename ( entry . name , ext )
116-
117- // Check if the basename matches fromStrings
118- const replacement = findReplacementForSegment ( base )
119- const newName = replacement ? replacement + ext : entry . name
120- const newPath = join ( directoryPath , newName )
98+ for ( const [ i , fromString ] of fromStrings . entries ( ) ) {
99+ newPath = newPath . replace ( new RegExp ( fromString , 'g' ) , toStrings [ i ] )
100+ }
121101
122- if ( oldPath !== newPath ) {
123- if ( ! isDryRun ) {
124- try {
102+ if ( oldPath !== newPath ) {
103+ if ( ! isDryRun ) {
125104 await rename ( oldPath , newPath )
126- } catch ( error ) {
127- console . error ( `Failed to rename ${ oldPath } -> ${ newPath } :` , error )
128- continue
105+ }
106+ if ( isVerbose ) {
107+ console . log ( ` ${ isDryRun ? '[Dry Run] ' : '' } Renamed: ${ oldPath } -> ${ newPath } ` )
129108 }
130109 }
131- if ( isVerbose ) {
132- console . log ( `${ isDryRun ? '[Dry Run] ' : '' } Renamed: ${ oldPath } -> ${ newPath } ` )
110+
111+ if ( entry . isDirectory ( ) ) {
112+ await renamePaths ( entry . isDirectory ( ) ? newPath : oldPath )
133113 }
134114 }
115+ } catch ( error ) {
116+ console . error ( `Error renaming paths in ${ directoryPath } :` , error )
135117 }
136118 }
137119
0 commit comments