@mdfriday/foundry
Version:
The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.
206 lines • 6.94 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Builder = exports.Factory = void 0;
exports.newTemplateFactory = newTemplateFactory;
exports.newBuilder = newBuilder;
exports.createTemplateEngine = createTemplateEngine;
exports.createTemplateEngineWithServices = createTemplateEngineWithServices;
const type_1 = require("../type");
const template_1 = require("../entity/template");
const executor_1 = require("../entity/executor");
const parser_1 = require("../entity/parser");
const lookup_1 = require("../entity/lookup");
const namespace_1 = require("../vo/namespace");
const baseof_1 = require("../vo/baseof");
const registry_1 = require("../vo/registry");
/**
* Template factory implementation
* TypeScript version of Go's template factory
* Following Go's factory pattern with service injection
*/
class Factory {
/**
* Create template engine with file system (core functions only)
*/
async create(fs) {
return this.createWithConfig(fs, {});
}
/**
* Create template engine with configuration
*/
async createWithConfig(fs, config) {
try {
const builder = new Builder()
.withFs(fs)
.withNamespaces((0, namespace_1.newRegularTemplateNamespace)(), (0, namespace_1.newPartialTemplateNamespace)(), (0, namespace_1.newShortcodeTemplateNamespace)());
// If services are provided, use them; otherwise use core functions only
if (config.services) {
builder.withServices(config.services);
}
else if (config.funcMap) {
builder.withFuncMap(config.funcMap);
}
else {
// Default to core functions only
builder.withFuncMap((0, registry_1.createCoreFuncMap)());
}
const engine = await builder
.buildLookup()
.buildParser()
.buildExecutor()
.build();
await engine.markReady();
return engine;
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new type_1.TemplateError(`Failed to create template engine: ${message}`, 'FACTORY_CREATE_FAILED');
}
}
/**
* Create template engine with services
* TypeScript equivalent of Go's New(fs, cfs) function
*/
async createWithServices(fs, services) {
return this.createWithConfig(fs, { services });
}
}
exports.Factory = Factory;
/**
* Builder for constructing template engine with dependencies
* TypeScript equivalent of Go's builder pattern
*/
class Builder {
constructor() {
this.funcMap = new Map();
}
/**
* Set file system
*/
withFs(fs) {
this.fs = fs;
return this;
}
/**
* Set namespaces
*/
withNamespaces(templateNamespace, partialNamespace, shortcodeNamespace) {
this.templateNamespace = templateNamespace;
this.partialNamespace = partialNamespace;
this.shortcodeNamespace = shortcodeNamespace;
return this;
}
/**
* Set function map directly
*/
withFuncMap(funcMap) {
this.funcMap = new Map([...this.funcMap, ...funcMap]);
return this;
}
/**
* Set services (will generate function map from services)
* TypeScript equivalent of Go's withCfs()
*/
withServices(services) {
this.services = services;
// Generate function map from services
this.funcMap = (0, registry_1.createStandardFuncMap)(services);
return this;
}
/**
* Build lookup component
* TypeScript equivalent of Go's buildLookup()
*/
buildLookup() {
const baseOf = (0, baseof_1.newBaseOf)();
this.lookup = (0, lookup_1.newLookup)(baseOf, this.funcMap);
return this;
}
/**
* Build parser component
* TypeScript equivalent of Go's buildParser()
*/
buildParser() {
this.parser = (0, parser_1.newParser)(this.funcMap);
return this;
}
/**
* Build executor component
* TypeScript equivalent of Go's buildExecutor()
*/
buildExecutor() {
this.executor = (0, executor_1.newExecutor)();
return this;
}
/**
* Build final template engine
* TypeScript equivalent of Go's build()
*/
async build() {
if (!this.fs) {
throw new type_1.TemplateError('File system is required', 'BUILDER_FS_REQUIRED');
}
if (!this.templateNamespace) {
throw new type_1.TemplateError('Template namespace is required', 'BUILDER_TEMPLATE_NAMESPACE_REQUIRED');
}
if (!this.partialNamespace) {
throw new type_1.TemplateError('Partial namespace is required', 'BUILDER_PARTIAL_NAMESPACE_REQUIRED');
}
if (!this.shortcodeNamespace) {
throw new type_1.TemplateError('Shortcode namespace is required', 'BUILDER_SHORTCODE_NAMESPACE_REQUIRED');
}
if (!this.lookup) {
throw new type_1.TemplateError('Lookup is required', 'BUILDER_LOOKUP_REQUIRED');
}
if (!this.parser) {
throw new type_1.TemplateError('Parser is required', 'BUILDER_PARSER_REQUIRED');
}
if (!this.executor) {
throw new type_1.TemplateError('Executor is required', 'BUILDER_EXECUTOR_REQUIRED');
}
const engine = (0, template_1.newTemplateEngine)(this.executor, this.lookup, this.parser, this.templateNamespace, this.partialNamespace, this.shortcodeNamespace, this.fs);
(0, registry_1.updateEngineDependentFunctions)(engine);
try {
// Load templates from file system
await engine.loadTemplates();
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new type_1.TemplateError(`Failed to load templates: ${message}`, 'BUILDER_LOAD_TEMPLATES_FAILED');
}
return engine;
}
}
exports.Builder = Builder;
/**
* Create a new template factory
*/
function newTemplateFactory() {
return new Factory();
}
/**
* Create a new builder
*/
function newBuilder() {
return new Builder();
}
/**
* Convenience function to create template engine with defaults
*/
async function createTemplateEngine(fs, funcMap) {
const factory = newTemplateFactory();
const config = {};
if (funcMap) {
config.funcMap = funcMap;
}
return factory.createWithConfig(fs, config);
}
/**
* Convenience function to create template engine with services
* TypeScript equivalent of Go's factory.New()
*/
async function createTemplateEngineWithServices(fs, services) {
const factory = newTemplateFactory();
return factory.createWithServices(fs, services);
}
//# sourceMappingURL=template.js.map