"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeApp = void 0; const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const cors_1 = __importDefault(require("cors")); const express_1 = __importDefault(require("express")); const zod_1 = require("zod"); const azure_service_1 = require("./azure-service"); const template_service_1 = require("./template-service"); const findAppNewRoot = () => { const candidates = [(0, node_path_1.join)(__dirname, "../../.."), (0, node_path_1.join)(__dirname, "../..")]; for (const candidate of candidates) { if ((0, node_fs_1.existsSync)((0, node_path_1.join)(candidate, "templates.json"))) { return candidate; } } throw new Error("Unable to resolve app-new root"); }; const queryLocation = zod_1.z.object({ location: zod_1.z.string().min(1) }); const queryOffer = zod_1.z.object({ location: zod_1.z.string().min(1), publisher: zod_1.z.string().min(1) }); const querySku = zod_1.z.object({ location: zod_1.z.string().min(1), publisher: zod_1.z.string().min(1), offer: zod_1.z.string().min(1) }); const queryVersion = zod_1.z.object({ location: zod_1.z.string().min(1), publisher: zod_1.z.string().min(1), offer: zod_1.z.string().min(1), sku: zod_1.z.string().min(1) }); const renderBody = zod_1.z.object({ templateFile: zod_1.z.string().min(1), selection: zod_1.z.object({ location: zod_1.z.string().min(1), publisher: zod_1.z.string().min(1), offer: zod_1.z.string().min(1), sku: zod_1.z.string().min(1), version: zod_1.z.string().min(1) }) }); const makeApp = () => { const app = (0, express_1.default)(); const port = Number.parseInt(process.env.PORT ?? "3000", 10); const subscriptionId = process.env.AZURE_SUBSCRIPTION_ID; app.use((0, cors_1.default)()); app.use(express_1.default.json()); if (!subscriptionId) { app.get("/api/health", (_req, res) => { res.status(500).json({ status: "error", message: "Missing AZURE_SUBSCRIPTION_ID" }); }); return { app, port }; } const azure = new azure_service_1.AzureImageService(subscriptionId); const templates = new template_service_1.TemplateService(); app.get("/api/health", (_req, res) => { res.json({ status: "ok" }); }); app.get("/api/locations", async (_req, res, next) => { try { res.json(await azure.getLocations()); } catch (error) { next(error); } }); app.get("/api/publishers", async (req, res, next) => { try { const { location } = queryLocation.parse(req.query); res.json(await azure.getPublishers(location)); } catch (error) { next(error); } }); app.get("/api/offers", async (req, res, next) => { try { const { location, publisher } = queryOffer.parse(req.query); res.json(await azure.getOffers(location, publisher)); } catch (error) { next(error); } }); app.get("/api/skus", async (req, res, next) => { try { const { location, publisher, offer } = querySku.parse(req.query); res.json(await azure.getSkus(location, publisher, offer)); } catch (error) { next(error); } }); app.get("/api/versions", async (req, res, next) => { try { const { location, publisher, offer, sku } = queryVersion.parse(req.query); res.json(await azure.getVersions(location, publisher, offer, sku)); } catch (error) { next(error); } }); app.get("/api/templates", (_req, res) => { res.json(templates.getTemplates()); }); app.post("/api/render", (req, res, next) => { try { const payload = renderBody.parse(req.body); const rendered = templates.render(payload.templateFile, payload.selection); res.json({ rendered }); } catch (error) { next(error); } }); app.get("/api/sku-export", async (req, res, next) => { try { const { location, publisher, offer } = querySku.parse(req.query); const skus = await azure.getSkus(location, publisher, offer); res.json({ rendered: templates.buildSkuExport(skus) }); } catch (error) { next(error); } }); app.use((err, _req, res, _next) => { if (err instanceof zod_1.z.ZodError) { res.status(400).json({ message: "Invalid request", issues: err.issues }); return; } const message = err instanceof Error ? err.message : "Unexpected error"; res.status(500).json({ message }); }); const frontendRoot = (0, node_path_1.join)(findAppNewRoot(), "dist/frontend"); if ((0, node_fs_1.existsSync)(frontendRoot)) { app.use(express_1.default.static(frontendRoot)); app.get(/^(?!\/api).*/, (_req, res) => { res.sendFile((0, node_path_1.join)(frontendRoot, "index.html")); }); } return { app, port }; }; exports.makeApp = makeApp; if (require.main === module) { const { app, port } = makeApp(); app.listen(port, () => { // eslint-disable-next-line no-console console.log(`azure-image-chooser listening on ${port}`); }); }