@dataramen/cli 0.0.66 → 0.0.67-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
- "use strict";var Or=Object.create;var Le=Object.defineProperty;var Pr=Object.getOwnPropertyDescriptor;var Ar=Object.getOwnPropertyNames;var _r=Object.getPrototypeOf,vr=Object.prototype.hasOwnProperty;var Dr=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Ar(t))!vr.call(e,a)&&a!==r&&Le(e,a,{get:()=>t[a],enumerable:!(o=Pr(t,a))||o.enumerable});return e};var _=(e,t,r)=>(r=e!=null?Or(_r(e)):{},Dr(t||!e||!e.__esModule?Le(r,"default",{value:e,enumerable:!0}):r,e));var te=require("dotenv"),re=require("node:path"),Me=require("node:fs"),Ur=(()=>{try{let e=(0,Me.readFileSync)((0,re.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})(),Fe=[];process.argv[3]&&Fe.push((0,re.resolve)(process.argv[3]));(0,te.config)({path:Fe});(0,te.populate)(process.env,{SERVER_VERSION:Ur.version,APP_DB_TYPE:"sqlite",APP_DB_DATABASE:"<home>/.dataramen/.runtime/db.sqlite3",PROD:"true"},{override:!1});var xr=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],qe=()=>{let e=[];for(let t of xr)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))};function Lr(e,t=void 0){return process.env[e]||t}function Mr(e,t=void 0){let r=process.env[e];if(!r)return t;let o=Number(r);return!isNaN(o)&&r.trim()!==""?o:t}function Fr(e){return process.env[e]==="true"||process.env[e]==="TRUE"||process.env[e]==="1"}var T={str:Lr,num:Mr,bool:Fr};var Ou=require("reflect-metadata"),br=_(require("fastify")),Ir=_(require("qs"));var Ke=require("typeorm");var ke=require("typeorm");var y=T.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp";var fe=new ke.EntitySchema({name:"DatabaseInspection",tableName:"db_inspection",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},tableName:{nullable:!0,type:String},columns:{type:"json",nullable:!0},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"}},relations:{datasource:{target:()=>"DataSource",type:"many-to-one",joinTable:!1,cascade:!0}}});var Qe=require("typeorm");var ye=new Qe.EntitySchema({name:"Team",tableName:"teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"}},relations:{users:{type:"one-to-many",target:()=>"UsersToTeams",inverseSide:"team"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"team"},datasources:{type:"one-to-many",target:()=>"DataSource",inverseSide:"team"}}});var $e=require("typeorm");var Te=new $e.EntitySchema({name:"User",tableName:"users",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},username:{type:String,unique:!0},password:{type:String}},relations:{teams:{type:"one-to-many",target:()=>"UsersToTeams",inverseSide:"user"},settings:{type:"one-to-one",target:()=>"UserSettings",inverseSide:"user"},currentTeam:{type:"one-to-one",target:()=>"UsersToTeams",inverseSide:"user",joinColumn:!0},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"user"}}});var Be=require("typeorm");var he=new Be.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"}},relations:{user:{type:"one-to-one",target:()=>"User",inverseSide:"settings",joinColumn:!0}}});var We=require("typeorm");var ge=new We.EntitySchema({name:"DataSource",tableName:"data_sources",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},dbUrl:{type:String},dbPort:{type:Number,nullable:!0},dbUser:{type:String},dbPassword:{type:String,nullable:!0,select:!1},dbPasswordIv:{type:String,nullable:!0,select:!1},dbPasswordTag:{type:String,nullable:!0,select:!1},dbType:{type:String},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},name:{type:String},description:{type:String,nullable:!0},dbDatabase:{type:String},dbSchema:{type:String,nullable:!0},allowInsert:{type:Boolean,default:!1},allowUpdate:{type:Boolean,default:!1},lastInspected:{type:y,nullable:!0,default:null},status:{type:String,nullable:!0}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"datasources",joinColumn:!0},inspections:{type:"one-to-many",target:()=>"DatabaseInspection",inverseSide:"datasource"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"dataSource"},owner:{type:"many-to-one",target:()=>"User",joinColumn:!0}}});var Ve=_(require("node:os")),ze=require("node:path");var He=require("typeorm");var we=new He.EntitySchema({name:"Query",tableName:"query",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},opts:{type:"json",default:"{}"},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"queries",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",inverseSide:"datasources",joinColumn:!0},user:{type:"many-to-one",target:()=>"User",inverseSide:"queries",joinColumn:!0,nullable:!0}}});var Ye=require("typeorm"),Ee=new Ye.EntitySchema({name:"UsersToTeams",tableName:"users_to_teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},role:{type:"varchar",default:"admin",nullable:!1}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"users"},user:{type:"many-to-one",target:()=>"User",inverseSide:"teams"}}});var je=require("typeorm");var Se=new je.EntitySchema({name:"SavedQuery",tableName:"saved_queries",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},isPersonal:{type:Boolean},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"},searchString:{type:String,default:()=>null}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"queries",joinColumn:!0},user:{type:"many-to-one",target:()=>"User",inverseSide:"queries",joinColumn:!0,nullable:!0},query:{type:"one-to-one",target:()=>"Query",joinColumn:!0,nullable:!1}}});var Ge=require("typeorm");var Re=new Ge.EntitySchema({name:"WorkbenchTab",tableName:"workbench_tabs",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"},opts:{type:"json",default:"{}"},archived:{type:Boolean,default:!1},searchString:{type:String,default:()=>null}},relations:{team:{type:"many-to-one",target:()=>"Team",joinColumn:!0},user:{type:"many-to-one",target:()=>"User",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",joinColumn:!0}}});function qr(){let e=T.str("APP_DB_DATABASE");if(!e)throw new Error("Bad value for TYPEORM_DATABASE. Please check your config!");return e.startsWith("<home>")&&(e=e.replace("<home>",Ve.default.homedir())),e}var g=new Ke.DataSource({type:T.str("APP_DB_TYPE"),database:qr(),host:T.str("APP_DB_HOST"),username:T.str("APP_DB_USERNAME"),password:T.str("APP_DB_PASSWORD"),port:T.num("APP_DB_PORT"),schema:T.str("APP_DB_SCHEMA"),logging:T.bool("APP_DB_LOGGING"),migrationsRun:!0,migrations:[ze.posix.join(__dirname,"migrations","*.js")],entities:[fe,ge,ye,Te,Ee,he,we,Se,Re]}),Je=async()=>{if(!g.isInitialized)return g.initialize();throw new Error("Already initialized")},D=g.getRepository(fe),b=g.getRepository(ge),M=g.getRepository(ye),R=g.getRepository(Te),C=g.getRepository(Ee),B=g.getRepository(he),I=g.getRepository(we),U=g.getRepository(Se),O=g.getRepository(Re);var be=_(require("bcryptjs")),Y=async e=>{let t=await be.default.genSalt(10);return be.default.hash(e,t)};var Ie={teamName:"Default Team",username:"admin",password:"admin"},kr=async()=>{let e=await M.findOneBy({});return e||M.save(M.create({name:Ie.teamName}))},Xe=async()=>{let e=await C.findOne({where:{role:"owner"},relations:{user:!0}});if(e)return e.user;let t=await kr(),r=await Y(Ie.password),o=await R.save(R.create({username:Ie.username,password:r})),a=await C.save(C.create({user:o,team:t,role:"owner"}));return await R.update(o.id,{currentTeam:a}),o};var Qr={hosted:{bindServerUrl:"0.0.0.0",skipAuth:!1,name:"hosted"},local:{bindServerUrl:"127.0.0.1",skipAuth:!0,name:"local"}},Ze=process.argv[2];if(!Ze)throw new Error(`Invalid mode "${process.argv[2]}"`);var Q=Qr[Ze];var et=T.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),tt=T.num("PORT",4466),j={port:tt,host:Q.bindServerUrl,allowedOrigins:et.includes("*")?"*":[`http://localhost:${tt}`,...et]};var h=e=>(t,r,o)=>{e(t),o()};var G=require("jose");var s=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var rt=new TextEncoder,ot=rt.encode(T.str("JWT_SECRET")),at=rt.encode(T.str("JWT_REFRESH_SECRET")),Ne=async({userId:e})=>new G.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(ot),Ce=async({userId:e})=>new G.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(at),nt=async(e,t)=>{try{let{payload:r}=await(0,G.jwtVerify)(e,t);if(!r.sub)throw new s(401,"Failed to verify access token");return{userId:r.sub}}catch(r){throw r instanceof s?r:r instanceof Error?new s(401,r.message):new s(401,"Failed to verify refresh token")}},st=async e=>nt(e,ot),it=async e=>nt(e,at);var f=(e,t)=>{let r=e.body;return t&&t(r),r},x=(e,t)=>{let r=e.query;return t&&t(r),r},m=(e,t)=>{let r=e.params;return t&&t(r),r};var ct=_(require("bcryptjs"));var ut=e=>{if(!e?.username)throw new s(400,"Username is required");if(!e?.password)throw new s(400,"Password is required")};var oe="DATARAMEN_refresh_token",Oe={httpOnly:!0,secure:T.bool("PROD"),sameSite:T.bool("PROD"),path:"/",maxAge:10*24*60*60},lt=h(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let{username:o,password:a}=f(t,ut),n=await R.findOne({where:{username:o}});if(!n||!ct.default.compareSync(a,n.password))throw new s(401,"Invalid credentials");let[i,u]=await Promise.all([Ne({userId:n?.id}),Ce({userId:n?.id})]);return r.setCookie(oe,u,Oe),{data:{accessToken:i}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies[oe];if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await it(o),[n,i]=await Promise.all([Ne({userId:a}),Ce({userId:a})]);return r.setCookie(oe,i,Oe),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie(oe,Oe),{data:!0})})});var mt=e=>{if(!e.dbUrl)throw new s(400,"url is required");if(!e.dbUser)throw new s(400,"user is required");if(!e.dbType)throw new s(400,"type is required");if(!e.name)throw new s(400,"name is required");if(!e.dbDatabase)throw new s(400,"database is required")};var pt=_(require("mysql2/promise"));function K(e){if(e!==void 0)return e.toLowerCase()}var $r=({database:e,password:t,user:r,url:o})=>pt.default.createConnection({host:o,user:r,database:e,password:t}),Br=async e=>{let t=`
1
+ "use strict";var kr=Object.create;var qe=Object.defineProperty;var qr=Object.getOwnPropertyDescriptor;var Fr=Object.getOwnPropertyNames;var Qr=Object.getPrototypeOf,Br=Object.prototype.hasOwnProperty;var $r=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Fr(t))!Br.call(e,a)&&a!==r&&qe(e,a,{get:()=>t[a],enumerable:!(o=qr(t,a))||o.enumerable});return e};var _=(e,t,r)=>(r=e!=null?kr(Qr(e)):{},$r(t||!e||!e.__esModule?qe(r,"default",{value:e,enumerable:!0}):r,e));var re=require("dotenv"),oe=require("node:path"),Fe=require("node:fs"),Wr=(()=>{try{let e=(0,Fe.readFileSync)((0,oe.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})(),Qe=[];process.argv[3]&&Qe.push((0,oe.resolve)(process.argv[3]));(0,re.config)({path:Qe});var he={APP_DB_TYPE:"sqlite",APP_DB_DATABASE:"<home>/.dataramen/.runtime/db.sqlite3"};(0,re.populate)(process.env,{SERVER_VERSION:Wr.version,PROD:"true",...he},{override:!1});var Hr=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],Be=()=>{let e=[];for(let t of Hr)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))};function Yr(e,t=void 0){return process.env[e]||t}function jr(e,t=void 0){let r=process.env[e];if(!r)return t;let o=Number(r);return!isNaN(o)&&r.trim()!==""?o:t}function Gr(e){return process.env[e]==="true"||process.env[e]==="TRUE"||process.env[e]==="1"}var y={str:Yr,num:jr,bool:Gr},$e=()=>y.str("APP_DB_TYPE")!==he.APP_DB_TYPE&&y.str("APP_DB_DATABASE")!==he.APP_DB_DATABASE;var rc=require("reflect-metadata"),Ur=_(require("fastify")),xr=_(require("qs"));var Xe=require("typeorm");var We=require("typeorm");var h=y.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp";var ge=new We.EntitySchema({name:"DatabaseInspection",tableName:"db_inspection",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},tableName:{nullable:!0,type:String},columns:{type:"json",nullable:!0},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP"}},relations:{datasource:{target:()=>"DataSource",type:"many-to-one",joinTable:!1,cascade:!0}}});var He=require("typeorm");var we=new He.EntitySchema({name:"Team",tableName:"teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP"}},relations:{users:{type:"one-to-many",target:()=>"UsersToTeams",inverseSide:"team"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"team"},datasources:{type:"one-to-many",target:()=>"DataSource",inverseSide:"team"}}});var Ye=require("typeorm");var Se=new Ye.EntitySchema({name:"User",tableName:"users",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},username:{type:String,unique:!0},password:{type:String}},relations:{teams:{type:"one-to-many",target:()=>"UsersToTeams",inverseSide:"user"},settings:{type:"one-to-one",target:()=>"UserSettings",inverseSide:"user"},currentTeam:{type:"one-to-one",target:()=>"UsersToTeams",inverseSide:"user",joinColumn:!0},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"user"}}});var je=require("typeorm");var Ee=new je.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP"}},relations:{user:{type:"one-to-one",target:()=>"User",inverseSide:"settings",joinColumn:!0}}});var Ge=require("typeorm");var Re=new Ge.EntitySchema({name:"DataSource",tableName:"data_sources",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},dbUrl:{type:String},dbPort:{type:Number,nullable:!0},dbUser:{type:String},dbPassword:{type:String,nullable:!0,select:!1},dbPasswordIv:{type:String,nullable:!0,select:!1},dbPasswordTag:{type:String,nullable:!0,select:!1},dbType:{type:String},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},name:{type:String},description:{type:String,nullable:!0},dbDatabase:{type:String},dbSchema:{type:String,nullable:!0},allowInsert:{type:Boolean,default:!1},allowUpdate:{type:Boolean,default:!1},lastInspected:{type:h,nullable:!0,default:null},status:{type:String,nullable:!0}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"datasources",joinColumn:!0},inspections:{type:"one-to-many",target:()=>"DatabaseInspection",inverseSide:"datasource"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"dataSource"},owner:{type:"many-to-one",target:()=>"User",joinColumn:!0}}});var Ze=_(require("node:os")),et=require("node:path");var Ke=require("typeorm");var be=new Ke.EntitySchema({name:"Query",tableName:"query",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},opts:{type:"json",default:"{}"},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"queries",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",inverseSide:"datasources",joinColumn:!0},user:{type:"many-to-one",target:()=>"User",inverseSide:"queries",joinColumn:!0,nullable:!0}}});var Ve=require("typeorm"),Ie=new Ve.EntitySchema({name:"UsersToTeams",tableName:"users_to_teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},role:{type:"varchar",default:"admin",nullable:!1}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"users"},user:{type:"many-to-one",target:()=>"User",inverseSide:"teams"}}});var ze=require("typeorm");var Ne=new ze.EntitySchema({name:"SavedQuery",tableName:"saved_queries",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},isPersonal:{type:Boolean},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"},searchString:{type:String,default:()=>null}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"queries",joinColumn:!0},user:{type:"many-to-one",target:()=>"User",inverseSide:"queries",joinColumn:!0,nullable:!0},query:{type:"one-to-one",target:()=>"Query",joinColumn:!0,nullable:!1}}});var Je=require("typeorm");var Ce=new Je.EntitySchema({name:"WorkbenchTab",tableName:"workbench_tabs",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:h,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:h,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"},opts:{type:"json",default:"{}"},archived:{type:Boolean,default:!1},searchString:{type:String,default:()=>null}},relations:{team:{type:"many-to-one",target:()=>"Team",joinColumn:!0},user:{type:"many-to-one",target:()=>"User",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",joinColumn:!0}}});function Kr(){let e=y.str("APP_DB_DATABASE");if(!e)throw new Error("Bad value for TYPEORM_DATABASE. Please check your config!");return e.startsWith("<home>")&&(e=e.replace("<home>",Ze.default.homedir())),e}var g=new Xe.DataSource({type:y.str("APP_DB_TYPE"),database:Kr(),host:y.str("APP_DB_HOST"),username:y.str("APP_DB_USERNAME"),password:y.str("APP_DB_PASSWORD"),port:y.num("APP_DB_PORT"),schema:y.str("APP_DB_SCHEMA"),logging:y.bool("APP_DB_LOGGING"),migrationsRun:!0,migrations:[et.posix.join(__dirname,"migrations","*.js")],entities:[ge,Re,we,Se,Ie,Ee,be,Ne,Ce]}),tt=async()=>{if(!g.isInitialized)return g.initialize();throw new Error("Already initialized")},D=g.getRepository(ge),b=g.getRepository(Re),k=g.getRepository(we),w=g.getRepository(Se),C=g.getRepository(Ie),W=g.getRepository(Ee),I=g.getRepository(be),U=g.getRepository(Ne),A=g.getRepository(Ce);var Vr={hosted:{bindServerUrl:"0.0.0.0",skipAuth:!1,name:"hosted"},local:{bindServerUrl:"127.0.0.1",skipAuth:!0,name:"local"}},rt=process.argv[2];if(!rt)throw new Error(`Invalid mode "${process.argv[2]}"`);var x=Vr[rt];var ot=y.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),at=y.num("PORT",4466),j={port:at,host:x.bindServerUrl,allowedOrigins:ot.includes("*")?"*":[`http://localhost:${at}`,...ot]};var T=e=>(t,r,o)=>{e(t),o()};var G=require("jose");var s=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var nt=new TextEncoder,st=nt.encode(y.str("JWT_SECRET")),it=nt.encode(y.str("JWT_REFRESH_SECRET")),Ae=async({userId:e})=>new G.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(st),Pe=async({userId:e})=>new G.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(it),ut=async(e,t)=>{try{let{payload:r}=await(0,G.jwtVerify)(e,t);if(!r.sub)throw new s(401,"Failed to verify access token");return{userId:r.sub}}catch(r){throw r instanceof s?r:r instanceof Error?new s(401,r.message):new s(401,"Failed to verify refresh token")}},ct=async e=>ut(e,st),lt=async e=>ut(e,it);var m=(e,t)=>{let r=e.body;return t&&t(r),r},L=(e,t)=>{let r=e.query;return t&&t(r),r},d=(e,t)=>{let r=e.params;return t&&t(r),r};var dt=_(require("bcryptjs"));var mt=e=>{if(!e?.username)throw new s(400,"Username is required");if(!e?.password)throw new s(400,"Password is required")};var ae="DATARAMEN_refresh_token",Oe={httpOnly:!0,secure:y.bool("PROD"),sameSite:y.bool("PROD"),path:"/",maxAge:10*24*60*60},pt=T(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let{username:o,password:a}=m(t,mt),n=await w.findOne({where:{username:o}});if(!n||!dt.default.compareSync(a,n.password))throw new s(401,"Invalid credentials");let[i,u]=await Promise.all([Ae({userId:n?.id}),Pe({userId:n?.id})]);return r.setCookie(ae,u,Oe),{data:{accessToken:i}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies[ae];if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await lt(o),[n,i]=await Promise.all([Ae({userId:a}),Pe({userId:a})]);return r.setCookie(ae,i,Oe),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie(ae,Oe),{data:!0})})});var ft=e=>{if(!e.dbUrl)throw new s(400,"url is required");if(!e.dbUser)throw new s(400,"user is required");if(!e.dbType)throw new s(400,"type is required");if(!e.name)throw new s(400,"name is required");if(!e.dbDatabase)throw new s(400,"database is required")};var Tt=_(require("mysql2/promise"));function K(e){if(e!==void 0)return e.toLowerCase()}var zr=({database:e,password:t,user:r,url:o})=>Tt.default.createConnection({host:o,user:r,database:e,password:t}),Jr=async e=>{let t=`
2
2
  SELECT LOWER(TABLE_NAME) as TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION
3
3
  FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
4
4
  WHERE CONSTRAINT_NAME = 'PRIMARY'
5
5
  ORDER BY TABLE_NAME, ORDINAL_POSITION;
6
- `,[r]=await e.execute(t),o={};return r.forEach(a=>{let n=K(a.TABLE_NAME),i=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(i)}),o},Wr=async e=>{let t=`
6
+ `,[r]=await e.execute(t),o={};return r.forEach(a=>{let n=K(a.TABLE_NAME),i=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(i)}),o},Xr=async e=>{let t=`
7
7
  SELECT
8
8
  LOWER(TABLE_NAME) AS table_name,
9
9
  COLUMN_NAME AS field,
@@ -14,7 +14,7 @@
14
14
  WHERE
15
15
  REFERENCED_TABLE_NAME IS NOT NULL
16
16
  AND CONSTRAINT_SCHEMA = DATABASE();
17
- `,[r]=await e.execute(t),o={};return Array.isArray(r)&&r.forEach(a=>{o[a.table_name]||(o[a.table_name]={}),o[a.table_name][a.field]={refTable:a.referenced_table,refField:a.referenced_field}}),o},Hr=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await Wr(t),n=await Br(t),i=o.map(async u=>{let d=K(Object.values(u)[0]),c=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and LOWER(table_name) = '${d}'`,[S]=await t.query(c),w=a[d];return{columns:S.map(l=>({name:l.COLUMN_NAME,type:l.DATA_TYPE,isPrimary:n[d]?.includes(l.COLUMN_NAME),ref:w?.[l.COLUMN_NAME]?{table:w[l.COLUMN_NAME].refTable,field:w[l.COLUMN_NAME].refField}:void 0})).sort((l,N)=>l.isPrimary&&N.isPrimary?l.name.localeCompare(N.name):l.isPrimary?-1:1),createdAt:new Date,tableName:d,updatedAt:new Date}});return Promise.all(i)},dt=async(e,t,r)=>{try{console.log(`[MYSQL CONN] Query: ${e}`);let[o,a]=await t.query({sql:e,rowsAsArray:!0}),n=o?.constructor?.name;if(n==="ResultSetHeader"){let i=o;if(i.affectedRows>1&&r.allowBulkUpdate!==!0)throw new Error("[MYSQL CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i.affectedRows]],query:e}}else if(n==="Array"){let i=o;return{columns:a?.map(u=>({column:u.orgName||u.name,table:K(u.orgTable),alias:u.name,full:u.orgTable?K(u.orgTable)+"."+u.orgName:u.name}))||[],rows:i,query:e}}throw new Error(`[MYSQL CONN] Unknown result type: ${n}`)}catch(o){throw console.error(o),o instanceof s?o:new s(400,o.message)}},Yr=async(e,t)=>{await e.beginTransaction();try{let r=await t();return await e.commit(),console.log("[MYSQL CONN] Commit"),r}catch(r){throw await e.rollback(),console.warn(r.message),console.log("[MYSQL CONN] Rollback"),r}},jr=async(e,t)=>{await e.query("START TRANSACTION READ ONLY");try{let r=await t();return console.log("[MYSQL CONN] Read only rollback"),await e.query("ROLLBACK"),r}catch(r){throw console.warn(r.message),await e.query("ROLLBACK"),r}},ft=async e=>{let t=await $r(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>Hr(e,t),executeQuery:(o,a)=>a.type==="SELECT"?jr(t,()=>dt(o,t,a)):Yr(t,()=>dt(o,t,a)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var Tt=_(require("pg"));var Gr=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new Tt.default.Client({host:o,user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},Kr=async e=>{let r=await e.query(`
17
+ `,[r]=await e.execute(t),o={};return Array.isArray(r)&&r.forEach(a=>{o[a.table_name]||(o[a.table_name]={}),o[a.table_name][a.field]={refTable:a.referenced_table,refField:a.referenced_field}}),o},Zr=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await Xr(t),n=await Jr(t),i=o.map(async u=>{let p=K(Object.values(u)[0]),c=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and LOWER(table_name) = '${p}'`,[R]=await t.query(c),S=a[p];return{columns:R.map(l=>({name:l.COLUMN_NAME,type:l.DATA_TYPE,isPrimary:n[p]?.includes(l.COLUMN_NAME),ref:S?.[l.COLUMN_NAME]?{table:S[l.COLUMN_NAME].refTable,field:S[l.COLUMN_NAME].refField}:void 0})).sort((l,N)=>l.isPrimary&&N.isPrimary?l.name.localeCompare(N.name):l.isPrimary?-1:1),createdAt:new Date,tableName:p,updatedAt:new Date}});return Promise.all(i)},yt=async(e,t,r)=>{try{console.log(`[MYSQL CONN] Query: ${e}`);let[o,a]=await t.query({sql:e,rowsAsArray:!0}),n=o?.constructor?.name;if(n==="ResultSetHeader"){let i=o;if(i.affectedRows>1&&r.allowBulkUpdate!==!0)throw new Error("[MYSQL CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i.affectedRows]],query:e}}else if(n==="Array"){let i=o;return{columns:a?.map(u=>({column:u.orgName||u.name,table:K(u.orgTable),alias:u.name,full:u.orgTable?K(u.orgTable)+"."+u.orgName:u.name}))||[],rows:i,query:e}}throw new Error(`[MYSQL CONN] Unknown result type: ${n}`)}catch(o){throw console.error(o),o instanceof s?o:new s(400,o.message)}},eo=async(e,t)=>{await e.beginTransaction();try{let r=await t();return await e.commit(),console.log("[MYSQL CONN] Commit"),r}catch(r){throw await e.rollback(),console.warn(r.message),console.log("[MYSQL CONN] Rollback"),r}},to=async(e,t)=>{await e.query("START TRANSACTION READ ONLY");try{let r=await t();return console.log("[MYSQL CONN] Read only rollback"),await e.query("ROLLBACK"),r}catch(r){throw console.warn(r.message),await e.query("ROLLBACK"),r}},ht=async e=>{let t=await zr(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>Zr(e,t),executeQuery:(o,a)=>a.type==="SELECT"?to(t,()=>yt(o,t,a)):eo(t,()=>yt(o,t,a)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var wt=_(require("pg"));var ro=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new wt.default.Client({host:o,user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},oo=async e=>{let r=await e.query(`
18
18
  SELECT
19
19
  LOWER(kcu.table_name) as table_name,
20
20
  kcu.column_name,
@@ -28,7 +28,7 @@
28
28
  tc.constraint_type = 'PRIMARY KEY'
29
29
  ORDER BY
30
30
  table_name, kcu.ordinal_position;
31
- `),o={};return r.rows.forEach(a=>{let n=a.table_name,i=a.column_name;o[n]||(o[n]=[]),o[n].push(i)}),o},Vr=async e=>{let r=await e.query(`
31
+ `),o={};return r.rows.forEach(a=>{let n=a.table_name,i=a.column_name;o[n]||(o[n]=[]),o[n].push(i)}),o},ao=async e=>{let r=await e.query(`
32
32
  SELECT
33
33
  LOWER(tc.table_name) AS table_name,
34
34
  kcu.column_name AS field,
@@ -43,15 +43,16 @@
43
43
  ON ccu.constraint_name = tc.constraint_name
44
44
  AND ccu.table_schema = tc.table_schema
45
45
  WHERE tc.constraint_type = 'FOREIGN KEY';
46
- `),o={};return r.rows.forEach(a=>{o[a.table_name]||(o[a.table_name]={}),o[a.table_name][a.field]={refTable:a.referenced_table,refField:a.referenced_field}}),o},zr=async(e,t)=>{let r=`SELECT LOWER(tablename) as tablename FROM pg_catalog.pg_tables WHERE schemaname = '${e.schema}'`,a=(await t.query(r)).rows,n=await Vr(t),i=await Kr(t),u=a.map(async d=>{let c=Object.values(d)[0],S=`
46
+ `),o={};return r.rows.forEach(a=>{o[a.table_name]||(o[a.table_name]={}),o[a.table_name][a.field]={refTable:a.referenced_table,refField:a.referenced_field}}),o},no=async(e,t)=>{let r=`SELECT LOWER(tablename) as tablename FROM pg_catalog.pg_tables WHERE schemaname = '${e.schema}'`,a=(await t.query(r)).rows,n=await ao(t),i=await oo(t),u=a.map(async p=>{let c=Object.values(p)[0],R=`
47
47
  SELECT column_name, data_type
48
48
  FROM information_schema.columns
49
49
  WHERE
50
50
  LOWER(table_name) = '${c}' and
51
51
  table_schema = '${e.schema}'
52
- `,{rows:w}=await t.query(S),l=n[c];return{columns:w.map(N=>({name:N.column_name,type:N.data_type,isPrimary:i[c]?.includes(N.column_name),ref:l?.[N.column_name]?{table:l[N.column_name].refTable,field:l[N.column_name].refField}:void 0})).sort((N,L)=>N.isPrimary&&L.isPrimary?N.name.localeCompare(L.name):N.isPrimary?-1:1),createdAt:new Date,tableName:c,updatedAt:new Date}});return Promise.all(u)},Jr=async(e,t)=>{let r=`select LOWER(relname) as relname, attname, concat(pg_class.oid, '-', attnum) as row_key
52
+ `,{rows:S}=await t.query(R),l=n[c];return{columns:S.map(N=>({name:N.column_name,type:N.data_type,isPrimary:i[c]?.includes(N.column_name),ref:l?.[N.column_name]?{table:l[N.column_name].refTable,field:l[N.column_name].refField}:void 0})).sort((N,M)=>N.isPrimary&&M.isPrimary?N.name.localeCompare(M.name):N.isPrimary?-1:1),createdAt:new Date,tableName:c,updatedAt:new Date}});return Promise.all(u)},so=async(e,t)=>{let r=`select LOWER(relname) as relname, attname, concat(pg_class.oid, '-', attnum) as row_key
53
53
  from pg_attribute
54
54
  left join pg_class on pg_attribute.attrelid = pg_class.oid
55
55
  where
56
56
  concat(pg_class.oid, '-', attnum) IN (${e.join(", ")})
57
- limit 75;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},yt=async(e,t,r)=>{try{console.log(`[PG CONN] Query: ${e}`);let{rows:o,fields:a,command:n,rowCount:i}=await t.query({text:e,rowMode:"array"});if(n==="UPDATE"||n==="INSERT"||n==="DELETE"){if(i!=null&&i>1&&r.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i]],query:e}}if(n==="SELECT"){let u=a.map(c=>`'${c.tableID}-${c.columnID}'`),d=await Jr(u,t);return{columns:a.map(c=>{let S=d[`${c.tableID}-${c.columnID}`];return{column:S?.column||c.name,alias:c.name,table:S?.table||"",full:S?S.table+"."+S.column:c.name}}),rows:o,query:e}}throw new Error(`[PG CONN] Unsupported command: ${n}`)}catch(o){throw o instanceof s?o:new s(400,o.message)}},Xr=async(e,t)=>{await e.query("BEGIN");try{let r=await t();return await e.query("COMMIT"),console.log("[PG CONN] Commit"),r}catch(r){throw await e.query("ROLLBACK"),console.log("[PG CONN] Rollback"),r}},Zr=async(e,t)=>{await e.query("BEGIN READ ONLY");try{let r=await t();return console.log("[PG CONN] Read only rollback"),await e.query("ROLLBACK"),r}catch(r){throw console.log("[PG CONN] Rollback"),await e.query("ROLLBACK"),r}},ht=async e=>{let t=await Gr(e),r=!1,o=!1,a=async n=>(o||await t.query(`SET search_path TO ${e.schema}`),n());return{dbType:"postgres",dataSource:e,inspectSchema:()=>zr(e,t),executeQuery:(n,i)=>a(()=>i.type==="SELECT"?Zr(t,()=>yt(n,t,i)):Xr(t,()=>yt(n,t,i))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var q=async(e,t,r)=>{try{let o;if(t==="mysql")o=await ft(e);else if(t==="postgres")o=await ht(e);else throw new s(500,`Connection manager for ${t} not found`);return r.__connections?r.__connections.push(o):r.__connections=[o],o}catch(o){throw console.error(o),o instanceof s?o:o?.code==="ECONNREFUSED"?new s(500,"Failed to connect to the database"):new s(500,o.message)}};var ae=_(require("node:crypto"));var gt="aes-256-gcm",eo=12,wt=()=>{let e=T.str("SYMM_ENCRYPTION_KEY");if(!e)throw new Error("Missing ENCRYPTION_KEY in environment variables.");let t=Buffer.from(e,"hex");if(t.length!==32)throw new Error("ENCRYPTION_KEY must be a 64-character hex string (256 bits).");return t},to=e=>{let t=ae.default.randomBytes(eo),r=wt(),o=ae.default.createCipheriv(gt,r,t),a=o.update(e,"utf8","hex");a+=o.final("hex");let n=o.getAuthTag();return{encrypted:a,iv:t.toString("hex"),tag:n.toString("hex")}},ro=({encrypted:e,iv:t,tag:r})=>{let o=wt(),a=ae.default.createDecipheriv(gt,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},ne={encrypt:to,decrypt:ro};var k=(e,t=!1)=>{if(t){let r=ne.decrypt({encrypted:e.dbPassword,tag:e.dbPasswordTag,iv:e.dbPasswordIv});return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:r,port:e.dbPort,schema:e.dbSchema}}return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:e.dbPassword,port:e.dbPort,schema:e.dbSchema}};var Et=[{value:"=",label:"equals"},{value:"<>",label:"not equal"},{value:">",label:"greater than"},{value:">=",label:"greater than or equal"},{value:"<",label:"less than"},{value:"<=",label:"less than or equal"},{value:"LIKE",label:"contains"},{value:"NOT LIKE",label:"not contains"},{value:"IN",label:"in list"},{value:"NOT IN",label:"not in list"},{value:"IS NULL",label:"is null"},{value:"IS NOT NULL",label:"is not null"}],oo=Et.reduce((e,t)=>(e[t.value]=t.label,e),{}),sn=Et.reduce((e,t)=>(e[t.label]=t.value,e),{}),W=e=>e.map(t=>({label:oo[t],value:t})),un=W(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),cn=W(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL"]),ln=W(["=","<>","IS NULL","IS NOT NULL"]),mn=W(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),dn=W(["IS NULL","IS NOT NULL"]),pn=W(["IN","NOT IN"]);var Pe=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],ao=new Set(Pe),se=e=>ao.has(e),no=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],so=new Set(no),St=e=>so.has(e);var fn=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var Ae=e=>e.fn?e.distinct===!0?`${e.fn} distinct ${e.value}`:`${e.fn} ${e.value}`:e.value;var _e={read_only:10,editor:20,admin:30,owner:40};var v=e=>e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;var Rt={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:v(t[1])}]},stringify:(e,t)=>se(t)?`${e.value?.[0].value}`:`LIKE "%${e.value?.[0].value}%"`},bt={operator:"NOT LIKE",parse:e=>{let t=e.match(/^NOT LIKE\s*["'](.*)["']$/i);if(t)return[{value:v(t[1])}]},stringify:e=>`NOT LIKE "%${e.value?.[0].value}%"`};function Nt(e){return e===""?[]:io(e).map(uo)}function io(e){let t=[],r=0,o="",a=!1,n=!1;for(;r<e.length;){let i=e[r];if((a||n)&&i==="\\"){o+=e[r+1],r+=2;continue}if(i==="'"&&!n){a=!a,o+=i,r++;continue}if(i==='"'&&!a){n=!n,o+=i,r++;continue}if(i===","&&!a&&!n){t.push(o.trim()),o="",r++;continue}o+=i,r++}if(o.trim()!==""&&t.push(o.trim()),a||n)throw new Error("Unterminated string literal");return t}function uo(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:It(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:It(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function It(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var Ct={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return Nt(t[1])},stringify:e=>`IN (${e.value?.map(t=>`"${t.value}"`).join(", ")})`},Ot={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return Nt(t[1])},stringify:e=>`NOT IN (${e.value?.map(t=>`"${t.value}"`).join(", ")})`};var Pt={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:(e,t)=>St(t)?`${e.value?.[0].value}`:`= ${e.value?.[0].value}`},At={operator:"!=",parse:e=>{let t=e.match(/^!=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`!= ${e.value?.[0].value}`},_t={operator:"<>",parse:e=>{let t=e.match(/^<>\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`<> ${e.value?.[0].value}`},vt={operator:">",parse:e=>{let t=e.match(/^>\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`> ${e.value?.[0].value}`},Dt={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`>= ${e.value?.[0].value}`},Ut={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`< ${e.value?.[0].value}`},xt={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`<= ${e.value?.[0].value}`};var Lt={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},Mt={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var Ft=[Rt,bt,Ct,Ot,Pt,At,_t,Dt,vt,xt,Ut,Lt,Mt],co=Ft.reduce((e,t)=>(e[t.operator]=t,e),{});function lo(e,t){return co[e.operator]?.stringify(e,t)||""}function mo(e){let t=e.trim();for(let r of Ft){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var qt={parse:mo,stringify:lo};var E=e=>{let t=_e[e];return r=>_e[r.currentTeamRole]>=t},kt=async e=>{let t=e.routeOptions.config.requireRole;if(t&&!t(e.user))throw new s(403,"You are not authorized to perform this action")};var Qt=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=m(t),o=await b.findOne({where:{id:r}});if(!o)throw new s(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=x(t);return{data:await b.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:E("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=f(t,mt),n=b.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),i=await q(k(n),n.dbType,t);try{await i.checkConnection()}catch{throw new s(400,"Cannot connect to the database, please check datasource configuration")}let{tag:u,iv:d,encrypted:c}=ne.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=d,n.dbPasswordTag=u,{data:await b.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=m(t),o=f(t),a=await b.findOneBy({id:r});if(!a)throw new s(404,"Data source not found");let n=b.merge(a,o);return await b.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async(t,r)=>g.transaction(async()=>{let{id:o}=m(t);await Promise.all([D.delete({datasource:{id:o}}),I.delete({dataSource:{id:o}})]),await b.delete({id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=m(t),a=await b.findOne({where:{id:o},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!a)throw new Error("Data source not found");a.status="INSPECTING",await b.save(a);let i=await(await q(k(a,!0),a.dbType,t)).inspectSchema();await D.delete({datasource:{id:o}}),await D.insert(i.sort().map(u=>D.create({tableName:u.tableName,columns:u.columns,datasource:{id:o}}))),a.status="READY",a.lastInspected=new Date,await b.save(a)}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=m(t);return{data:await D.find({where:{datasource:{id:r}}})}}})});var $=require("typeorm"),$t=h(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=m(t);return{data:await b.find({where:{team:{id:r}},order:{name:"ASC"},select:{id:!0,name:!0,updatedAt:!0,dbType:!0,description:!0,allowInsert:!0,allowUpdate:!0}})}}}),e.route({method:"get",url:"/team/:teamId/queries",handler:async t=>{let o=m(t).teamId||t.user.currentTeamId;return{data:(await U.find({where:[{isPersonal:!1,team:{id:o}},{isPersonal:!0,team:{id:o},user:{id:t.user.id}}],relations:{query:!0},select:{id:!0,query:{id:!0,name:!0,updatedAt:!0}}})).map(i=>({name:i.query.name,id:i.query.id,updatedAt:i.query.updatedAt,savedQueryId:i.id}))}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=m(t),{search:o,size:a,selectedDataSources:n}=x(t),i=o.length>3?parseInt(a)||20:8,u={};n?.length&&(u.id=(0,$.In)(n));let[d,c,S]=await Promise.all([D.find({where:{tableName:(0,$.Raw)(l=>`LOWER(${l}) LIKE :search`,{search:`%${o.toLowerCase()}%`}),datasource:u},relations:{datasource:!0},select:{id:!0,tableName:!0,datasource:{name:!0,id:!0}},order:{tableName:"ASC"},take:i}),O.find({where:{searchString:(0,$.Like)(`%${o.toLowerCase()}%`),team:{id:r},user:{id:t.user.id},dataSource:u},relations:{dataSource:!0},select:{id:!0,name:!0,updatedAt:!0,dataSource:{id:!0,name:!0}},order:{updatedAt:"ASC"},take:i}),U.find({where:{searchString:(0,$.Like)(`%${o.toLowerCase()}%`),team:{id:r},query:{dataSource:u}},relations:{query:{dataSource:!0}},select:{id:!0,updatedAt:!0,query:{id:!0,name:!0,dataSource:{name:!0}}},order:{updatedAt:"ASC"},take:i})]),w=[];return d.forEach(l=>{w.push({name:l.tableName,id:l.id,dataSourceName:l.datasource?.name||"--",dataSourceId:l.datasource?.id||"--",type:"table"})}),c.forEach(l=>{w.push({name:l.name,id:l.id,dataSourceName:l.dataSource?.name||"--",dataSourceId:l.dataSource?.id||"--",type:"tab"})}),S.forEach(l=>{w.push({name:l.query.name,id:l.query.id,dataSourceName:l.query.dataSource?.name||"--",dataSourceId:l.query.dataSource?.id||"--",type:"query"})}),{data:w}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=m(t),o=x(t),a=Number(o.page),n=Number(o.size),i=t.user.id,u=await O.find({where:{team:{id:r},user:{id:i}},relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),d=!1;return u.length>n&&(u.pop(),d=!0),{data:u.map(c=>({name:c.name,id:c.id,updatedAt:c.updatedAt,archived:c.archived,createdAt:c.createdAt,dataSourceId:c.dataSource?.id,dataSourceName:c.dataSource?.name,dataSourceType:c.dataSource?.dbType})),hasMore:d}}})});var Bt=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=m(t),o=await I.findOne({where:{id:r},select:{dataSource:{id:!0}},relations:{dataSource:!0}});return o?{data:o}:{status:404,data:"Query not found"}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=f(t),o=await b.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await I.save(I.create({name:r.name,opts:r.opts,team:{id:o?.team.id},dataSource:{id:r.dataSourceId},user:{id:t.user.id}}))}}}),e.route({method:"patch",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=m(t),o=f(t);if(!(await I.update(r,o)).affected)throw new s(404,"Query not found");return{data:await I.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>g.transaction(async()=>{let{id:r}=m(t);if(!(await I.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var ie=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},V={YEAR:e=>`EXTRACT(YEAR FROM ${e.value})`,MONTH:e=>`EXTRACT(MONTH FROM ${e.value})`,DAY:e=>`EXTRACT(DAY FROM ${e.value})`,SUM:e=>`COALESCE(SUM(${e.distinct===!0?"distinct ":""}${e.value}), 0)`,AVG:ie,MAX:ie,MIN:ie,COUNT:ie};var ue=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},z={YEAR:e=>`YEAR(${e.value})`,MONTH:e=>`MONTH(${e.value})`,DAY:e=>`DAY(${e.value})`,SUM:e=>{let t=e.distinct===!0?"distinct ":"";return`coalesce(${e.fn}(${t}${e.value}), 0)`},AVG:ue,MAX:ue,MIN:ue,COUNT:ue};var Wt=["SUM","COUNT","AVG","MAX","MIN"],po=["YEAR","MONTH","DAY",...Wt],fo=po.reduce((e,t)=>(e[t]=!0,e),{}),yo=Wt.reduce((e,t)=>(e[t]=!0,e),{}),ce=e=>fo[e],Ht=e=>yo[e],Yt=(e,t)=>e.fn&&ce(e.fn)?(t==="postgres"?V:z)[e.fn](e):e.value;var le=e=>typeof e=="string",jt=e=>{let t="SELECT ";if(e.columns&&e.columns.length>0?t+=e.columns.join(", "):t+="*",e.table&&(t+=` FROM ${e.table}`),e.joins&&e.joins.length>0&&e.joins.forEach(r=>{t+=` ${r.type} JOIN ${r.table} ON ${r.on}`}),e.where&&(t+=` WHERE ${e.where}`),e.groupBy&&e.groupBy.length>0&&(t+=` GROUP BY ${e.groupBy.join(", ")}`),e.having&&(t+=` HAVING ${e.having}`),e.orderBy&&e.orderBy.length>0){let r=e.orderBy.reduce((a,n)=>(a[n.column]=n.direction,a),{}),o=Object.entries(r).map(([a,n])=>`${a} ${n}`);t+=` ORDER BY ${o.join(", ")}`}return e.limit!==void 0&&(t+=` LIMIT ${e.limit}`),e.offset!==void 0&&(t+=` OFFSET ${e.offset}`),t},J=(e,t)=>{let{column:r,operator:o,value:a,fn:n}=e,i=Yt({value:r,fn:n},t);switch(o){case"IS NULL":case"IS NOT NULL":return`${i} ${o}`;case"IN":case"NOT IN":let u=a?.map(l=>le(l.value)?`'${l.value}'`:l.value).join(", ");return`${i} ${o} (${u})`;case"LIKE":return`${i} ${t==="postgres"?"ILIKE":"LIKE"} '%${a?.[0].value}%'`;case"NOT LIKE":return`${i} ${t==="postgres"?"NOT ILIKE":"NOT LIKE"} '%${a?.[0].value}%'`;default:let S=a?.[0],w;return le(S?.value)&&S?.isColumn!==!0?w=`'${S?.value}'`:w=S?.value,`${i} ${o} ${w}`}};var X=class{constructor(t="mysql"){this.dialect=t,this.skeleton={type:"SELECT"}}addWhere(t){let r=J(t,this.dialect);if(this.skeleton.where){let o=t.connector||"AND";this.skeleton.where+=` ${o} ${r}`}else this.skeleton.where=r;return this}addWhereRaw(t,r="AND"){return this.skeleton.where?this.skeleton.where+=` ${r} ${t}`:this.skeleton.where=t,this}clearWhere(){return this.skeleton.where=void 0,this}addHaving(t){let r=J(t,this.dialect);if(this.skeleton.having){let o=t.connector||"AND";this.skeleton.having+=` ${o} ${r}`}else this.skeleton.having=r;return this}clearHaving(){return this.skeleton.having=void 0,this}addOrderBy(...t){return this.skeleton.orderBy||(this.skeleton.orderBy=[]),this.skeleton.orderBy.push(...t),this}clearOrderBy(){return this.skeleton.orderBy=void 0,this}setLimit(t){return this.skeleton.limit=t,this}setOffset(t){return this.skeleton.offset=t,this}addGroupBy(t){this.skeleton.groupBy||(this.skeleton.groupBy=[]);let r=this.skeleton.groupBy.findIndex(o=>o===t);return r>-1?this.skeleton.groupBy[r]=t:this.skeleton.groupBy.push(t),this}setTable(t){return this.skeleton.table=t,this}addJoin(...t){return this.skeleton.joins||(this.skeleton.joins=[]),this.skeleton.joins.push(...t),this}selectColumns(t){if(this.skeleton.type!=="SELECT")throw new Error("Column selection is only supported for SELECT queries");return this.skeleton.columns=t,this}toSQL(){return jt(this.skeleton)}};var zt=require("typeorm");var Gt=e=>se(e)?"LIKE":"=",Kt=(e,t)=>{let r=[];for(let o of e)if(!(!o.column?.length||!o.value?.length||o.isEnabled===!1))if(o.isAdvanced){let a=qt.parse(o.value);if(!a)throw new s(400,`Invalid value for '${o.column}': ${o.value}`);r.push({value:a.value,column:o.column,id:o.id,operator:a.operator||Gt(t[o.column]),connector:"AND"})}else r.push({value:o.value?[{value:o.value}]:[],column:o.column,id:o.id,operator:Gt(t[o.column]),connector:"AND"});return r};var me=async(e,t)=>{let{datasourceId:r,size:o=20,page:a,name:n}=t,{table:i,joins:u,groupBy:d,searchAll:c,orderBy:S}=t.opts,w=Eo(t.opts.columns,t.opts.groupBy,t.opts.aggregations),l=await de(r),N=[i],L=[];if(!l)throw new s(404,"Data source not found");let Nr=await I.save(I.create({user:{id:e.user.id},team:{id:e.user.currentTeamId},dataSource:{id:r},name:n,opts:t.opts})),P=new X(l.dbType);P.setTable(i),P.setLimit(o+1),P.setOffset(o*a),u&&(P.addJoin(...u),u.forEach(p=>{N.push(p.table)}));let De=wo(w,S,l.dbType);De.length>0&&P.addOrderBy(...De),d&&d.length>0&&d.forEach(p=>P.addGroupBy(go(p,l.dbType)));let Cr=await D.find({where:{tableName:(0,zt.In)(N),datasource:{id:r}}});for(let p of Cr)if(p.columns)for(let A of p.columns)L.push({column:A.name,table:p.tableName||"",full:`${p.tableName}.${A.name}`,type:A.type});let Ue=L.reduce((p,A)=>(p[A.full]=A.type,p),{});Kt(t.opts.filters,Ue)?.forEach(p=>{p.fn&&Ht(p.fn)?P.addHaving(p):P.addWhere(p)});let Z;if(w&&w.length>0?Z=w.map(p=>ho(p,l.dbType)):Z=L.map(p=>`${p.full} as "${p.full}"`),P.selectColumns(Z),c){let p=L.filter(A=>Pe.includes(A.type)&&Z.some(pe=>pe.startsWith(A.full)));if(p.length>0){let A=p.map(pe=>`LOWER(${pe.full}) LIKE '%${c.toLowerCase()}%'`);P.addWhereRaw(`(${A.join(" OR ")})`,"AND")}}let ee=await(await q(k(l,!0),l.dbType,e)).executeQuery(P.toSQL(),{type:"SELECT",allowBulkUpdate:!1}),xe=ee.rows.length>o;return xe&&ee.rows.pop(),{...ee,queryHistoryId:Nr.id,tables:N,allColumns:L,columns:ee.columns.map(p=>({...p,type:Ue[p.full]})),hasMore:xe}},Jt=async(e,t)=>{let r=await de(t.dataSourceId);if(!r)throw new s(400,"Invalid datasource");let o=await q(k(r,!0),r.dbType,e),a=new X(r.dbType);a.setTable(t.table),a.setLimit(2);for(let[u,d]of Object.entries(t.props))a.addWhere({value:[{value:d}],column:u,connector:"AND",isEnabled:!0,operator:"=",id:"dummy"});let n=a.toSQL(),i=await o.executeQuery(n,{type:"SELECT",allowBulkUpdate:!1});if(i.rows.length>1)throw new s(400,"Found multiple rows for given query");if(i.rows.length<1)throw new s(404,"Entity not found");return{entity:i.rows[0],columns:i.columns,sql:n}},Xt=async(e,t)=>{let r=await de(t.datasourceId);if(!r)throw new s(404,"Data source not found");if(!r.allowUpdate)throw new s(403,"This datasource does not allow update operations");let o=t.values.map(({value:u,column:d})=>typeof u=="string"?u&&u.startsWith("=")?`${d}=${u.substring(1)}`:`${d}='${u}'`:`${d}='${u}'`).join(", "),a=t.filters.map(u=>J(u,r.dbType)).join(" AND "),n=`UPDATE ${t.table} SET ${o} WHERE ${a}`;return(await q(k(r,!0),r.dbType,e)).executeQuery(n,{type:"UPDATE",allowBulkUpdate:!1})},Zt=async(e,t)=>{let r=await de(t.datasourceId);if(!r)throw new s(404,"Data source not found");if(!r.allowInsert)throw new s(403,"This datasource does not allow insert operations");let{keys:o,values:a}=To(t.values),n=`INSERT INTO ${t.table} (${o}) VALUES (${a})`;return(await q(k(r,!0),r.dbType,e)).executeQuery(n,{type:"INSERT",allowBulkUpdate:!1})},To=e=>{let t=e.map(({column:o})=>o).join(", "),r=e.map(({value:o})=>typeof o=="string"?o&&o.startsWith("=")?o.substring(1):`'${o}'`:o).join(", ");return{keys:t,values:r}},ho=(e,t)=>{if(e.fn){if(ce(e.fn))return`${(t==="postgres"?V:z)[e.fn](e)} as "${Ae(e)}"`;throw new Error("Function not allowed: "+e.fn)}return`${e.value} as "${e.value}"`},go=(e,t)=>{if(e.fn){if(ce(e.fn))return(t==="postgres"?V:z)[e.fn]({...e,value:Vt(e.value,t)});throw new Error("Function not allowed: "+e.fn)}return Vt(e.value,t)},ve=(e,t)=>t==="postgres"?`"${e}"`:t==="mysql"?`\`${e}\``:e,Vt=(e,t)=>{let[r,o]=e.split(".");return ve(r,t)+"."+ve(o,t)},wo=(e,t,r)=>{if(e&&e.length>0){let o=e.reduce((a,n)=>(a.set(Ae(n),{isFn:!!(n.fn||n.distinct)}),a),new Map);t=t.filter(a=>o.has(a.column)).map(a=>o.get(a.column)?.isFn?{...a,column:ve(a.column,r)}:a)}return t},Eo=(e,t,r)=>{let o=[];return t.length>0||r.length>0?o.push(...t,...r):e.length>0&&o.push(...e),o};async function de(e){return b.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var er=e=>{},So=["--",";","DROP","drop"],tr=e=>{if(le(e.value)&&e.value.startsWith("=")){let t=e.value;So.forEach(r=>{if(t.includes(r))throw new s(400,"Invalid input value for "+e.column)})}},rr=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(tr)},or=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(tr)};var ar=h(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=f(t,er);return{data:await me(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=m(t),a=x(t);return{data:await Jt(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:E("editor")},handler:async t=>{let r=f(t,rr);return{data:await Zt(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:E("editor")},handler:async t=>{let r=f(t,or);return{data:await Xt(t,r)}}})});var nr=h(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:T.str("SERVER_VERSION")}}))});var sr=h(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=m(t),o=await M.findOne({where:{id:r},relations:{users:{user:!0}}});if(!o)throw new s(404,"Team not found");return{data:o.users.map(a=>({role:a.role,id:a.user.id,name:a.user.username}))}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>g.transaction(async()=>{let r=t.user.id,o=f(t),a=R.create();a.id=r;let n=M.create(o);await M.save(n);let i=C.create({user:a,team:n});return await C.save(i),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=m(t),{role:o,userId:a}=f(t,({role:i})=>{if(i==="owner")throw new s(400,"Only one owner is allowed")});if((await C.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new s(400,"Cannot change owner role");await C.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async t=>g.transaction(async()=>{let{id:r}=m(t),{userId:o}=x(t);if((await C.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new s(400,"Cannot delete team owner");await R.update(o,{currentTeam:null}),await C.delete({user:{id:o},team:{id:r}}),await R.delete({id:o})})})});var ir=h(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=await R.findOne({where:{id:t.user.id},relations:{currentTeam:{team:!0}}});if(!r)throw new s(404,"User not found");return{data:{id:r.id,teamId:r.currentTeam?.team.id,teamName:r.currentTeam?.team.name,teamRole:r.currentTeam?.role,username:r.username}}}}),e.route({method:"patch",url:"/",handler:async t=>{let r=t.user.id,o=f(t);if(o.password&&(o.password=await Y(o.password)),!(await R.update(r,o)).affected)throw new s(404,"User not found");let n=await R.findOne({where:{id:r},relations:{currentTeam:{team:!0}}});return{data:{id:n?.id,teamId:n?.currentTeam?.team.id,teamName:n?.currentTeam?.team.name,teamRole:n?.currentTeam?.role,username:n?.username}}}}),e.route({method:"post",url:"/",config:{requireRole:E("admin")},handler:async t=>g.transaction(async()=>{let r=f(t),o=await Y(r.password),a=await R.save(R.create({username:r.username,password:o})),n=await C.save(C.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await R.update(a.id,{currentTeam:{id:n.id}})})})});var ur=h(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await B.findOneBy({user:{id:r}});return o||(o=await B.save(B.create({user:{id:r}}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=f(t);if(!r.id)throw new s(400,"Settings id is required!");if(!(await B.update(r.id,r)).affected)throw new s(404,"You do not own these settings!");return{data:await B.findOneBy({id:r.id})}}})});function H(e,...t){let r=[...t];if(e.searchAll&&r.push(e.searchAll),e.filters)for(let o of e.filters)o.value&&r.push(o.value);return r.map(o=>o.toLowerCase()).join(",")}var cr=h(e=>{e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=f(t),o=await I.findOne({where:{id:r.queryId}});if(!o)throw new s(400,"Query not found");let a=await U.save(U.create({isPersonal:!1,team:{id:t.user.currentTeamId},user:{id:t.user.id},query:{id:r.queryId},searchString:H(o.opts,r.name)}));return await I.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=m(t);if(!(await U.delete({id:r})).affected)return{status:404,data:"Query not found"}}}),e.route({method:"patch",url:"/:id",handler:async t=>await g.transaction(async()=>{let{id:r}=m(t),o=f(t,i=>{if(!i.name)throw new s(400,"Name is required")}),a=await U.findOne({where:{id:r},relations:{query:!0}});if(!a)throw new s(400,"Query not found");let n=H(a.query.opts,o.name);return await Promise.all([U.update({id:r},{searchString:n}),I.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var lr=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new s(400,"Either queryId or name and opts are required")};var mr=h(e=>{e.route({method:"get",url:"/",handler:async t=>{let{currentTeamId:r,id:o}=t.user;return{data:(await O.find({where:{team:{id:r},user:{id:o},archived:!1},select:["id","name"]})).map(n=>({name:n.name,id:n.id}))}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=m(t),{currentTeamId:o,id:a}=t.user,n=await O.findOne({where:{id:r,team:{id:o},user:{id:a}}});if(!n)throw new s(404,"Not Found");return{data:n}}}),e.route({method:"post",url:"/",handler:async t=>{let{opts:r,name:o,queryId:a}=f(t,lr),n,i,u=o;if(r)i=r.dataSourceId,n=r;else{let c=await I.findOne({where:{id:a},relations:{dataSource:!0}});if(!c)throw new s(404,"Query not Found");i=c.dataSource.id,n={table:c.opts.table,filters:c.opts.filters,joins:c.opts.joins,orderBy:c.opts.orderBy,columns:c.opts.columns,groupBy:c.opts.groupBy,searchAll:c.opts.searchAll,aggregations:c.opts.aggregations,dataSourceId:c.dataSource.id,page:0,size:50},o||(u=c.name)}return{data:await O.save(O.create({name:u||new Date().toISOString(),opts:n,dataSource:{id:i},user:{id:t.user.id},team:{id:t.user.currentTeamId}}))}}}),e.route({method:"post",url:"/:id/run",handler:async t=>{let{id:r}=m(t),o=f(t),a=await O.findOne({where:{id:r},relations:{user:!0}});if(!a)throw new s(404,"Not found");if(a.user?.id!==t.user.id)throw new s(404,"Not found");return o&&O.update(r,{opts:o,searchString:H(o,a.name),updatedAt:new Date}),{data:{result:await me(t,{datasourceId:o.dataSourceId,size:o.size,name:a.name,page:o.page,opts:{table:o.table,filters:o.filters,joins:o.joins,orderBy:o.orderBy,columns:o.columns,groupBy:o.groupBy,searchAll:o.searchAll,aggregations:o.aggregations}})}}}}),e.route({method:"patch",url:"/:id",handler:async t=>{let{id:r}=m(t),o=f(t),a=await O.findOne({where:{id:r,user:{id:t.user.id}}});if(!a)throw new s(404,"Not Found");let n=a.searchString;return o.name&&(n=H(a.opts,o.name)),await O.update(r,{...o,searchString:n}),{data:{id:r}}}}),e.route({method:"delete",url:"/:id",handler:async t=>{let{id:r}=m(t),o=t.user.id;return await O.delete({id:r,user:{id:o}}),{data:!0}}})});var dr=h(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:Q.skipAuth,modeName:Q.name};r.type("application/javascript").send(`window.__CLIENT_CONFIG__ = ${JSON.stringify(o)};`)}}),e.route({method:"get",url:"/",handler:(t,r)=>{r.sendFile("index.html")}})});var Ro=[[dr,"/"],[lt,"/api/auth"],[Qt,"/api/data-sources"],[$t,"/api/project"],[Bt,"/api/queries"],[ar,"/api/runner"],[nr,"/api/status"],[sr,"/api/teams"],[ir,"/api/users"],[ur,"/api/user-settings"],[cr,"/api/saved-queries"],[mr,"/api/workbench-tabs"]],pr=e=>{for(let[t,r]of Ro)e.register(t,{prefix:r}),console.log("Registered "+r)};var bo=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),Io=async e=>{let t=await C.findOne({where:{role:"owner"},relations:{user:!0,team:!0}});if(!t)throw new s(401,"User is not part of a team");e.user={id:t.user.id,currentTeamId:t.team.id,currentTeamRole:t.role}},No=async e=>{let t=e.headers.authorization;if(!t)throw new s(401,"Missing auth token");let[r,o]=t.split(" ");try{let{userId:a}=await st(o),n=await R.findOne({where:{id:a},select:{id:!0,currentTeam:{role:!0,team:{id:!0}}},relations:{currentTeam:{team:!0}}});if(!n)throw new s(401,"User is not part of a team");e.user={id:a,currentTeamId:n.currentTeam.team.id,currentTeamRole:n.currentTeam.role}}catch{throw new s(401,"Unauthorized")}},fr=async e=>{bo(e)||(Q.skipAuth?await Io(e):await No(e))};var yr=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Tr=e=>{e.addHook("onRequest",fr),e.addHook("onRequest",kt),e.addHook("onResponse",yr)};var hr=e=>{e.setNotFoundHandler((t,r)=>{if(t.raw.url?.startsWith("/api/")){r.code(404).send({error:"API route not found"});return}r.sendFile("index.html")}),e.setErrorHandler((t,r,o)=>{console.error(t),t instanceof s?o.status(t.status).send({error:t.message}):o.status(500).send({error:"Internal Server Error"})})};var gr=_(require("@fastify/cookie")),wr=_(require("@fastify/cors"));var Er=_(require("@fastify/static")),Sr=require("node:path"),Rr=e=>{e.register(gr.default,{}),e.register(wr.default,{origin:j.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(Er.default,{root:(0,Sr.join)(__dirname,"web")})};(async function(){let t=(0,br.default)({querystringParser:r=>Ir.default.parse(r)});qe(),Rr(t),Tr(t),pr(t),hr(t),await t.after(),await Je(),await Xe(),t.listen({port:j.port,host:j.host},(r,o)=>{r&&(console.error(r),process.exit(1)),console.log(`Server listening at ${o}`)})})();
57
+ limit 75;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},gt=async(e,t,r)=>{try{console.log(`[PG CONN] Query: ${e}`);let{rows:o,fields:a,command:n,rowCount:i}=await t.query({text:e,rowMode:"array"});if(n==="UPDATE"||n==="INSERT"||n==="DELETE"){if(i!=null&&i>1&&r.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i]],query:e}}if(n==="SELECT"){let u=a.map(c=>`'${c.tableID}-${c.columnID}'`),p=await so(u,t);return{columns:a.map(c=>{let R=p[`${c.tableID}-${c.columnID}`];return{column:R?.column||c.name,alias:c.name,table:R?.table||"",full:R?R.table+"."+R.column:c.name}}),rows:o,query:e}}throw new Error(`[PG CONN] Unsupported command: ${n}`)}catch(o){throw o instanceof s?o:new s(400,o.message)}},io=async(e,t)=>{await e.query("BEGIN");try{let r=await t();return await e.query("COMMIT"),console.log("[PG CONN] Commit"),r}catch(r){throw await e.query("ROLLBACK"),console.log("[PG CONN] Rollback"),r}},uo=async(e,t)=>{await e.query("BEGIN READ ONLY");try{let r=await t();return console.log("[PG CONN] Read only rollback"),await e.query("ROLLBACK"),r}catch(r){throw console.log("[PG CONN] Rollback"),await e.query("ROLLBACK"),r}},St=async e=>{let t=await ro(e),r=!1,o=!1,a=async n=>(o||await t.query(`SET search_path TO ${e.schema}`),n());return{dbType:"postgres",dataSource:e,inspectSchema:()=>no(e,t),executeQuery:(n,i)=>a(()=>i.type==="SELECT"?uo(t,()=>gt(n,t,i)):io(t,()=>gt(n,t,i))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var q=async(e,t,r)=>{try{let o;if(t==="mysql")o=await ht(e);else if(t==="postgres")o=await St(e);else throw new s(500,`Connection manager for ${t} not found`);return r.__connections?r.__connections.push(o):r.__connections=[o],o}catch(o){throw console.error(o),o instanceof s?o:o?.code==="ECONNREFUSED"?new s(500,"Failed to connect to the database"):new s(500,o.message)}};var ne=_(require("node:crypto"));var Et="aes-256-gcm",co=12,Rt=()=>{let e=y.str("SYMM_ENCRYPTION_KEY");if(!e)throw new Error("Missing ENCRYPTION_KEY in environment variables.");let t=Buffer.from(e,"hex");if(t.length!==32)throw new Error("ENCRYPTION_KEY must be a 64-character hex string (256 bits).");return t},lo=e=>{let t=ne.default.randomBytes(co),r=Rt(),o=ne.default.createCipheriv(Et,r,t),a=o.update(e,"utf8","hex");a+=o.final("hex");let n=o.getAuthTag();return{encrypted:a,iv:t.toString("hex"),tag:n.toString("hex")}},mo=({encrypted:e,iv:t,tag:r})=>{let o=Rt(),a=ne.default.createDecipheriv(Et,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},se={encrypt:lo,decrypt:mo};var F=(e,t=!1)=>{if(t){let r=se.decrypt({encrypted:e.dbPassword,tag:e.dbPasswordTag,iv:e.dbPasswordIv});return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:r,port:e.dbPort,schema:e.dbSchema}}return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:e.dbPassword,port:e.dbPort,schema:e.dbSchema}};var bt=[{value:"=",label:"equals"},{value:"<>",label:"not equal"},{value:">",label:"greater than"},{value:">=",label:"greater than or equal"},{value:"<",label:"less than"},{value:"<=",label:"less than or equal"},{value:"LIKE",label:"contains"},{value:"NOT LIKE",label:"not contains"},{value:"IN",label:"in list"},{value:"NOT IN",label:"not in list"},{value:"IS NULL",label:"is null"},{value:"IS NOT NULL",label:"is not null"}],po=bt.reduce((e,t)=>(e[t.value]=t.label,e),{}),fn=bt.reduce((e,t)=>(e[t.label]=t.value,e),{}),H=e=>e.map(t=>({label:po[t],value:t})),yn=H(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),Tn=H(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL"]),hn=H(["=","<>","IS NULL","IS NOT NULL"]),gn=H(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),wn=H(["IS NULL","IS NOT NULL"]),Sn=H(["IN","NOT IN"]);var _e=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],fo=new Set(_e),ie=e=>fo.has(e),yo=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],To=new Set(yo),It=e=>To.has(e);var En=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var ve=e=>e.fn?e.distinct===!0?`${e.fn} distinct ${e.value}`:`${e.fn} ${e.value}`:e.value;var De={read_only:10,editor:20,admin:30,owner:40};var v=e=>e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;var Nt={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:v(t[1])}]},stringify:(e,t)=>ie(t)?`${e.value?.[0].value}`:`LIKE "%${e.value?.[0].value}%"`},Ct={operator:"NOT LIKE",parse:e=>{let t=e.match(/^NOT LIKE\s*["'](.*)["']$/i);if(t)return[{value:v(t[1])}]},stringify:e=>`NOT LIKE "%${e.value?.[0].value}%"`};function Pt(e){return e===""?[]:ho(e).map(go)}function ho(e){let t=[],r=0,o="",a=!1,n=!1;for(;r<e.length;){let i=e[r];if((a||n)&&i==="\\"){o+=e[r+1],r+=2;continue}if(i==="'"&&!n){a=!a,o+=i,r++;continue}if(i==='"'&&!a){n=!n,o+=i,r++;continue}if(i===","&&!a&&!n){t.push(o.trim()),o="",r++;continue}o+=i,r++}if(o.trim()!==""&&t.push(o.trim()),a||n)throw new Error("Unterminated string literal");return t}function go(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:At(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:At(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function At(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var Ot={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return Pt(t[1])},stringify:e=>`IN (${e.value?.map(t=>`"${t.value}"`).join(", ")})`},_t={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return Pt(t[1])},stringify:e=>`NOT IN (${e.value?.map(t=>`"${t.value}"`).join(", ")})`};var vt={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:(e,t)=>It(t)?`${e.value?.[0].value}`:`= ${e.value?.[0].value}`},Dt={operator:"!=",parse:e=>{let t=e.match(/^!=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`!= ${e.value?.[0].value}`},Ut={operator:"<>",parse:e=>{let t=e.match(/^<>\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`<> ${e.value?.[0].value}`},xt={operator:">",parse:e=>{let t=e.match(/^>\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`> ${e.value?.[0].value}`},Lt={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`>= ${e.value?.[0].value}`},Mt={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`< ${e.value?.[0].value}`},kt={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:v(t[1])}]},stringify:e=>`<= ${e.value?.[0].value}`};var qt={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},Ft={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var Qt=[Nt,Ct,Ot,_t,vt,Dt,Ut,Lt,xt,kt,Mt,qt,Ft],wo=Qt.reduce((e,t)=>(e[t.operator]=t,e),{});function So(e,t){return wo[e.operator]?.stringify(e,t)||""}function Eo(e){let t=e.trim();for(let r of Qt){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var Bt={parse:Eo,stringify:So};var E=e=>{let t=De[e];return r=>De[r.currentTeamRole]>=t},$t=async e=>{let t=e.routeOptions.config.requireRole;if(t&&!t(e.user))throw new s(403,"You are not authorized to perform this action")};var Wt=T(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),o=await b.findOne({where:{id:r}});if(!o)throw new s(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=L(t);return{data:await b.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:E("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=m(t,ft),n=b.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),i=await q(F(n),n.dbType,t);try{await i.checkConnection()}catch{throw new s(400,"Cannot connect to the database, please check datasource configuration")}let{tag:u,iv:p,encrypted:c}=se.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=p,n.dbPasswordTag=u,{data:await b.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=d(t),o=m(t),a=await b.findOneBy({id:r});if(!a)throw new s(404,"Data source not found");let n=b.merge(a,o);return await b.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async(t,r)=>g.transaction(async()=>{let{id:o}=d(t);await Promise.all([D.delete({datasource:{id:o}}),I.delete({dataSource:{id:o}})]),await b.delete({id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=d(t),a=await b.findOne({where:{id:o},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!a)throw new Error("Data source not found");a.status="INSPECTING",await b.save(a);let i=await(await q(F(a,!0),a.dbType,t)).inspectSchema();await D.delete({datasource:{id:o}}),await D.insert(i.sort().map(u=>D.create({tableName:u.tableName,columns:u.columns,datasource:{id:o}}))),a.status="READY",a.lastInspected=new Date,await b.save(a)}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=d(t);return{data:await D.find({where:{datasource:{id:r}}})}}})});var B=require("typeorm"),Ht=T(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=d(t);return{data:await b.find({where:{team:{id:r}},order:{name:"ASC"},select:{id:!0,name:!0,updatedAt:!0,dbType:!0,description:!0,allowInsert:!0,allowUpdate:!0}})}}}),e.route({method:"get",url:"/team/:teamId/queries",handler:async t=>{let o=d(t).teamId||t.user.currentTeamId;return{data:(await U.find({where:[{isPersonal:!1,team:{id:o}},{isPersonal:!0,team:{id:o},user:{id:t.user.id}}],relations:{query:!0},select:{id:!0,query:{id:!0,name:!0,updatedAt:!0}}})).map(i=>({name:i.query.name,id:i.query.id,updatedAt:i.query.updatedAt,savedQueryId:i.id}))}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=d(t),{search:o,size:a,selectedDataSources:n}=L(t),i=o.length>3?parseInt(a)||20:8,u={};n?.length&&(u.id=(0,B.In)(n));let[p,c,R]=await Promise.all([D.find({where:{tableName:(0,B.Raw)(l=>`LOWER(${l}) LIKE :search`,{search:`%${o.toLowerCase()}%`}),datasource:u},relations:{datasource:!0},select:{id:!0,tableName:!0,datasource:{name:!0,id:!0}},order:{tableName:"ASC"},take:i}),A.find({where:{searchString:(0,B.Like)(`%${o.toLowerCase()}%`),team:{id:r},user:{id:t.user.id},dataSource:u},relations:{dataSource:!0},select:{id:!0,name:!0,updatedAt:!0,dataSource:{id:!0,name:!0}},order:{updatedAt:"ASC"},take:i}),U.find({where:{searchString:(0,B.Like)(`%${o.toLowerCase()}%`),team:{id:r},query:{dataSource:u}},relations:{query:{dataSource:!0}},select:{id:!0,updatedAt:!0,query:{id:!0,name:!0,dataSource:{name:!0}}},order:{updatedAt:"ASC"},take:i})]),S=[];return p.forEach(l=>{S.push({name:l.tableName,id:l.id,dataSourceName:l.datasource?.name||"--",dataSourceId:l.datasource?.id||"--",type:"table"})}),c.forEach(l=>{S.push({name:l.name,id:l.id,dataSourceName:l.dataSource?.name||"--",dataSourceId:l.dataSource?.id||"--",type:"tab"})}),R.forEach(l=>{S.push({name:l.query.name,id:l.query.id,dataSourceName:l.query.dataSource?.name||"--",dataSourceId:l.query.dataSource?.id||"--",type:"query"})}),{data:S}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=d(t),o=L(t),a=Number(o.page),n=Number(o.size),i=t.user.id,u=await A.find({where:{team:{id:r},user:{id:i}},relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),p=!1;return u.length>n&&(u.pop(),p=!0),{data:u.map(c=>({name:c.name,id:c.id,updatedAt:c.updatedAt,archived:c.archived,createdAt:c.createdAt,dataSourceId:c.dataSource?.id,dataSourceName:c.dataSource?.name,dataSourceType:c.dataSource?.dbType})),hasMore:p}}})});var Yt=T(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),o=await I.findOne({where:{id:r},select:{dataSource:{id:!0}},relations:{dataSource:!0}});return o?{data:o}:{status:404,data:"Query not found"}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=m(t),o=await b.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await I.save(I.create({name:r.name,opts:r.opts,team:{id:o?.team.id},dataSource:{id:r.dataSourceId},user:{id:t.user.id}}))}}}),e.route({method:"patch",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=d(t),o=m(t);if(!(await I.update(r,o)).affected)throw new s(404,"Query not found");return{data:await I.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>g.transaction(async()=>{let{id:r}=d(t);if(!(await I.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var ue=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},V={YEAR:e=>`EXTRACT(YEAR FROM ${e.value})`,MONTH:e=>`EXTRACT(MONTH FROM ${e.value})`,DAY:e=>`EXTRACT(DAY FROM ${e.value})`,SUM:e=>`COALESCE(SUM(${e.distinct===!0?"distinct ":""}${e.value}), 0)`,AVG:ue,MAX:ue,MIN:ue,COUNT:ue};var ce=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},z={YEAR:e=>`YEAR(${e.value})`,MONTH:e=>`MONTH(${e.value})`,DAY:e=>`DAY(${e.value})`,SUM:e=>{let t=e.distinct===!0?"distinct ":"";return`coalesce(${e.fn}(${t}${e.value}), 0)`},AVG:ce,MAX:ce,MIN:ce,COUNT:ce};var jt=["SUM","COUNT","AVG","MAX","MIN"],Ro=["YEAR","MONTH","DAY",...jt],bo=Ro.reduce((e,t)=>(e[t]=!0,e),{}),Io=jt.reduce((e,t)=>(e[t]=!0,e),{}),le=e=>bo[e],Gt=e=>Io[e],Kt=(e,t)=>e.fn&&le(e.fn)?(t==="postgres"?V:z)[e.fn](e):e.value;var me=e=>typeof e=="string",Vt=e=>{let t="SELECT ";if(e.columns&&e.columns.length>0?t+=e.columns.join(", "):t+="*",e.table&&(t+=` FROM ${e.table}`),e.joins&&e.joins.length>0&&e.joins.forEach(r=>{t+=` ${r.type} JOIN ${r.table} ON ${r.on}`}),e.where&&(t+=` WHERE ${e.where}`),e.groupBy&&e.groupBy.length>0&&(t+=` GROUP BY ${e.groupBy.join(", ")}`),e.having&&(t+=` HAVING ${e.having}`),e.orderBy&&e.orderBy.length>0){let r=e.orderBy.reduce((a,n)=>(a[n.column]=n.direction,a),{}),o=Object.entries(r).map(([a,n])=>`${a} ${n}`);t+=` ORDER BY ${o.join(", ")}`}return e.limit!==void 0&&(t+=` LIMIT ${e.limit}`),e.offset!==void 0&&(t+=` OFFSET ${e.offset}`),t},J=(e,t)=>{let{column:r,operator:o,value:a,fn:n}=e,i=Kt({value:r,fn:n},t);switch(o){case"IS NULL":case"IS NOT NULL":return`${i} ${o}`;case"IN":case"NOT IN":let u=a?.map(l=>me(l.value)?`'${l.value}'`:l.value).join(", ");return`${i} ${o} (${u})`;case"LIKE":return`${i} ${t==="postgres"?"ILIKE":"LIKE"} '%${a?.[0].value}%'`;case"NOT LIKE":return`${i} ${t==="postgres"?"NOT ILIKE":"NOT LIKE"} '%${a?.[0].value}%'`;default:let R=a?.[0],S;return me(R?.value)&&R?.isColumn!==!0?S=`'${R?.value}'`:S=R?.value,`${i} ${o} ${S}`}};var X=class{constructor(t="mysql"){this.dialect=t,this.skeleton={type:"SELECT"}}addWhere(t){let r=J(t,this.dialect);if(this.skeleton.where){let o=t.connector||"AND";this.skeleton.where+=` ${o} ${r}`}else this.skeleton.where=r;return this}addWhereRaw(t,r="AND"){return this.skeleton.where?this.skeleton.where+=` ${r} ${t}`:this.skeleton.where=t,this}clearWhere(){return this.skeleton.where=void 0,this}addHaving(t){let r=J(t,this.dialect);if(this.skeleton.having){let o=t.connector||"AND";this.skeleton.having+=` ${o} ${r}`}else this.skeleton.having=r;return this}clearHaving(){return this.skeleton.having=void 0,this}addOrderBy(...t){return this.skeleton.orderBy||(this.skeleton.orderBy=[]),this.skeleton.orderBy.push(...t),this}clearOrderBy(){return this.skeleton.orderBy=void 0,this}setLimit(t){return this.skeleton.limit=t,this}setOffset(t){return this.skeleton.offset=t,this}addGroupBy(t){this.skeleton.groupBy||(this.skeleton.groupBy=[]);let r=this.skeleton.groupBy.findIndex(o=>o===t);return r>-1?this.skeleton.groupBy[r]=t:this.skeleton.groupBy.push(t),this}setTable(t){return this.skeleton.table=t,this}addJoin(...t){return this.skeleton.joins||(this.skeleton.joins=[]),this.skeleton.joins.push(...t),this}selectColumns(t){if(this.skeleton.type!=="SELECT")throw new Error("Column selection is only supported for SELECT queries");return this.skeleton.columns=t,this}toSQL(){return Vt(this.skeleton)}};var Zt=require("typeorm");var zt=e=>ie(e)?"LIKE":"=",Jt=(e,t)=>{let r=[];for(let o of e)if(!(!o.column?.length||!o.value?.length||o.isEnabled===!1))if(o.isAdvanced){let a=Bt.parse(o.value);if(!a)throw new s(400,`Invalid value for '${o.column}': ${o.value}`);r.push({value:a.value,column:o.column,id:o.id,operator:a.operator||zt(t[o.column]),connector:"AND"})}else r.push({value:o.value?[{value:o.value}]:[],column:o.column,id:o.id,operator:zt(t[o.column]),connector:"AND"});return r};var de=async(e,t)=>{let{datasourceId:r,size:o=20,page:a,name:n}=t,{table:i,joins:u,groupBy:p,searchAll:c,orderBy:R}=t.opts,S=Oo(t.opts.columns,t.opts.groupBy,t.opts.aggregations),l=await pe(r),N=[i],M=[];if(!l)throw new s(404,"Data source not found");let Lr=await I.save(I.create({user:{id:e.user.id},team:{id:e.user.currentTeamId},dataSource:{id:r},name:n,opts:t.opts})),P=new X(l.dbType);P.setTable(i),P.setLimit(o+1),P.setOffset(o*a),u&&(P.addJoin(...u),u.forEach(f=>{N.push(f.table)}));let Le=Po(S,R,l.dbType);Le.length>0&&P.addOrderBy(...Le),p&&p.length>0&&p.forEach(f=>P.addGroupBy(Ao(f,l.dbType)));let Mr=await D.find({where:{tableName:(0,Zt.In)(N),datasource:{id:r}}});for(let f of Mr)if(f.columns)for(let O of f.columns)M.push({column:O.name,table:f.tableName||"",full:`${f.tableName}.${O.name}`,type:O.type});let Me=M.reduce((f,O)=>(f[O.full]=O.type,f),{});Jt(t.opts.filters,Me)?.forEach(f=>{f.fn&&Gt(f.fn)?P.addHaving(f):P.addWhere(f)});let ee;if(S&&S.length>0?ee=S.map(f=>Co(f,l.dbType)):ee=M.map(f=>`${f.full} as "${f.full}"`),P.selectColumns(ee),c){let f=M.filter(O=>_e.includes(O.type)&&ee.some(Te=>Te.startsWith(O.full)));if(f.length>0){let O=f.map(Te=>`LOWER(${Te.full}) LIKE '%${c.toLowerCase()}%'`);P.addWhereRaw(`(${O.join(" OR ")})`,"AND")}}let te=await(await q(F(l,!0),l.dbType,e)).executeQuery(P.toSQL(),{type:"SELECT",allowBulkUpdate:!1}),ke=te.rows.length>o;return ke&&te.rows.pop(),{...te,queryHistoryId:Lr.id,tables:N,allColumns:M,columns:te.columns.map(f=>({...f,type:Me[f.full]})),hasMore:ke}},er=async(e,t)=>{let r=await pe(t.dataSourceId);if(!r)throw new s(400,"Invalid datasource");let o=await q(F(r,!0),r.dbType,e),a=new X(r.dbType);a.setTable(t.table),a.setLimit(2);for(let[u,p]of Object.entries(t.props))a.addWhere({value:[{value:p}],column:u,connector:"AND",isEnabled:!0,operator:"=",id:"dummy"});let n=a.toSQL(),i=await o.executeQuery(n,{type:"SELECT",allowBulkUpdate:!1});if(i.rows.length>1)throw new s(400,"Found multiple rows for given query");if(i.rows.length<1)throw new s(404,"Entity not found");return{entity:i.rows[0],columns:i.columns,sql:n}},tr=async(e,t)=>{let r=await pe(t.datasourceId);if(!r)throw new s(404,"Data source not found");if(!r.allowUpdate)throw new s(403,"This datasource does not allow update operations");let o=t.values.map(({value:u,column:p})=>typeof u=="string"?u&&u.startsWith("=")?`${p}=${u.substring(1)}`:`${p}='${u}'`:`${p}='${u}'`).join(", "),a=t.filters.map(u=>J(u,r.dbType)).join(" AND "),n=`UPDATE ${t.table} SET ${o} WHERE ${a}`;return(await q(F(r,!0),r.dbType,e)).executeQuery(n,{type:"UPDATE",allowBulkUpdate:!1})},rr=async(e,t)=>{let r=await pe(t.datasourceId);if(!r)throw new s(404,"Data source not found");if(!r.allowInsert)throw new s(403,"This datasource does not allow insert operations");let{keys:o,values:a}=No(t.values),n=`INSERT INTO ${t.table} (${o}) VALUES (${a})`;return(await q(F(r,!0),r.dbType,e)).executeQuery(n,{type:"INSERT",allowBulkUpdate:!1})},No=e=>{let t=e.map(({column:o})=>o).join(", "),r=e.map(({value:o})=>typeof o=="string"?o&&o.startsWith("=")?o.substring(1):`'${o}'`:o).join(", ");return{keys:t,values:r}},Co=(e,t)=>{if(e.fn){if(le(e.fn))return`${(t==="postgres"?V:z)[e.fn](e)} as "${ve(e)}"`;throw new Error("Function not allowed: "+e.fn)}return`${e.value} as "${e.value}"`},Ao=(e,t)=>{if(e.fn){if(le(e.fn))return(t==="postgres"?V:z)[e.fn]({...e,value:Xt(e.value,t)});throw new Error("Function not allowed: "+e.fn)}return Xt(e.value,t)},Ue=(e,t)=>t==="postgres"?`"${e}"`:t==="mysql"?`\`${e}\``:e,Xt=(e,t)=>{let[r,o]=e.split(".");return Ue(r,t)+"."+Ue(o,t)},Po=(e,t,r)=>{if(e&&e.length>0){let o=e.reduce((a,n)=>(a.set(ve(n),{isFn:!!(n.fn||n.distinct)}),a),new Map);t=t.filter(a=>o.has(a.column)).map(a=>o.get(a.column)?.isFn?{...a,column:Ue(a.column,r)}:a)}return t},Oo=(e,t,r)=>{let o=[];return t.length>0||r.length>0?o.push(...t,...r):e.length>0&&o.push(...e),o};async function pe(e){return b.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var or=e=>{},_o=["--",";","DROP","drop"],ar=e=>{if(me(e.value)&&e.value.startsWith("=")){let t=e.value;_o.forEach(r=>{if(t.includes(r))throw new s(400,"Invalid input value for "+e.column)})}},nr=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(ar)},sr=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(ar)};var ir=T(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=m(t,or);return{data:await de(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=d(t),a=L(t);return{data:await er(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:E("editor")},handler:async t=>{let r=m(t,nr);return{data:await rr(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:E("editor")},handler:async t=>{let r=m(t,sr);return{data:await tr(t,r)}}})});var ur=T(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:y.str("SERVER_VERSION")}}))});var cr=T(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=d(t),o=await k.findOne({where:{id:r},relations:{users:{user:!0}}});if(!o)throw new s(404,"Team not found");return{data:o.users.map(a=>({role:a.role,id:a.user.id,name:a.user.username}))}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>g.transaction(async()=>{let r=t.user.id,o=m(t),a=w.create();a.id=r;let n=k.create(o);await k.save(n);let i=C.create({user:a,team:n});return await C.save(i),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=d(t),{role:o,userId:a}=m(t,({role:i})=>{if(i==="owner")throw new s(400,"Only one owner is allowed")});if((await C.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new s(400,"Cannot change owner role");await C.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async t=>g.transaction(async()=>{let{id:r}=d(t),{userId:o}=L(t);if((await C.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new s(400,"Cannot delete team owner");await w.update(o,{currentTeam:null}),await C.delete({user:{id:o},team:{id:r}}),await w.delete({id:o})})})});var xe=_(require("bcryptjs")),Z=async e=>{let t=await xe.default.genSalt(10);return xe.default.hash(e,t)};var lr=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=await w.findOne({where:{id:t.user.id},relations:{currentTeam:{team:!0}}});if(!r)throw new s(404,"User not found");return{data:{id:r.id,teamId:r.currentTeam?.team.id,teamName:r.currentTeam?.team.name,teamRole:r.currentTeam?.role,username:r.username}}}}),e.route({method:"patch",url:"/",handler:async t=>{let r=t.user.id,o=m(t);if(o.password&&(o.password=await Z(o.password)),!(await w.update(r,o)).affected)throw new s(404,"User not found");let n=await w.findOne({where:{id:r},relations:{currentTeam:{team:!0}}});return{data:{id:n?.id,teamId:n?.currentTeam?.team.id,teamName:n?.currentTeam?.team.name,teamRole:n?.currentTeam?.role,username:n?.username}}}}),e.route({method:"post",url:"/",config:{requireRole:E("admin")},handler:async t=>g.transaction(async()=>{let r=m(t),o=await Z(r.password),a=await w.save(w.create({username:r.username,password:o})),n=await C.save(C.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await w.update(a.id,{currentTeam:{id:n.id}})})})});var mr=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await W.findOneBy({user:{id:r}});return o||(o=await W.save(W.create({user:{id:r}}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=m(t);if(!r.id)throw new s(400,"Settings id is required!");if(!(await W.update(r.id,r)).affected)throw new s(404,"You do not own these settings!");return{data:await W.findOneBy({id:r.id})}}})});function Y(e,...t){let r=[...t];if(e.searchAll&&r.push(e.searchAll),e.filters)for(let o of e.filters)o.value&&r.push(o.value);return r.map(o=>o.toLowerCase()).join(",")}var dr=T(e=>{e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=m(t),o=await I.findOne({where:{id:r.queryId}});if(!o)throw new s(400,"Query not found");let a=await U.save(U.create({isPersonal:!1,team:{id:t.user.currentTeamId},user:{id:t.user.id},query:{id:r.queryId},searchString:Y(o.opts,r.name)}));return await I.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=d(t);if(!(await U.delete({id:r})).affected)return{status:404,data:"Query not found"}}}),e.route({method:"patch",url:"/:id",handler:async t=>await g.transaction(async()=>{let{id:r}=d(t),o=m(t,i=>{if(!i.name)throw new s(400,"Name is required")}),a=await U.findOne({where:{id:r},relations:{query:!0}});if(!a)throw new s(400,"Query not found");let n=Y(a.query.opts,o.name);return await Promise.all([U.update({id:r},{searchString:n}),I.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var pr=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new s(400,"Either queryId or name and opts are required")};var fr=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let{currentTeamId:r,id:o}=t.user;return{data:(await A.find({where:{team:{id:r},user:{id:o},archived:!1},select:["id","name"]})).map(n=>({name:n.name,id:n.id}))}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),{currentTeamId:o,id:a}=t.user,n=await A.findOne({where:{id:r,team:{id:o},user:{id:a}}});if(!n)throw new s(404,"Not Found");return{data:n}}}),e.route({method:"post",url:"/",handler:async t=>{let{opts:r,name:o,queryId:a}=m(t,pr),n,i,u=o;if(r)i=r.dataSourceId,n=r;else{let c=await I.findOne({where:{id:a},relations:{dataSource:!0}});if(!c)throw new s(404,"Query not Found");i=c.dataSource.id,n={table:c.opts.table,filters:c.opts.filters,joins:c.opts.joins,orderBy:c.opts.orderBy,columns:c.opts.columns,groupBy:c.opts.groupBy,searchAll:c.opts.searchAll,aggregations:c.opts.aggregations,dataSourceId:c.dataSource.id,page:0,size:50},o||(u=c.name)}return{data:await A.save(A.create({name:u||new Date().toISOString(),opts:n,dataSource:{id:i},user:{id:t.user.id},team:{id:t.user.currentTeamId}}))}}}),e.route({method:"post",url:"/:id/run",handler:async t=>{let{id:r}=d(t),o=m(t),a=await A.findOne({where:{id:r},relations:{user:!0}});if(!a)throw new s(404,"Not found");if(a.user?.id!==t.user.id)throw new s(404,"Not found");return o&&A.update(r,{opts:o,searchString:Y(o,a.name),updatedAt:new Date}),{data:{result:await de(t,{datasourceId:o.dataSourceId,size:o.size,name:a.name,page:o.page,opts:{table:o.table,filters:o.filters,joins:o.joins,orderBy:o.orderBy,columns:o.columns,groupBy:o.groupBy,searchAll:o.searchAll,aggregations:o.aggregations}})}}}}),e.route({method:"patch",url:"/:id",handler:async t=>{let{id:r}=d(t),o=m(t),a=await A.findOne({where:{id:r,user:{id:t.user.id}}});if(!a)throw new s(404,"Not Found");let n=a.searchString;return o.name&&(n=Y(a.opts,o.name)),await A.update(r,{...o,searchString:n}),{data:{id:r}}}}),e.route({method:"delete",url:"/:id",handler:async t=>{let{id:r}=d(t),o=t.user.id;return await A.delete({id:r,user:{id:o}}),{data:!0}}})});var hr=require("node:crypto");var yr=require("node:crypto"),Tr={teamName:"Default Team",username:"admin"},vo=async()=>{let e=await k.findOneBy({});return e||k.save(k.create({name:Tr.teamName}))},fe=async e=>{let t=await C.findOne({where:{role:"owner"},relations:{user:!0}});if(t)return t.user;let r=await vo(),o=await Z(e?.password||(0,yr.randomBytes)(32).toString("hex")),a=await w.save(w.create({username:e?.name||Tr.username,password:o})),n=await C.save(C.create({user:a,team:r,role:"owner"}));return await w.update(a.id,{currentTeam:n}),a};var ye={setupAccessToken:void 0},gr=()=>(ye.setupAccessToken=(0,hr.randomBytes)(32).toString("hex"),ye.setupAccessToken),Do=e=>{if(!ye.setupAccessToken)throw new s(400,"Setup already performed");if(!e||e!==ye.setupAccessToken)throw new s(400,"Invalid setup access token")},$=async()=>x.skipAuth?!1:await w.count()<1,wr=async e=>{Do(e.setupAccessToken),await fe({name:e.userName,password:e.userPassword})};var Sr=T(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:x.skipAuth,modeName:x.name,usesCustomDb:$e()};return r.type("application/javascript").send(`window.__CLIENT_CONFIG__ = ${JSON.stringify(o)};`)}}),e.route({method:"get",url:"/",handler:async(t,r)=>await $()?r.redirect("/setup"):r.sendFile("index.html")}),e.route({method:"get",url:"/setup",handler:async(t,r)=>await $()?r.sendFile("setup.html"):r.redirect("/")})});var Er=e=>{if(!e.setupAccessToken)throw new s(400,"Invalid setup access token");if(!e.userPassword||e.userPassword.length<8)throw new s(400,"Password should be at least 8 chars long");if(!e.userName)throw new s(400,"User name is required")};var Rr=T(e=>{e.route({method:"post",url:"/",config:{isPublic:!0},handler:async t=>{if(!await $())throw new s(400,"Setup has already been completed");let o=m(t,Er);return await wr(o),{data:!0}}})});var Uo=[[Sr,"/"],[pt,"/api/auth"],[Wt,"/api/data-sources"],[Ht,"/api/project"],[Yt,"/api/queries"],[ir,"/api/runner"],[ur,"/api/status"],[cr,"/api/teams"],[lr,"/api/users"],[mr,"/api/user-settings"],[dr,"/api/saved-queries"],[fr,"/api/workbench-tabs"],[Rr,"/api/setup"]],br=e=>{for(let[t,r]of Uo)e.register(t,{prefix:r}),console.log("Registered "+r)};var xo=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),Lo=async()=>C.findOne({where:{role:"owner"},relations:{user:!0,team:!0}}),Mo=async e=>{let t=await Lo();if(!t)throw new s(401,"User is not part of a team");e.user={id:t.user.id,currentTeamId:t.team.id,currentTeamRole:t.role}},ko=async e=>{let t=e.headers.authorization;if(!t)throw new s(401,"Missing auth token");let[r,o]=t.split(" "),{userId:a}=await ct(o),n=await w.findOne({where:{id:a},select:{id:!0,currentTeam:{role:!0,team:{id:!0}}},relations:{currentTeam:{team:!0}}});if(!n)throw new s(401,"Unauthorized");e.user={id:a,currentTeamId:n.currentTeam.team.id,currentTeamRole:n.currentTeam.role}},Ir=async e=>{xo(e)||(x.skipAuth?await Mo(e):await ko(e))};var Nr=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Cr=e=>{e.addHook("onRequest",Ir),e.addHook("onRequest",$t),e.addHook("onResponse",Nr)};var Ar=e=>{e.setNotFoundHandler((t,r)=>{if(t.raw.url?.startsWith("/api/")){r.code(404).send({error:"API route not found"});return}r.sendFile("index.html")}),e.setErrorHandler((t,r,o)=>{console.error(t),t instanceof s?o.status(t.status).send({error:t.message}):o.status(500).send({error:"Internal Server Error"})})};var Pr=_(require("@fastify/cookie")),Or=_(require("@fastify/cors"));var _r=_(require("@fastify/static")),vr=require("node:path"),Dr=e=>{e.register(Pr.default,{}),e.register(Or.default,{origin:j.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(_r.default,{root:(0,vr.join)(__dirname,"web")})};(async function(){let t=(0,Ur.default)({querystringParser:o=>xr.default.parse(o)});if(Be(),Dr(t),Cr(t),br(t),Ar(t),await t.after(),await tt(),t.listen({port:j.port,host:j.host},(o,a)=>{o&&(console.error(o),process.exit(1)),console.log(`Server listening at ${a}`)}),await $()){let o=gr();console.log(`Setup access token:
58
+ ${o}`),console.log("Use the above token to finish the setup process when opening the app for the first time.")}else await fe()})();
@@ -0,0 +1,85 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ width="512"
6
+ height="512"
7
+ viewBox="0 0 512 512"
8
+ version="1.1"
9
+ id="svg1"
10
+ xml:space="preserve"
11
+ xmlns:xlink="http://www.w3.org/1999/xlink"
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
14
+ id="defs1" /><image
15
+ width="512"
16
+ height="512"
17
+ preserveAspectRatio="none"
18
+ xlink:href="data:image/png;base64,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&#10;"
19
+ id="image5"
20
+ x="0"
21
+ y="0"
22
+ style="display:none;opacity:0.246" /><g
23
+ id="layer1"><rect
24
+ style="fill:#f2b88f;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
25
+ id="rect9"
26
+ width="496"
27
+ height="36.862289"
28
+ x="11.293897"
29
+ y="47.497002"
30
+ ry="16"
31
+ transform="rotate(2.6267544)" /><circle
32
+ style="fill:#ffd883;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
33
+ id="path16"
34
+ cx="236.18539"
35
+ cy="327.10275"
36
+ r="160" /><circle
37
+ style="fill:#ffd883;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
38
+ id="circle16"
39
+ cx="236.18539"
40
+ cy="327.10275"
41
+ r="120" /><path
42
+ style="fill:#ffd883;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
43
+ d="m 83.889831,7.1027542 h 48.000009 c 0,0 8,21.0050518 8,31.9999998 0,10.994948 -8,32 -8,32 0,0 -8,21.005052 -8,31.999996 0,10.99495 8,32 8,32 0,0 8,21.00505 8,32 0,10.99495 -8,32 -8,32 0,0 -8,21.00505 -8,32 0,10.99495 8,32 8,32 0,0 8,21.00505 8,32 0,10.99495 -8,32 -8,32 H 83.889831 c 0,0 8,-21.00505 8,-32 0,-10.99495 -8,-32 -8,-32 0,0 -8,-21.00505 -8,-32 0,-10.99495 8,-32 8,-32 0,0 8,-21.00505 8,-32 0,-10.99495 -8,-32 -8,-32 0,0 -8,-21.00505 -8,-32 0,-10.994944 8,-31.999996 8,-31.999996 0,0 8,-21.005052 8,-32 0,-10.994948 -8,-31.9999998 -8,-31.9999998 z"
44
+ id="path9" /><path
45
+ style="fill:#ffd883;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
46
+ d="m 133.38348,7.1027542 h 48 c 0,0 8,21.0050518 8,31.9999998 0,10.994948 -8,32 -8,32 0,0 -8,21.005052 -8,31.999996 0,10.99495 8,32 8,32 0,0 8,21.00505 8,32 0,10.99495 -8,32 -8,32 0,0 -8,21.00505 -8,32 0,10.99495 8,32 8,32 0,0 8,21.00505 8,32 0,10.99495 -8,32 -8,32 h -48 c 0,0 8,-21.00505 8,-32 0,-10.99495 -8,-32 -8,-32 0,0 -8,-21.00505 -8,-32 0,-10.99495 8,-32 8,-32 0,0 8,-21.00505 8,-32 0,-10.99495 -8,-32 -8,-32 0,0 -8,-21.00505 -8,-32 0,-10.994944 8,-31.999996 8,-31.999996 0,0 8,-21.005052 8,-32 0,-10.994948 -8,-31.9999998 -8,-31.9999998 z"
47
+ id="path11" /><path
48
+ style="fill:#ffd883;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
49
+ d="m 180.18539,7.1027542 h 48 c 0,0 8,21.0050518 8,31.9999998 0,10.994948 -8,32 -8,32 0,0 -8,21.005052 -8,31.999996 0,10.99495 8,32 8,32 0,0 8,21.00505 8,32 0,10.99495 -8,32 -8,32 0,0 -8,21.00505 -8,32 0,10.99495 8,32 8,32 0,0 8,21.00505 8,32 0,10.99495 -8,32 -8,32 h -48 c 0,0 8,-21.00505 8,-32 0,-10.99495 -8,-32 -8,-32 0,0 -8,-21.00505 -8,-32 0,-10.99495 8,-32 8,-32 0,0 8,-21.00505 8,-32 0,-10.99495 -8,-32 -8,-32 0,0 -8,-21.00505 -8,-32 0,-10.994944 8,-31.999996 8,-31.999996 0,0 8,-21.005052 8,-32 0,-10.994948 -8,-31.9999998 -8,-31.9999998 z"
50
+ id="path12" /><rect
51
+ style="fill:#f2b88f;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
52
+ id="rect8"
53
+ width="496"
54
+ height="36.862289"
55
+ x="8"
56
+ y="8"
57
+ ry="16" /></g><g
58
+ id="layer3"
59
+ transform="rotate(3.9375263,-844.78065,-3921.8229)"><ellipse
60
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
61
+ id="path14"
62
+ cx="680.76331"
63
+ cy="140.84758"
64
+ rx="79.306068"
65
+ ry="99.608429" /><ellipse
66
+ style="display:inline;fill:#ffa100;fill-opacity:1;stroke:none;stroke-width:18.1962;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:436.709, 436.709;stroke-dashoffset:0;stroke-opacity:1"
67
+ id="path15"
68
+ cx="683.64093"
69
+ cy="158.35594"
70
+ rx="46.178188"
71
+ ry="61.330406" /><path
72
+ id="ellipse16"
73
+ style="fill:#000000;fill-opacity:0.3;stroke:none;stroke-width:16.322;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
74
+ d="M 682.03125,41.251953 V 240.44336 a 82.529814,99.608429 0 0 0 81.2113,-99.5957 82.529814,99.608429 0 0 0 -81.2113,-99.595707 z" /></g><g
75
+ id="layer2"
76
+ style="display:inline"><path
77
+ id="path5"
78
+ style="fill:#ff9b87;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
79
+ d="M 8.1289062,240.67161 C 10.937662,327.69773 58.339875,437.95276 127.97531,480 165.38832,502.59071 209.21915,504.00003 256,504 c 46.77056,3e-5 90.59239,-1.40358 128,-23.9851 69.64892,-42.04433 117.062,-152.30689 119.87109,-239.34329 z" /><path
80
+ id="path13"
81
+ style="fill:#ff6c52;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
82
+ d="m 11.023438,272.8125 c 3.499357,24.23767 9.952488,49.33995 18.943359,73.5957 H 482.03125 c 8.99127,-24.25564 15.44584,-49.3578 18.94531,-73.5957 z" /><path
83
+ style="display:inline;fill:#000000;fill-opacity:0.301653;stroke:none;stroke-width:15.0442;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
84
+ d="m 260.75549,498.04372 c 17.17737,-8.91298 36.49094,-23.93077 53.89626,-41.9085 44.3552,-45.8139 73.50119,-133.15473 81.14702,-199.94817 0.77681,-6.78613 1.41237,-12.87571 1.41237,-13.53238 0,-0.94441 11.16006,-1.19396 53.39443,-1.19396 H 504 l -0.36305,3.56439 c -3.64843,35.81994 -10.95682,88.53657 -24.3212,119.03858 -9.18329,20.95936 -25.34142,47.33594 -39.6031,64.64821 -21.54611,26.15487 -49.61549,48.45367 -73.58787,58.4595 -24.42993,10.19679 -58.67966,15.23864 -102.85351,15.14087 l -10.69658,-0.0238 z"
85
+ id="path8" /></g></svg>