drizzle-cube
Version:
Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.
212 lines (211 loc) • 5.73 kB
JavaScript
import { S as j, c as i, f as q, a as $, b as h, h as v } from "../compiler-Ce33cdy6.js";
const Q = function(a, C, p) {
const {
cubes: g,
drizzle: w,
schema: x,
extractSecurityContext: y,
engineType: S,
cors: f,
basePath: d = "/cubejs-api/v1",
bodyLimit: b = 10485760
// 10MB
} = C;
if (!g || g.length === 0)
return p(new Error("At least one cube must be provided in the cubes array"));
f && a.register(import("@fastify/cors"), f), a.addHook("onRequest", async (r, t) => {
r.method === "POST" && (r.body = void 0);
});
const o = new j({
drizzle: w,
schema: x,
engineType: S
});
g.forEach((r) => {
o.registerCube(r);
}), a.post(`${d}/load`, {
bodyLimit: b,
schema: {
body: {
type: "object",
additionalProperties: !0
}
}
}, async (r, t) => {
try {
const e = r.body, s = e.query || e, u = await y(r), n = o.validateQuery(s);
if (!n.isValid)
return t.status(400).send(i(
`Query validation failed: ${n.errors.join(", ")}`,
400
));
const c = await o.executeMultiCubeQuery(s, u);
return q(s, c, o);
} catch (e) {
return r.log.error(e, "Query execution error"), t.status(500).send(i(
e instanceof Error ? e.message : "Query execution failed",
500
));
}
}), a.get(`${d}/load`, {
schema: {
querystring: {
type: "object",
properties: {
query: { type: "string" }
},
required: ["query"]
}
}
}, async (r, t) => {
try {
const { query: e } = r.query;
let s;
try {
s = JSON.parse(e);
} catch {
return t.status(400).send(i(
"Invalid JSON in query parameter",
400
));
}
const u = await y(r), n = o.validateQuery(s);
if (!n.isValid)
return t.status(400).send(i(
`Query validation failed: ${n.errors.join(", ")}`,
400
));
const c = await o.executeMultiCubeQuery(s, u);
return q(s, c, o);
} catch (e) {
return r.log.error(e, "Query execution error"), t.status(500).send(i(
e instanceof Error ? e.message : "Query execution failed",
500
));
}
}), a.get(`${d}/meta`, async (r, t) => {
try {
const e = o.getMetadata();
return $(e);
} catch (e) {
return r.log.error(e, "Metadata error"), t.status(500).send(i(
e instanceof Error ? e.message : "Failed to fetch metadata",
500
));
}
}), a.post(`${d}/sql`, {
bodyLimit: b,
schema: {
body: {
type: "object",
additionalProperties: !0
}
}
}, async (r, t) => {
try {
const e = r.body, s = await y(r), u = o.validateQuery(e);
if (!u.isValid)
return t.status(400).send(i(
`Query validation failed: ${u.errors.join(", ")}`,
400
));
const n = e.measures?.[0] || e.dimensions?.[0];
if (!n)
return t.status(400).send(i(
"No measures or dimensions specified",
400
));
const c = n.split(".")[0], m = await o.generateSQL(c, e, s);
return h(e, m);
} catch (e) {
return r.log.error(e, "SQL generation error"), t.status(500).send(i(
e instanceof Error ? e.message : "SQL generation failed",
500
));
}
}), a.get(`${d}/sql`, {
schema: {
querystring: {
type: "object",
properties: {
query: { type: "string" }
},
required: ["query"]
}
}
}, async (r, t) => {
try {
const { query: e } = r.query, s = JSON.parse(e), u = await y(r), n = o.validateQuery(s);
if (!n.isValid)
return t.status(400).send(i(
`Query validation failed: ${n.errors.join(", ")}`,
400
));
const c = s.measures?.[0] || s.dimensions?.[0];
if (!c)
return t.status(400).send(i(
"No measures or dimensions specified",
400
));
const m = c.split(".")[0], E = await o.generateSQL(m, s, u);
return h(s, E);
} catch (e) {
return r.log.error(e, "SQL generation error"), t.status(500).send(i(
e instanceof Error ? e.message : "SQL generation failed",
500
));
}
}), a.post(`${d}/dry-run`, {
bodyLimit: b,
schema: {
body: {
type: "object",
additionalProperties: !0
}
}
}, async (r, t) => {
try {
const e = r.body, s = e.query || e, u = await y(r);
return await v(s, u, o);
} catch (e) {
return r.log.error(e, "Dry-run error"), t.status(400).send({
error: e instanceof Error ? e.message : "Dry-run validation failed",
valid: !1
});
}
}), a.get(`${d}/dry-run`, {
schema: {
querystring: {
type: "object",
properties: {
query: { type: "string" }
},
required: ["query"]
}
}
}, async (r, t) => {
try {
const { query: e } = r.query, s = JSON.parse(e), u = await y(r);
return await v(s, u, o);
} catch (e) {
return r.log.error(e, "Dry-run error"), t.status(400).send({
error: e instanceof Error ? e.message : "Dry-run validation failed",
valid: !1
});
}
}), a.setErrorHandler(async (r, t, e) => (t.log.error(r, "Fastify cube adapter error"), e.statusCode < 400 && e.status(500), i(r, e.statusCode))), p();
};
async function L(l, a) {
await l.register(Q, a);
}
function R(l) {
const a = require("fastify")({
logger: !0
});
return a.register(Q, l), a;
}
export {
R as createCubeApp,
Q as cubePlugin,
L as registerCubeRoutes
};