149 lines
5.5 KiB
JavaScript
149 lines
5.5 KiB
JavaScript
"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}`);
|
|
});
|
|
}
|