mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 11:54:10 +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);
 |