feat: Add built dist files with EU compliance routes
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s

- Include compiled TypeScript with new /impressum, /privacy, /terms routes
- Temporary commit of dist files for Docker deployment
This commit is contained in:
openclawd 2026-02-16 13:09:25 +00:00
parent 5ef8f34133
commit 1ef8f5743c
21 changed files with 2179 additions and 0 deletions

122
dist/__tests__/api.test.js vendored Normal file
View file

@ -0,0 +1,122 @@
import { describe, it, expect, beforeAll, afterAll } from "vitest";
import { app } from "../index.js";
// Note: These tests require Puppeteer/Chrome to be available
// For CI, use the Dockerfile which includes Chrome
const BASE = "http://localhost:3199";
let server;
beforeAll(async () => {
process.env.API_KEYS = "test-key";
process.env.PORT = "3199";
// Import fresh to pick up env
server = app.listen(3199);
// Wait for browser init
await new Promise((r) => setTimeout(r, 2000));
});
afterAll(async () => {
server?.close();
});
describe("Auth", () => {
it("rejects requests without API key", async () => {
const res = await fetch(`${BASE}/v1/convert/html`, { method: "POST" });
expect(res.status).toBe(401);
});
it("rejects invalid API key", async () => {
const res = await fetch(`${BASE}/v1/convert/html`, {
method: "POST",
headers: { Authorization: "Bearer wrong-key" },
});
expect(res.status).toBe(403);
});
});
describe("Health", () => {
it("returns ok", async () => {
const res = await fetch(`${BASE}/health`);
expect(res.status).toBe(200);
const data = await res.json();
expect(data.status).toBe("ok");
});
});
describe("HTML to PDF", () => {
it("converts simple HTML", async () => {
const res = await fetch(`${BASE}/v1/convert/html`, {
method: "POST",
headers: {
Authorization: "Bearer test-key",
"Content-Type": "application/json",
},
body: JSON.stringify({ html: "<h1>Test</h1>" }),
});
expect(res.status).toBe(200);
expect(res.headers.get("content-type")).toBe("application/pdf");
const buf = await res.arrayBuffer();
expect(buf.byteLength).toBeGreaterThan(100);
// PDF magic bytes
const header = new Uint8Array(buf.slice(0, 5));
expect(String.fromCharCode(...header)).toBe("%PDF-");
});
it("rejects missing html field", async () => {
const res = await fetch(`${BASE}/v1/convert/html`, {
method: "POST",
headers: {
Authorization: "Bearer test-key",
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
expect(res.status).toBe(400);
});
});
describe("Markdown to PDF", () => {
it("converts markdown", async () => {
const res = await fetch(`${BASE}/v1/convert/markdown`, {
method: "POST",
headers: {
Authorization: "Bearer test-key",
"Content-Type": "application/json",
},
body: JSON.stringify({ markdown: "# Hello\n\nWorld" }),
});
expect(res.status).toBe(200);
expect(res.headers.get("content-type")).toBe("application/pdf");
});
});
describe("Templates", () => {
it("lists templates", async () => {
const res = await fetch(`${BASE}/v1/templates`, {
headers: { Authorization: "Bearer test-key" },
});
expect(res.status).toBe(200);
const data = await res.json();
expect(data.templates).toBeInstanceOf(Array);
expect(data.templates.length).toBeGreaterThan(0);
});
it("renders invoice template", async () => {
const res = await fetch(`${BASE}/v1/templates/invoice/render`, {
method: "POST",
headers: {
Authorization: "Bearer test-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
invoiceNumber: "TEST-001",
date: "2026-02-14",
from: { name: "Seller", email: "s@test.com" },
to: { name: "Buyer", email: "b@test.com" },
items: [{ description: "Widget", quantity: 2, unitPrice: 50, taxRate: 20 }],
}),
});
expect(res.status).toBe(200);
expect(res.headers.get("content-type")).toBe("application/pdf");
});
it("returns 404 for unknown template", async () => {
const res = await fetch(`${BASE}/v1/templates/nonexistent/render`, {
method: "POST",
headers: {
Authorization: "Bearer test-key",
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
expect(res.status).toBe(404);
});
});