mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-30 17:37:26 +00:00 
			
		
		
		
	
		
			
	
	
		
			113 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			113 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|   | 'use strict'; | ||
|  | 
 | ||
|  | const { promisify } = require('util'); | ||
|  | const path = require('path'); | ||
|  | const readFile = promisify(require('fs').readFile); | ||
|  | const { readFileSync, writeFileSync } = require('fs'); | ||
|  | const _ = require('lodash'); | ||
|  | const glob = promisify(require('glob').glob); | ||
|  | const chalk = require('chalk'); | ||
|  | 
 | ||
|  | const findFilesInDirectories = async ( | ||
|  |   directories = [], | ||
|  |   matchPatterns = [], | ||
|  |   ignorePatterns = [] | ||
|  | ) => { | ||
|  |   let files = []; | ||
|  |   for (const directory of directories) { | ||
|  |     for (const pattern of matchPatterns) { | ||
|  |       files = files.concat(await glob(path.join(directory, pattern), { ignore: ignorePatterns })); | ||
|  |     } | ||
|  |   } | ||
|  |   return files; | ||
|  | }; | ||
|  | 
 | ||
|  | const loadFilesInMemory = async files => { | ||
|  |   return Promise.all( | ||
|  |     files.map(async file => ({ | ||
|  |       path: file, | ||
|  |       content: (await readFile(file)).toString(), | ||
|  |     })) | ||
|  |   ); | ||
|  | }; | ||
|  | 
 | ||
|  | const getMatches = (content, matchedString) => { | ||
|  |   const lines = content.split('\n'); | ||
|  |   const highlightedLines = []; | ||
|  | 
 | ||
|  |   for (const line of lines) { | ||
|  |     if (line.includes(matchedString)) { | ||
|  |       highlightedLines.push( | ||
|  |         line | ||
|  |           .split(matchedString) | ||
|  |           .join(chalk.bgMagentaBright(matchedString)) | ||
|  |           .trim() | ||
|  |       ); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return highlightedLines; | ||
|  | }; | ||
|  | 
 | ||
|  | class FilesContentSearch { | ||
|  |   constructor(directories, matchPatterns, ignorePatterns) { | ||
|  |     this.directories = directories; | ||
|  |     this.matchPatterns = matchPatterns; | ||
|  |     this.ignorePatterns = ignorePatterns; | ||
|  |   } | ||
|  | 
 | ||
|  |   async loadFiles() { | ||
|  |     console.log('Searching for matching files'); | ||
|  |     this.fileList = await findFilesInDirectories( | ||
|  |       this.directories, | ||
|  |       this.matchPatterns, | ||
|  |       this.ignorePatterns | ||
|  |     ); | ||
|  |     console.log(`Found ${this.fileList.length} files`); | ||
|  | 
 | ||
|  |     console.log('Loading files content in memory'); | ||
|  |     this.files = await loadFilesInMemory(this.fileList); | ||
|  |     console.log(`Loaded ${this.files.length} files in memory`); | ||
|  |   } | ||
|  | 
 | ||
|  |   search(matchFunction) { | ||
|  |     const results = []; | ||
|  |     const localFiles = _.cloneDeep(this.files); | ||
|  | 
 | ||
|  |     for (const file of localFiles) { | ||
|  |       const matchedString = matchFunction(file.content); | ||
|  | 
 | ||
|  |       if (matchedString) { | ||
|  |         file.matches = getMatches(file.content, matchedString); | ||
|  |         file.replaceAll = replaceValue => { | ||
|  |           let fileContent = readFileSync(file.path, { encoding: 'utf-8' }); | ||
|  |           fileContent = fileContent.replaceAll(matchedString, replaceValue); | ||
|  |           writeFileSync(file.path, fileContent, { encoding: 'utf-8' }); | ||
|  |         }; | ||
|  |         results.push(file); | ||
|  |       } | ||
|  |     } | ||
|  |     return results; | ||
|  |   } | ||
|  | 
 | ||
|  |   searchString(string) { | ||
|  |     return this.search(fileContent => { | ||
|  |       if (fileContent.includes(string)) return string; | ||
|  |       return null; | ||
|  |     }); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = FilesContentSearch; | ||
|  | 
 | ||
|  | // Usage example
 | ||
|  | 
 | ||
|  | // const fcs = new FilesContentSearch(
 | ||
|  | //   [path.join(__dirname, '../../../')],
 | ||
|  | //   ['**/*.js'],
 | ||
|  | //   ['**/node_modules/**', '**/cache/**', '**/build/**']
 | ||
|  | // );
 | ||
|  | 
 | ||
|  | // await fcs.loadFiles();
 | ||
|  | // const results = await fcs.searchString(yolo);
 |