@mdfriday/foundry
Version:
The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.
296 lines • 9.35 kB
JavaScript
"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.OsFs = exports.OsFile = exports.OsFileInfo = void 0;
exports.newOsFs = newOsFs;
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const log_1 = require("../../../../pkg/log");
const log = (0, log_1.getDomainLogger)('fs', { component: 'osfs' });
/**
* OsFileInfo implements FileInfo for Node.js fs.Stats
*/
class OsFileInfo {
constructor(stats, _name) {
this.stats = stats;
this._name = _name;
}
name() {
return this._name;
}
size() {
return this.stats.size;
}
mode() {
return this.stats.mode;
}
modTime() {
return this.stats.mtime;
}
isDir() {
return this.stats.isDirectory();
}
sys() {
return this.stats;
}
}
exports.OsFileInfo = OsFileInfo;
/**
* OsFile implements File for Node.js file handles
*/
class OsFile {
constructor(filePath, flags = 'r') {
this.filePath = filePath;
this.flags = flags;
this.handle = null;
this.closed = false;
this.position = 0;
}
async ensureOpen() {
if (!this.handle && !this.closed) {
this.handle = await fs.open(this.filePath, this.flags);
}
}
async close() {
if (this.handle) {
try {
await this.handle.close();
}
catch (error) {
log.error(`❌ Error closing file handle for ${(this.filePath)}:`, error);
throw error;
}
this.handle = null;
}
this.closed = true;
}
async read(buffer) {
if (this.closed)
throw new Error('File is closed');
await this.ensureOpen();
if (!this.handle)
throw new Error('Failed to open file');
const result = await this.handle.read(buffer, 0, buffer.length, this.position);
this.position += result.bytesRead;
return { bytesRead: result.bytesRead, buffer };
}
async readAt(buffer, offset) {
if (this.closed)
throw new Error('File is closed');
await this.ensureOpen();
if (!this.handle)
throw new Error('Failed to open file');
const result = await this.handle.read(buffer, 0, buffer.length, offset);
return { bytesRead: result.bytesRead, buffer };
}
async seek(offset, whence) {
if (this.closed)
throw new Error('File is closed');
// 实现基本的 seek 操作
switch (whence) {
case 0: // SEEK_SET
this.position = offset;
break;
case 1: // SEEK_CUR
this.position += offset;
break;
case 2: // SEEK_END
await this.ensureOpen();
if (this.handle) {
const stats = await this.handle.stat();
this.position = stats.size + offset;
}
break;
default:
this.position = offset;
}
return this.position;
}
async write(buffer) {
if (this.closed)
throw new Error('File is closed');
await this.ensureOpen();
if (!this.handle)
throw new Error('Failed to open file');
const result = await this.handle.write(buffer, 0, buffer.length, this.position);
this.position += result.bytesWritten;
return { bytesWritten: result.bytesWritten, buffer };
}
async writeAt(buffer, offset) {
if (this.closed)
throw new Error('File is closed');
await this.ensureOpen();
if (!this.handle)
throw new Error('Failed to open file');
const result = await this.handle.write(buffer, 0, buffer.length, offset);
return { bytesWritten: result.bytesWritten, buffer };
}
name() {
return this.filePath;
}
async readdir(count) {
if (this.closed)
throw new Error('File is closed');
const entries = await fs.readdir(this.filePath, { withFileTypes: true });
const result = [];
const limit = count > 0 ? Math.min(count, entries.length) : entries.length;
for (let i = 0; i < limit; i++) {
const entry = entries[i];
const entryPath = path.join(this.filePath, entry.name);
const stats = await fs.stat(entryPath);
result.push(new OsFileInfo(stats, entry.name));
}
return result;
}
async readdirnames(n) {
if (this.closed)
throw new Error('File is closed');
const entries = await fs.readdir(this.filePath);
return n > 0 ? entries.slice(0, n) : entries;
}
async stat() {
if (this.closed)
throw new Error('File is closed');
const stats = await fs.stat(this.filePath);
return new OsFileInfo(stats, path.basename(this.filePath));
}
async sync() {
if (this.closed)
throw new Error('File is closed');
await this.ensureOpen();
if (this.handle) {
await this.handle.sync();
}
}
async truncate(size) {
if (this.closed)
throw new Error('File is closed');
await this.ensureOpen();
if (this.handle) {
await this.handle.truncate(size);
// 如果当前位置超过了截断大小,重置位置
if (this.position > size) {
this.position = size;
}
}
}
async writeString(s) {
const buffer = Buffer.from(s, 'utf8');
const result = await this.write(buffer);
return { bytesWritten: result.bytesWritten };
}
}
exports.OsFile = OsFile;
/**
* OsFs implements Fs for Node.js file system operations
*/
class OsFs {
async create(name) {
// Create the file and return a file handle
await fs.writeFile(name, '');
return new OsFile(name, 'w+');
}
async mkdir(name, perm) {
await fs.mkdir(name, { mode: perm });
}
async mkdirAll(dirPath, perm) {
await fs.mkdir(dirPath, { mode: perm, recursive: true });
}
async open(name) {
// Check if file exists first
await fs.access(name);
const stats = await fs.stat(name);
if (stats.isDirectory()) {
return new OsFile(name, 'r'); // Directory
}
else {
return new OsFile(name, 'r'); // Regular file
}
}
async openFile(name, flag, perm) {
// Convert numeric flags to string flags
let flags = 'r';
if (flag & 1)
flags = 'w'; // O_WRONLY
if (flag & 2)
flags = 'r+'; // O_RDWR
if (flag & 64)
flags = 'w'; // O_CREATE
if (flag & 512)
flags = 'w'; // O_TRUNC
if (flag & 1024)
flags = 'a'; // O_APPEND
return new OsFile(name, flags);
}
async remove(name) {
const stats = await fs.stat(name);
if (stats.isDirectory()) {
await fs.rmdir(name);
}
else {
await fs.unlink(name);
}
}
async removeAll(dirPath) {
await fs.rm(dirPath, { recursive: true, force: true });
}
async rename(oldname, newname) {
await fs.rename(oldname, newname);
}
async stat(name) {
const stats = await fs.stat(name);
return new OsFileInfo(stats, path.basename(name));
}
name() {
return 'OsFs';
}
async chmod(name, mode) {
await fs.chmod(name, mode);
}
async chown(name, uid, gid) {
await fs.chown(name, uid, gid);
}
async chtimes(name, atime, mtime) {
await fs.utimes(name, atime, mtime);
}
}
exports.OsFs = OsFs;
/**
* Create a new OsFs instance
*/
function newOsFs() {
return new OsFs();
}
//# sourceMappingURL=osfs.js.map