UNPKG

drizzle-cube

Version:

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

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