UNPKG

drizzle-cube

Version:

Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.

209 lines (208 loc) 7.1 kB
import { Hono as w } from "hono"; import { S as x, f as j, h as Q, a as b, b as g, c as p } from "../compiler-DdaSPwZs.js"; var A = (y) => { const u = { ...{ origin: "*", allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"], allowHeaders: [], exposeHeaders: [] }, ...y }, h = /* @__PURE__ */ ((i) => typeof i == "string" ? i === "*" ? () => i : (o) => i === o ? o : null : typeof i == "function" ? i : (o) => i.includes(o) ? o : null)(u.origin), d = ((i) => typeof i == "function" ? i : Array.isArray(i) ? () => i : () => [])(u.allowMethods); return async function(o, c) { function n(r, e) { o.res.headers.set(r, e); } const s = await h(o.req.header("origin") || "", o); if (s && n("Access-Control-Allow-Origin", s), u.credentials && n("Access-Control-Allow-Credentials", "true"), u.exposeHeaders?.length && n("Access-Control-Expose-Headers", u.exposeHeaders.join(",")), o.req.method === "OPTIONS") { u.origin !== "*" && n("Vary", "Origin"), u.maxAge != null && n("Access-Control-Max-Age", u.maxAge.toString()); const r = await d(o.req.header("origin") || "", o); r.length && n("Access-Control-Allow-Methods", r.join(",")); let e = u.allowHeaders; if (!e?.length) { const t = o.req.header("Access-Control-Request-Headers"); t && (e = t.split(/\s*,\s*/)); } return e?.length && (n("Access-Control-Allow-Headers", e.join(",")), o.res.headers.append("Vary", "Access-Control-Request-Headers")), o.res.headers.delete("Content-Length"), o.res.headers.delete("Content-Type"), new Response(null, { headers: o.res.headers, status: 204, statusText: "No Content" }); } await c(), u.origin !== "*" && o.header("Vary", "Origin", { append: !0 }); }; }; function v(y) { const { cubes: f, drizzle: u, schema: h, extractSecurityContext: d, engineType: i, cors: o, basePath: c = "/cubejs-api/v1" } = y; if (!f || f.length === 0) throw new Error("At least one cube must be provided in the cubes array"); const n = new w(); o && n.use("/*", A(o)); const s = new x({ drizzle: u, schema: h, engineType: i }); return f.forEach((r) => { s.registerCube(r); }), n.post(`${c}/load`, async (r) => { try { const e = await r.req.json(), t = e.query || e, l = await d(r), a = s.validateQuery(t); if (!a.isValid) return r.json({ error: `Query validation failed: ${a.errors.join(", ")}` }, 400); const m = await s.executeMultiCubeQuery(t, l); return r.json(j(t, m, s)); } catch (e) { return console.error("Query execution error:", e), r.json({ error: e instanceof Error ? e.message : "Query execution failed" }, 500); } }), n.get(`${c}/load`, async (r) => { try { const e = r.req.query("query"); if (!e) return r.json({ error: "Query parameter is required" }, 400); let t; try { t = JSON.parse(e); } catch { return r.json({ error: "Invalid JSON in query parameter" }, 400); } const l = await d(r), a = s.validateQuery(t); if (!a.isValid) return r.json({ error: `Query validation failed: ${a.errors.join(", ")}` }, 400); const m = await s.executeMultiCubeQuery(t, l); return r.json(j(t, m, s)); } catch (e) { return console.error("Query execution error:", e), r.json({ error: e instanceof Error ? e.message : "Query execution failed" }, 500); } }), n.post(`${c}/batch`, async (r) => { try { const e = await r.req.json(), { queries: t } = e; if (!t || !Array.isArray(t)) return r.json({ error: 'Request body must contain a "queries" array' }, 400); if (t.length === 0) return r.json({ error: "Queries array cannot be empty" }, 400); const l = await d(r), a = await Q(t, l, s); return r.json(a); } catch (e) { return console.error("Batch execution error:", e), r.json({ error: e instanceof Error ? e.message : "Batch execution failed" }, 500); } }), n.get(`${c}/meta`, (r) => { try { const e = s.getMetadata(); return r.json(b(e)); } catch (e) { return console.error("Metadata error:", e), r.json({ error: e instanceof Error ? e.message : "Failed to fetch metadata" }, 500); } }), n.post(`${c}/sql`, async (r) => { try { const e = await r.req.json(), t = await d(r), l = s.validateQuery(e); if (!l.isValid) return r.json({ error: `Query validation failed: ${l.errors.join(", ")}` }, 400); const a = e.measures?.[0] || e.dimensions?.[0]; if (!a) return r.json({ error: "No measures or dimensions specified" }, 400); const m = a.split(".")[0], q = await s.generateSQL(m, e, t); return r.json(g(e, q)); } catch (e) { return console.error("SQL generation error:", e), r.json({ error: e instanceof Error ? e.message : "SQL generation failed" }, 500); } }), n.get(`${c}/sql`, async (r) => { try { const e = r.req.query("query"); if (!e) return r.json({ error: "Query parameter is required" }, 400); const t = JSON.parse(e), l = await d(r), a = s.validateQuery(t); if (!a.isValid) return r.json({ error: `Query validation failed: ${a.errors.join(", ")}` }, 400); const m = t.measures?.[0] || t.dimensions?.[0]; if (!m) return r.json({ error: "No measures or dimensions specified" }, 400); const q = m.split(".")[0], C = await s.generateSQL(q, t, l); return r.json(g(t, C)); } catch (e) { return console.error("SQL generation error:", e), r.json({ error: e instanceof Error ? e.message : "SQL generation failed" }, 500); } }), n.post(`${c}/dry-run`, async (r) => { try { const e = await r.req.json(), t = e.query || e, l = await d(r), a = await p(t, l, s); return r.json(a); } catch (e) { return console.error("Dry-run error:", e), r.json({ error: e instanceof Error ? e.message : "Dry-run validation failed", valid: !1 }, 400); } }), n.get(`${c}/dry-run`, async (r) => { try { const e = r.req.query("query"); if (!e) return r.json({ error: "Query parameter is required", valid: !1 }, 400); const t = JSON.parse(e), l = await d(r), a = await p(t, l, s); return r.json(a); } catch (e) { return console.error("Dry-run error:", e), r.json({ error: e instanceof Error ? e.message : "Dry-run validation failed", valid: !1 }, 400); } }), n; } function E(y, f) { const u = v(f); return y.route("/", u), y; } function H(y) { const f = new w(); return E(f, y); } export { H as createCubeApp, v as createCubeRoutes, E as mountCubeRoutes };