UNPKG

filesops

Version:

Advanced file operations library with search, type detection, size calculation, and permission utilities

203 lines 7.66 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.FileSearch = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const util_1 = require("util"); const readdir = (0, util_1.promisify)(fs.readdir); const stat = (0, util_1.promisify)(fs.stat); const access = (0, util_1.promisify)(fs.access); /** * Advanced file search with multiple filtering options */ class FileSearch { static async getFileInfo(filePath) { const stats = await stat(filePath); const parsedPath = path.parse(filePath); return { path: filePath, name: parsedPath.base, extension: parsedPath.ext, size: stats.size, isDirectory: stats.isDirectory(), isFile: stats.isFile(), createdAt: stats.birthtime, modifiedAt: stats.mtime, accessedAt: stats.atime, }; } static matchesPattern(filename, pattern, caseSensitive) { if (pattern instanceof RegExp) { return pattern.test(filename); } const targetName = caseSensitive ? filename : filename.toLowerCase(); const targetPattern = caseSensitive ? pattern : pattern.toLowerCase(); // Support glob-like patterns const regexPattern = targetPattern .replace(/\./g, '\\.') .replace(/\*/g, '.*') .replace(/\?/g, '.'); return new RegExp(`^${regexPattern}$`).test(targetName); } static matchesOptions(fileInfo, options) { // Extension filter if (options.extensions && options.extensions.length > 0) { const ext = fileInfo.extension.toLowerCase(); const extensions = options.extensions.map(e => e.toLowerCase().startsWith('.') ? e : `.${e}`); if (!extensions.includes(ext)) { return false; } } // Size filters if (options.maxSize && fileInfo.size > options.maxSize) { return false; } if (options.minSize && fileInfo.size < options.minSize) { return false; } // Date filters if (options.modifiedSince && fileInfo.modifiedAt < options.modifiedSince) { return false; } if (options.modifiedBefore && fileInfo.modifiedAt > options.modifiedBefore) { return false; } return true; } /** * Search for files in a directory with advanced filtering options */ static async search(searchPath, options = {}) { const files = []; const directories = []; await this.searchRecursive(searchPath, options, files, directories, 0); const totalSize = files.reduce((sum, file) => sum + file.size, 0); return { files, directories, totalFiles: files.length, totalDirectories: directories.length, totalSize, }; } static async searchRecursive(currentPath, options, files, directories, currentDepth) { // Check depth limit if (options.maxDepth !== undefined && currentDepth > options.maxDepth) { return; } try { const items = await readdir(currentPath); for (const item of items) { // Skip hidden files if not included if (!options.includeHidden && item.startsWith('.')) { continue; } const itemPath = path.join(currentPath, item); try { const fileInfo = await this.getFileInfo(itemPath); // Handle symlinks if (!options.followSymlinks && (await stat(itemPath)).isSymbolicLink()) { continue; } if (fileInfo.isDirectory) { if (this.matchesPattern(fileInfo.name, options.pattern || '*', options.caseSensitive || false)) { directories.push(fileInfo); } // Recursively search subdirectories await this.searchRecursive(itemPath, options, files, directories, currentDepth + 1); } else if (fileInfo.isFile) { // Check if file matches all criteria if (this.matchesPattern(fileInfo.name, options.pattern || '*', options.caseSensitive || false) && this.matchesOptions(fileInfo, options)) { files.push(fileInfo); } } } catch (error) { // Skip files that can't be accessed continue; } } } catch (error) { // Skip directories that can't be read return; } } /** * Find files by name pattern */ static async findByName(searchPath, pattern, caseSensitive = false) { const result = await this.search(searchPath, { pattern, caseSensitive }); return result.files; } /** * Find files by extension */ static async findByExtension(searchPath, extensions) { const result = await this.search(searchPath, { extensions }); return result.files; } /** * Find files larger than specified size */ static async findLargeFiles(searchPath, minSize) { const result = await this.search(searchPath, { minSize }); return result.files.sort((a, b) => b.size - a.size); } /** * Find recently modified files */ static async findRecentFiles(searchPath, since) { const result = await this.search(searchPath, { modifiedSince: since }); return result.files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime()); } /** * Check if a file or directory exists and is accessible */ static async exists(filePath) { try { await access(filePath, fs.constants.F_OK); return true; } catch { return false; } } } exports.FileSearch = FileSearch; //# sourceMappingURL=search.js.map