UNPKG

drizzle-cube

Version:

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

197 lines (196 loc) 5.8 kB
import p, { Router as C } from "express"; import S from "cors"; import { S as R, d as o, f as g, h as E, a as $, b as Q, c as q } from "../compiler-DdaSPwZs.js"; function L(d) { const { cubes: y, drizzle: j, schema: x, extractSecurityContext: l, engineType: v, cors: b, basePath: c = "/cubejs-api/v1", jsonLimit: h = "10mb" } = d; if (!y || y.length === 0) throw new Error("At least one cube must be provided in the cubes array"); const i = C(); b && i.use(S(b)), i.use(p.json({ limit: h })), i.use(p.urlencoded({ extended: !0, limit: h })); const a = new R({ drizzle: j, schema: x, engineType: v }); return y.forEach((t) => { a.registerCube(t); }), i.post(`${c}/load`, async (t, r) => { try { const e = t.body.query || t.body, s = await l(t, r), n = a.validateQuery(e); if (!n.isValid) return r.status(400).json(o( `Query validation failed: ${n.errors.join(", ")}`, 400 )); const u = await a.executeMultiCubeQuery(e, s); r.json(g(e, u, a)); } catch (e) { console.error("Query execution error:", e), r.status(500).json(o( e instanceof Error ? e.message : "Query execution failed", 500 )); } }), i.get(`${c}/load`, async (t, r) => { try { const e = t.query.query; if (!e) return r.status(400).json(o( "Query parameter is required", 400 )); let s; try { s = JSON.parse(e); } catch { return r.status(400).json(o( "Invalid JSON in query parameter", 400 )); } const n = await l(t, r), u = a.validateQuery(s); if (!u.isValid) return r.status(400).json(o( `Query validation failed: ${u.errors.join(", ")}`, 400 )); const f = await a.executeMultiCubeQuery(s, n); r.json(g(s, f, a)); } catch (e) { console.error("Query execution error:", e), r.status(500).json(o( e instanceof Error ? e.message : "Query execution failed", 500 )); } }), i.post(`${c}/batch`, async (t, r) => { try { const { queries: e } = t.body; if (!e || !Array.isArray(e)) return r.status(400).json(o( 'Request body must contain a "queries" array', 400 )); if (e.length === 0) return r.status(400).json(o( "Queries array cannot be empty", 400 )); const s = await l(t, r), n = await E(e, s, a); r.json(n); } catch (e) { console.error("Batch execution error:", e), r.status(500).json(o( e instanceof Error ? e.message : "Batch execution failed", 500 )); } }), i.get(`${c}/meta`, (t, r) => { try { const e = a.getMetadata(); r.json($(e)); } catch (e) { console.error("Metadata error:", e), r.status(500).json(o( e instanceof Error ? e.message : "Failed to fetch metadata", 500 )); } }), i.post(`${c}/sql`, async (t, r) => { try { const e = t.body, s = await l(t, r), n = a.validateQuery(e); if (!n.isValid) return r.status(400).json(o( `Query validation failed: ${n.errors.join(", ")}`, 400 )); const u = e.measures?.[0] || e.dimensions?.[0]; if (!u) return r.status(400).json(o( "No measures or dimensions specified", 400 )); const f = u.split(".")[0], m = await a.generateSQL(f, e, s); r.json(Q(e, m)); } catch (e) { console.error("SQL generation error:", e), r.status(500).json(o( e instanceof Error ? e.message : "SQL generation failed", 500 )); } }), i.get(`${c}/sql`, async (t, r) => { try { const e = t.query.query; if (!e) return r.status(400).json(o( "Query parameter is required", 400 )); const s = JSON.parse(e), n = await l(t, r), u = a.validateQuery(s); if (!u.isValid) return r.status(400).json(o( `Query validation failed: ${u.errors.join(", ")}`, 400 )); const f = s.measures?.[0] || s.dimensions?.[0]; if (!f) return r.status(400).json(o( "No measures or dimensions specified", 400 )); const m = f.split(".")[0], w = await a.generateSQL(m, s, n); r.json(Q(s, w)); } catch (e) { console.error("SQL generation error:", e), r.status(500).json(o( e instanceof Error ? e.message : "SQL generation failed", 500 )); } }), i.post(`${c}/dry-run`, async (t, r) => { try { const e = t.body.query || t.body, s = await l(t, r), n = await q(e, s, a); r.json(n); } catch (e) { console.error("Dry-run error:", e), r.status(400).json({ error: e instanceof Error ? e.message : "Dry-run validation failed", valid: !1 }); } }), i.get(`${c}/dry-run`, async (t, r) => { try { const e = t.query.query; if (!e) return r.status(400).json({ error: "Query parameter is required", valid: !1 }); const s = JSON.parse(e), n = await l(t, r), u = await q(s, n, a); r.json(u); } catch (e) { console.error("Dry-run error:", e), r.status(400).json({ error: e instanceof Error ? e.message : "Dry-run validation failed", valid: !1 }); } }), i.use((t, r, e, s) => { console.error("Express adapter error:", t), e.headersSent || e.status(500).json(o(t, 500)); }), i; } function N(d, y) { const j = L(y); return d.use("/", j), d; } function J(d) { const y = p(); return N(y, d); } export { J as createCubeApp, L as createCubeRouter, N as mountCubeRoutes };