All files / core template-resolver.ts

100% Statements 28/28
100% Branches 4/4
100% Functions 6/6
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47      6x 6x   6x 6x       6x 6x   6x 7x 1x   6x     6x 5x 1x     4x 1x   3x 5x 3x 3x 2x   1x     6x 2x 2x     6x 3x    
// Copyright 2026 ForgeKit Contributors
// SPDX-License-Identifier: Apache-2.0
// https://github.com/SubhanshuMG/ForgeKit
import * as path from 'path';
import * as fs from 'fs-extra';
import { Template, TemplateRegistry } from '../types';
import { validateTemplateId } from './security';
import { isExternalTemplate, loadExternalTemplate } from './template-loader';
 
// In the published package: dist/core/ -> dist/templates/
// In the monorepo dev build: dist/core/ -> dist/templates/ (copied during build)
const TEMPLATES_DIR = path.resolve(__dirname, '../templates');
const REGISTRY_PATH = path.join(TEMPLATES_DIR, 'registry.json');
 
export async function loadRegistry(): Promise<TemplateRegistry> {
  if (!await fs.pathExists(REGISTRY_PATH)) {
    throw new Error(`Template registry not found at ${REGISTRY_PATH}`);
  }
  return fs.readJson(REGISTRY_PATH);
}
 
export async function getTemplate(id: string): Promise<Template> {
  if (isExternalTemplate(id)) {
    return loadExternalTemplate(id);
  }
 
  if (!validateTemplateId(id)) {
    throw new Error(`Invalid template ID: "${id}". IDs must be lowercase alphanumeric with hyphens.`);
  }
  const registry = await loadRegistry();
  const template = registry.templates.find(t => t.id === id);
  if (!template) {
    const available = registry.templates.map(t => t.id).join(', ');
    throw new Error(`Template "${id}" not found. Available templates: ${available}`);
  }
  return template;
}
 
export async function listTemplates(): Promise<Template[]> {
  const registry = await loadRegistry();
  return registry.templates;
}
 
export function getTemplateDir(templateId: string): string {
  return path.join(TEMPLATES_DIR, templateId);
}