UNPKG

drizzle-cube

Version:

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

247 lines (246 loc) 6.61 kB
import { S as E, d as o, f, h as R, a as $, b as q, c as Q } from "../compiler-DdaSPwZs.js"; const v = function(a, x, p) { const { cubes: b, drizzle: C, schema: w, extractSecurityContext: y, engineType: S, cors: h, basePath: c = "/cubejs-api/v1", bodyLimit: m = 10485760 // 10MB } = x; if (!b || b.length === 0) return p(new Error("At least one cube must be provided in the cubes array")); h && a.register(import("@fastify/cors"), h), a.addHook("onRequest", async (r, t) => { r.method === "POST" && (r.body = void 0); }); const n = new E({ drizzle: C, schema: w, engineType: S }); b.forEach((r) => { n.registerCube(r); }), a.post(`${c}/load`, { bodyLimit: m, schema: { body: { type: "object", additionalProperties: !0 } } }, async (r, t) => { try { const e = r.body, s = e.query || e, i = await y(r), u = n.validateQuery(s); if (!u.isValid) return t.status(400).send(o( `Query validation failed: ${u.errors.join(", ")}`, 400 )); const d = await n.executeMultiCubeQuery(s, i); return f(s, d, n); } catch (e) { return r.log.error(e, "Query execution error"), t.status(500).send(o( e instanceof Error ? e.message : "Query execution failed", 500 )); } }), a.get(`${c}/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(o( "Invalid JSON in query parameter", 400 )); } const i = await y(r), u = n.validateQuery(s); if (!u.isValid) return t.status(400).send(o( `Query validation failed: ${u.errors.join(", ")}`, 400 )); const d = await n.executeMultiCubeQuery(s, i); return f(s, d, n); } catch (e) { return r.log.error(e, "Query execution error"), t.status(500).send(o( e instanceof Error ? e.message : "Query execution failed", 500 )); } }), a.post(`${c}/batch`, { bodyLimit: m, schema: { body: { type: "object", required: ["queries"], properties: { queries: { type: "array", items: { type: "object" } } } } } }, async (r, t) => { try { const { queries: e } = r.body; if (!e || !Array.isArray(e)) return t.status(400).send(o( 'Request body must contain a "queries" array', 400 )); if (e.length === 0) return t.status(400).send(o( "Queries array cannot be empty", 400 )); const s = await y(r); return await R(e, s, n); } catch (e) { return r.log.error(e, "Batch execution error"), t.status(500).send(o( e instanceof Error ? e.message : "Batch execution failed", 500 )); } }), a.get(`${c}/meta`, async (r, t) => { try { const e = n.getMetadata(); return $(e); } catch (e) { return r.log.error(e, "Metadata error"), t.status(500).send(o( e instanceof Error ? e.message : "Failed to fetch metadata", 500 )); } }), a.post(`${c}/sql`, { bodyLimit: m, schema: { body: { type: "object", additionalProperties: !0 } } }, async (r, t) => { try { const e = r.body, s = await y(r), i = n.validateQuery(e); if (!i.isValid) return t.status(400).send(o( `Query validation failed: ${i.errors.join(", ")}`, 400 )); const u = e.measures?.[0] || e.dimensions?.[0]; if (!u) return t.status(400).send(o( "No measures or dimensions specified", 400 )); const d = u.split(".")[0], g = await n.generateSQL(d, e, s); return q(e, g); } catch (e) { return r.log.error(e, "SQL generation error"), t.status(500).send(o( e instanceof Error ? e.message : "SQL generation failed", 500 )); } }), a.get(`${c}/sql`, { schema: { querystring: { type: "object", properties: { query: { type: "string" } }, required: ["query"] } } }, async (r, t) => { try { const { query: e } = r.query, s = JSON.parse(e), i = await y(r), u = n.validateQuery(s); if (!u.isValid) return t.status(400).send(o( `Query validation failed: ${u.errors.join(", ")}`, 400 )); const d = s.measures?.[0] || s.dimensions?.[0]; if (!d) return t.status(400).send(o( "No measures or dimensions specified", 400 )); const g = d.split(".")[0], j = await n.generateSQL(g, s, i); return q(s, j); } catch (e) { return r.log.error(e, "SQL generation error"), t.status(500).send(o( e instanceof Error ? e.message : "SQL generation failed", 500 )); } }), a.post(`${c}/dry-run`, { bodyLimit: m, schema: { body: { type: "object", additionalProperties: !0 } } }, async (r, t) => { try { const e = r.body, s = e.query || e, i = await y(r); return await Q(s, i, n); } 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(`${c}/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), i = await y(r); return await Q(s, i, n); } 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), o(r, e.statusCode))), p(); }; async function L(l, a) { await l.register(v, a); } function N(l) { const a = require("fastify")({ logger: !0 }); return a.register(v, l), a; } export { N as createCubeApp, v as cubePlugin, L as registerCubeRoutes };