feat: initial codebase v0.4.1
Some checks failed
Deploy to Staging / build-and-deploy (push) Failing after 9m44s

- Extract complete codebase from running staging pod
- Add Dockerfile with multi-stage build for Node.js + Puppeteer
- Configure CI/CD workflows for staging and production deployment
- Include all source files, configs, and public assets
This commit is contained in:
OpenClaw DevOps 2026-02-19 17:05:16 +00:00
commit b58f634318
28 changed files with 5669 additions and 0 deletions

50
src/routes/screenshot.ts Normal file
View file

@ -0,0 +1,50 @@
import { Router } from "express";
import { takeScreenshot } from "../services/screenshot.js";
import logger from "../services/logger.js";
export const screenshotRouter = Router();
screenshotRouter.post("/", async (req: any, res) => {
const { url, format, width, height, fullPage, quality, waitForSelector, deviceScale, delay } = req.body;
if (!url || typeof url !== "string") {
res.status(400).json({ error: "Missing required parameter: url" });
return;
}
try {
const result = await takeScreenshot({
url,
format: format || "png",
width: width ? parseInt(width, 10) : undefined,
height: height ? parseInt(height, 10) : undefined,
fullPage: fullPage === true || fullPage === "true",
quality: quality ? parseInt(quality, 10) : undefined,
waitForSelector,
deviceScale: deviceScale ? parseFloat(deviceScale) : undefined,
delay: delay ? parseInt(delay, 10) : undefined,
});
res.setHeader("Content-Type", result.contentType);
res.setHeader("Content-Length", result.buffer.length);
res.setHeader("Cache-Control", "no-store");
res.send(result.buffer);
} catch (err: any) {
logger.error({ err: err.message, url }, "Screenshot failed");
if (err.message === "QUEUE_FULL") {
res.status(503).json({ error: "Service busy. Try again shortly." });
return;
}
if (err.message === "SCREENSHOT_TIMEOUT") {
res.status(504).json({ error: "Screenshot timed out. The page may be too slow to load." });
return;
}
if (err.message.includes("blocked") || err.message.includes("not allowed") || err.message.includes("Invalid URL")) {
res.status(400).json({ error: err.message });
return;
}
res.status(500).json({ error: "Screenshot failed", details: err.message });
}
});