mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 09:56:44 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			110 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.8 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);
 | 
