UNPKG

drizzle-cube

Version:

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

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