@synet/fs
Version:
Robust, battle-tested filesystem abstraction for Node.js
277 lines (276 loc) • 9.65 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObservableFileSystem = exports.FilesystemEventTypes = void 0;
const unit_1 = require("@synet/unit");
var FilesystemEventTypes;
(function (FilesystemEventTypes) {
FilesystemEventTypes["EXISTS"] = "file.exists";
FilesystemEventTypes["READ"] = "file.read";
FilesystemEventTypes["WRITE"] = "file.write";
FilesystemEventTypes["DELETE"] = "file.delete";
FilesystemEventTypes["CHMOD"] = "file.chmod";
FilesystemEventTypes["ENSURE_DIR"] = "file.ensureDir";
FilesystemEventTypes["DELETE_DIR"] = "file.deleteDir";
FilesystemEventTypes["READ_DIR"] = "file.readDir";
})(FilesystemEventTypes || (exports.FilesystemEventTypes = FilesystemEventTypes = {}));
class ObservableFileSystem {
constructor(baseFilesystem, events) {
this.baseFilesystem = baseFilesystem;
this.events = events;
this.eventEmitter = new unit_1.EventEmitter();
}
getEventEmitter() {
return this.eventEmitter;
}
shouldEmit(eventType) {
return !this.events || this.events.includes(eventType);
}
async exists(filename) {
try {
const result = await this.baseFilesystem.exists(filename);
if (this.shouldEmit(FilesystemEventTypes.EXISTS)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.EXISTS,
data: {
filePath: filename,
result,
},
timestamp: new Date(),
});
}
return result;
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.EXISTS)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.EXISTS,
data: {
filePath: filename
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async readFile(filename) {
try {
const content = await this.baseFilesystem.readFile(filename);
if (this.shouldEmit(FilesystemEventTypes.READ)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.READ,
data: {
filePath: filename,
result: content.length,
},
timestamp: new Date(),
});
}
return content;
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.READ)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.READ,
data: {
filePath: filename,
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async writeFile(filename, data) {
try {
await this.baseFilesystem.writeFile(filename, data);
if (this.shouldEmit(FilesystemEventTypes.WRITE)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.WRITE,
data: {
filePath: filename,
result: data.length,
},
timestamp: new Date(),
});
}
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.WRITE)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.WRITE,
data: {
filePath: filename,
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async deleteFile(filename) {
try {
await this.baseFilesystem.deleteFile(filename);
if (this.shouldEmit(FilesystemEventTypes.DELETE)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.DELETE,
data: {
filePath: filename,
},
timestamp: new Date(),
});
}
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.DELETE)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.DELETE,
data: {
filePath: filename,
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async deleteDir(dirPath) {
try {
await this.baseFilesystem.deleteDir(dirPath);
if (this.shouldEmit(FilesystemEventTypes.DELETE_DIR)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.DELETE_DIR,
data: {
filePath: dirPath,
},
timestamp: new Date(),
});
}
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.DELETE_DIR)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.DELETE_DIR,
data: {
filePath: dirPath,
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async ensureDir(dirPath) {
try {
await this.baseFilesystem.ensureDir(dirPath);
if (this.shouldEmit(FilesystemEventTypes.ENSURE_DIR)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.ENSURE_DIR,
data: {
filePath: dirPath,
},
timestamp: new Date(),
});
}
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.ENSURE_DIR)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.ENSURE_DIR,
data: {
filePath: dirPath,
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async readDir(dirPath) {
try {
const result = await this.baseFilesystem.readDir(dirPath);
if (this.shouldEmit(FilesystemEventTypes.READ_DIR)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.READ_DIR,
data: {
filePath: dirPath,
result: result.length,
},
timestamp: new Date(),
});
}
return result;
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.READ_DIR)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.READ_DIR,
data: {
filePath: dirPath,
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async chmod(path, mode) {
try {
await this.baseFilesystem.chmod(path, mode);
if (this.shouldEmit(FilesystemEventTypes.CHMOD)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.CHMOD,
data: {
filePath: path,
result: mode,
},
timestamp: new Date(),
});
}
}
catch (error) {
if (this.shouldEmit(FilesystemEventTypes.CHMOD)) {
this.eventEmitter.emit({
type: FilesystemEventTypes.CHMOD,
data: {
filePath: path,
},
error: {
message: error instanceof Error ? error.message : String(error),
},
timestamp: new Date(),
});
}
throw error;
}
}
async clear(dirPath) {
if (this.baseFilesystem.clear) {
await this.baseFilesystem.clear(dirPath);
// We could emit a clear event, but it's not in our enum
// Could be added if needed
}
}
}
exports.ObservableFileSystem = ObservableFileSystem;