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
JavaScript
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
};