UNPKG

drizzle-cube

Version:

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

2 lines (1 loc) 4.67 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("express"),v=require("cors"),o=require("../compiler-CITtZq3r.cjs");function E(d){const{cubes:y,drizzle:p,schema:g,extractSecurityContext:l,engineType:h,cors:R,basePath:c="/cubejs-api/v1",jsonLimit:b="10mb"}=d;if(!y||y.length===0)throw new Error("At least one cube must be provided in the cubes array");const i=m.Router();R&&i.use(v(R)),i.use(m.json({limit:b})),i.use(m.urlencoded({extended:!0,limit:b}));const a=new o.SemanticLayerCompiler({drizzle:p,schema:g,engineType:h});return y.forEach(t=>{a.registerCube(t)}),i.post(`${c}/load`,async(t,r)=>{try{const e=t.body.query||t.body,s=await l(t,r),n=a.validateQuery(e);if(!n.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${n.errors.join(", ")}`,400));const u=await a.executeMultiCubeQuery(e,s);r.json(o.formatCubeResponse(e,u,a))}catch(e){console.error("Query execution error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),i.get(`${c}/load`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json(o.formatErrorResponse("Query parameter is required",400));let s;try{s=JSON.parse(e)}catch{return r.status(400).json(o.formatErrorResponse("Invalid JSON in query parameter",400))}const n=await l(t,r),u=a.validateQuery(s);if(!u.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${u.errors.join(", ")}`,400));const f=await a.executeMultiCubeQuery(s,n);r.json(o.formatCubeResponse(s,f,a))}catch(e){console.error("Query execution error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),i.post(`${c}/batch`,async(t,r)=>{try{const{queries:e}=t.body;if(!e||!Array.isArray(e))return r.status(400).json(o.formatErrorResponse('Request body must contain a "queries" array',400));if(e.length===0)return r.status(400).json(o.formatErrorResponse("Queries array cannot be empty",400));const s=await l(t,r),n=await o.handleBatchRequest(e,s,a);r.json(n)}catch(e){console.error("Batch execution error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Batch execution failed",500))}}),i.get(`${c}/meta`,(t,r)=>{try{const e=a.getMetadata();r.json(o.formatMetaResponse(e))}catch(e){console.error("Metadata error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Failed to fetch metadata",500))}}),i.post(`${c}/sql`,async(t,r)=>{try{const e=t.body,s=await l(t,r),n=a.validateQuery(e);if(!n.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${n.errors.join(", ")}`,400));const u=e.measures?.[0]||e.dimensions?.[0];if(!u)return r.status(400).json(o.formatErrorResponse("No measures or dimensions specified",400));const f=u.split(".")[0],j=await a.generateSQL(f,e,s);r.json(o.formatSqlResponse(e,j))}catch(e){console.error("SQL generation error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),i.get(`${c}/sql`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json(o.formatErrorResponse("Query parameter is required",400));const s=JSON.parse(e),n=await l(t,r),u=a.validateQuery(s);if(!u.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${u.errors.join(", ")}`,400));const f=s.measures?.[0]||s.dimensions?.[0];if(!f)return r.status(400).json(o.formatErrorResponse("No measures or dimensions specified",400));const j=f.split(".")[0],Q=await a.generateSQL(j,s,n);r.json(o.formatSqlResponse(s,Q))}catch(e){console.error("SQL generation error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),i.post(`${c}/dry-run`,async(t,r)=>{try{const e=t.body.query||t.body,s=await l(t,r),n=await o.handleDryRun(e,s,a);r.json(n)}catch(e){console.error("Dry-run error:",e),r.status(400).json({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),i.get(`${c}/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),n=await l(t,r),u=await o.handleDryRun(s,n,a);r.json(u)}catch(e){console.error("Dry-run error:",e),r.status(400).json({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),i.use((t,r,e,s)=>{console.error("Express adapter error:",t),e.headersSent||e.status(500).json(o.formatErrorResponse(t,500))}),i}function q(d,y){const p=E(y);return d.use("/",p),d}function x(d){const y=m();return q(y,d)}exports.createCubeApp=x;exports.createCubeRouter=E;exports.mountCubeRoutes=q;