@mdfriday/foundry
Version:
The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.
135 lines • 6.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateClient = void 0;
const resources_1 = require("../../../domain/resources");
/**
* ExecuteAsTemplateTransform implements the template execution transformation
* This follows the golang version's executeAsTemplateTransform structure
*/
class ExecuteAsTemplateTransform {
constructor(templateExecutor, targetPath, data) {
this.templateExecutor = templateExecutor;
this._targetPath = targetPath;
this.data = data;
}
key() {
return resources_1.ResourceTransformationKey.newResourceTransformationKey('execute-as-template', this._targetPath);
}
async transform(ctx) {
try {
ctx.data.targetPath = this._targetPath;
let templateContent = '';
// Check if the source stream has a direct way to get content
if (typeof ctx.source.from.read === 'function') {
// Try to read all available data directly
let chunk;
const chunks = [];
// Read all available data
while ((chunk = ctx.source.from.read()) !== null) {
if (chunk) {
chunks.push(chunk);
}
}
if (chunks.length > 0) {
templateContent = Buffer.concat(chunks).toString();
}
else {
// If no data available, check if it's a PassThrough stream with internal data
if (ctx.source.from._readableState && ctx.source.from._readableState.buffer) {
const buffer = ctx.source.from._readableState.buffer;
// Extract data from internal buffer
const bufferChunks = [];
for (const entry of buffer) {
if (entry && entry.chunk) {
bufferChunks.push(entry.chunk);
}
}
if (bufferChunks.length > 0) {
templateContent = Buffer.concat(bufferChunks).toString();
}
}
}
}
// If we still don't have content, try the stream event approach as fallback
if (!templateContent) {
return new Promise((resolve, reject) => {
const contentChunks = [];
ctx.source.from.on('data', (chunk) => {
contentChunks.push(chunk);
});
ctx.source.from.on('end', async () => {
try {
const content = Buffer.concat(contentChunks).toString();
await this.executeTemplate(content, ctx, resolve, reject);
}
catch (error) {
reject(new Error(`failed to parse Resource "${ctx.source.inPath}" as Template: ${error}`));
}
});
ctx.source.from.on('error', (error) => {
reject(error);
});
// Try to trigger the stream
if (typeof ctx.source.from.resume === 'function') {
ctx.source.from.resume();
}
});
}
else {
// We have content, execute template directly
await this.executeTemplateSync(templateContent, ctx);
}
}
catch (error) {
throw new Error(`failed to parse Resource "${ctx.source.inPath}" as Template: ${error}`);
}
}
async executeTemplateSync(templateContent, ctx) {
// Parse and execute template - following golang's t.t.Parse() and t.t.ExecuteWithContext()
const templateResult = await this.templateExecutor.executeTemplate(ctx.source.inPath, templateContent, this.data);
// Write result to target - following golang's ctx.Target.To
ctx.target.to.write(templateResult);
ctx.target.to.end();
}
async executeTemplate(templateContent, ctx, resolve, reject) {
try {
await this.executeTemplateSync(templateContent, ctx);
resolve();
}
catch (error) {
reject(error instanceof Error ? error : new Error(String(error)));
}
}
}
/**
* TemplateClient provides template execution functionality for resources
* This implements the ExecuteAsTemplate operation following golang version
*/
class TemplateClient {
constructor(templateExecutor) {
this.templateExecutor = templateExecutor;
}
async executeAsTemplate(resource, targetPath, data) {
try {
// Following golang version: transRes := res.(Transformer)
// Check if resource implements transform method
if (!resource) {
throw new Error(`Resource is null or undefined`);
}
if (typeof resource.transform !== 'function') {
throw new Error(`Resource does not implement Transformer interface. Resource type: ${typeof resource}`);
}
// Create the transformation following golang's executeAsTemplateTransform
const transformation = new ExecuteAsTemplateTransform(this.templateExecutor, targetPath.replace(/\\/g, '/').replace(/^\/+/, ''), // Following golang's paths.ToSlashTrimLeading
data);
// Following golang version: return transRes.TransformWithContext(ctx, &executeAsTemplateTransform{...})
const transformedResource = await resource.transform(transformation);
return transformedResource;
}
catch (error) {
throw error;
}
}
}
exports.TemplateClient = TemplateClient;
//# sourceMappingURL=template.js.map