@mdfriday/foundry
Version:
The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.
173 lines • 5.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StaticCopier = void 0;
const log_1 = require("../../../../pkg/log");
// Create domain-specific logger for static operations
const log = (0, log_1.getDomainLogger)('fs', { component: 'static-copier' });
class StaticCopier {
constructor(froms, to) {
this.fromFss = froms;
this.toFs = to;
}
async copy() {
if (!this.fromFss || this.fromFss.length === 0) {
log.error('No static filesystems found');
return;
}
if (!this.toFs) {
log.error('No publish filesystem found');
return;
}
await this.doWithPublishDirs(this.toFs, async (publishDir) => {
for (const sf of this.fromFss) {
await this.copyStaticTo(sf, publishDir);
}
});
}
/**
* Execute function with publish directories
*/
async doWithPublishDirs(publishFs, fn) {
try {
// For now, we assume the publish directory is the root of the publish filesystem
await fn('/');
}
catch (error) {
log.error('Error in doWithPublishDirs:', error);
throw error;
}
}
/**
* Copy static files from source to target directory
* TypeScript equivalent of Go's copyStaticTo
*/
async copyStaticTo(sourceFs, targetDir) {
try {
return await this.walkSourceFiles(sourceFs, targetDir);
}
catch (error) {
log.error(`Error copying static files to ${targetDir}:`, error);
throw error;
}
}
/**
* Walk source files and copy them
*/
async walkSourceFiles(sourceFs, targetDir) {
let fileCount = 0;
try {
// Walk through all files in the source filesystem
await this.walkFileSystem(sourceFs, '/', async (path, isDir) => {
if (!isDir) {
await this.copyFile(sourceFs, path, this.toFs, targetDir);
fileCount++;
}
});
}
catch (error) {
log.error('Error walking source files:', error);
throw error;
}
return fileCount;
}
/**
* Walk filesystem recursively
*/
async walkFileSystem(fs, basePath, callback) {
try {
const file = await fs.open(basePath);
const fileInfo = await file.stat();
if (!fileInfo.isDir()) {
await file.close();
await callback(basePath, false);
return;
}
const entries = await file.readdir(-1);
await file.close();
for (const entry of entries) {
const fullPath = this.joinPath(basePath, entry.name());
if (entry.isDir()) {
await callback(fullPath, true);
await this.walkFileSystem(fs, fullPath, callback);
}
else {
await callback(fullPath, false);
}
}
}
catch (error) {
// If directory doesn't exist or can't be read, skip it
log.error(`Could not read directory ${basePath}:`, error);
}
}
/**
* Copy a single file from source to target
*/
async copyFile(sourceFs, sourcePath, targetFs, targetDir) {
let sourceFile = null;
let targetFile = null;
try {
// For static files, copy directly to publish root without preserving source path structure
// Remove leading slash if present
const cleanSourcePath = sourcePath.startsWith('/') ? sourcePath.slice(1) : sourcePath;
const targetPath = this.joinPath(targetDir, cleanSourcePath);
// Ensure target directory exists
const targetDirPath = this.dirname(targetPath);
if (targetDirPath !== '/') {
await targetFs.mkdirAll(targetDirPath, 0o755);
}
// Read source file
sourceFile = await sourceFs.open(sourcePath);
const sourceInfo = await sourceFile.stat();
const buffer = new Uint8Array(sourceInfo.size());
await sourceFile.read(buffer);
// Write to target
targetFile = await targetFs.create(targetPath);
await targetFile.write(buffer);
}
catch (error) {
log.warn(`Failed to copy static file ${sourcePath}:`, error);
// Don't throw here, just log and continue with other files
}
finally {
// Ensure files are closed in reverse order of opening
if (targetFile) {
try {
await targetFile.close();
}
catch (closeError) {
log.warn(`Failed to close target file: ${closeError}`);
}
}
if (sourceFile) {
try {
await sourceFile.close();
}
catch (closeError) {
log.warn(`Failed to close source file: ${closeError}`);
}
}
}
}
/**
* Join path components
*/
joinPath(...parts) {
return parts
.map(part => part.replace(/^\/+|\/+$/g, ''))
.filter(part => part.length > 0)
.join('/')
.replace(/^/, '/');
}
/**
* Get directory name from path
*/
dirname(path) {
const parts = path.split('/').filter(part => part.length > 0);
if (parts.length <= 1)
return '/';
return '/' + parts.slice(0, -1).join('/');
}
}
exports.StaticCopier = StaticCopier;
//# sourceMappingURL=static-copier.js.map