gpreview
Version:
Preview Ghost themes locally without a full Ghost installation
112 lines • 4.29 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ThemeLoader = void 0;
const glob_1 = require("glob");
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
const fs_1 = require("fs");
const templatePreprocessor_1 = require("./templatePreprocessor");
class ThemeLoader {
themePath;
templates = new Map();
partials = new Map();
constructor(themePath) {
this.themePath = path_1.default.resolve(themePath);
}
async load() {
await this.validateThemePath();
await this.loadPackageJson();
await this.loadTemplates();
await this.loadPartials();
const hasRequiredTemplates = this.validateRequiredTemplates();
return {
templates: this.templates,
partials: this.partials,
hasRequiredTemplates,
themePath: this.themePath,
packageJson: (await this.loadPackageJson()) || undefined,
};
}
async validateThemePath() {
if (!(0, fs_1.existsSync)(this.themePath)) {
throw new Error(`Theme directory not found: ${this.themePath}`);
}
const stats = await promises_1.default.stat(this.themePath);
if (!stats.isDirectory()) {
throw new Error(`Theme path is not a directory: ${this.themePath}`);
}
}
async loadPackageJson() {
const packagePath = path_1.default.join(this.themePath, 'package.json');
if ((0, fs_1.existsSync)(packagePath)) {
const content = await promises_1.default.readFile(packagePath, 'utf-8');
return JSON.parse(content);
}
return null;
}
async loadTemplates() {
const templatePattern = path_1.default.join(this.themePath, '*.hbs');
const templateFiles = await (0, glob_1.glob)(templatePattern);
for (const filePath of templateFiles) {
const name = path_1.default.basename(filePath, '.hbs');
const rawContent = await promises_1.default.readFile(filePath, 'utf-8');
const content = (0, templatePreprocessor_1.preprocessTemplate)(rawContent);
this.templates.set(name, {
name,
path: filePath,
content,
});
}
}
async loadPartials() {
const partialsDir = path_1.default.join(this.themePath, 'partials');
if (!(0, fs_1.existsSync)(partialsDir)) {
return;
}
const partialPattern = path_1.default.join(partialsDir, '**/*.hbs');
const partialFiles = await (0, glob_1.glob)(partialPattern);
for (const filePath of partialFiles) {
const relativePath = path_1.default.relative(partialsDir, filePath);
const name = relativePath.replace(/\.hbs$/, '').replace(/\\/g, '/');
const rawContent = await promises_1.default.readFile(filePath, 'utf-8');
const content = (0, templatePreprocessor_1.preprocessTemplate)(rawContent);
this.partials.set(name, {
name,
path: filePath,
content,
});
}
}
validateRequiredTemplates() {
const required = ['index', 'post'];
const missing = required.filter(name => !this.templates.has(name));
if (missing.length > 0) {
console.warn(`Warning: Missing required templates: ${missing.join(', ')}`);
return false;
}
return true;
}
async getTemplate(name) {
const template = this.templates.get(name);
return template?.content || null;
}
async getPartial(name) {
const partial = this.partials.get(name);
return partial?.content || null;
}
getTemplatePath(name) {
const template = this.templates.get(name);
return template?.path || null;
}
getAvailableTemplates() {
return Array.from(this.templates.keys());
}
getAvailablePartials() {
return Array.from(this.partials.keys());
}
}
exports.ThemeLoader = ThemeLoader;
//# sourceMappingURL=themeLoader.js.map