import { Request, Response } from "express";
import { exec } from "child_process";
import path from "path";
import fs from "fs";
import { widgetTemplates } from "../models/templates";
function getTemplateByName(name: string): string | undefined {
for (const category of Object.values(widgetTemplates)) {
if (typeof category === "object" && name in category) {
return (category as Record<string, string>)[name];
}
}
return undefined;
}
const GENERATED_DIR = path.join(__dirname, "../../generated");
class GenerateArtifactController {
generateArtifact(req: Request, res: Response) {
const { appName, type, name, directory, template, html, css, ts } = req.body;
if (!appName || !type || !name) {
return res.status(400).json({ error: "appName, type, and name are required" });
}
// Supported types
const validTypes = [
"component", "service", "directive", "pipe", "class", "interface", "enum", "guard", "module"
];
if (!validTypes.includes(type)) {
return res.status(400).json({ error: `Invalid type. Supported: ${validTypes.join(", ")}` });
}
const appPath = path.join(GENERATED_DIR, appName);
if (!fs.existsSync(appPath)) {
return res.status(404).json({ error: "App not found. Please generate the app first." });
}
// Directory option
const artifactName = directory ? path.join(directory, name) : name;
const artifactPath = path.join("src", "app", directory || "", name);
// Generate artifact using Angular CLI
exec(
`npx ng generate ${type} ${artifactName} --project=${appName}`,
{ cwd: appPath },
(error, stdout, stderr) => {
if (error) {
return res.status(500).json({ error: stderr });
}
// Customization for component
if (type === "component") {
const compDir = path.join(appPath, artifactPath);
const compHtml = path.join(compDir, `${name}.component.html`);
const compCss = path.join(compDir, `${name}.component.css`);
const compTs = path.join(compDir, `${name}.component.ts`);
// Priority: html > template (object or string) > default
if (html) {
fs.writeFileSync(compHtml, html, "utf8");
} else if (typeof template === "string") {
const tpl = getTemplateByName(template) || widgetTemplates.default.default;
fs.writeFileSync(compHtml, tpl, "utf8");
} else if (typeof template === "object" && template.html) {
fs.writeFileSync(compHtml, template.html, "utf8");
if (template.css) fs.writeFileSync(compCss, template.css, "utf8");
if (template.ts) fs.writeFileSync(compTs, template.ts, "utf8");
} else {
fs.writeFileSync(compHtml, widgetTemplates.default.default, "utf8");
}
// Custom CSS
if (css) {
fs.writeFileSync(compCss, css, "utf8");
}
// Custom TS
if (ts) {
fs.writeFileSync(compTs, ts, "utf8");
}
}
// Customization for directive, service, etc.
if (type === "directive" && ts) {
const dirDir = path.join(appPath, artifactPath);
const dirTs = path.join(dirDir, `${name}.directive.ts`);
fs.writeFileSync(dirTs, ts, "utf8");
}
if (type === "service" && ts) {
const svcDir = path.join(appPath, artifactPath);
const svcTs = path.join(svcDir, `${name}.service.ts`);
fs.writeFileSync(svcTs, ts, "utf8");
}
// Add similar logic for other types if needed
res.json({ message: `${type} '${name}' generated successfully in ${appName}.` });
}
);
}
}
export default new GenerateArtifactController();