@dataramen/cli 0.0.75-beta.1 → 0.0.75-beta.3

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 oo=Object.create;var Be=Object.defineProperty;var ao=Object.getOwnPropertyDescriptor;var no=Object.getOwnPropertyNames;var so=Object.getPrototypeOf,io=Object.prototype.hasOwnProperty;var uo=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of no(t))!io.call(e,a)&&a!==r&&Be(e,a,{get:()=>t[a],enumerable:!(o=ao(t,a))||o.enumerable});return e};var O=(e,t,r)=>(r=e!=null?oo(so(e)):{},uo(t||!e||!e.__esModule?Be(r,"default",{value:e,enumerable:!0}):r,e));var oe=require("dotenv"),ae=require("node:path"),Fe=require("node:fs");var te=e=>{function t(a,n=void 0){return e[a]||n}function r(a,n=void 0){let i=e[a];if(!i)return n;let s=Number(i);return!isNaN(s)&&i.trim()!==""?s:n}function o(a){return e[a]==="true"||e[a]==="TRUE"||e[a]==="1"}return{str:t,num:r,bool:o}};function co(e){let t={mode:void 0,env:void 0};for(let r of e){if(!r.startsWith("--"))continue;let[o,...a]=r.slice(2).split("=");if(!o||a.length===0)continue;let n=a.join("=");n=n.replace(/^["'](.+)["']$/,"$1"),t[o]=n}return t}var re=te(co(process.argv.slice(2)));var mo=(()=>{try{let e=(0,Fe.readFileSync)((0,ae.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})(),Me=[],Qe=re.str("env");Qe&&Me.push((0,ae.resolve)(Qe));(0,oe.config)({path:Me});var be={APP_DB_TYPE:"sqlite",APP_DB_DATABASE:"<home>/.dataramen/.runtime/db.sqlite3"};(0,oe.populate)(process.env,{SERVER_VERSION:mo.version,PROD:"true",...be},{override:!1});var lo=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],$e=()=>{let e=[];for(let t of lo)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))},T=te(process.env),He=()=>T.str("APP_DB_TYPE")!==be.APP_DB_TYPE&&T.str("APP_DB_DATABASE")!==be.APP_DB_DATABASE;var wm=require("reflect-metadata"),Kr=O(require("fastify")),Vr=O(require("qs"));var et=require("typeorm");var We=require("typeorm");var po={default:{bindServerUrl:"0.0.0.0",skipAuth:!1,name:"default"},docker:{bindServerUrl:"0.0.0.0",skipAuth:!1,name:"docker"},cli:{bindServerUrl:"127.0.0.1",skipAuth:!0,name:"cli"},dev:{bindServerUrl:"127.0.0.1",skipAuth:!0,name:"dev"}},fo=re.str("mode","default"),D=po[fo];var g=T.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp",ne=D.name==="docker"?e=>e==="localhost"||e==="127.0.0.1"?"host.docker.internal":e:e=>e;var we=new We.EntitySchema({name:"Team",tableName:"teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},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:g,createDate:!0},updatedAt:{type:g,updateDate:!0},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 Ge=require("typeorm");var Ie=new Ge.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},relations:{user:{type:"one-to-one",target:()=>"User",inverseSide:"settings",joinColumn:!0}}});var je=require("typeorm");var k=new je.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:g,createDate:!0},updatedAt:{type:g,updateDate:!0},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:g,nullable:!0,default:null},status:{type:String,nullable:!0}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"datasources",joinColumn:!0},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"dataSource"},owner:{type:"many-to-one",target:()=>"User",joinColumn:!0}}});var tt=O(require("node:os")),rt=require("node:path");var Ke=require("typeorm");var K=new Ke.EntitySchema({name:"Query",tableName:"query",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},opts:{type:"json",nullable:!1},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},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"),Ee=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 Ce=new ze.EntitySchema({name:"SavedQuery",tableName:"saved_queries",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},isPersonal:{type:Boolean},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0},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 Re=new Je.EntitySchema({name:"WorkbenchTab",tableName:"workbench_tabs",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0},opts:{type:"json",nullable:!1},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}}});var Xe=require("typeorm");var q=new Xe.EntitySchema({name:"DatabaseColumn",tableName:"database_columns",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},name:{nullable:!0,type:String},type:{type:String},isPrimary:{type:Boolean},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0},meta:{type:"json",nullable:!0},tableId:{type:String}},relations:{table:{target:()=>"DatabaseTable",type:"many-to-one",inverseSide:"columns"}}});var Ze=require("typeorm");var B=new Ze.EntitySchema({name:"DatabaseTable",tableName:"database_tables",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},name:{nullable:!0,type:String},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},relations:{datasource:{target:()=>"DataSource",type:"many-to-one"},columns:{target:()=>"DatabaseColumn",type:"one-to-many",inverseSide:"table"}}});function yo(){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>",tt.default.homedir())),e}var b=new et.DataSource({type:T.str("APP_DB_TYPE"),database:yo(),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:[rt.posix.join(__dirname,"migrations","*.js")],entities:[k,we,Se,Ee,Ie,K,Ce,Re,B,q]}),ot=async()=>{if(!b.isInitialized)return b.initialize();throw new Error("Already initialized")},R=b.getRepository(k),Q=b.getRepository(we),w=b.getRepository(Se),E=b.getRepository(Ee),W=b.getRepository(Ie),C=b.getRepository(K),v=b.getRepository(Ce),A=b.getRepository(Re),se=b.getRepository(q),ie=b.getRepository(B);var at=T.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),nt=T.num("PORT",4466),V={port:nt,host:D.bindServerUrl,allowedOrigins:at.includes("*")?"*":[`http://localhost:${nt}`,...at]};var h=e=>(t,r,o)=>{e(t),o()};var z=require("jose");var u=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var st=new TextEncoder,it=st.encode(T.str("JWT_SECRET")),ut=st.encode(T.str("JWT_REFRESH_SECRET")),Ne=async({userId:e})=>new z.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(it),Ae=async({userId:e})=>new z.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(ut),ct=async(e,t)=>{try{let{payload:r}=await(0,z.jwtVerify)(e,t);if(!r.sub)throw new u(401,"Failed to verify access token");return{userId:r.sub}}catch(r){throw r instanceof u?r:r instanceof Error?new u(401,r.message):new u(401,"Failed to verify refresh token")}},mt=async e=>ct(e,it),lt=async e=>ct(e,ut);var y=(e,t)=>{let r=e.body;return t&&t(r),r},_=(e,t)=>{let r=e.query;return t&&t(r),r},f=(e,t)=>{let r=e.params;return t&&t(r),r};var pt=O(require("bcryptjs"));var dt=e=>{if(!e?.username)throw new u(400,"Username is required");if(!e?.password)throw new u(400,"Password is required")};var ue="DATARAMEN_refresh_token",Pe={httpOnly:!0,secure:T.bool("PROD"),sameSite:T.bool("PROD"),path:"/",maxAge:14400*60},ft=h(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let{username:o,password:a}=y(t,dt),n=await w.findOne({where:{username:o}});if(!n||!pt.default.compareSync(a,n.password))throw new u(401,"Invalid credentials");let[i,s]=await Promise.all([Ne({userId:n?.id}),Ae({userId:n?.id})]);return r.setCookie(ue,s,Pe),{data:{accessToken:i}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies[ue];if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await lt(o),[n,i]=await Promise.all([Ne({userId:a}),Ae({userId:a})]);return r.setCookie(ue,i,Pe),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie(ue,Pe),{data:!0})})});var yt=e=>{if(!e.dbUrl)throw new u(400,"url is required");if(!e.dbUser)throw new u(400,"user is required");if(!e.dbType)throw new u(400,"type is required");if(!e.name)throw new u(400,"name is required");if(!e.dbDatabase)throw new u(400,"database is required")};var ht=O(require("mysql2/promise"));function J(e){if(e!==void 0)return e.toLowerCase()}var To=({database:e,password:t,user:r,url:o})=>ht.default.createConnection({host:ne(o),user:r,database:e,password:t,dateStrings:!0}),go=async e=>{let t=`
1
+ "use strict";var no=Object.create;var Fe=Object.defineProperty;var so=Object.getOwnPropertyDescriptor;var io=Object.getOwnPropertyNames;var uo=Object.getPrototypeOf,co=Object.prototype.hasOwnProperty;var mo=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of io(t))!co.call(e,a)&&a!==r&&Fe(e,a,{get:()=>t[a],enumerable:!(o=so(t,a))||o.enumerable});return e};var P=(e,t,r)=>(r=e!=null?no(uo(e)):{},mo(t||!e||!e.__esModule?Fe(r,"default",{value:e,enumerable:!0}):r,e));var oe=require("dotenv"),ae=require("node:path"),$e=require("node:fs");var te=e=>{function t(a,n=void 0){return e[a]||n}function r(a,n=void 0){let u=e[a];if(!u)return n;let s=Number(u);return!isNaN(s)&&u.trim()!==""?s:n}function o(a){return e[a]==="true"||e[a]==="TRUE"||e[a]==="1"}return{str:t,num:r,bool:o}};function lo(e){let t={mode:void 0,env:void 0};for(let r of e){if(!r.startsWith("--"))continue;let[o,...a]=r.slice(2).split("=");if(!o||a.length===0)continue;let n=a.join("=");n=n.replace(/^["'](.+)["']$/,"$1"),t[o]=n}return t}var re=te(lo(process.argv.slice(2)));var po=(()=>{try{let e=(0,$e.readFileSync)((0,ae.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})(),He=[],Me=re.str("env");Me&&He.push((0,ae.resolve)(Me));(0,oe.config)({path:He});var we={APP_DB_TYPE:"sqlite",APP_DB_DATABASE:"<home>/.dataramen/.runtime/db.sqlite3"};(0,oe.populate)(process.env,{SERVER_VERSION:po.version,PROD:"true",...we},{override:!1});var fo=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],We=()=>{let e=[];for(let t of fo)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))},T=te(process.env),Ye=()=>T.str("APP_DB_TYPE")!==we.APP_DB_TYPE&&T.str("APP_DB_DATABASE")!==we.APP_DB_DATABASE;var Dm=require("reflect-metadata"),zr=P(require("fastify")),Jr=P(require("qs"));var rt=require("typeorm");var Ge=require("typeorm");var yo={default:{bindServerUrl:"0.0.0.0",skipAuth:!1,name:"default"},docker:{bindServerUrl:"0.0.0.0",skipAuth:!1,name:"docker"},cli:{bindServerUrl:"127.0.0.1",skipAuth:!0,name:"cli"},dev:{bindServerUrl:"127.0.0.1",skipAuth:!0,name:"dev"}},To=re.str("mode","default"),D=yo[To];var g=T.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp",ne=D.name==="docker"?e=>e==="localhost"||e==="127.0.0.1"?"host.docker.internal":e:e=>e;var Se=new Ge.EntitySchema({name:"Team",tableName:"teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},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 je=require("typeorm");var Ee=new je.EntitySchema({name:"User",tableName:"users",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0},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 Ke=require("typeorm");var Ie=new Ke.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},relations:{user:{type:"one-to-one",target:()=>"User",inverseSide:"settings",joinColumn:!0}}});var Ve=require("typeorm");var M=new Ve.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:g,createDate:!0},updatedAt:{type:g,updateDate:!0},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:g,nullable:!0,default:null},status:{type:String,nullable:!0}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"datasources",joinColumn:!0},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"dataSource"},owner:{type:"many-to-one",target:()=>"User",joinColumn:!0}}});var ot=P(require("node:os")),at=require("node:path");var ze=require("typeorm");var K=new ze.EntitySchema({name:"Query",tableName:"query",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},opts:{type:"json",nullable:!1},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},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 Je=require("typeorm"),Ce=new Je.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 Xe=require("typeorm");var Re=new Xe.EntitySchema({name:"SavedQuery",tableName:"saved_queries",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},isPersonal:{type:Boolean},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0},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 Ze=require("typeorm");var Ne=new Ze.EntitySchema({name:"WorkbenchTab",tableName:"workbench_tabs",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0},opts:{type:"json",nullable:!1},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}}});var et=require("typeorm");var q=new et.EntitySchema({name:"DatabaseColumn",tableName:"database_columns",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},name:{nullable:!0,type:String},type:{type:String},isPrimary:{type:Boolean},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0},meta:{type:"json",nullable:!0},tableId:{type:String}},relations:{table:{target:()=>"DatabaseTable",type:"many-to-one",inverseSide:"columns"}}});var tt=require("typeorm");var B=new tt.EntitySchema({name:"DatabaseTable",tableName:"database_tables",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},name:{nullable:!0,type:String},createdAt:{type:g,createDate:!0},updatedAt:{type:g,updateDate:!0}},relations:{datasource:{target:()=>"DataSource",type:"many-to-one"},columns:{target:()=>"DatabaseColumn",type:"one-to-many",inverseSide:"table"}}});function go(){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>",ot.default.homedir())),e}var b=new rt.DataSource({type:T.str("APP_DB_TYPE"),database:go(),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:[at.posix.join(__dirname,"migrations","*.js")],entities:[M,Se,Ee,Ce,Ie,K,Re,Ne,B,q]}),nt=async()=>{if(!b.isInitialized)return b.initialize();throw new Error("Already initialized")},E=b.getRepository(M),Q=b.getRepository(Se),w=b.getRepository(Ee),C=b.getRepository(Ce),W=b.getRepository(Ie),R=b.getRepository(K),_=b.getRepository(Re),A=b.getRepository(Ne),se=b.getRepository(q),ie=b.getRepository(B);var st=T.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),it=T.num("PORT",4466),V={port:it,host:D.bindServerUrl,allowedOrigins:st.includes("*")?"*":[`http://localhost:${it}`,...st]};var h=e=>(t,r,o)=>{e(t),o()};var z=require("jose");var i=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var ut=new TextEncoder,ct=ut.encode(T.str("JWT_SECRET")),mt=ut.encode(T.str("JWT_REFRESH_SECRET")),Ae=async({userId:e})=>new z.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(ct),Oe=async({userId:e})=>new z.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(mt),lt=async(e,t)=>{try{let{payload:r}=await(0,z.jwtVerify)(e,t);if(!r.sub)throw new i(401,"Failed to verify access token");return{userId:r.sub}}catch(r){throw r instanceof i?r:r instanceof Error?new i(401,r.message):new i(401,"Failed to verify refresh token")}},dt=async e=>lt(e,ct),pt=async e=>lt(e,mt);var f=(e,t)=>{let r=e.body;return t&&t(r),r},v=(e,t)=>{let r=e.query;return t&&t(r),r},y=(e,t)=>{let r=e.params;return t&&t(r),r};var yt=P(require("bcryptjs"));var ft=e=>{if(!e?.username)throw new i(400,"Username is required");if(!e?.password)throw new i(400,"Password is required")};var ue="DATARAMEN_refresh_token",Pe={httpOnly:!0,secure:T.bool("PROD"),sameSite:T.bool("PROD"),path:"/",maxAge:14400*60},Tt=h(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let{username:o,password:a}=f(t,ft),n=await w.findOne({where:{username:o}});if(!n||!yt.default.compareSync(a,n.password))throw new i(401,"Invalid credentials");let[u,s]=await Promise.all([Ae({userId:n?.id}),Oe({userId:n?.id})]);return r.setCookie(ue,s,Pe),{data:{accessToken:u}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies[ue];if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await pt(o),[n,u]=await Promise.all([Ae({userId:a}),Oe({userId:a})]);return r.setCookie(ue,u,Pe),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie(ue,Pe),{data:!0})})});var gt=e=>{if(!e.dbUrl)throw new i(400,"url is required");if(!e.dbUser)throw new i(400,"user is required");if(!e.dbType)throw new i(400,"type is required");if(!e.name)throw new i(400,"name is required");if(!e.dbDatabase)throw new i(400,"database is required")};var wt=P(require("mysql2/promise"));function J(e){if(e!==void 0)return e.toLowerCase()}var ho=({database:e,password:t,user:r,url:o})=>wt.default.createConnection({host:ne(o),user:r,database:e,password:t,dateStrings:!0}),bo=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=J(a.TABLE_NAME),i=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(i)}),o},ho=async e=>{let t=`
6
+ `,[r]=await e.execute(t),o={};return r.forEach(a=>{let n=J(a.TABLE_NAME),u=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(u)}),o},wo=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},bo=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await ho(t),n=await go(t),i=o.map(async s=>{let m=J(Object.values(s)[0]),c=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and LOWER(table_name) = '${m}'`,[l]=await t.query(c),p=a[m];return{columns:l.map(d=>({name:d.COLUMN_NAME,type:d.DATA_TYPE,isPrimary:n[m]?.includes(d.COLUMN_NAME),ref:p?.[d.COLUMN_NAME]?{table:p[d.COLUMN_NAME].refTable,field:p[d.COLUMN_NAME].refField}:void 0})),createdAt:new Date,tableName:m,updatedAt:new Date}});return Promise.all(i)},Tt=async(e,t,r,o)=>{try{console.log(`[MYSQL CONN] Query: ${e}`),console.log(`[MYSQL CONN] Params: ${JSON.stringify(t)}`);let[a,n]=await r.query({sql:e,rowsAsArray:!0,values:t,timeout:1e4}),i=a?.constructor?.name;if(i==="ResultSetHeader"){let s=a;if(s.affectedRows>1&&o.allowBulkUpdate!==!0)throw new Error("[MYSQL CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[s.affectedRows]],query:e}}else if(i==="Array"){let s=a;return{columns:n?.map(m=>({column:m.orgName||m.name,table:J(m.orgTable),alias:m.name,full:m.orgTable?J(m.orgTable)+"."+m.orgName:m.name}))||[],rows:s,query:e}}throw new Error(`[MYSQL CONN] Unknown result type: ${i}`)}catch(a){throw console.error(a),a instanceof u?a:new u(400,a.message)}},wo=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}},So=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}},bt=async e=>{let t=await To(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>bo(e,t),executeQuery:o=>o.type==="SELECT"?So(t,()=>Tt(o.sql,o.params,t,o)):wo(t,()=>Tt(o.sql,o.params,t,o)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var St=O(require("pg"));var Io=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new St.default.Client({host:ne(o),user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},Eo=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},So=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await wo(t),n=await bo(t),u=o.map(async s=>{let m=J(Object.values(s)[0]),c=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and LOWER(table_name) = '${m}'`,[l]=await t.query(c),p=a[m];return{columns:l.map(d=>({name:d.COLUMN_NAME,type:d.DATA_TYPE,isPrimary:n[m]?.includes(d.COLUMN_NAME),ref:p?.[d.COLUMN_NAME]?{table:p[d.COLUMN_NAME].refTable,field:p[d.COLUMN_NAME].refField}:void 0})),createdAt:new Date,tableName:m,updatedAt:new Date}});return Promise.all(u)},ht=async(e,t,r,o)=>{try{console.log(`[MYSQL CONN] Query: ${e}`),console.log(`[MYSQL CONN] Params: ${JSON.stringify(t)}`);let[a,n]=await r.query({sql:e,rowsAsArray:!0,values:t,timeout:1e4}),u=a?.constructor?.name;if(u==="ResultSetHeader"){let s=a;if(s.affectedRows>1&&o.allowBulkUpdate!==!0)throw new Error("[MYSQL CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[s.affectedRows]],query:e}}else if(u==="Array"){let s=a;return{columns:n?.map(m=>({column:m.orgName||m.name,table:J(m.orgTable),alias:m.name,full:m.orgTable?J(m.orgTable)+"."+m.orgName:m.name}))||[],rows:s,query:e}}throw new Error(`[MYSQL CONN] Unknown result type: ${u}`)}catch(a){throw console.error(a),a instanceof i?a:new i(400,a.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}},Io=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}},De=async e=>{let t=await ho(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>So(e,t),executeQuery:o=>o.type==="SELECT"?Io(t,()=>ht(o.sql,o.params,t,o)):Eo(t,()=>ht(o.sql,o.params,t,o)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var Et=P(require("pg"));var Co=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new Et.default.Client({host:ne(o),user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},Ro=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},Co=async e=>{let r=await e.query(`
31
+ `),o={};return r.rows.forEach(a=>{let n=a.table_name,u=a.column_name;o[n]||(o[n]=[]),o[n].push(u)}),o},No=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,16 +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},Ro=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 Co(t),i=await Eo(t),s=a.map(async m=>{let c=Object.values(m)[0],l=`
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},Ao=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 No(t),u=await Ro(t),s=a.map(async m=>{let c=Object.values(m)[0],l=`
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:p}=await t.query(l),d=n[c];return{columns:p.map(N=>({name:N.column_name,type:N.data_type,isPrimary:i[c]?.includes(N.column_name),ref:d?.[N.column_name]?{table:d[N.column_name].refTable,field:d[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(s)},No=async(e,t)=>{let r=`select LOWER(relname) as relname, attname, concat(pg_class.oid, '-', attnum) as row_key
52
+ `,{rows:p}=await t.query(l),d=n[c];return{columns:p.map(N=>({name:N.column_name,type:N.data_type,isPrimary:u[c]?.includes(N.column_name),ref:d?.[N.column_name]?{table:d[N.column_name].refTable,field:d[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(s)},Oo=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),{})},wt=async(e,t,r,o)=>{try{console.log(`[PG CONN] Query: ${e}`),console.log(`[PG CONN] Params: ${JSON.stringify(t,null,2)}`);let{rows:a,fields:n,command:i,rowCount:s}=await r.query({text:e,rowMode:"array",values:t});if(i==="UPDATE"||i==="INSERT"||i==="DELETE"){if(s!=null&&s>1&&o.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[s]],query:e}}if(i==="SELECT"){let m=n.map(l=>`'${l.tableID}-${l.columnID}'`),c=await No(m,r);return{columns:n.map(l=>{let p=c[`${l.tableID}-${l.columnID}`];return{column:p?.column||l.name,alias:l.name,table:p?.table||"",full:p?p.table+"."+p.column:l.name}}),rows:a,query:e}}throw new Error(`[PG CONN] Unsupported command: ${i}`)}catch(a){throw a instanceof u?a:new u(400,a.message)}},Ao=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}},Po=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}},It=async e=>{let t=await Io(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:()=>Ro(e,t),executeQuery:n=>a(()=>n.type==="SELECT"?Po(t,()=>wt(n.sql,n.params,t,n)):Ao(t,()=>wt(n.sql,n.params,t,n))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var F=async(e,t,r)=>{try{let o;if(t==="mysql")o=await bt(e);else if(t==="postgres")o=await It(e);else throw new u(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 u?o:o?.code==="ECONNREFUSED"?new u(500,"Failed to connect to the database"):new u(500,o.message)}};var ce=O(require("node:crypto"));var Et="aes-256-gcm",Oo=12,Ct=()=>{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},Do=e=>{let t=ce.default.randomBytes(Oo),r=Ct(),o=ce.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")}},xo=({encrypted:e,iv:t,tag:r})=>{let o=Ct(),a=ce.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},me={encrypt:Do,decrypt:xo};var M=(e,t=!1)=>{if(t){let r=me.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 Rt=[{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:"like"},{value:"NOT LIKE",label:"not like"},{value:"CONTAINS",label:"contains"},{value:"NOT CONTAINS",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"}],vo=Rt.reduce((e,t)=>(e[t.value]=t.label,e),{}),us=Rt.reduce((e,t)=>(e[t.label]=t.value,e),{}),Y=e=>e.map(t=>({label:vo[t],value:t})),cs=Y(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),ms=Y(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL","CONTAINS","NOT CONTAINS"]),ls=Y(["=","<>","IS NULL","IS NOT NULL"]),ds=Y(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),ps=Y(["IS NULL","IS NOT NULL"]),fs=Y(["IN","NOT IN"]),_o=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],Uo=new Set(_o),le=e=>Uo.has(e),Lo=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],ko=new Set(Lo),Nt=e=>ko.has(e);var ys=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var Oe={read_only:10,editor:20,admin:30,owner:40};var P=e=>e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;var At={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`LIKE "%${e[0]?.value}%"`},Pt={operator:"NOT LIKE",parse:e=>{let t=e.match(/^NOT LIKE\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`NOT LIKE "%${e[0]?.value}%"`},Ot={operator:"CONTAINS",parse:e=>{let t=e.match(/^CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>le(t)?`${e[0]?.value}`:`CONTAINS "%${e[0]?.value}%"`},Dt={operator:"NOT CONTAINS",parse:e=>{let t=e.match(/^NOT CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`NOT CONTAINS "%${e[0]?.value}%"`};function vt(e){return e===""?[]:qo(e).map(Bo)}function qo(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 Bo(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:xt(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:xt(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function xt(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var _t={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return vt(t[1])},stringify:e=>`IN (${e?.map(t=>`"${t.value}"`).join(", ")})`},Ut={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return vt(t[1])},stringify:e=>`NOT IN (${e?.map(t=>`"${t.value}"`).join(", ")})`};var Lt={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>Nt(t)?`${e[0]?.value}`:`= ${e[0]?.value}`},kt={operator:"!=",parse:e=>{let t=e.match(/^!=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`!= ${e[0]?.value}`},qt={operator:"<>",parse:e=>{let t=e.match(/^<>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<> ${e[0]?.value}`},Bt={operator:">",parse:e=>{let t=e.match(/^>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`> ${e[0]?.value}`},Qt={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`>= ${e[0]?.value}`},Ft={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`< ${e[0]?.value}`},Mt={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<= ${e[0]?.value}`};var $t={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},Ht={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var Qo=[At,Ot,Pt,Dt,_t,Ut,Lt,kt,qt,Qt,Bt,Mt,Ft,$t,Ht];function Fo(e){let t=e.trim();for(let r of Qo){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var Wt={parse:Fo};var S=e=>{let t=Oe[e];return r=>Oe[r.currentTeamRole]>=t},Yt=async e=>{let t=e.routeOptions.config.requireRole;if(t&&!t(e.user))throw new u(403,"You are not authorized to perform this action")};var De=async(e,t)=>{let r=await e.find(B,{where:{datasource:{id:t}},select:["id"]});for(let o of r){let a=await e.find(q,{where:{tableId:o.id},select:["id"]});await e.remove(q,a),await e.delete(B,o)}};function Mo(e){let t=new Map;for(let r of e)r.columns?.forEach(o=>{if(o.ref){let a=`${o.ref.table}.${o.ref.field}`,n=t.get(a)||[];n.push({table:r.tableName,field:o.name}),t.set(a,n)}});return t}var Gt=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=f(t),o=await R.findOne({where:{id:r}});if(!o)throw new u(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=_(t);return{data:await R.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:S("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=y(t,yt),n=R.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),i=await F(M(n),n.dbType,t);try{await i.checkConnection()}catch{throw new u(400,"Cannot connect to the database, please check datasource configuration")}let{tag:s,iv:m,encrypted:c}=me.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=m,n.dbPasswordTag=s,{data:await R.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:S("admin")},handler:async t=>{let{id:r}=f(t),o=y(t),a=await R.findOneBy({id:r});if(!a)throw new u(404,"Data source not found");let n=R.merge(a,o);return await R.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("admin")},handler:async t=>b.transaction(async r=>{let{id:o}=f(t);await Promise.all([De(r,o),r.delete(K,{dataSource:{id:o}})]),await r.delete(k,{id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>b.transaction(async o=>{let{id:a}=f(t),n=await o.findOne(k,{where:{id:a},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!n)throw new Error("Data source not found");n.status="INSPECTING",await o.save(k,n);let s=await(await F(M(n,!0),n.dbType,t)).inspectSchema();await De(o,n.id);let m=Mo(s);for(let c of s){let l=await o.save(B,{datasource:{id:a},name:c.tableName});if(c.columns){let p=[];for(let d of c.columns)p.push(se.create({table:{id:l.id},name:d.name,isPrimary:!!d.isPrimary,type:d.type,meta:{refs:d.ref,referencedBy:m.get(`${l.name}.${d.name}`)}}));await o.save(q,p)}}n.status="READY",n.lastInspected=new Date,await o.save(k,n)})}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=f(t);return{data:(await ie.find({where:{datasource:{id:r}},relations:{columns:!0},order:{name:"ASC",columns:{isPrimary:"DESC",name:"ASC"}}})).map(n=>({tableName:n.name,id:n.id,updatedAt:n.updatedAt,createdAt:n.createdAt,columns:n.columns.map(i=>({name:i.name,type:i.type,isPrimary:i.isPrimary,ref:i.meta?.refs}))}))}}})});var U=require("typeorm"),jt=h(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=f(t);return{data:await R.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 r=f(t),o=_(t),a=r.teamId||t.user.currentTeamId,n=Number(o.size)||20,i=Number(o.page)||0,s=o.nameFilter?.length?{name:(0,U.Raw)(p=>`LOWER(${p}) LIKE :search`,{search:`%${o.nameFilter.toLowerCase()}%`})}:void 0,m=await v.find({where:[{isPersonal:!1,team:{id:a},query:s},{isPersonal:!0,team:{id:a},query:s,user:{id:t.user.id}}],relations:{query:{dataSource:!0}},take:n+1,skip:i*n,select:{id:!0,query:{id:!0,name:!0,updatedAt:!0,dataSource:{name:!0,dbType:!0}}},order:{query:{updatedAt:"DESC"}}}),c=m.length>n;return c&&m.pop(),{data:m.map(p=>({name:p.query.name,id:p.query.id,updatedAt:p.query.updatedAt,savedQueryId:p.id,datasourceName:p.query.dataSource.name,datasourceType:p.query.dataSource.dbType})),hasMore:c}}}),e.route({method:"get",url:"/team/:teamId/count-saved-queries",handler:async t=>{let o=f(t).teamId||t.user.currentTeamId;return{data:await v.count({where:[{isPersonal:!1,team:{id:o}},{isPersonal:!0,team:{id:o},user:{id:t.user.id}}],select:{id:!0}})}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=f(t),{search:o,size:a,selectedDataSources:n}=_(t),i=o.length>3?parseInt(a)||20:8,s={};n?.length&&(s.id=(0,U.In)(n));let[m,c,l]=await Promise.all([ie.find({where:{name:(0,U.Raw)(d=>`LOWER(${d}) LIKE :search`,{search:`%${o.toLowerCase()}%`}),datasource:s},relations:{datasource:!0},select:{id:!0,name:!0,datasource:{name:!0,id:!0}},order:{name:"ASC"},take:i}),A.find({where:{searchString:(0,U.Like)(`%${o.toLowerCase()}%`),team:{id:r},user:{id:t.user.id},dataSource:s},relations:{dataSource:!0},select:{id:!0,name:!0,updatedAt:!0,dataSource:{id:!0,name:!0}},order:{updatedAt:"ASC"},take:i}),v.find({where:{searchString:(0,U.Like)(`%${o.toLowerCase()}%`),team:{id:r},query:{dataSource:s}},relations:{query:{dataSource:!0}},select:{id:!0,updatedAt:!0,query:{id:!0,name:!0,dataSource:{name:!0}}},order:{updatedAt:"ASC"},take:i})]),p=[];return m.forEach(d=>{p.push({name:d.name,id:d.id,dataSourceName:d.datasource?.name||"--",dataSourceId:d.datasource?.id||"--",type:"table"})}),c.forEach(d=>{p.push({name:d.name,id:d.id,dataSourceName:d.dataSource?.name||"--",dataSourceId:d.dataSource?.id||"--",type:"tab"})}),l.forEach(d=>{p.push({name:d.query.name,id:d.query.id,dataSourceName:d.query.dataSource?.name||"--",dataSourceId:d.query.dataSource?.id||"--",type:"query"})}),{data:p}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=f(t),o=_(t),a=Number(o.page),n=Number(o.size),i=t.user.id,s={team:{id:r},user:{id:i}};o.nameFilter?.length&&(s.name=(0,U.Like)(`%${o.nameFilter}%`)),o.archived&&(s.archived=o.archived==="true");let m=await A.find({where:s,relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),c=!1;return m.length>n&&(m.pop(),c=!0),{data:m.map(l=>({name:l.name,id:l.id,updatedAt:l.updatedAt,archived:l.archived,createdAt:l.createdAt,dataSourceId:l.dataSource?.id,dataSourceName:l.dataSource?.name,dataSourceType:l.dataSource?.dbType})),hasMore:c}}})});var Kt=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=f(t),o=await C.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:S("editor")},handler:async t=>{let r=y(t),o=await R.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await C.save(C.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:S("editor")},handler:async t=>{let{id:r}=f(t),o=y(t);if(!(await C.update(r,o)).affected)throw new u(404,"Query not found");return{data:await C.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("editor")},handler:async t=>b.transaction(async()=>{let{id:r}=f(t);if(!(await C.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var Vt=e=>e&&le(e)?"CONTAINS":"=",ve=(e,t)=>{let r=[];for(let o of e){if(!o.column?.length||!o.value?.length||o.isEnabled===!1)continue;let[a,n]=o.column.split("."),i=t(a,n);if(o.isAdvanced){let s=Wt.parse(o.value);if(!s)throw new u(400,`Invalid value for '${o.column}': ${o.value}`);r.push({value:s.value,column:o.column,operator:s.operator||Vt(i?.type),fn:o.fn})}else r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:Vt(i?.type),fn:o.fn})}return r},zt=e=>{let t=[e.table];return e.joins&&e.joins.forEach(({table:r})=>t.push(r)),t},xe=e=>({column:e.value,fn:e.fn,distinct:e.distinct}),Jt=(e,t,r)=>{let o=[];return t.length>0||r.length>0?o.push(...t.map(xe),...r.map(xe)):e.length>0&&o.push(...e.map(xe)),o},$o=e=>e.isPrimary&&e.table?.name?{table:e.table.name,field:e.name}:e?.meta?.refs,Ho=e=>e?.meta?.referencedBy,Xt=(e,t,r)=>t.map((o,a)=>{let n=o.table?r(o.table,o.column):void 0,i=n?$o(n):void 0,s=n?Ho(n):void 0;return{...o,full:e[a].fn?e[a].column:o.full,type:n?.type,fn:e[a].fn,ref:i,referencedBy:s}}),Zt=e=>{let t=[],r=[];for(let o of e)o.referencedBy?.forEach(a=>{t.push({id:[a.table,a.field,o.column,o.table].join("."),fromColumn:a.field,fromTable:a.table,toColumn:o.column,toTable:o.table,direction:"in"})}),o.ref&&r.push({id:[o.column,o.table,o.ref.table,o.ref.field].join("."),fromColumn:o.column,fromTable:o.table,toColumn:o.ref.field,toTable:o.ref.table,direction:"out"});return{hooks:t,entities:r}};var _e=require("typeorm"),er=new _e.DataSource({type:"mysql"}),tr=new _e.DataSource({type:"postgres"}),G=e=>{switch(e){case"postgres":return tr.createQueryBuilder();case"mysql":return er.createQueryBuilder();default:throw new Error("Unsupported database connection")}},de={postgres:tr.driver,mysql:er.driver};var X=(e,t,r)=>{let{column:o,operator:a,value:n}=e,i="_"+t;switch(a){case"IS NULL":case"IS NOT NULL":return[`${o} ${a}`,{value:void 0}];case"IN":case"NOT IN":return[`${o} ${a} (:...${i})`,{[i]:n?.map(c=>c.value)}];case"LIKE":case"CONTAINS":return[`${o} ${r==="postgres"?"ILIKE":"LIKE"} :${i}`,{[i]:a==="CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];case"NOT LIKE":case"NOT CONTAINS":return[`${o} ${r==="postgres"?"NOT ILIKE":"NOT LIKE"} :${i}`,{[i]:a==="NOT CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];default:return[`${o} ${a} :${i}`,{[i]:n?.[0]?.value}]}};var rr=e=>{let t=de[e];return r=>{if(r.includes(".")){let[o,a]=r.split(".");return t.escape(o)+"."+t.escape(a)}return r==="*"?r:t.escape(r)}};var or=["SUM","COUNT","AVG","MAX","MIN"],Wo=["YEAR","MONTH","DAY",...or],Yo=Wo.reduce((e,t)=>(e[t]=!0,e),{}),Go=or.reduce((e,t)=>(e[t]=!0,e),{}),ar=e=>Yo[e],nr=e=>Go[e];var pe=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,sr={YEAR:e=>`EXTRACT(YEAR FROM ${e})`,MONTH:e=>`EXTRACT(MONTH FROM ${e})`,DAY:e=>`EXTRACT(DAY FROM ${e})`,SUM:(e,t,r)=>r?`COALESCE(SUM(distinct ${e}), 0)`:`COALESCE(SUM(${e}), 0)`,AVG:pe,MAX:pe,MIN:pe,COUNT:pe};var fe=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,ir={YEAR:e=>`YEAR(${e})`,MONTH:e=>`MONTH(${e})`,DAY:e=>`DAY(${e})`,SUM:(e,t,r)=>r?`coalesce(${t}(distinct ${e}), 0)`:`coalesce(${t}(${e}), 0)`,AVG:fe,MAX:fe,MIN:fe,COUNT:fe};var jo=e=>{let t=[];return e.fn&&t.push(e.fn),e.distinct&&t.push("distinct"),t.push(e.column),t.join(" ")},Ko=e=>{let t=rr(e),r=e==="postgres"?sr:ir;return o=>o.fn&&ar(o.fn)?r[o.fn](t(o.column),o.fn,o.distinct):t(o.column)};function ur(e,t){let r=G(t.dbType).from(e,e),o=!1,a=0,n=Ko(t.dbType),i={};return{setColumns(s){s.forEach(m=>{let c=jo(m);i[c]=c,r.addSelect(n(m),c)})},setLimit:s=>{r.limit(s),o=!0},setOffset(s){r.offset(s)},addOrderBy(s,m){r.addOrderBy(s,m)},addJoin({table:s,alias:m,on:c}){r.leftJoin(s,m||s,c)},addWhere(s){let[m,c]=X({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andWhere(m,c)},addHaving(s){let[m,c]=X({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andHaving(m,c)},addGroupBy(s){r.addGroupBy(n(s))},hasAlias(s){return!!i[s]},build(){o||r.limit(50);let[s,m]=r.getQueryAndParameters();return{sql:s,params:m}}}}var cr=(e,t)=>{let r=G(t.dbType).update(e),o=0;return{addWhere(a){let[n,i]=X(a,++o,t.dbType);r.andWhere(n,i)},setParams(a){let n={};for(let[i,s]of Object.entries(a)){let m=`${s}`;m.startsWith("=")?n[i]=()=>m.substring(1):n[i]=m}r.set(n)},build(){let[a,n]=r.getQueryAndParameters();return{sql:a,params:n}}}};var mr=(e,t)=>{let r=G(t.dbType).insert().into(e);return{setValues(o){let a={};for(let[n,i]of Object.entries(o)){let s=`${i}`;s.startsWith("=")?a[n]=()=>s.substring(1):a[n]=s}r.values([a])},build(){let[o,a]=r.getQueryAndParameters();return{sql:o,params:a}}}};var Ue=ur,lr=cr,dr=mr;var pr=require("typeorm"),fr=async(e,t)=>{let r=await se.find({where:{table:{name:(0,pr.In)(t),datasource:{id:e}}},relations:{table:!0},order:{table:{name:"ASC"},isPrimary:"DESC",name:"ASC"}}),o=[];for(let s of r)o.push({column:s.name,table:s.table.name||"",full:`${s.table.name}.${s.name}`,type:s.type});let a=o.reduce((s,m)=>(s[m.full]=m.type,s),{});return{getAllColumns(){return o},hasColumn(s){return!!a[s]||s==="*"},getAvailableJoins:()=>{let s=[],m=new Set(t);for(let c of r)if(c.meta?.referencedBy?.forEach(l=>{m.has(l.table)||s.push({id:[l.table,l.field,c.name,c.table.name].join("."),fromColumn:l.field,fromTable:l.table,toColumn:c.name,toTable:c.table.name,direction:"in"})}),c.meta?.refs){let l=c.meta.refs;m.has(l.table)||s.push({id:[c.name,c.table.name,l.table,l.field].join("."),fromColumn:c.name,fromTable:c.table.name,toColumn:l.field,toTable:l.table,direction:"out"})}return s},getColumnByName:(s,m)=>{for(let c of r)if(c.name===m&&c.table.name===s)return c}}};async function Vo(e,t,r){return C.save(C.create({user:{id:e},team:{id:t},dataSource:{id:r.datasourceId},name:r.name,opts:r.opts}))}var ye=async(e,t)=>{let{datasourceId:r,size:o=20,page:a}=t,{table:n,joins:i,groupBy:s,orderBy:m}=t.opts,c=await Te(r);if(!c)throw new u(404,"Datasource not found");let l=Jt(t.opts.columns,t.opts.groupBy,t.opts.aggregations),p=zt(t.opts),d=await fr(r,p),N=d.getAllColumns(),L;l&&l.length>0?L=l:L=N.map(I=>({column:I.full})),L.forEach(I=>{if(!d.hasColumn(I.column))throw new u(400,`Invalid column ${I.column}`)});let zr=Vo(e.user.id,e.user.currentTeamId,t),x=Ue(n,c);x.setLimit(o+1),x.setOffset(o*a),x.setColumns(L),i&&i.forEach(x.addJoin),m.length>0&&m.forEach(({column:I,direction:ro})=>{x.hasAlias(I)&&x.addOrderBy(de[c.dbType].escape(I),ro)}),s&&s.length>0&&s.forEach(I=>{d.hasColumn(I.value)&&x.addGroupBy({column:I.value,fn:I.fn,distinct:I.distinct})}),ve(t.opts.filters,d.getColumnByName).forEach(I=>{I.fn&&nr(I.fn)?x.addHaving(I):x.addWhere(I)});let{sql:Jr,params:Xr}=x.build(),ee=await(await F(M(c,!0),c.dbType,e)).executeQuery({sql:Jr,params:Xr,type:"SELECT",allowBulkUpdate:!1}),ke=ee.rows.length>o;ke&&ee.rows.pop();let{id:Zr}=await zr,qe=Xt(L,ee.columns,d.getColumnByName),{hooks:eo,entities:to}=Zt(qe);return{...ee,queryHistoryId:Zr,tables:p,allColumns:N,availableHooks:eo,availableEntities:to,availableJoins:d.getAvailableJoins(),columns:qe,hasMore:ke}},yr=async(e,t)=>{let r=await Te(t.dataSourceId);if(!r)throw new u(400,"Invalid datasource");let o=await F(M(r,!0),r.dbType,e),a=Ue(t.table,r);a.setLimit(2);for(let[m,c]of Object.entries(t.props))a.addWhere({value:[{value:c}],column:m});let{sql:n,params:i}=a.build(),s=await o.executeQuery({sql:n,params:i,type:"SELECT",allowBulkUpdate:!1});if(s.rows.length>1)throw new u(400,"Found multiple rows for given query");if(s.rows.length<1)throw new u(404,"Entity not found");return{entity:s.rows[0],columns:s.columns,sql:n}},Tr=async(e,t)=>{let r=await Te(t.datasourceId);if(!r)throw new u(404,"Data source not found");if(!r.allowUpdate)throw new u(403,"This datasource does not allow update operations");let o=lr(t.table,r);o.setParams(t.values),ve(t.filters,()=>{}).forEach(s=>{o.addWhere(s)});let{sql:a,params:n}=o.build();return(await F(M(r,!0),r.dbType,e)).executeQuery({sql:a,params:n,type:"UPDATE",allowBulkUpdate:!1})},gr=async(e,t)=>{let r=await Te(t.datasourceId);if(!r)throw new u(404,"Data source not found");if(!r.allowInsert)throw new u(403,"This datasource does not allow insert operations");let o=dr(t.table,r);o.setValues(t.values);let{sql:a,params:n}=o.build();return(await F(M(r,!0),r.dbType,e)).executeQuery({sql:a,type:"INSERT",params:n,allowBulkUpdate:!1})};async function Te(e){return R.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var hr=e=>{},zo=["--",";","DROP","drop"],br=([e,t])=>{if(typeof t=="string"&&t.startsWith("=")){let r=t;zo.forEach(o=>{if(r.includes(o))throw new u(400,"Invalid input value for "+e)})}},wr=e=>{if(!e.table)throw new u(400,"Table is required");Object.entries(e.values).forEach(br)},Sr=e=>{if(!e.table)throw new u(400,"Table is required");Object.entries(e.values).forEach(br)};var Ir=h(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=y(t,hr);return{data:await ye(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=f(t),a=_(t);return{data:await yr(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:S("editor")},handler:async t=>{let r=y(t,wr);return{data:await gr(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:S("editor")},handler:async t=>{let r=y(t,Sr);return{data:await Tr(t,r)}}})});var Er=h(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:T.str("SERVER_VERSION")}}))});var Cr=h(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=f(t),o=await Q.findOne({where:{id:r},relations:{users:{user:!0}}});if(!o)throw new u(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:S("editor")},handler:async t=>b.transaction(async()=>{let r=t.user.id,o=y(t),a=w.create();a.id=r;let n=Q.create(o);await Q.save(n);let i=E.create({user:a,team:n});return await E.save(i),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:S("admin")},handler:async t=>{let{id:r}=f(t),{role:o,userId:a}=y(t,({role:i})=>{if(i==="owner")throw new u(400,"Only one owner is allowed")});if((await E.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new u(400,"Cannot change owner role");await E.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("admin")},handler:async t=>b.transaction(async()=>{let{id:r}=f(t),{userId:o}=_(t);if((await E.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new u(400,"Cannot delete team owner");await w.update(o,{currentTeam:null}),await E.delete({user:{id:o},team:{id:r}}),await w.delete({id:o})})})});var Le=O(require("bcryptjs")),Z=async e=>{let t=await Le.default.genSalt(10);return Le.default.hash(e,t)};var Rr=h(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 u(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=y(t);if(o.password&&(o.password=await Z(o.password)),!(await w.update(r,o)).affected)throw new u(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:S("admin")},handler:async t=>b.transaction(async()=>{let r=y(t),o=await Z(r.password),a=await w.save(w.create({username:r.username,password:o})),n=await E.save(E.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await w.update(a.id,{currentTeam:{id:n.id}})})})});var Nr=h(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}=y(t);if(!r.id)throw new u(400,"Settings id is required!");if(!(await W.update(r.id,r)).affected)throw new u(404,"You do not own these settings!");return{data:await W.findOneBy({id:r.id})}}})});function j(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 Ar=h(e=>{e.route({method:"post",url:"/",config:{requireRole:S("editor")},handler:async t=>{let r=y(t),o=await C.findOne({where:{id:r.queryId}});if(!o)throw new u(400,"Query not found");let a=await v.save(v.create({isPersonal:!1,team:{id:t.user.currentTeamId},user:{id:t.user.id},query:{id:r.queryId},searchString:j(o.opts,r.name)}));return await C.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("editor")},handler:async t=>{let{id:r}=f(t);if(!(await v.delete({id:r})).affected)return{status:404,data:"Query not found"}}}),e.route({method:"patch",url:"/:id",handler:async t=>await b.transaction(async()=>{let{id:r}=f(t),o=y(t,i=>{if(!i.name)throw new u(400,"Name is required")}),a=await v.findOne({where:{id:r},relations:{query:!0}});if(!a)throw new u(400,"Query not found");let n=j(a.query.opts,o.name);return await Promise.all([v.update({id:r},{searchString:n}),C.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var Pr=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new u(400,"Either queryId or name and opts are required")};var Or=h(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}=f(t),{currentTeamId:o,id:a}=t.user,n=await A.findOne({where:{id:r,team:{id:o},user:{id:a}}});if(!n)throw new u(404,"Not Found");return{data:n}}}),e.route({method:"post",url:"/",handler:async t=>{let{opts:r,name:o,queryId:a}=y(t,Pr),n,i,s=o;if(r)i=r.dataSourceId,n=r;else{let c=await C.findOne({where:{id:a},relations:{dataSource:!0}});if(!c)throw new u(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||(s=c.name)}return{data:await A.save(A.create({name:s||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}=f(t),o=y(t),a=await A.findOne({where:{id:r},relations:{user:!0}});if(!a)throw new u(404,"Not found");if(a.user?.id!==t.user.id)throw new u(404,"Not found");return o&&A.update(r,{opts:o||{},searchString:j(o,a.name),updatedAt:new Date}),{data:{result:await ye(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}=f(t),o=y(t),a=await A.findOne({where:{id:r,user:{id:t.user.id}}});if(!a)throw new u(404,"Not Found");let n=a.searchString;return o.name&&(n=j(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}=f(t),o=t.user.id;return await A.delete({id:r,user:{id:o}}),{data:!0}}})});var vr=require("node:crypto");var Dr=require("node:crypto"),xr={teamName:"Default Team",username:"admin"},Jo=async()=>{let e=await Q.findOneBy({});return e||Q.save(Q.create({name:xr.teamName}))},ge=async e=>{let t=await E.findOne({where:{role:"owner"},relations:{user:!0}});if(t)return t.user;let r=await Jo(),o=await Z(e?.password||(0,Dr.randomBytes)(32).toString("hex")),a=await w.save(w.create({username:e?.name||xr.username,password:o})),n=await E.save(E.create({user:a,team:r,role:"owner"}));return await w.update(a.id,{currentTeam:n}),a};var he={setupAccessToken:void 0},_r=()=>(he.setupAccessToken=(0,vr.randomBytes)(32).toString("hex"),he.setupAccessToken),Xo=e=>{if(!he.setupAccessToken)throw new u(400,"Setup already performed");if(!e||e!==he.setupAccessToken)throw new u(400,"Invalid setup access token")},H=async()=>D.skipAuth?!1:await w.count()<1,Ur=async e=>{Xo(e.setupAccessToken),await ge({name:e.userName,password:e.userPassword})};var Lr=h(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:D.skipAuth,modeName:D.name,usesCustomDb:He(),serverVersion:T.str("SERVER_VERSION","--")};return r.type("application/javascript").send(`window.__CLIENT_CONFIG__ = ${JSON.stringify(o)};`)}}),e.route({method:"get",url:"/",handler:async(t,r)=>await H()?r.redirect("/setup"):r.sendFile("index.html")}),e.route({method:"get",url:"/setup",handler:async(t,r)=>await H()?r.sendFile("setup.html"):r.redirect("/")})});var kr=e=>{if(!e.setupAccessToken)throw new u(400,"Invalid setup access token");if(!e.userPassword||e.userPassword.length<8)throw new u(400,"Password should be at least 8 chars long");if(!e.userName)throw new u(400,"User name is required")};var qr=h(e=>{e.route({method:"post",url:"/",config:{isPublic:!0},handler:async t=>{if(!await H())throw new u(400,"Setup has already been completed");let o=y(t,kr);return await Ur(o),{data:!0}}})});var Zo=[[Lr,"/"],[ft,"/api/auth"],[Gt,"/api/data-sources"],[jt,"/api/project"],[Kt,"/api/queries"],[Ir,"/api/runner"],[Er,"/api/status"],[Cr,"/api/teams"],[Rr,"/api/users"],[Nr,"/api/user-settings"],[Ar,"/api/saved-queries"],[Or,"/api/workbench-tabs"],[qr,"/api/setup"]],Br=e=>{for(let[t,r]of Zo)e.register(t,{prefix:r}),console.log("Registered "+r)};var ea=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),ta=async()=>E.findOne({where:{role:"owner"},relations:{user:!0,team:!0}}),ra=async e=>{let t=await ta();if(!t)throw new u(401,"User is not part of a team");e.user={id:t.user.id,currentTeamId:t.team.id,currentTeamRole:t.role}},oa=async e=>{let t=e.headers.authorization;if(!t)throw new u(401,"Missing auth token");let[r,o]=t.split(" "),{userId:a}=await mt(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 u(401,"Unauthorized");e.user={id:a,currentTeamId:n.currentTeam.team.id,currentTeamRole:n.currentTeam.role}},Qr=async e=>{ea(e)||(D.skipAuth?await ra(e):await oa(e))};var Fr=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Mr=e=>{e.addHook("onRequest",Qr),e.addHook("onRequest",Yt),e.addHook("onResponse",Fr)};var $r=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 u?o.status(t.status).send({error:t.message}):o.status(500).send({error:"Internal Server Error"})})};var Hr=O(require("@fastify/cookie")),Wr=O(require("@fastify/cors"));var Yr=O(require("@fastify/static")),Gr=require("node:path"),jr=e=>{e.register(Hr.default,{}),e.register(Wr.default,{origin:V.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(Yr.default,{root:(0,Gr.join)(__dirname,"web")})};(async function(){let t=(0,Kr.default)({querystringParser:o=>Vr.default.parse(o)});if($e(),jr(t),Mr(t),Br(t),$r(t),await t.after(),await ot(),t.listen({port:V.port,host:V.host},(o,a)=>{o&&(console.error(o),process.exit(1)),console.log(`Server listening at ${a}`)}),await H()){let o=_r();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 ge()})();
57
+ limit 75;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},St=async(e,t,r,o)=>{try{console.log(`[PG CONN] Query: ${e}`),console.log(`[PG CONN] Params: ${JSON.stringify(t,null,2)}`);let{rows:a,fields:n,command:u,rowCount:s}=await r.query({text:e,rowMode:"array",values:t});if(u==="UPDATE"||u==="INSERT"||u==="DELETE"){if(s!=null&&s>1&&o.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[s]],query:e}}if(u==="SELECT"){let m=n.map(l=>`'${l.tableID}-${l.columnID}'`),c=await Oo(m,r);return{columns:n.map(l=>{let p=c[`${l.tableID}-${l.columnID}`];return{column:p?.column||l.name,alias:l.name,table:p?.table||"",full:p?p.table+"."+p.column:l.name}}),rows:a,query:e}}throw new Error(`[PG CONN] Unsupported command: ${u}`)}catch(a){throw a instanceof i?a:new i(400,a.message)}},Po=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}},Do=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}},xe=async e=>{let t=await Co(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:()=>Ao(e,t),executeQuery:n=>a(()=>n.type==="SELECT"?Do(t,()=>St(n.sql,n.params,t,n)):Po(t,()=>St(n.sql,n.params,t,n))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var $=async(e,t,r)=>{try{let o;if(t==="mysql")o=await De(e);else if(t==="postgres")o=await xe(e);else throw new i(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 i?o:o?.code==="ECONNREFUSED"?new i(500,"Failed to connect to the database"):new i(500,o.message)}},It=async(e,t)=>{try{let r;if(t==="mysql")r=await De(e);else if(t==="postgres")r=await xe(e);else throw new i(500,`Connection manager for ${t} not found`);return r}catch(r){throw console.error(r),r instanceof i?r:r?.code==="ECONNREFUSED"?new i(500,"Failed to connect to the database"):new i(500,r.message)}};var ce=P(require("node:crypto"));var Ct="aes-256-gcm",xo=12,Rt=()=>{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},vo=e=>{let t=ce.default.randomBytes(xo),r=Rt(),o=ce.default.createCipheriv(Ct,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")}},_o=({encrypted:e,iv:t,tag:r})=>{let o=Rt(),a=ce.default.createDecipheriv(Ct,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},me={encrypt:vo,decrypt:_o};var U=(e,t=!1)=>{if(t){let r=me.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 Nt=[{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:"like"},{value:"NOT LIKE",label:"not like"},{value:"CONTAINS",label:"contains"},{value:"NOT CONTAINS",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"}],Uo=Nt.reduce((e,t)=>(e[t.value]=t.label,e),{}),ms=Nt.reduce((e,t)=>(e[t.label]=t.value,e),{}),Y=e=>e.map(t=>({label:Uo[t],value:t})),ls=Y(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),ds=Y(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL","CONTAINS","NOT CONTAINS"]),ps=Y(["=","<>","IS NULL","IS NOT NULL"]),fs=Y(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),ys=Y(["IS NULL","IS NOT NULL"]),Ts=Y(["IN","NOT IN"]),ko=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],Lo=new Set(ko),le=e=>Lo.has(e),qo=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],Bo=new Set(qo),At=e=>Bo.has(e);var gs=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var ve={read_only:10,editor:20,admin:30,owner:40};var O=e=>e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;var Ot={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:O(t[1])}]},stringify:e=>`LIKE "%${e[0]?.value}%"`},Pt={operator:"NOT LIKE",parse:e=>{let t=e.match(/^NOT LIKE\s*["'](.*)["']$/i);if(t)return[{value:O(t[1])}]},stringify:e=>`NOT LIKE "%${e[0]?.value}%"`},Dt={operator:"CONTAINS",parse:e=>{let t=e.match(/^CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:O(t[1])}]},stringify:(e,t)=>le(t)?`${e[0]?.value}`:`CONTAINS "%${e[0]?.value}%"`},xt={operator:"NOT CONTAINS",parse:e=>{let t=e.match(/^NOT CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:O(t[1])}]},stringify:e=>`NOT CONTAINS "%${e[0]?.value}%"`};function _t(e){return e===""?[]:Qo(e).map(Fo)}function Qo(e){let t=[],r=0,o="",a=!1,n=!1;for(;r<e.length;){let u=e[r];if((a||n)&&u==="\\"){o+=e[r+1],r+=2;continue}if(u==="'"&&!n){a=!a,o+=u,r++;continue}if(u==='"'&&!a){n=!n,o+=u,r++;continue}if(u===","&&!a&&!n){t.push(o.trim()),o="",r++;continue}o+=u,r++}if(o.trim()!==""&&t.push(o.trim()),a||n)throw new Error("Unterminated string literal");return t}function Fo(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:vt(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:vt(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function vt(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var Ut={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return _t(t[1])},stringify:e=>`IN (${e?.map(t=>`"${t.value}"`).join(", ")})`},kt={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return _t(t[1])},stringify:e=>`NOT IN (${e?.map(t=>`"${t.value}"`).join(", ")})`};var Lt={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:(e,t)=>At(t)?`${e[0]?.value}`:`= ${e[0]?.value}`},qt={operator:"!=",parse:e=>{let t=e.match(/^!=\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`!= ${e[0]?.value}`},Bt={operator:"<>",parse:e=>{let t=e.match(/^<>\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`<> ${e[0]?.value}`},Qt={operator:">",parse:e=>{let t=e.match(/^>\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`> ${e[0]?.value}`},Ft={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`>= ${e[0]?.value}`},Mt={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`< ${e[0]?.value}`},$t={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`<= ${e[0]?.value}`};var Ht={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},Wt={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var Mo=[Ot,Dt,Pt,xt,Ut,kt,Lt,qt,Bt,Ft,Qt,$t,Mt,Ht,Wt];function $o(e){let t=e.trim();for(let r of Mo){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var Yt={parse:$o};var S=e=>{let t=ve[e];return r=>ve[r.currentTeamRole]>=t},Gt=async e=>{let t=e.routeOptions.config.requireRole;if(t&&!t(e.user))throw new i(403,"You are not authorized to perform this action")};var de=async(e,t)=>{let r=await e.find(B,{where:{datasource:{id:t}},select:["id"]});for(let o of r){let a=await e.find(q,{where:{tableId:o.id},select:["id"]});await e.remove(q,a),await e.delete(B,o)}};function Ho(e){let t=new Map;for(let r of e)r.columns?.forEach(o=>{if(o.ref){let a=`${o.ref.table}.${o.ref.field}`,n=t.get(a)||[];n.push({table:r.tableName,field:o.name}),t.set(a,n)}});return t}var jt=async e=>{let t=await E.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!t)throw new Error("Data source not found");return t.status="INSPECTING",await E.save(t),b.transaction(async r=>{let a=await(await It(U(t,!0),t.dbType)).inspectSchema();await de(r,t.id);let n=Ho(a);for(let u of a){let s=await r.save(B,{datasource:{id:e},name:u.tableName});if(u.columns){let m=[];for(let c of u.columns)m.push(se.create({table:{id:s.id},name:c.name,isPrimary:!!c.isPrimary,type:c.type,meta:{refs:c.ref,referencedBy:n.get(`${s.name}.${c.name}`)}}));await r.save(q,m)}}await r.save(M,{id:e,status:"READY",lastInspected:new Date})}).catch(r=>{console.error(r),E.save({id:e,status:"FAILED"})}),!0};var Kt=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=y(t),o=await E.findOne({where:{id:r}});if(!o)throw new i(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=v(t);return{data:await E.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:S("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=f(t,gt),n=E.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),u=await $(U(n),n.dbType,t);try{await u.checkConnection()}catch{throw new i(400,"Cannot connect to the database, please check datasource configuration")}let{tag:s,iv:m,encrypted:c}=me.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=m,n.dbPasswordTag=s,{data:await E.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:S("admin")},handler:async t=>{let{id:r}=y(t),o=f(t),a=await E.findOneBy({id:r});if(!a)throw new i(404,"Data source not found");let n=E.merge(a,o);return await E.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("admin")},handler:async t=>b.transaction(async r=>{let{id:o}=y(t);await Promise.all([de(r,o),r.delete(K,{dataSource:{id:o}})]),await r.delete(M,{id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=y(t);return{data:{started:await jt(o)}}}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=y(t);return{data:(await ie.find({where:{datasource:{id:r}},relations:{columns:!0},order:{name:"ASC",columns:{isPrimary:"DESC",name:"ASC"}}})).map(n=>({tableName:n.name,id:n.id,updatedAt:n.updatedAt,createdAt:n.createdAt,columns:n.columns.map(u=>({name:u.name,type:u.type,isPrimary:u.isPrimary,ref:u.meta?.refs}))}))}}})});var k=require("typeorm"),Vt=h(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=y(t);return{data:await E.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 r=y(t),o=v(t),a=r.teamId||t.user.currentTeamId,n=Number(o.size)||20,u=Number(o.page)||0,s=o.nameFilter?.length?{name:(0,k.Raw)(p=>`LOWER(${p}) LIKE :search`,{search:`%${o.nameFilter.toLowerCase()}%`})}:void 0,m=await _.find({where:[{isPersonal:!1,team:{id:a},query:s},{isPersonal:!0,team:{id:a},query:s,user:{id:t.user.id}}],relations:{query:{dataSource:!0}},take:n+1,skip:u*n,select:{id:!0,query:{id:!0,name:!0,updatedAt:!0,dataSource:{name:!0,dbType:!0}}},order:{query:{updatedAt:"DESC"}}}),c=m.length>n;return c&&m.pop(),{data:m.map(p=>({name:p.query.name,id:p.query.id,updatedAt:p.query.updatedAt,savedQueryId:p.id,datasourceName:p.query.dataSource.name,datasourceType:p.query.dataSource.dbType})),hasMore:c}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=y(t),{search:o,size:a,selectedDataSources:n}=v(t),u=o.length>3?parseInt(a)||20:8,s={};n?.length&&(s.id=(0,k.In)(n));let[m,c,l]=await Promise.all([ie.find({where:{name:(0,k.Raw)(d=>`LOWER(${d}) LIKE :search`,{search:`%${o.toLowerCase()}%`}),datasource:s},relations:{datasource:!0},select:{id:!0,name:!0,datasource:{name:!0,id:!0}},order:{name:"ASC"},take:u}),A.find({where:{searchString:(0,k.Like)(`%${o.toLowerCase()}%`),team:{id:r},user:{id:t.user.id},dataSource:s},relations:{dataSource:!0},select:{id:!0,name:!0,updatedAt:!0,dataSource:{id:!0,name:!0}},order:{updatedAt:"ASC"},take:u}),_.find({where:{searchString:(0,k.Like)(`%${o.toLowerCase()}%`),team:{id:r},query:{dataSource:s}},relations:{query:{dataSource:!0}},select:{id:!0,updatedAt:!0,query:{id:!0,name:!0,dataSource:{name:!0}}},order:{updatedAt:"ASC"},take:u})]),p=[];return m.forEach(d=>{p.push({name:d.name,id:d.id,dataSourceName:d.datasource?.name||"--",dataSourceId:d.datasource?.id||"--",type:"table"})}),c.forEach(d=>{p.push({name:d.name,id:d.id,dataSourceName:d.dataSource?.name||"--",dataSourceId:d.dataSource?.id||"--",type:"tab"})}),l.forEach(d=>{p.push({name:d.query.name,id:d.query.id,dataSourceName:d.query.dataSource?.name||"--",dataSourceId:d.query.dataSource?.id||"--",type:"query"})}),{data:p}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=y(t),o=v(t),a=Number(o.page),n=Number(o.size),u=t.user.id,s={team:{id:r},user:{id:u}};o.nameFilter?.length&&(s.name=(0,k.Like)(`%${o.nameFilter}%`)),o.archived&&(s.archived=o.archived==="true");let m=await A.find({where:s,relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),c=!1;return m.length>n&&(m.pop(),c=!0),{data:m.map(l=>({name:l.name,id:l.id,updatedAt:l.updatedAt,archived:l.archived,createdAt:l.createdAt,dataSourceId:l.dataSource?.id,dataSourceName:l.dataSource?.name,dataSourceType:l.dataSource?.dbType})),hasMore:c}}})});var zt=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=y(t),o=await R.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:S("editor")},handler:async t=>{let r=f(t),o=await E.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await R.save(R.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:S("editor")},handler:async t=>{let{id:r}=y(t),o=f(t);if(!(await R.update(r,o)).affected)throw new i(404,"Query not found");return{data:await R.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("editor")},handler:async t=>b.transaction(async()=>{let{id:r}=y(t);if(!(await R.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var Jt=e=>e&&le(e)?"CONTAINS":"=",Ue=(e,t)=>{let r=[];for(let o of e){if(!o.column?.length||!o.value?.length||o.isEnabled===!1)continue;let[a,n]=o.column.split("."),u=t(a,n);if(o.isAdvanced){let s=Yt.parse(o.value);if(!s)throw new i(400,`Invalid value for '${o.column}': ${o.value}`);r.push({value:s.value,column:o.column,operator:s.operator||Jt(u?.type),fn:o.fn})}else r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:Jt(u?.type),fn:o.fn})}return r},Xt=e=>{let t=[e.table];return e.joins&&e.joins.forEach(({table:r})=>t.push(r)),t},_e=e=>({column:e.value,fn:e.fn,distinct:e.distinct}),Zt=(e,t,r)=>{let o=[];return t.length>0||r.length>0?o.push(...t.map(_e),...r.map(_e)):e.length>0&&o.push(...e.map(_e)),o},Wo=e=>e.isPrimary&&e.table?.name?{table:e.table.name,field:e.name}:e?.meta?.refs,Yo=e=>e?.meta?.referencedBy,er=(e,t,r)=>t.map((o,a)=>{let n=o.table?r(o.table,o.column):void 0,u=n?Wo(n):void 0,s=n?Yo(n):void 0;return{...o,full:e[a].fn?e[a].column:o.full,type:n?.type,fn:e[a].fn,ref:u,referencedBy:s}}),tr=e=>{let t=[],r=[];for(let o of e)o.referencedBy?.forEach(a=>{t.push({id:[a.table,a.field,o.column,o.table].join("."),fromColumn:a.field,fromTable:a.table,toColumn:o.column,toTable:o.table,direction:"in"})}),o.ref&&(r.push({id:[o.column,o.table,o.ref.table,o.ref.field].join("."),fromColumn:o.column,fromTable:o.table,toColumn:o.ref.field,toTable:o.ref.table,direction:"out"}),t.push({id:[o.column,o.table,o.ref.table,o.ref.field].join("."),fromColumn:o.column,fromTable:o.table,toColumn:o.ref.field,toTable:o.ref.table,direction:"out"}));return{hooks:t,entities:r}};var ke=require("typeorm"),rr=new ke.DataSource({type:"mysql"}),or=new ke.DataSource({type:"postgres"}),G=e=>{switch(e){case"postgres":return or.createQueryBuilder();case"mysql":return rr.createQueryBuilder();default:throw new Error("Unsupported database connection")}},pe={postgres:or.driver,mysql:rr.driver};var X=(e,t,r)=>{let{column:o,operator:a,value:n}=e,u="_"+t;switch(a){case"IS NULL":case"IS NOT NULL":return[`${o} ${a}`,{value:void 0}];case"IN":case"NOT IN":return[`${o} ${a} (:...${u})`,{[u]:n?.map(c=>c.value)}];case"LIKE":case"CONTAINS":return[`${o} ${r==="postgres"?"ILIKE":"LIKE"} :${u}`,{[u]:a==="CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];case"NOT LIKE":case"NOT CONTAINS":return[`${o} ${r==="postgres"?"NOT ILIKE":"NOT LIKE"} :${u}`,{[u]:a==="NOT CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];default:return[`${o} ${a} :${u}`,{[u]:n?.[0]?.value}]}};var ar=e=>{let t=pe[e];return r=>{if(r.includes(".")){let[o,a]=r.split(".");return t.escape(o)+"."+t.escape(a)}return r==="*"?r:t.escape(r)}};var nr=["SUM","COUNT","AVG","MAX","MIN"],Go=["YEAR","MONTH","DAY",...nr],jo=Go.reduce((e,t)=>(e[t]=!0,e),{}),Ko=nr.reduce((e,t)=>(e[t]=!0,e),{}),sr=e=>jo[e],ir=e=>Ko[e];var fe=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,ur={YEAR:e=>`EXTRACT(YEAR FROM ${e})`,MONTH:e=>`EXTRACT(MONTH FROM ${e})`,DAY:e=>`EXTRACT(DAY FROM ${e})`,SUM:(e,t,r)=>r?`COALESCE(SUM(distinct ${e}), 0)`:`COALESCE(SUM(${e}), 0)`,AVG:fe,MAX:fe,MIN:fe,COUNT:fe};var ye=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,cr={YEAR:e=>`YEAR(${e})`,MONTH:e=>`MONTH(${e})`,DAY:e=>`DAY(${e})`,SUM:(e,t,r)=>r?`coalesce(${t}(distinct ${e}), 0)`:`coalesce(${t}(${e}), 0)`,AVG:ye,MAX:ye,MIN:ye,COUNT:ye};var Vo=e=>{let t=[];return e.fn&&t.push(e.fn),e.distinct&&t.push("distinct"),t.push(e.column),t.join(" ")},zo=e=>{let t=ar(e),r=e==="postgres"?ur:cr;return o=>o.fn&&sr(o.fn)?r[o.fn](t(o.column),o.fn,o.distinct):t(o.column)};function mr(e,t){let r=G(t.dbType).from(e,e),o=!1,a=0,n=zo(t.dbType),u={};return{setColumns(s){s.forEach(m=>{let c=Vo(m);u[c]=c,r.addSelect(n(m),c)})},setLimit:s=>{r.limit(s),o=!0},setOffset(s){r.offset(s)},addOrderBy(s,m){r.addOrderBy(s,m)},addJoin({table:s,alias:m,on:c}){r.leftJoin(s,m||s,c)},addWhere(s){let[m,c]=X({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andWhere(m,c)},addHaving(s){let[m,c]=X({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andHaving(m,c)},addGroupBy(s){r.addGroupBy(n(s))},hasAlias(s){return!!u[s]},build(){o||r.limit(50);let[s,m]=r.getQueryAndParameters();return{sql:s,params:m}}}}var lr=(e,t)=>{let r=G(t.dbType).update(e),o=0;return{addWhere(a){let[n,u]=X(a,++o,t.dbType);r.andWhere(n,u)},setParams(a){let n={};for(let[u,s]of Object.entries(a)){let m=`${s}`;m.startsWith("=")?n[u]=()=>m.substring(1):n[u]=m}r.set(n)},build(){let[a,n]=r.getQueryAndParameters();return{sql:a,params:n}}}};var dr=(e,t)=>{let r=G(t.dbType).insert().into(e);return{setValues(o){let a={};for(let[n,u]of Object.entries(o)){let s=`${u}`;s.startsWith("=")?a[n]=()=>s.substring(1):a[n]=s}r.values([a])},build(){let[o,a]=r.getQueryAndParameters();return{sql:o,params:a}}}};var Le=mr,pr=lr,fr=dr;var yr=require("typeorm"),Tr=async(e,t)=>{let r=await se.find({where:{table:{name:(0,yr.In)(t),datasource:{id:e}}},relations:{table:!0},order:{table:{name:"ASC"},isPrimary:"DESC",name:"ASC"}}),o=[];for(let s of r)o.push({column:s.name,table:s.table.name||"",full:`${s.table.name}.${s.name}`,type:s.type});let a=o.reduce((s,m)=>(s[m.full]=m.type,s),{});return{getAllColumns(){return o},hasColumn(s){return!!a[s]||s==="*"},getAvailableJoins:()=>{let s=[],m=new Set(t);for(let c of r)if(c.meta?.referencedBy?.forEach(l=>{m.has(l.table)||s.push({id:[l.table,l.field,c.name,c.table.name].join("."),fromColumn:l.field,fromTable:l.table,toColumn:c.name,toTable:c.table.name,direction:"in"})}),c.meta?.refs){let l=c.meta.refs;m.has(l.table)||s.push({id:[c.name,c.table.name,l.table,l.field].join("."),fromColumn:c.name,fromTable:c.table.name,toColumn:l.field,toTable:l.table,direction:"out"})}return s},getColumnByName:(s,m)=>{for(let c of r)if(c.name===m&&c.table.name===s)return c}}};async function Jo(e,t,r){return R.save(R.create({user:{id:e},team:{id:t},dataSource:{id:r.datasourceId},name:r.name,opts:r.opts}))}var Te=async(e,t)=>{let{datasourceId:r,size:o=20,page:a}=t,{table:n,joins:u,groupBy:s,orderBy:m}=t.opts,c=await ge(r);if(!c)throw new i(404,"Datasource not found");let l=Zt(t.opts.columns,t.opts.groupBy,t.opts.aggregations),p=Xt(t.opts),d=await Tr(r,p),N=d.getAllColumns(),L;l&&l.length>0?L=l:L=N.map(I=>({column:I.full})),L.forEach(I=>{if(!d.hasColumn(I.column))throw new i(400,`Invalid column ${I.column}`)});let Xr=Jo(e.user.id,e.user.currentTeamId,t),x=Le(n,c);x.setLimit(o+1),x.setOffset(o*a),x.setColumns(L),u&&u.forEach(x.addJoin),m.length>0&&m.forEach(({column:I,direction:ao})=>{x.hasAlias(I)&&x.addOrderBy(pe[c.dbType].escape(I),ao)}),s&&s.length>0&&s.forEach(I=>{d.hasColumn(I.value)&&x.addGroupBy({column:I.value,fn:I.fn,distinct:I.distinct})}),Ue(t.opts.filters,d.getColumnByName).forEach(I=>{I.fn&&ir(I.fn)?x.addHaving(I):x.addWhere(I)});let{sql:Zr,params:eo}=x.build(),ee=await(await $(U(c,!0),c.dbType,e)).executeQuery({sql:Zr,params:eo,type:"SELECT",allowBulkUpdate:!1}),Be=ee.rows.length>o;Be&&ee.rows.pop();let{id:to}=await Xr,Qe=er(L,ee.columns,d.getColumnByName),{hooks:ro,entities:oo}=tr(Qe);return{...ee,queryHistoryId:to,tables:p,allColumns:N,availableHooks:ro,availableEntities:oo,availableJoins:d.getAvailableJoins(),columns:Qe,hasMore:Be}},gr=async(e,t)=>{let r=await ge(t.dataSourceId);if(!r)throw new i(400,"Invalid datasource");let o=await $(U(r,!0),r.dbType,e),a=Le(t.table,r);a.setLimit(2);for(let[m,c]of Object.entries(t.props))a.addWhere({value:[{value:c}],column:m});let{sql:n,params:u}=a.build(),s=await o.executeQuery({sql:n,params:u,type:"SELECT",allowBulkUpdate:!1});if(s.rows.length>1)throw new i(400,"Found multiple rows for given query");if(s.rows.length<1)throw new i(404,"Entity not found");return{entity:s.rows[0],columns:s.columns,sql:n}},hr=async(e,t)=>{let r=await ge(t.datasourceId);if(!r)throw new i(404,"Data source not found");if(!r.allowUpdate)throw new i(403,"This datasource does not allow update operations");let o=pr(t.table,r);o.setParams(t.values),Ue(t.filters,()=>{}).forEach(s=>{o.addWhere(s)});let{sql:a,params:n}=o.build();return(await $(U(r,!0),r.dbType,e)).executeQuery({sql:a,params:n,type:"UPDATE",allowBulkUpdate:!1})},br=async(e,t)=>{let r=await ge(t.datasourceId);if(!r)throw new i(404,"Data source not found");if(!r.allowInsert)throw new i(403,"This datasource does not allow insert operations");let o=fr(t.table,r);o.setValues(t.values);let{sql:a,params:n}=o.build();return(await $(U(r,!0),r.dbType,e)).executeQuery({sql:a,type:"INSERT",params:n,allowBulkUpdate:!1})};async function ge(e){return E.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var wr=e=>{},Xo=["--",";","DROP","drop"],Sr=([e,t])=>{if(typeof t=="string"&&t.startsWith("=")){let r=t;Xo.forEach(o=>{if(r.includes(o))throw new i(400,"Invalid input value for "+e)})}},Er=e=>{if(!e.table)throw new i(400,"Table is required");Object.entries(e.values).forEach(Sr)},Ir=e=>{if(!e.table)throw new i(400,"Table is required");Object.entries(e.values).forEach(Sr)};var Cr=h(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=f(t,wr);return{data:await Te(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=y(t),a=v(t);return{data:await gr(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:S("editor")},handler:async t=>{let r=f(t,Er);return{data:await br(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:S("editor")},handler:async t=>{let r=f(t,Ir);return{data:await hr(t,r)}}})});var Rr=h(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:T.str("SERVER_VERSION")}}))});var Nr=h(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=y(t),o=await Q.findOne({where:{id:r},relations:{users:{user:!0}}});if(!o)throw new i(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:S("editor")},handler:async t=>b.transaction(async()=>{let r=t.user.id,o=f(t),a=w.create();a.id=r;let n=Q.create(o);await Q.save(n);let u=C.create({user:a,team:n});return await C.save(u),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:S("admin")},handler:async t=>{let{id:r}=y(t),{role:o,userId:a}=f(t,({role:u})=>{if(u==="owner")throw new i(400,"Only one owner is allowed")});if((await C.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new i(400,"Cannot change owner role");await C.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("admin")},handler:async t=>b.transaction(async()=>{let{id:r}=y(t),{userId:o}=v(t);if((await C.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new i(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 qe=P(require("bcryptjs")),Z=async e=>{let t=await qe.default.genSalt(10);return qe.default.hash(e,t)};var Ar=h(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 i(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 Z(o.password)),!(await w.update(r,o)).affected)throw new i(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:S("admin")},handler:async t=>b.transaction(async()=>{let r=f(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 Or=h(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}=f(t);if(!r.id)throw new i(400,"Settings id is required!");if(!(await W.update(r.id,r)).affected)throw new i(404,"You do not own these settings!");return{data:await W.findOneBy({id:r.id})}}})});function j(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 Pr=h(e=>{e.route({method:"post",url:"/",config:{requireRole:S("editor")},handler:async t=>{let r=f(t),o=await R.findOne({where:{id:r.queryId}});if(!o)throw new i(400,"Query not found");let a=await _.save(_.create({isPersonal:!1,team:{id:t.user.currentTeamId},user:{id:t.user.id},query:{id:r.queryId},searchString:j(o.opts,r.name)}));return await R.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:S("editor")},handler:async t=>{let{id:r}=y(t);if(!(await _.delete({id:r})).affected)return{status:404,data:"Query not found"}}}),e.route({method:"patch",url:"/:id",handler:async t=>await b.transaction(async()=>{let{id:r}=y(t),o=f(t,u=>{if(!u.name)throw new i(400,"Name is required")}),a=await _.findOne({where:{id:r},relations:{query:!0}});if(!a)throw new i(400,"Query not found");let n=j(a.query.opts,o.name);return await Promise.all([_.update({id:r},{searchString:n}),R.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var Dr=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new i(400,"Either queryId or name and opts are required")};var xr=h(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}=y(t),{currentTeamId:o,id:a}=t.user,n=await A.findOne({where:{id:r,team:{id:o},user:{id:a}}});if(!n)throw new i(404,"Not Found");return{data:n}}}),e.route({method:"post",url:"/",handler:async t=>{let{opts:r,name:o,queryId:a}=f(t,Dr),n,u,s=o;if(r)u=r.dataSourceId,n=r;else{let c=await R.findOne({where:{id:a},relations:{dataSource:!0}});if(!c)throw new i(404,"Query not Found");u=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||(s=c.name)}return{data:await A.save(A.create({name:s||new Date().toISOString(),opts:n||{},dataSource:{id:u},user:{id:t.user.id},team:{id:t.user.currentTeamId}}))}}}),e.route({method:"post",url:"/:id/run",handler:async t=>{let{id:r}=y(t),o=f(t),a=await A.findOne({where:{id:r},relations:{user:!0}});if(!a)throw new i(404,"Not found");if(a.user?.id!==t.user.id)throw new i(404,"Not found");return o&&A.update(r,{opts:o||{},searchString:j(o,a.name),updatedAt:new Date}),{data:{result:await Te(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}=y(t),o=f(t),a=await A.findOne({where:{id:r,user:{id:t.user.id}}});if(!a)throw new i(404,"Not Found");let n=a.searchString;return o.name&&(n=j(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}=y(t),o=t.user.id;return await A.delete({id:r,user:{id:o}}),{data:!0}}})});var Ur=require("node:crypto");var vr=require("node:crypto"),_r={teamName:"Default Team",username:"admin"},Zo=async()=>{let e=await Q.findOneBy({});return e||Q.save(Q.create({name:_r.teamName}))},he=async e=>{let t=await C.findOne({where:{role:"owner"},relations:{user:!0}});if(t)return t.user;let r=await Zo(),o=await Z(e?.password||(0,vr.randomBytes)(32).toString("hex")),a=await w.save(w.create({username:e?.name||_r.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 be={setupAccessToken:void 0},kr=()=>(be.setupAccessToken=(0,Ur.randomBytes)(32).toString("hex"),be.setupAccessToken),ea=e=>{if(!be.setupAccessToken)throw new i(400,"Setup already performed");if(!e||e!==be.setupAccessToken)throw new i(400,"Invalid setup access token")},H=async()=>D.skipAuth?!1:await w.count()<1,Lr=async e=>{ea(e.setupAccessToken),await he({name:e.userName,password:e.userPassword})};var qr=h(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:D.skipAuth,modeName:D.name,usesCustomDb:Ye(),serverVersion:T.str("SERVER_VERSION","--")};return r.type("application/javascript").send(`window.__CLIENT_CONFIG__ = ${JSON.stringify(o)};`)}}),e.route({method:"get",url:"/",handler:async(t,r)=>await H()?r.redirect("/setup"):r.sendFile("index.html")}),e.route({method:"get",url:"/setup",handler:async(t,r)=>await H()?r.sendFile("setup.html"):r.redirect("/")})});var Br=e=>{if(!e.setupAccessToken)throw new i(400,"Invalid setup access token");if(!e.userPassword||e.userPassword.length<8)throw new i(400,"Password should be at least 8 chars long");if(!e.userName)throw new i(400,"User name is required")};var Qr=h(e=>{e.route({method:"post",url:"/",config:{isPublic:!0},handler:async t=>{if(!await H())throw new i(400,"Setup has already been completed");let o=f(t,Br);return await Lr(o),{data:!0}}})});var ta=[[qr,"/"],[Tt,"/api/auth"],[Kt,"/api/data-sources"],[Vt,"/api/project"],[zt,"/api/queries"],[Cr,"/api/runner"],[Rr,"/api/status"],[Nr,"/api/teams"],[Ar,"/api/users"],[Or,"/api/user-settings"],[Pr,"/api/saved-queries"],[xr,"/api/workbench-tabs"],[Qr,"/api/setup"]],Fr=e=>{for(let[t,r]of ta)e.register(t,{prefix:r}),console.log("Registered "+r)};var ra=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),oa=async()=>C.findOne({where:{role:"owner"},relations:{user:!0,team:!0}}),aa=async e=>{let t=await oa();if(!t)throw new i(401,"User is not part of a team");e.user={id:t.user.id,currentTeamId:t.team.id,currentTeamRole:t.role}},na=async e=>{let t=e.headers.authorization;if(!t)throw new i(401,"Missing auth token");let[r,o]=t.split(" "),{userId:a}=await dt(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 i(401,"Unauthorized");e.user={id:a,currentTeamId:n.currentTeam.team.id,currentTeamRole:n.currentTeam.role}},Mr=async e=>{ra(e)||(D.skipAuth?await aa(e):await na(e))};var $r=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Hr=e=>{e.addHook("onRequest",Mr),e.addHook("onRequest",Gt),e.addHook("onResponse",$r)};var Wr=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 i?o.status(t.status).send({error:t.message}):o.status(500).send({error:"Internal Server Error"})})};var Yr=P(require("@fastify/cookie")),Gr=P(require("@fastify/cors"));var jr=P(require("@fastify/static")),Kr=require("node:path"),Vr=e=>{e.register(Yr.default,{}),e.register(Gr.default,{origin:V.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(jr.default,{root:(0,Kr.join)(__dirname,"web")})};(async function(){let t=(0,zr.default)({querystringParser:o=>Jr.default.parse(o)});if(We(),Vr(t),Hr(t),Fr(t),Wr(t),await t.after(),await nt(),t.listen({port:V.port,host:V.host},(o,a)=>{o&&(console.error(o),process.exit(1)),console.log(`Server listening at ${a}`)}),await H()){let o=kr();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 he()})();
@@ -0,0 +1 @@
1
+ @import"https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap";@import"https://fonts.googleapis.com/css2?family=Comfortaa:wght@300..700&display=swap";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-800:oklch(44.4% .177 26.899);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-600:oklch(62.7% .194 149.214);--color-green-800:oklch(44.8% .119 151.328);--color-blue-50:oklch(97% .014 254.604);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-800:oklch(42.4% .199 265.638);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-semibold:600;--radius-md:.375rem;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{._pointer-events-auto_1q7gf_2{pointer-events:auto}._pointer-events-none_1q7gf_2{pointer-events:none}._visible_1q7gf_2{visibility:visible}._sr-only_1q7gf_2{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}._absolute_1q7gf_2{position:absolute}._relative_1q7gf_2{position:relative}._sticky_1q7gf_2{position:sticky}._top-0_1q7gf_2{top:calc(var(--spacing)*0)}._top-2_1q7gf_2{top:calc(var(--spacing)*2)}._right-2_1q7gf_2{right:calc(var(--spacing)*2)}._z-0_1q7gf_2{z-index:0}._z-1_1q7gf_2{z-index:1}._z-10_1q7gf_2{z-index:10}._z-100_1q7gf_2{z-index:100}._col-span-2_1q7gf_2{grid-column:span 2/span 2}._m-2_1q7gf_2{margin:calc(var(--spacing)*2)}._mx-1_1q7gf_2{margin-inline:calc(var(--spacing)*1)}._mx-2_1q7gf_2{margin-inline:calc(var(--spacing)*2)}._mx-auto_1q7gf_2{margin-inline:auto}._my-2_1q7gf_2{margin-block:calc(var(--spacing)*2)}._my-10_1q7gf_2{margin-block:calc(var(--spacing)*10)}._mt-1_1q7gf_2{margin-top:calc(var(--spacing)*1)}._mt-2_1q7gf_2{margin-top:calc(var(--spacing)*2)}._mt-4_1q7gf_2{margin-top:calc(var(--spacing)*4)}._mt-8_1q7gf_2{margin-top:calc(var(--spacing)*8)}._mt-10_1q7gf_2{margin-top:calc(var(--spacing)*10)}._mr-1_1q7gf_2{margin-right:calc(var(--spacing)*1)}._mr-2_1q7gf_2{margin-right:calc(var(--spacing)*2)}._mb-0\.5_1q7gf_2{margin-bottom:calc(var(--spacing)*.5)}._mb-1_1q7gf_2{margin-bottom:calc(var(--spacing)*1)}._mb-2_1q7gf_2{margin-bottom:calc(var(--spacing)*2)}._mb-4_1q7gf_2{margin-bottom:calc(var(--spacing)*4)}._mb-10_1q7gf_2{margin-bottom:calc(var(--spacing)*10)}._ml-1_1q7gf_2{margin-left:calc(var(--spacing)*1)}._block_1q7gf_2{display:block}._flex_1q7gf_2{display:flex}._grid_1q7gf_2{display:grid}._hidden_1q7gf_2{display:none}._table_1q7gf_2{display:table}._h-0\.5_1q7gf_2{height:calc(var(--spacing)*.5)}._h-1_1q7gf_2{height:calc(var(--spacing)*1)}._h-screen_1q7gf_2{height:100vh}._max-h-full_1q7gf_2{max-height:100%}._max-h-screen_1q7gf_2{max-height:100vh}._min-h-screen_1q7gf_2{min-height:100vh}._w-full_1q7gf_2{width:100%}._max-w-none_1q7gf_2{max-width:none}._max-w-xl_1q7gf_2{max-width:var(--container-xl)}._flex-1_1q7gf_2{flex:1}._rotate-180_1q7gf_2{rotate:180deg}._rotate-270_1q7gf_2{rotate:270deg}._transform_1q7gf_2{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}._animate-spin_1q7gf_2{animation:var(--animate-spin)}._cursor-auto\!_1q7gf_2{cursor:auto!important}._cursor-pointer_1q7gf_2{cursor:pointer}._grid-cols-2_1q7gf_2{grid-template-columns:repeat(2,minmax(0,1fr))}._grid-cols-4_1q7gf_2{grid-template-columns:repeat(4,minmax(0,1fr))}._flex-col_1q7gf_2{flex-direction:column}._items-center_1q7gf_2{align-items:center}._justify-between_1q7gf_2{justify-content:space-between}._justify-center_1q7gf_2{justify-content:center}._justify-end_1q7gf_2{justify-content:flex-end}._gap-1_1q7gf_2{gap:calc(var(--spacing)*1)}._gap-2_1q7gf_2{gap:calc(var(--spacing)*2)}._gap-8_1q7gf_2{gap:calc(var(--spacing)*8)}._justify-self-center_1q7gf_2{justify-self:center}._justify-self-end_1q7gf_2{justify-self:flex-end}._truncate_1q7gf_2{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._overflow-auto_1q7gf_2{overflow:auto}._overflow-hidden_1q7gf_2{overflow:hidden}._overflow-x-auto_1q7gf_2{overflow-x:auto}._overflow-y-auto_1q7gf_2{overflow-y:auto}._rounded_1q7gf_2{border-radius:.25rem}._rounded-full_1q7gf_2{border-radius:3.40282e38px}._rounded-lg_1q7gf_2{border-radius:var(--radius-lg)}._rounded-md_1q7gf_2{border-radius:var(--radius-md)}._rounded-t-md_1q7gf_2{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}._rounded-r-none\!_1q7gf_2{border-top-right-radius:0!important;border-bottom-right-radius:0!important}._rounded-b-lg_1q7gf_2{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}._rounded-b-md_1q7gf_2{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}._border_1q7gf_2{border-style:var(--tw-border-style);border-width:1px}._border-t_1q7gf_2{border-top-style:var(--tw-border-style);border-top-width:1px}._border-b_1q7gf_2{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}._border-gray-200_1q7gf_2{border-color:var(--color-gray-200)}._border-red-600_1q7gf_2{border-color:var(--color-red-600)}._border-t-gray-200_1q7gf_2{border-top-color:var(--color-gray-200)}._bg-\(--bg\)_1q7gf_2{background-color:var(--bg)}._bg-blue-50_1q7gf_2{background-color:var(--color-blue-50)}._bg-gray-50_1q7gf_2{background-color:var(--color-gray-50)}._bg-gray-100_1q7gf_2{background-color:var(--color-gray-100)}._bg-gray-800_1q7gf_2{background-color:var(--color-gray-800)}._bg-gray-900_1q7gf_2{background-color:var(--color-gray-900)}._bg-green-200_1q7gf_2{background-color:var(--color-green-200)}._bg-red-50_1q7gf_2{background-color:var(--color-red-50)}._bg-white_1q7gf_2{background-color:var(--color-white)}._bg-yellow-200_1q7gf_2{background-color:var(--color-yellow-200)}._fill-blue-600_1q7gf_2{fill:var(--color-blue-600)}._p-0\.5_1q7gf_2{padding:calc(var(--spacing)*.5)}._p-1_1q7gf_2{padding:calc(var(--spacing)*1)}._p-2_1q7gf_2{padding:calc(var(--spacing)*2)}._p-4_1q7gf_2{padding:calc(var(--spacing)*4)}._px-1\.5_1q7gf_2{padding-inline:calc(var(--spacing)*1.5)}._px-2_1q7gf_2{padding-inline:calc(var(--spacing)*2)}._px-4_1q7gf_2{padding-inline:calc(var(--spacing)*4)}._py-0\.5_1q7gf_2{padding-block:calc(var(--spacing)*.5)}._py-1_1q7gf_2{padding-block:calc(var(--spacing)*1)}._py-2_1q7gf_2{padding-block:calc(var(--spacing)*2)}._py-4_1q7gf_2{padding-block:calc(var(--spacing)*4)}._py-10_1q7gf_2{padding-block:calc(var(--spacing)*10)}._pb-24_1q7gf_2{padding-bottom:calc(var(--spacing)*24)}._pl-5\!_1q7gf_2{padding-left:calc(var(--spacing)*5)!important}._text-center_1q7gf_2{text-align:center}._text-left_1q7gf_2{text-align:left}._font-mono_1q7gf_2{font-family:var(--font-mono)}._text-3xl_1q7gf_2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}._text-lg_1q7gf_2{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}._text-sm_1q7gf_2{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}._text-xl_1q7gf_2{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}._text-xs_1q7gf_2{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}._text-xs\!_1q7gf_2{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}._font-semibold_1q7gf_2{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}._whitespace-nowrap_1q7gf_2{white-space:nowrap}._text-\(--text-color-primary\)_1q7gf_2{color:var(--text-color-primary)}._text-\(--text-color-secondary\)_1q7gf_2{color:var(--text-color-secondary)}._text-black\/30_1q7gf_2{color:#0000004d}@supports (color:color-mix(in lab,red,red)){._text-black\/30_1q7gf_2{color:color-mix(in oklab,var(--color-black)30%,transparent)}}._text-blue-600_1q7gf_2{color:var(--color-blue-600)}._text-blue-800_1q7gf_2{color:var(--color-blue-800)}._text-gray-100_1q7gf_2{color:var(--color-gray-100)}._text-gray-200_1q7gf_2{color:var(--color-gray-200)}._text-gray-300_1q7gf_2{color:var(--color-gray-300)}._text-gray-600_1q7gf_2{color:var(--color-gray-600)}._text-green-600_1q7gf_2{color:var(--color-green-600)}._text-green-800_1q7gf_2{color:var(--color-green-800)}._text-red-500_1q7gf_2{color:var(--color-red-500)}._text-red-600_1q7gf_2{color:var(--color-red-600)}._text-red-800_1q7gf_2{color:var(--color-red-800)}._text-white_1q7gf_2{color:var(--color-white)}._text-yellow-800_1q7gf_2{color:var(--color-yellow-800)}._capitalize_1q7gf_2{text-transform:capitalize}._italic_1q7gf_2{font-style:italic}._underline_1q7gf_2{text-decoration-line:underline}._opacity-30_1q7gf_2{opacity:.3}._opacity-40_1q7gf_2{opacity:.4}._shadow-md_1q7gf_2{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}._blur_1q7gf_2{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}._filter_1q7gf_2{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}._outline-none_1q7gf_2{--tw-outline-style:none;outline-style:none}@media(hover:hover){._hover\:bg-\(--bg-ter\)_1q7gf_2:hover{background-color:var(--bg-ter)}._hover\:bg-gray-100_1q7gf_2:hover{background-color:var(--color-gray-100)}._hover\:bg-gray-600_1q7gf_2:hover{background-color:var(--color-gray-600)}._hover\:text-blue-600_1q7gf_2:hover{color:var(--color-blue-600)}._hover\:text-green-600_1q7gf_2:hover{color:var(--color-green-600)}}@media(min-width:48rem){._md\:grid_1q7gf_2{display:grid}._md\:w-2xl_1q7gf_2{width:var(--container-2xl)}._md\:grid-cols-3_1q7gf_2{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:64rem){._lg\:w-lg_1q7gf_2{width:var(--container-lg)}._lg\:w-md_1q7gf_2{width:var(--container-md)}._lg\:w-sm_1q7gf_2{width:var(--container-sm)}._lg\:flex-row_1q7gf_2{flex-direction:row}._lg\:items-center_1q7gf_2{align-items:center}._lg\:pb-12_1q7gf_2{padding-bottom:calc(var(--spacing)*12)}}@media(prefers-color-scheme:dark){._dark\:text-gray-600_1q7gf_2{color:var(--color-gray-600)}}}._alert_1q7gf_2{padding:calc(var(--spacing)*4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}._info_1q7gf_2{background-color:var(--color-blue-50);color:var(--color-blue-800)}._danger_1q7gf_2{background-color:var(--color-red-50);color:var(--color-red-800)}._success_1q7gf_2{background-color:var(--color-green-50);color:var(--color-green-800)}._warning_1q7gf_2{background-color:var(--color-yellow-50);color:var(--color-yellow-800)}._dark_1q7gf_2{background-color:var(--color-gray-50);color:var(--color-gray-800)}@keyframes _spin_1q7gf_1{to{transform:rotate(360deg)}}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-800:oklch(44.4% .177 26.899);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-200:oklch(92.5% .084 155.995);--color-green-600:oklch(62.7% .194 149.214);--color-green-800:oklch(44.8% .119 151.328);--color-blue-50:oklch(97% .014 254.604);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-semibold:600;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--bg:#fff;--bg-sec:#f9f9f9;--bg-ter:#f2f2f2;--bg-quat:#e9e9e9;--text-color-primary:#212121;--text-color-secondary:#6b6b6b}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components{.hotkey{cursor:pointer;border-radius:var(--radius-sm);text-align:center;min-width:26px;max-width:26px;min-height:22px;max-height:22px;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);justify-content:center;align-items:center;display:none}@media(min-width:64rem){.hotkey{display:flex}}.hotkey.secondary{border:1px solid var(--bg-ter);background-color:var(--bg)}.hotkey:not(.secondary){border:1px solid var(--bg-ter);background-color:var(--bg-sec)}.comfortaa{font-family:Comfortaa,sans-serif}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.top-0{top:calc(var(--spacing)*0)}.top-2{top:calc(var(--spacing)*2)}.right-2{right:calc(var(--spacing)*2)}.z-0{z-index:0}.z-1{z-index:1}.z-10{z-index:10}.z-100{z-index:100}.col-span-2{grid-column:span 2/span 2}.m-2{margin:calc(var(--spacing)*2)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-auto{margin-inline:auto}.my-2{margin-block:calc(var(--spacing)*2)}.my-10{margin-block:calc(var(--spacing)*10)}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose{--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:oklab(21% -.00316127 -.0338527/.1);--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:#ffffff1a;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-10{margin-top:calc(var(--spacing)*10)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.ml-1{margin-left:calc(var(--spacing)*1)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.table{display:table}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-screen{height:100vh}.max-h-full{max-height:100%}.max-h-screen{max-height:100vh}.min-h-screen{min-height:100vh}.w-full{width:100%}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.flex-1{flex:1}.rotate-180{rotate:180deg}.rotate-270{rotate:270deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-auto\!{cursor:auto!important}.cursor-pointer{cursor:pointer}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-8{gap:calc(var(--spacing)*8)}.justify-self-center{justify-self:center}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-t-md{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}.rounded-r-none\!{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-b-md{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-gray-200{border-color:var(--color-gray-200)}.border-red-600{border-color:var(--color-red-600)}.border-t-gray-200{border-top-color:var(--color-gray-200)}.bg-\(--bg\){background-color:var(--bg)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-200{background-color:var(--color-green-200)}.bg-red-50{background-color:var(--color-red-50)}.bg-white{background-color:var(--color-white)}.bg-yellow-200{background-color:var(--color-yellow-200)}.fill-blue-600{fill:var(--color-blue-600)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-4{padding:calc(var(--spacing)*4)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.py-10{padding-block:calc(var(--spacing)*10)}.pb-24{padding-bottom:calc(var(--spacing)*24)}.pl-5\!{padding-left:calc(var(--spacing)*5)!important}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-xs\!{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-\(--text-color-primary\){color:var(--text-color-primary)}.text-\(--text-color-secondary\){color:var(--text-color-secondary)}.text-black\/30{color:#0000004d}@supports (color:color-mix(in lab,red,red)){.text-black\/30{color:color-mix(in oklab,var(--color-black)30%,transparent)}}.text-blue-600{color:var(--color-blue-600)}.text-blue-800{color:var(--color-blue-800)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-600{color:var(--color-gray-600)}.text-green-600{color:var(--color-green-600)}.text-green-800{color:var(--color-green-800)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-800{color:var(--color-red-800)}.text-white{color:var(--color-white)}.text-yellow-800{color:var(--color-yellow-800)}.capitalize{text-transform:capitalize}.italic{font-style:italic}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.outline-none{--tw-outline-style:none;outline-style:none}@media(hover:hover){.hover\:bg-\(--bg-ter\):hover{background-color:var(--bg-ter)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.hover\:text-blue-600:hover{color:var(--color-blue-600)}.hover\:text-green-600:hover{color:var(--color-green-600)}}@media(min-width:48rem){.md\:grid{display:grid}.md\:w-2xl{width:var(--container-2xl)}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:64rem){.lg\:w-lg{width:var(--container-lg)}.lg\:w-md{width:var(--container-md)}.lg\:w-sm{width:var(--container-sm)}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:pb-12{padding-bottom:calc(var(--spacing)*12)}}@media(prefers-color-scheme:dark){.dark\:text-gray-600{color:var(--color-gray-600)}}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.scrollbar::-webkit-scrollbar{border-radius:10pt;width:5px}.scrollbar::-webkit-scrollbar-track{background-color:var(--color-gray-100);border-radius:10px}.scrollbar::-webkit-scrollbar-thumb{background-color:var(--color-gray-300);border-radius:10px}.scrollbar::-webkit-scrollbar-thumb:hover{background-color:var(--color-gray-400)}}.page-container{max-width:100%;padding:calc(var(--spacing)*4)}.page-content{width:100%;max-width:1024px;padding-bottom:calc(var(--spacing)*12);flex-direction:column;margin-left:auto;margin-right:auto;display:flex}@media(min-width:48rem){.page-content{padding-bottom:calc(var(--spacing)*0)}}.hr-slide{cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:1;width:8px;height:100%;position:absolute;right:-4px}@media(hover:hover){.hr-slide:hover{background-color:var(--color-blue-200)}}.hl-slide{cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:1;width:8px;height:100%;position:absolute;left:-4px}@media(hover:hover){.hl-slide:hover{background-color:var(--color-blue-200)}}.vb-slide{cursor:row-resize;-webkit-user-select:none;user-select:none;z-index:1;width:100%;height:8px;position:absolute;bottom:-4px}@media(hover:hover){.vb-slide:hover{background-color:var(--color-blue-200)}}.vt-slide{cursor:row-resize;-webkit-user-select:none;user-select:none;z-index:1;width:100%;height:8px;position:absolute;top:-4px}@media(hover:hover){.vt-slide:hover{background-color:var(--color-blue-200)}}.input{border:1px solid var(--bg-quat);background-color:var(--color-white);padding:calc(var(--spacing)*1);outline-style:var(--tw-outline-style);border-radius:.25rem;outline-width:0}.input:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--color-blue-400);--tw-ring-inset:inset}.input:disabled{cursor:not-allowed;background-color:var(--bg-ter)}.form{gap:calc(var(--spacing)*2);background-color:var(--color-white);flex-direction:column;display:flex}.form.shadow{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.form.padding{padding:calc(var(--spacing)*4)}.button{cursor:pointer;border-radius:var(--radius-md);padding-inline:calc(var(--spacing)*2);padding-block:calc(var(--spacing)*.5);--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.button:disabled{opacity:.6;cursor:not-allowed}.button.primary{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-blue-600);background-color:var(--color-blue-600);color:var(--color-white)}.button.primary:hover:not(:disabled){border-color:var(--color-blue-700);background-color:var(--color-blue-700)}.button.secondary{background-color:var(--color-gray-300);color:var(--color-gray-800)}.button.tertiary{border:1px solid var(--bg-quat);background-color:var(--color-white);color:var(--color-gray-700)}.button.tertiary:hover{background-color:var(--bg-sec)}.button.danger{color:#fff;background-color:#dc3545}.button.danger:hover{background-color:#bf2e3c}.page-head{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.roboto{font-family:Roboto,sans-serif}.context-menu-container{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-200);background-color:var(--color-white);min-width:150px;max-width:400px;max-height:400px;padding:calc(var(--spacing)*2);--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);overflow:hidden}.context-menu-item{cursor:pointer;border-radius:var(--radius-lg);text-align:left;text-overflow:ellipsis;white-space:nowrap;width:100%;padding:2px 4px;font-size:15px;display:block;overflow:hidden}@media(hover:hover){.context-menu-item:hover{background-color:var(--color-gray-100)}}.a{color:var(--color-blue-400);text-decoration-line:underline}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes spin{to{transform:rotate(360deg)}}