UNPKG

axiodb

Version:

The Pure JavaScript Alternative to SQLite. Embedded NoSQL database for Node.js with MongoDB-style queries, zero native dependencies, built-in InMemoryCache, and web GUI. Perfect for desktop apps, CLI tools, and embedded systems. No compilation, no platfor

309 lines 14.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable @typescript-eslint/no-unused-vars */ const promises_1 = __importDefault(require("fs/promises")); const response_helper_1 = __importDefault(require("../../Helper/response.helper")); const worker_process_1 = __importDefault(require("../cli/worker_process")); const FolderManager_1 = __importDefault(require("./FolderManager")); class FileManager { constructor() { this.responseHelper = new response_helper_1.default(); this.WorkerProcess = new worker_process_1.default(); } /** * Writes data to a file at the specified path. * * @param path - The path where the file will be written. * @param data - The data to be written to the file. * @returns A promise that resolves to a SuccessInterface if the file is written successfully, * or an ErrorInterface if an error occurs. */ WriteFile(path, data) { return __awaiter(this, void 0, void 0, function* () { try { yield promises_1.default.writeFile(path, data, "utf-8"); return this.responseHelper.Success("File written successfully."); } catch (error) { return this.responseHelper.Error(error); } }); } /** * Reads the content of a file at the specified path. * * @param path - The path to the file to be read. * @returns A promise that resolves to a SuccessInterface containing the file data if the read operation is successful, * or an ErrorInterface if an error occurs. */ ReadFile(path) { return __awaiter(this, void 0, void 0, function* () { try { const data = yield promises_1.default.readFile(path, "utf-8"); return this.responseHelper.Success(data); } catch (error) { return this.responseHelper.Error(error); } }); } /** * Deletes a file at the specified path. * * @param {string} path - The path to the file to be deleted. * @returns {Promise<SuccessInterface | ErrorInterface>} A promise that resolves to a SuccessInterface if the file is deleted successfully, or an ErrorInterface if an error occurs. */ DeleteFile(path) { return __awaiter(this, void 0, void 0, function* () { try { yield promises_1.default.unlink(path); return this.responseHelper.Success("File deleted successfully."); } catch (error) { return this.responseHelper.Error(error); } }); } /** * Checks if a file exists at the given path. * * @param path - The path to the file. * @returns A promise that resolves to a SuccessInterface if the file exists, * or an ErrorInterface if the file does not exist. */ FileExists(path) { return __awaiter(this, void 0, void 0, function* () { try { yield promises_1.default.access(path); return this.responseHelper.Success(true); } catch (_a) { return this.responseHelper.Error(false); } }); } /** * Creates a new file at the specified path. * * @param path - The path where the new file will be created. * @returns A promise that resolves to a SuccessInterface if the file is created successfully, * or an ErrorInterface if there is an error during file creation. */ CreateFile(path) { return __awaiter(this, void 0, void 0, function* () { return yield this.WriteFile(path, ""); }); } /** * Locks the specified file by changing its permissions to read-only. * * @param path - The path to the file to be locked. * @returns A promise that resolves to a SuccessInterface if the file is locked successfully, * or an ErrorInterface if an error occurs. */ LockFile(path) { return __awaiter(this, void 0, void 0, function* () { try { yield promises_1.default.chmod(path, 0o400); return this.responseHelper.Success("File locked successfully."); } catch (error) { return this.responseHelper.Error(error); } }); } /** * Unlocks the file at the specified path by changing its permissions to 777. * * @param {string} path - The path to the file to be unlocked. * @returns {Promise<SuccessInterface | ErrorInterface>} A promise that resolves to a SuccessInterface if the file is unlocked successfully, or an ErrorInterface if an error occurs. */ UnlockFile(path) { return __awaiter(this, void 0, void 0, function* () { try { yield promises_1.default.chmod(path, 0o777); return this.responseHelper.Success("File unlocked successfully."); } catch (error) { return this.responseHelper.Error(error); } }); } /** * Moves a file from the specified old path to the new path. * * @param oldPath - The current path of the file to be moved. * @param newPath - The destination path where the file should be moved. * @returns A promise that resolves to a SuccessInterface if the file is moved successfully, * or an ErrorInterface if an error occurs during the file move operation. */ MoveFile(oldPath, newPath) { return __awaiter(this, void 0, void 0, function* () { try { yield promises_1.default.rename(oldPath, newPath); return this.responseHelper.Success("File moved successfully."); } catch (error) { return this.responseHelper.Error(error); } }); } /** * Checks if the file at the given path is locked. * * A file is considered locked if its permissions are set to read-only for the owner (mode 0o400). * * @param path - The path to the file to check. * @returns A promise that resolves to a SuccessInterface if the file is locked, or an ErrorInterface if an error occurs. */ IsFileLocked(path) { return __awaiter(this, void 0, void 0, function* () { try { const stats = yield promises_1.default.stat(path); return this.responseHelper.Success((stats.mode & 0o777) === 0o400); } catch (error) { return this.responseHelper.Error(error); } }); } /** * Retrieves the size of a file in bytes. * * @param path - The path to the file. * @returns A promise that resolves to a SuccessInterface containing the file size in bytes, * or an ErrorInterface if an error occurs. */ GetFileSize(path) { return __awaiter(this, void 0, void 0, function* () { try { // Try using native Node.js first (most reliable) try { // Check file permissions before reading let originalMode = null; try { const stats = yield promises_1.default.stat(path); originalMode = stats.mode; // If file isn't readable, temporarily make it readable if ((stats.mode & 0o444) !== 0o444) { yield promises_1.default.chmod(path, 0o644); } } catch (permError) { // Continue with attempt to read the file even if we couldn't modify permissions } try { const stats = yield promises_1.default.stat(path); // Restore original permissions if they were modified if (originalMode !== null && (originalMode & 0o444) !== 0o444) { yield promises_1.default.chmod(path, originalMode); } return this.responseHelper.Success(stats.size); } catch (statError) { // Fall back to system commands if native method fails const osType = worker_process_1.default.getOS(); if (osType === "windows") { const stdout = yield this.WorkerProcess.execCommand(`powershell -command "(Get-Item '${path}').length"`); const size = parseInt(stdout, 10) || 0; // Restore original permissions if they were modified if (originalMode !== null && (originalMode & 0o444) !== 0o444) { yield promises_1.default.chmod(path, originalMode); } return this.responseHelper.Success(size); } else { // For Unix-like systems const stdout = yield this.WorkerProcess.execCommand(`wc -c < "${path}" 2>/dev/null || echo 0`); const size = parseInt(stdout, 10) || 0; // Restore original permissions if they were modified if (originalMode !== null && (originalMode & 0o444) !== 0o444) { yield promises_1.default.chmod(path, originalMode); } return this.responseHelper.Success(size); } } } catch (err) { // Try to restore original permissions if they were saved, even if an error occurred try { const stats = yield promises_1.default.stat(path); const originalMode = stats.mode; if ((originalMode & 0o444) !== 0o444) { yield promises_1.default.chmod(path, originalMode); } } catch (_a) { // Ignore errors in the final cleanup attempt } return this.responseHelper.Error(`Failed to get file size: ${err}`); } } catch (err) { return this.responseHelper.Error(`Failed to get file size: ${err}`); } }); } /** * Safely deletes a file with directory lock management. * * This method handles file deletion with proper directory lock/unlock sequences: * - If directory is unlocked: deletes file directly * - If directory is locked: unlocks, deletes file, then relocks directory * * @param collectionPath - The path to the collection directory * @param fileName - The name of the file to delete * @returns A promise that resolves to a SuccessInterface if the file is deleted successfully, * or an ErrorInterface if an error occurs during the deletion process. */ DeleteFileWithLock(collectionPath, fileName) { return __awaiter(this, void 0, void 0, function* () { const folderManager = new FolderManager_1.default(); const filePath = `${collectionPath}/${fileName}`; // Check if directory is locked const isLocked = yield folderManager.IsDirectoryLocked(collectionPath); if (!("data" in isLocked)) { return this.responseHelper.Error("Failed to check directory lock status"); } if (isLocked.data === false) { // Directory not locked - delete directly const deleteResponse = yield this.DeleteFile(filePath); return "data" in deleteResponse ? this.responseHelper.Success("File deleted successfully") : this.responseHelper.Error("Failed to delete file"); } else { // Directory locked - unlock, delete, relock const unlockResponse = yield folderManager.UnlockDirectory(collectionPath); if (!("data" in unlockResponse)) { return this.responseHelper.Error("Failed to unlock directory"); } const deleteResponse = yield this.DeleteFile(filePath); if (!("data" in deleteResponse)) { // Attempt to relock even if delete failed yield folderManager.LockDirectory(collectionPath); return this.responseHelper.Error("Failed to delete file"); } const lockResponse = yield folderManager.LockDirectory(collectionPath); if (!("data" in lockResponse)) { return this.responseHelper.Error("File deleted but failed to relock directory"); } return this.responseHelper.Success("File deleted successfully"); } }); } } exports.default = FileManager; //# sourceMappingURL=FileManager.js.map