import fs from 'fs'; import { builtinModules } from 'module'; import path from 'path'; // A map to store regular expressions for built-in Node.js modules const builtInModulesMap = new Map(); // Populating the map with built-in module names and their corresponding regex patterns [ 'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'console', 'constants', 'crypto', 'dgram', 'diagnostics_channel', 'dns', 'domain', 'events', 'fs', 'http', 'http2', 'https', 'inspector', 'module', 'net', 'os', 'path', 'perf_hooks', 'process', 'punycode', 'querystring', 'readline', 'repl', 'stream', 'string_decoder', 'timers', 'tls', 'trace_events', 'tty', 'url', 'util', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib', ].forEach((moduleName) => { const regex = new RegExp(`(['"]${moduleName}['"]).*?`, 'g'); const modulePath = `$1node:${moduleName}$1`; builtInModulesMap.set(regex, modulePath); }); class FileService { private static _instance: FileService; // Singleton pattern to ensure only one instance of FileService public static getInstance(): FileService { if (!this._instance) { this._instance = new FileService(); } return this._instance; } // Generates a configuration file with default content async generateConfigFile(filePath?: string) { let rootDir = filePath || process.cwd(); // Checks if the configuration file already exists if (fs.existsSync(path.join(rootDir, 'apilib.config.json'))) { return [false, 'Configuration file already exists. Delete the existing one to generate a new file.']; } // Writes the default content to the configuration file fs.writeFileSync( path.join(rootDir, 'apilib.config.json'), JSON.stringify({ projectid: '', secretkey: '' }, null, 2), ); return [true, 'Configuration file generated. Please fill in the projectid and secretkey.']; } // Retrieves the configuration info from the file async getConfigInfo(filePath?: string) { let rootDir = filePath || process.cwd(); // Checks if the configuration file exists if (!fs.existsSync(path.join(rootDir, 'apilib.config.json'))) { return [false, 'Configuration file does not exist. Please generate one first.']; } // Reads and returns the content of the configuration file const configFileContent = fs.readFileSync(path.join(rootDir, 'apilib.config.json'), 'utf8'); const config = JSON.parse(configFileContent); return [true, config]; } // Finds the operator folder in the given directory async findOperatorFolder(filePath?: string) { let rootDir = filePath || process.cwd(); const files = fs.readdirSync(rootDir); for (const file of files) { const filePath = path.join(rootDir, file); const stats = fs.statSync(filePath); // Skips node_modules, .apilib directories and hidden files if (stats.isDirectory() && !file.startsWith('.') && !['node_modules', '.apilib'].includes(file.toLowerCase())) { if (['operator', 'operators', 'routes'].includes(file.toLowerCase())) { return path.relative(process.cwd(), filePath); } else { const foundPath: any = await this.findOperatorFolder(filePath); if (foundPath) { return foundPath; } } } } return null; } // Replaces content in a file based on a search pattern async replaceContentInFile(filePath: string, searchPattern: string | RegExp, replaceValue: string): Promise { return new Promise((resolve, reject) => { fs.readFile(filePath, 'utf8', (err, fileContent) => { if (err) { reject(err); return; } const updatedContent = fileContent.replace(searchPattern, replaceValue); fs.writeFile(filePath, updatedContent, err => { if (err) { reject(err); return; } resolve(); }); }); }); } } // Exporting the singleton instance of FileService export default FileService.getInstance();