@dataramen/cli 0.0.82 → 0.0.84-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,35 +1,26 @@
1
- # 🍜 DataRamen CLI
1
+ # DataRamen
2
2
 
3
- Your cozy corner for exploring and working with SQL databases - no query writing required.
3
+ A lightweight web GUI for MySQL and PostgreSQL, built for developers who move fast and stay focused. Connect, explore, and inspect your data effortlessly, no boilerplate, no friction. Visit [dataramen.xyz](https://dataramen.xyz) for more info.
4
4
 
5
- DataRamen CLI lets you launch a powerful, local database exploration app that connects effortlessly to MySQL and PostgreSQL databases. Browse schemas, follow relationships, and insert/update data - all from your browser.
5
+ ## Why use it?
6
6
 
7
- ## Features
7
+ - **Follow relationships easily**
8
+ DataRamen allows you to easily navigate between related records and tables.
8
9
 
9
- - 🔌 **Connect to PostgreSQL & MySQL**
10
- Securely plug in your credentials - you're ready to explore.
10
+ - **No-SQL querying**
11
+ Filter, sort, join, and summarize data using intuitive interface.
11
12
 
12
- - 🧭 **Visual Schema Explorer**
13
- Instantly browse tables, columns, types, primary/foreign keys, and relationships.
13
+ - **Insert & update visually**
14
+ Add or modify records with a visual editor.
14
15
 
15
- - 🧙 **No-SQL Querying**
16
- Filter, sort, join, and summarize data using a beautiful, intuitive interface.
16
+ - **Connect to PostgreSQL & MySQL**
17
+ Plug in your credentials - you're ready to explore.
17
18
 
18
- - 🔗 **Follow Relationships Easily**
19
- Click to expand related records.
20
-
21
- - ✏️ **Insert & Update Visually**
22
- Add or modify rows with a visual editor - no SQL errors.
23
-
24
- - 💾 **Save Queries**
25
- Save your favorite views for quick access later.
26
-
27
- ## 🛠️ Installation
19
+ ## Installation
28
20
 
29
21
  ### 1. Install Node.js
30
22
 
31
- DataRamen requires Node.js **v22 or above**.
32
- 👉 [Download Node.js](https://nodejs.org/)
23
+ DataRamen requires Node.js **v22 or above**: [Download Node.js](https://nodejs.org/)
33
24
 
34
25
  ### 2. Install DataRamen CLI
35
26
 
@@ -39,7 +30,7 @@ Open your terminal and run:
39
30
  npm i -g @dataramen/cli
40
31
  ```
41
32
 
42
- ## 🖥️ Usage
33
+ ## Usage
43
34
 
44
35
  ### Start the Local Server
45
36
 
@@ -49,7 +40,7 @@ dataramen start
49
40
 
50
41
  ### Open the App
51
42
 
52
- Go to `localhost:4466` in your browser. Your local server will connect automatically.
43
+ Open your app in the browser. By default, the app runs on `localhost:4466`.
53
44
 
54
45
  ### Update the App
55
46
 
@@ -61,7 +52,7 @@ npm i -g @dataramen/cli
61
52
 
62
53
  The above command will install latest stable version.
63
54
 
64
- ## 🔧 Additional CLI Commands
55
+ ## Additional CLI Commands
65
56
 
66
57
  | Command | Description |
67
58
  |-------------------|----------------------------------|
@@ -70,6 +61,7 @@ The above command will install latest stable version.
70
61
  | `dataramen open` | Open local webapp |
71
62
  | `dataramen logs` | Show logs from the running server|
72
63
 
73
- ## ❤️ Made with love by [Oleksandr Demian](https://github.com/OleksandrDemian)
64
+
65
+ ## Other
74
66
 
75
67
  Visit [dataramen.xyz](https://dataramen.xyz) for more info.
@@ -1,9 +1,9 @@
1
- "use strict";var lo=Object.create;var Me=Object.defineProperty;var po=Object.getOwnPropertyDescriptor;var fo=Object.getOwnPropertyNames;var yo=Object.getPrototypeOf,To=Object.prototype.hasOwnProperty;var ho=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of fo(t))!To.call(e,a)&&a!==r&&Me(e,a,{get:()=>t[a],enumerable:!(o=po(t,a))||o.enumerable});return e};var P=(e,t,r)=>(r=e!=null?lo(yo(e)):{},ho(t||!e||!e.__esModule?Me(r,"default",{value:e,enumerable:!0}):r,e));var ne=require("dotenv"),se=require("node:path"),We=require("node:fs");var oe=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 go(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 ae=oe(go(process.argv.slice(2)));var bo=(()=>{try{let e=(0,We.readFileSync)((0,se.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})(),He=[],$e=ae.str("env");$e&&He.push((0,se.resolve)($e));(0,ne.config)({path:He});var Ie={APP_DB_TYPE:"sqlite",APP_DB_DATABASE:"<home>/.dataramen/.runtime/db.sqlite3"};(0,ne.populate)(process.env,{SERVER_VERSION:bo.version,PROD:"true",...Ie},{override:!1});var wo=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],Ye=()=>{let e=[];for(let t of wo)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))},T=oe(process.env),Ge=()=>T.str("APP_DB_TYPE")!==Ie.APP_DB_TYPE&&T.str("APP_DB_DATABASE")!==Ie.APP_DB_DATABASE;var jm=require("reflect-metadata"),ro=P(require("fastify")),oo=P(require("qs"));var nt=require("typeorm");var je=require("typeorm");var So={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"}},Io=ae.str("mode","default"),D=So[Io];var h=T.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp",ie=D.name==="docker"?e=>e==="localhost"||e==="127.0.0.1"?"host.docker.internal":e:e=>e;var Ee=new je.EntitySchema({name:"Team",tableName:"teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:h,createDate:!0},updatedAt:{type:h,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 Ke=require("typeorm");var Ce=new Ke.EntitySchema({name:"User",tableName:"users",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:h,createDate:!0},updatedAt:{type:h,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 Ve=require("typeorm");var Re=new Ve.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:h,createDate:!0},updatedAt:{type:h,updateDate:!0}},relations:{user:{type:"one-to-one",target:()=>"User",inverseSide:"settings",joinColumn:!0}}});var ze=require("typeorm");var F=new ze.EntitySchema({name:"DataSource",tableName:"data_sources",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},dbUrl:{type:String},dbPort:{type:Number,nullable:!0},dbUser:{type:String},dbPassword:{type:String,nullable:!0,select:!1},dbPasswordIv:{type:String,nullable:!0,select:!1},dbPasswordTag:{type:String,nullable:!0,select:!1},dbType:{type:String},createdAt:{type:h,createDate:!0},updatedAt:{type:h,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:h,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 st=P(require("node:os")),it=require("node:path");var Je=require("typeorm");var K=new Je.EntitySchema({name:"Query",tableName:"query",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},opts:{type:"json",nullable:!1},createdAt:{type:h,createDate:!0},updatedAt:{type:h,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},savedQueries:{type:"one-to-many",target:()=>"SavedQuery",inverseSide:"query"}}});var Xe=require("typeorm"),Ne=new Xe.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 V=new Ze.EntitySchema({name:"SavedQuery",tableName:"saved_queries",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},isPersonal:{type:Boolean},createdAt:{type:h,createDate:!0},updatedAt:{type:h,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 et=require("typeorm");var z=new et.EntitySchema({name:"WorkbenchTab",tableName:"workbench_tabs",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:h,createDate:!0},updatedAt:{type:h,updateDate:!0},opts:{type:"json",nullable:!1},archived:{type:Boolean,default:!1},orderIndex:{type:Number,default:0},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 tt=require("typeorm");var M=new tt.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:h,createDate:!0},updatedAt:{type:h,updateDate:!0},meta:{type:"json",nullable:!0},tableId:{type:String}},relations:{table:{target:()=>"DatabaseTable",type:"many-to-one",inverseSide:"columns"}}});var rt=require("typeorm");var q=new rt.EntitySchema({name:"DatabaseTable",tableName:"database_tables",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{nullable:!0,type:String},createdAt:{type:h,createDate:!0},updatedAt:{type:h,updateDate:!0}},relations:{datasource:{target:()=>"DataSource",type:"many-to-one",joinColumn:{name:"dataSourceId"}},columns:{target:()=>"DatabaseColumn",type:"one-to-many",inverseSide:"table"}}});var ot=require("uuid");function Eo(e){let t={};for(let r of e.entityMetadatas)for(let o of r.columns)o.isPrimary&&o.generationStrategy==="uuid"&&(t[r.name]?t[r.name].push(o.propertyName):t[r.name]=[o.propertyName]);return t}function Co(e){let t=Eo(e);return{beforeInsert(r){if(t[r.metadata.name])for(let o of t[r.metadata.name])r.entity[o]||(r.entity[o]=(0,ot.v4)())}}}var at=e=>{e.subscribers.push(Co(e))};function Ro(){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>",st.default.homedir())),e}var b=new nt.DataSource({type:T.str("APP_DB_TYPE"),database:Ro(),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:[it.posix.join(__dirname,"migrations","*.js")],entities:[F,Ee,Ce,Ne,Re,K,V,z,q,M]}),ut=async()=>{if(!b.isInitialized)return b.initialize().then(e=>(at(e),e));throw new Error("Already initialized")},E=b.getRepository(F),B=b.getRepository(Ee),w=b.getRepository(Ce),R=b.getRepository(Ne),H=b.getRepository(Re),N=b.getRepository(K),_=b.getRepository(V),S=b.getRepository(z),ue=b.getRepository(M),ce=b.getRepository(q);var ct=T.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),mt=T.num("PORT",4466),J={port:mt,host:D.bindServerUrl,allowedOrigins:ct.includes("*")?"*":[`http://localhost:${mt}`,...ct]};var g=e=>(t,r,o)=>{e(t),o()};var X=require("jose");var u=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var lt=new TextEncoder,dt=lt.encode(T.str("JWT_SECRET")),pt=lt.encode(T.str("JWT_REFRESH_SECRET")),Ae=async({userId:e})=>new X.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(dt),Oe=async({userId:e})=>new X.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(pt),ft=async(e,t)=>{try{let{payload:r}=await(0,X.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")}},yt=async e=>ft(e,dt),Tt=async e=>ft(e,pt);var f=(e,t)=>{let r=e.body;return t&&t(r),r},x=(e,t)=>{let r=e.query;return t&&t(r),r},p=(e,t)=>{let r=e.params;return t&&t(r),r};var gt=P(require("bcryptjs"));var ht=e=>{if(!e?.username)throw new u(400,"Username is required");if(!e?.password)throw new u(400,"Password is required")};var me="DATARAMEN_refresh_token",Pe={httpOnly:!0,secure:T.bool("PROD"),sameSite:T.bool("PROD"),path:"/",maxAge:14400*60},bt=g(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let{username:o,password:a}=f(t,ht),n=await w.findOne({where:{username:o}});if(!n||!gt.default.compareSync(a,n.password))throw new u(401,"Invalid credentials");let[i,s]=await Promise.all([Ae({userId:n?.id}),Oe({userId:n?.id})]);return r.setCookie(me,s,Pe),{data:{accessToken:i}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies[me];if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await Tt(o),[n,i]=await Promise.all([Ae({userId:a}),Oe({userId:a})]);return r.setCookie(me,i,Pe),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie(me,Pe),{data:!0})})});var wt=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 Et=P(require("mysql2/promise"));function Z(e){if(e!==void 0)return e.toLowerCase()}var No=({database:e,password:t,user:r,url:o})=>Et.default.createConnection({host:ie(o),user:r,database:e,password:t,dateStrings:!0,multipleStatements:!1}),Ao=async e=>{let t=`
1
+ "use strict";var fo=Object.create;var We=Object.defineProperty;var yo=Object.getOwnPropertyDescriptor;var To=Object.getOwnPropertyNames;var go=Object.getPrototypeOf,ho=Object.prototype.hasOwnProperty;var bo=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of To(t))!ho.call(e,a)&&a!==r&&We(e,a,{get:()=>t[a],enumerable:!(o=yo(t,a))||o.enumerable});return e};var O=(e,t,r)=>(r=e!=null?fo(go(e)):{},bo(t||!e||!e.__esModule?We(r,"default",{value:e,enumerable:!0}):r,e));var se=require("dotenv"),ie=require("node:path"),Ge=require("node:fs");var ae=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 wo(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 ne=ae(wo(process.argv.slice(2)));var So=(()=>{try{let e=(0,Ge.readFileSync)((0,ie.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})(),Ye=[],He=ne.str("env");He&&Ye.push((0,ie.resolve)(He));(0,se.config)({path:Ye});var Ce={APP_DB_TYPE:"sqlite",APP_DB_DATABASE:"<home>/.dataramen/.runtime/db.sqlite3"};(0,se.populate)(process.env,{SERVER_VERSION:So.version,PROD:"true",...Ce},{override:!1});var Io=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],je=()=>{let e=[];for(let t of Io)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))},T=ae(process.env),Ke=()=>T.str("APP_DB_TYPE")!==Ce.APP_DB_TYPE&&T.str("APP_DB_DATABASE")!==Ce.APP_DB_DATABASE;var Vm=require("reflect-metadata"),ao=O(require("fastify")),no=O(require("qs"));var it=require("typeorm");var Ve=require("typeorm");var Eo={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"}},Co=ne.str("mode","default"),D=Eo[Co];var g=T.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp",ue=D.name==="docker"?e=>e==="localhost"||e==="127.0.0.1"?"host.docker.internal":e:e=>e;var Re=new Ve.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 ze=require("typeorm");var Ne=new ze.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 Je=require("typeorm");var Ae=new Je.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 Xe=require("typeorm");var F=new Xe.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 ut=O(require("node:os")),ct=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},savedQueries:{type:"one-to-many",target:()=>"SavedQuery",inverseSide:"query"}}});var et=require("typeorm"),Pe=new et.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 tt=require("typeorm");var V=new tt.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 rt=require("typeorm");var z=new rt.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},orderIndex:{type:Number,default:0},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 ot=require("typeorm");var M=new ot.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 at=require("typeorm");var q=new at.EntitySchema({name:"DatabaseTable",tableName:"database_tables",columns:{id:{type:"uuid",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",joinColumn:{name:"dataSourceId"}},columns:{target:()=>"DatabaseColumn",type:"one-to-many",inverseSide:"table"}}});var nt=require("uuid");function Ro(e){let t={};for(let r of e.entityMetadatas)for(let o of r.columns)o.isPrimary&&o.generationStrategy==="uuid"&&(t[r.name]?t[r.name].push(o.propertyName):t[r.name]=[o.propertyName]);return t}function No(e){let t=Ro(e);return{beforeInsert(r){if(t[r.metadata.name])for(let o of t[r.metadata.name])r.entity[o]||(r.entity[o]=(0,nt.v4)())}}}var st=e=>{e.subscribers.push(No(e))};function Ao(){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>",ut.default.homedir())),e}var b=new it.DataSource({type:T.str("APP_DB_TYPE"),database:Ao(),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:[ct.posix.join(__dirname,"migrations","*.js")],entities:[F,Re,Ne,Pe,Ae,K,V,z,q,M]}),mt=async()=>{if(!b.isInitialized)return b.initialize().then(e=>(st(e),e));throw new Error("Already initialized")},C=b.getRepository(F),B=b.getRepository(Re),w=b.getRepository(Ne),R=b.getRepository(Pe),H=b.getRepository(Ae),N=b.getRepository(K),U=b.getRepository(V),S=b.getRepository(z),ce=b.getRepository(M),me=b.getRepository(q);var lt=T.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),dt=T.num("PORT",4466),J={port:dt,host:D.bindServerUrl,allowedOrigins:lt.includes("*")?"*":[`http://localhost:${dt}`,...lt]};var h=e=>(t,r,o)=>{e(t),o()};var X=require("jose");var u=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var pt=new TextEncoder,ft=pt.encode(T.str("JWT_SECRET")),yt=pt.encode(T.str("JWT_REFRESH_SECRET")),Oe=async({userId:e})=>new X.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(ft),De=async({userId:e})=>new X.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(yt),Tt=async(e,t)=>{try{let{payload:r}=await(0,X.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")}},gt=async e=>Tt(e,ft),ht=async e=>Tt(e,yt);var f=(e,t)=>{let r=e.body;return t&&t(r),r},_=(e,t)=>{let r=e.query;return t&&t(r),r},p=(e,t)=>{let r=e.params;return t&&t(r),r};var wt=O(require("bcryptjs"));var bt=e=>{if(!e?.username)throw new u(400,"Username is required");if(!e?.password)throw new u(400,"Password is required")};var le="DATARAMEN_refresh_token",ve={httpOnly:!0,secure:T.bool("PROD"),sameSite:T.bool("PROD"),path:"/",maxAge:14400*60},St=h(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let{username:o,password:a}=f(t,bt),n=await w.findOne({where:{username:o}});if(!n||!wt.default.compareSync(a,n.password))throw new u(401,"Invalid credentials");let[i,s]=await Promise.all([Oe({userId:n?.id}),De({userId:n?.id})]);return r.setCookie(le,s,ve),{data:{accessToken:i}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies[le];if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await ht(o),[n,i]=await Promise.all([Oe({userId:a}),De({userId:a})]);return r.setCookie(le,i,ve),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie(le,ve),{data:!0})})});var It=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 Rt=O(require("mysql2/promise"));function Z(e){if(e!==void 0)return e.toLowerCase()}var Po=({database:e,password:t,user:r,url:o})=>Rt.default.createConnection({host:ue(o),user:r,database:e,password:t,dateStrings:!0,multipleStatements:!1}),Oo=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=Z(a.TABLE_NAME),i=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(i)}),o},Oo=async e=>{let t=`
6
+ `,[r]=await e.execute(t),o={};return r.forEach(a=>{let n=Z(a.TABLE_NAME),i=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(i)}),o},Do=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},Po=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await Oo(t),n=await Ao(t),i=o.map(async s=>{let c=Z(Object.values(s)[0]),m=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and LOWER(table_name) = '${c}'`,[l]=await t.query(m),y=a[c];return{columns:l.map(d=>({name:d.COLUMN_NAME,type:d.DATA_TYPE,isPrimary:n[c]?.includes(d.COLUMN_NAME),ref:y?.[d.COLUMN_NAME]?{table:y[d.COLUMN_NAME].refTable,field:y[d.COLUMN_NAME].refField}:void 0})),createdAt:new Date,tableName:c,updatedAt:new Date}});return Promise.all(i)},St=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(c=>({column:c.orgName||c.name,table:Z(c.orgTable),alias:c.name,full:c.orgTable?Z(c.orgTable)+"."+c.orgName:c.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)}},Do=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}},vo=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 No(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>Po(e,t),executeQuery:o=>o.type==="SELECT"?vo(t,()=>St(o.sql,o.params,t,o)):Do(t,()=>St(o.sql,o.params,t,o)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var Rt=P(require("pg"));var xo=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new Rt.default.Client({host:ie(o),user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},_o=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},vo=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await Do(t),n=await Oo(t),i=o.map(async s=>{let c=Z(Object.values(s)[0]),m=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and LOWER(table_name) = '${c}'`,[l]=await t.query(m),y=a[c];return{columns:l.map(d=>({name:d.COLUMN_NAME,type:d.DATA_TYPE,isPrimary:n[c]?.includes(d.COLUMN_NAME),ref:y?.[d.COLUMN_NAME]?{table:y[d.COLUMN_NAME].refTable,field:y[d.COLUMN_NAME].refField}:void 0})),createdAt:new Date,tableName:c,updatedAt:new Date}});return Promise.all(i)},Et=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(c=>({column:c.orgName||c.name,table:Z(c.orgTable),alias:c.name,full:c.orgTable?Z(c.orgTable)+"."+c.orgName:c.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)}},xo=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}},_o=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}},xe=async e=>{let t=await Po(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>vo(e,t),executeQuery:o=>o.type==="SELECT"?_o(t,()=>Et(o.sql,o.params,t,o)):xo(t,()=>Et(o.sql,o.params,t,o)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var At=O(require("pg"));var Uo=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new At.default.Client({host:ue(o),user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},ko=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},Uo=async e=>{let r=await e.query(`
31
+ `),o={};return r.rows.forEach(a=>{let n=a.table_name,i=a.column_name;o[n]||(o[n]=[]),o[n].push(i)}),o},Lo=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,20 +43,20 @@
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},ko=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 Uo(t),i=await _o(t),s=a.map(async c=>{let m=Object.values(c)[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},qo=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 Lo(t),i=await ko(t),s=a.map(async c=>{let m=Object.values(c)[0],l=`
47
47
  SELECT column_name, data_type
48
48
  FROM information_schema.columns
49
49
  WHERE
50
50
  LOWER(table_name) = '${m}' and
51
51
  table_schema = '${e.schema}'
52
- `,{rows:y}=await t.query(l),d=n[m];return{columns:y.map(A=>({name:A.column_name,type:A.data_type,isPrimary:i[m]?.includes(A.column_name),ref:d?.[A.column_name]?{table:d[A.column_name].refTable,field:d[A.column_name].refField}:void 0})).sort((A,L)=>A.isPrimary&&L.isPrimary?A.name.localeCompare(L.name):A.isPrimary?-1:1),createdAt:new Date,tableName:m,updatedAt:new Date}});return Promise.all(s)},Lo=async(e,t)=>{let r=`select LOWER(relname) as relname, attname, concat(pg_class.oid, '-', attnum) as row_key
52
+ `,{rows:y}=await t.query(l),d=n[m];return{columns:y.map(A=>({name:A.column_name,type:A.data_type,isPrimary:i[m]?.includes(A.column_name),ref:d?.[A.column_name]?{table:d[A.column_name].refTable,field:d[A.column_name].refField}:void 0})).sort((A,v)=>A.isPrimary&&v.isPrimary?A.name.localeCompare(v.name):A.isPrimary?-1:1),createdAt:new Date,tableName:m,updatedAt:new Date}});return Promise.all(s)},Bo=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),{})},Ct=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 c=n.map(l=>`'${l.tableID}-${l.columnID}'`),m=await Lo(c,r);return{columns:n.map(l=>{let y=m[`${l.tableID}-${l.columnID}`];return{column:y?.column||l.name,alias:l.name,table:y?.table||"",full:y?y.table+"."+y.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)}},qo=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}},Bo=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}},ve=async e=>{let t=await xo(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:()=>ko(e,t),executeQuery:n=>a(()=>n.type==="SELECT"?Bo(t,()=>Ct(n.sql,n.params,t,n)):qo(t,()=>Ct(n.sql,n.params,t,n))),checkConnection:async()=>{await a(()=>t.query("SELECT 1;"))},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 ve(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)}},Nt=async(e,t)=>{try{let r;if(t==="mysql")r=await De(e);else if(t==="postgres")r=await ve(e);else throw new u(500,`Connection manager for ${t} not found`);return r}catch(r){throw console.error(r),r instanceof u?r:r?.code==="ECONNREFUSED"?new u(500,"Failed to connect to the database"):new u(500,r.message)}};var le=P(require("node:crypto"));var At="aes-256-gcm",Qo=12,Ot=()=>{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},Fo=e=>{let t=le.default.randomBytes(Qo),r=Ot(),o=le.default.createCipheriv(At,r,t),a=o.update(e,"utf8","hex");a+=o.final("hex");let n=o.getAuthTag();return{encrypted:a,iv:t.toString("hex"),tag:n.toString("hex")}},Mo=({encrypted:e,iv:t,tag:r})=>{let o=Ot(),a=le.default.createDecipheriv(At,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},de={encrypt:Fo,decrypt:Mo};var U=(e,t=!1)=>{if(t){let r=de.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 Pt=[{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"}],$o=Pt.reduce((e,t)=>(e[t.value]=t.label,e),{}),Ss=Pt.reduce((e,t)=>(e[t.label]=t.value,e),{}),Y=e=>e.map(t=>({label:$o[t],value:t})),Is=Y(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),Es=Y(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL","CONTAINS","NOT CONTAINS"]),Cs=Y(["=","<>","IS NULL","IS NOT NULL"]),Rs=Y(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),Ns=Y(["IS NULL","IS NOT NULL"]),As=Y(["IN","NOT IN"]),Wo=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],Ho=new Set(Wo),pe=e=>Ho.has(e),Yo=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],Go=new Set(Yo),Dt=e=>Go.has(e);var Os=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var xe={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 vt={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:O(t[1])}]},stringify:e=>`LIKE "%${e[0]?.value}%"`},xt={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}%"`},_t={operator:"CONTAINS",parse:e=>{let t=e.match(/^CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:O(t[1])}]},stringify:(e,t)=>pe(t)?`${e[0]?.value}`:`CONTAINS "%${e[0]?.value}%"`},Ut={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 Lt(e){return e===""?[]:jo(e).map(Ko)}function jo(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 Ko(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:kt(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:kt(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function kt(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var qt={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return Lt(t[1])},stringify:e=>`IN (${e?.map(t=>`"${t.value}"`).join(", ")})`},Bt={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return Lt(t[1])},stringify:e=>`NOT IN (${e?.map(t=>`"${t.value}"`).join(", ")})`};var Qt={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:(e,t)=>Dt(t)?`${e[0]?.value}`:`= ${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}`},Wt={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`>= ${e[0]?.value}`},Ht={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`< ${e[0]?.value}`},Yt={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:O(t[1])}]},stringify:e=>`<= ${e[0]?.value}`};var Gt={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},jt={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var Vo=[vt,_t,xt,Ut,qt,Bt,Qt,Ft,Mt,Wt,$t,Yt,Ht,Gt,jt];function zo(e){let t=e.trim();for(let r of Vo){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var Kt={parse:zo};var I=e=>{let t=xe[e];return r=>xe[r.currentTeamRole]>=t},Vt=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 zt=async(e,t)=>{await e.createQueryBuilder().delete().from(V).where(`queryId IN (
57
+ limit 75;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},Nt=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 c=n.map(l=>`'${l.tableID}-${l.columnID}'`),m=await Bo(c,r);return{columns:n.map(l=>{let y=m[`${l.tableID}-${l.columnID}`];return{column:y?.column||l.name,alias:l.name,table:y?.table||"",full:y?y.table+"."+y.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)}},Qo=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}},Fo=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}},_e=async e=>{let t=await Uo(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:()=>qo(e,t),executeQuery:n=>a(()=>n.type==="SELECT"?Fo(t,()=>Nt(n.sql,n.params,t,n)):Qo(t,()=>Nt(n.sql,n.params,t,n))),checkConnection:async()=>{await a(()=>t.query("SELECT 1;"))},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var $=async(e,t,r)=>{try{let o;if(t==="mysql")o=await xe(e);else if(t==="postgres")o=await _e(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)}},Pt=async(e,t)=>{try{let r;if(t==="mysql")r=await xe(e);else if(t==="postgres")r=await _e(e);else throw new u(500,`Connection manager for ${t} not found`);return r}catch(r){throw console.error(r),r instanceof u?r:r?.code==="ECONNREFUSED"?new u(500,"Failed to connect to the database"):new u(500,r.message)}};var de=O(require("node:crypto"));var Ot="aes-256-gcm",Mo=12,Dt=()=>{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},$o=e=>{let t=de.default.randomBytes(Mo),r=Dt(),o=de.default.createCipheriv(Ot,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")}},Wo=({encrypted:e,iv:t,tag:r})=>{let o=Dt(),a=de.default.createDecipheriv(Ot,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},pe={encrypt:$o,decrypt:Wo};var k=(e,t=!1)=>{if(t){let r=pe.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 vt=[{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"}],Ho=vt.reduce((e,t)=>(e[t.value]=t.label,e),{}),Es=vt.reduce((e,t)=>(e[t.label]=t.value,e),{}),G=e=>e.map(t=>({label:Ho[t],value:t})),Cs=G(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),Rs=G(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL","CONTAINS","NOT CONTAINS"]),Ns=G(["=","<>","IS NULL","IS NOT NULL"]),As=G(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),Ps=G(["IS NULL","IS NOT NULL"]),Os=G(["IN","NOT IN"]),Go=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],Yo=new Set(Go),fe=e=>Yo.has(e),jo=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],Ko=new Set(jo),xt=e=>Ko.has(e);var Ds=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var Ue={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 _t={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`LIKE "%${e[0]?.value}%"`},Ut={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}%"`},kt={operator:"CONTAINS",parse:e=>{let t=e.match(/^CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>fe(t)?`${e[0]?.value}`:`CONTAINS "%${e[0]?.value}%"`},Lt={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 Bt(e){return e===""?[]:Vo(e).map(zo)}function Vo(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 zo(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:qt(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:qt(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function qt(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var Qt={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return Bt(t[1])},stringify:e=>`IN (${e?.map(t=>`"${t.value}"`).join(", ")})`},Ft={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return Bt(t[1])},stringify:e=>`NOT IN (${e?.map(t=>`"${t.value}"`).join(", ")})`};var Mt={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>xt(t)?`${e[0]?.value}`:`= ${e[0]?.value}`},$t={operator:"!=",parse:e=>{let t=e.match(/^!=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`!= ${e[0]?.value}`},Wt={operator:"<>",parse:e=>{let t=e.match(/^<>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<> ${e[0]?.value}`},Ht={operator:">",parse:e=>{let t=e.match(/^>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`> ${e[0]?.value}`},Gt={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`>= ${e[0]?.value}`},Yt={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`< ${e[0]?.value}`},jt={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<= ${e[0]?.value}`};var Kt={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},Vt={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var Jo=[_t,kt,Ut,Lt,Qt,Ft,Mt,$t,Wt,Gt,Ht,jt,Yt,Kt,Vt];function Xo(e){let t=e.trim();for(let r of Jo){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var zt={parse:Xo};var I=e=>{let t=Ue[e];return r=>Ue[r.currentTeamRole]>=t},Jt=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 Xt=async(e,t)=>{await e.createQueryBuilder().delete().from(V).where(`queryId IN (
58
58
  SELECT id
59
59
  FROM query
60
60
  WHERE dataSourceId = :dataSourceId
61
- )`).setParameter("dataSourceId",t).execute(),await e.delete(K,{dataSource:{id:t}})},fe=async(e,t)=>{let r=await e.find(q,{where:{datasource:{id:t}},select:["id"]});for(let o of r)await e.delete(M,{table:{id:o.id}}),await e.delete(q,o)};function Jo(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 Nt(U(t,!0),t.dbType)).inspectSchema();await fe(r,t.id);let n=Jo(a);for(let i of a){let s=await r.save(q,{datasource:{id:e},name:i.tableName});if(i.columns){let c=[];for(let m of i.columns)c.push(ue.create({table:{id:s.id},name:m.name,isPrimary:!!m.isPrimary,type:m.type,meta:{refs:m.ref,referencedBy:n.get(`${s.name}.${m.name}`)}}));await r.save(M,c)}}await r.save(F,{id:e,status:"READY",lastInspected:new Date})}).catch(r=>{console.error(r),E.save({id:e,status:"FAILED"})}),!0};var Xt=g(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=p(t),o=await E.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}=x(t);return{data:await E.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:I("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=f(t,wt),n=E.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),i=await $(U(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:c,encrypted:m}=de.encrypt(n.dbPassword);return n.dbPassword=m,n.dbPasswordIv=c,n.dbPasswordTag=s,{data:await E.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:I("admin")},handler:async t=>{let{id:r}=p(t),o=f(t),a=await E.findOneBy({id:r});if(!a)throw new u(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:I("admin")},handler:async t=>b.transaction(async r=>{let{id:o}=p(t);await r.delete(z,{dataSource:{id:o}}),await zt(r,o),await fe(r,o),await r.delete(F,{id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=p(t);return{data:{started:await Jt(o)}}}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=p(t);return{data:(await ce.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 k=require("typeorm"),Zt=g(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=p(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=p(t),o=x(t),a=r.teamId||t.user.currentTeamId,n=Number(o.size)||20,i=Number(o.page)||0,s=o.nameFilter?.length?{name:(0,k.Raw)(y=>`LOWER(${y}) LIKE :search`,{search:`%${o.nameFilter.toLowerCase()}%`})}:void 0,c=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:i*n,select:{id:!0,query:{id:!0,name:!0,updatedAt:!0,dataSource:{name:!0,dbType:!0}}},order:{query:{updatedAt:"DESC"}}}),m=c.length>n;return m&&c.pop(),{data:c.map(y=>({name:y.query.name,id:y.query.id,updatedAt:y.query.updatedAt,savedQueryId:y.id,datasourceName:y.query.dataSource.name,datasourceType:y.query.dataSource.dbType})),hasMore:m}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=p(t),{search:o,size:a,selectedDataSources:n}=x(t),i=o.length>3?parseInt(a)||20:8,s={};n?.length&&(s.id=(0,k.In)(n));let[c,m,l]=await Promise.all([ce.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:i}),S.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:"DESC"},take:i}),_.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:"DESC"},take:i})]),y=[];return c.forEach(d=>{y.push({name:d.name,id:d.id,dataSourceName:d.datasource?.name||"--",dataSourceId:d.datasource?.id||"--",type:"table"})}),m.forEach(d=>{y.push({name:d.name,id:d.id,dataSourceName:d.dataSource?.name||"--",dataSourceId:d.dataSource?.id||"--",type:"tab"})}),l.forEach(d=>{y.push({name:d.query.name,id:d.query.id,dataSourceName:d.query.dataSource?.name||"--",dataSourceId:d.query.dataSource?.id||"--",type:"query"})}),{data:y}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=p(t),o=x(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,k.Like)(`%${o.nameFilter}%`)),o.archived&&(s.archived=o.archived==="true");let c=await S.find({where:s,relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),m=!1;return c.length>n&&(c.pop(),m=!0),{data:c.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:m}}})});var er=g(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=p(t),o=await N.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:I("editor")},handler:async t=>{let r=f(t),o=await E.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await N.save(N.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:I("editor")},handler:async t=>{let{id:r}=p(t),o=f(t);if(!(await N.update(r,o)).affected)throw new u(404,"Query not found");return{data:await N.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:I("editor")},handler:async t=>b.transaction(async()=>{let{id:r}=p(t);if(!(await N.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var tr=e=>e&&pe(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("."),i=t(a,n);if(o.mode==="advanced"){let s=Kt.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||tr(i?.type),fn:o.fn})}else o.mode==="raw"?r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:"RAW",fn:o.fn}):r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:tr(i?.type),fn:o.fn})}return r},rr=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}),or=(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},Xo=e=>e.isPrimary&&e.table?.name?{table:e.table.name,field:e.name}:e?.meta?.refs,Zo=e=>e?.meta?.referencedBy,ar=(e,t,r)=>t.map((o,a)=>{let n=o.table?r(o.table,o.column):void 0,i=n?Xo(n):void 0,s=n?Zo(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}}),nr=e=>{let t=[],r=[];for(let o of e)o.referencedBy?.forEach(a=>{t.push({id:[a.table,a.field,o.table,o.column].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"}),o.ref.table!==o.table&&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"),sr=new ke.DataSource({type:"mysql"}),ir=new ke.DataSource({type:"postgres"}),G=e=>{switch(e){case"postgres":return ir.createQueryBuilder();case"mysql":return sr.createQueryBuilder();default:throw new Error("Unsupported database connection")}},ye={postgres:ir.driver,mysql:sr.driver};var ee=(e,t,r)=>{let{column:o,operator:a,value:n}=e,i="_"+t;switch(a){case"RAW":let s=" "+o+" ";return[`(${o} ${n[0].value.replace(/\s_\s/g,s)})`,{}];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(l=>l.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 ur=e=>{let t=ye[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 cr=["SUM","COUNT","AVG","MAX","MIN"],ea=["YEAR","MONTH","DAY",...cr],ta=ea.reduce((e,t)=>(e[t]=!0,e),{}),ra=cr.reduce((e,t)=>(e[t]=!0,e),{}),mr=e=>ta[e],lr=e=>ra[e];var Te=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,dr={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:Te,MAX:Te,MIN:Te,COUNT:Te};var he=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,pr={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:he,MAX:he,MIN:he,COUNT:he};var oa=e=>{let t=[];return e.fn&&t.push(e.fn),e.distinct&&t.push("distinct"),t.push(e.column),t.join(" ")},aa=e=>{let t=ur(e),r=e==="postgres"?dr:pr;return o=>o.fn&&mr(o.fn)?r[o.fn](t(o.column),o.fn,o.distinct):t(o.column)};function fr(e,t){let r=G(t.dbType).from(e,e),o=!1,a=0,n=aa(t.dbType),i={};return{setColumns(s){s.forEach(c=>{let m=oa(c);i[m]=m,r.addSelect(n(c),m)})},setLimit:s=>{r.limit(s),o=!0},setOffset(s){r.offset(s)},addOrderBy(s,c){r.addOrderBy(s,c)},addJoin({table:s,alias:c,on:m}){r.leftJoin(s,c||s,m)},addWhere(s){let[c,m]=ee({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andWhere(c,m)},addHaving(s){let[c,m]=ee({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andHaving(c,m)},addGroupBy(s){r.addGroupBy(n(s))},hasAlias(s){return!!i[s]},build(){o||r.limit(50);let[s,c]=r.getQueryAndParameters();return{sql:s,params:c}}}}var yr=(e,t)=>{let r=G(t.dbType).update(e),o=0;return{addWhere(a){let[n,i]=ee(a,++o,t.dbType);r.andWhere(n,i)},setParams(a){let n={};for(let[i,s]of Object.entries(a))s.mode==="raw"?n[i]=()=>s.value:n[i]=s.value;r.set(n)},build(){let[a,n]=r.getQueryAndParameters();return{sql:a,params:n}}}};var Tr=(e,t)=>{let r=G(t.dbType).insert().into(e);return{setValues(o){let a={};for(let[n,i]of Object.entries(o))i.mode==="raw"?a[n]=()=>i.value:a[n]=i.value;r.values([a])},build(){let[o,a]=r.getQueryAndParameters();return{sql:o,params:a}}}};var Le=fr,hr=yr,gr=Tr;var br=require("typeorm"),wr=async(e,t)=>{let r=await ue.find({where:{table:{name:(0,br.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,c)=>(s[c.full]=c.type,s),{});return{getAllColumns(){return o},hasColumn(s){return!!a[s]||s==="*"},getAvailableJoins:()=>{let s=[],c=new Set(t);for(let m of r)if(m.meta?.referencedBy?.forEach(l=>{c.has(l.table)||s.push({id:[l.table,l.field,m.name,m.table.name].join("."),fromColumn:l.field,fromTable:l.table,toColumn:m.name,toTable:m.table.name,direction:"in"})}),m.meta?.refs){let l=m.meta.refs;c.has(l.table)||s.push({id:[m.name,m.table.name,l.table,l.field].join("."),fromColumn:m.name,fromTable:m.table.name,toColumn:l.field,toTable:l.table,direction:"out"})}return s},getColumnByName:(s,c)=>{for(let m of r)if(m.name===c&&m.table.name===s)return m}}};async function na(e,t,r){return N.save(N.create({user:{id:e},team:{id:t},dataSource:{id:r.datasourceId},name:r.name,opts:r.opts}))}var ge=async(e,t)=>{let{datasourceId:r,size:o=20,page:a}=t,{table:n,joins:i,groupBy:s,orderBy:c}=t.opts,m=await be(r);if(!m)throw new u(404,"Datasource not found");let l=or(t.opts.columns,t.opts.groupBy,t.opts.aggregations),y=rr(t.opts),d=await wr(r,y),A=d.getAllColumns(),L;l&&l.length>0?L=l:L=A.map(C=>({column:C.full})),L.forEach(C=>{if(!d.hasColumn(C.column))throw new u(400,`Invalid column ${C.column}`)});let ao=na(e.user.id,e.user.currentTeamId,t),v=Le(n,m);v.setLimit(o+1),v.setOffset(o*a),v.setColumns(L),i&&i.forEach(v.addJoin),c.length>0&&c.forEach(({column:C,direction:mo})=>{v.hasAlias(C)&&v.addOrderBy(ye[m.dbType].escape(C),mo)}),s&&s.length>0&&s.forEach(C=>{d.hasColumn(C.value)&&v.addGroupBy({column:C.value,fn:C.fn,distinct:C.distinct})}),Ue(t.opts.filters,d.getColumnByName).forEach(C=>{C.fn&&lr(C.fn)?v.addHaving(C):v.addWhere(C)});let{sql:no,params:so}=v.build(),re=await(await $(U(m,!0),m.dbType,e)).executeQuery({sql:no,params:so,type:"SELECT",allowBulkUpdate:!1}),Qe=re.rows.length>o;Qe&&re.rows.pop();let{id:io}=await ao,Fe=ar(L,re.columns,d.getColumnByName),{hooks:uo,entities:co}=nr(Fe);return{...re,queryHistoryId:io,tables:y,allColumns:A,availableHooks:uo,availableEntities:co,availableJoins:d.getAvailableJoins(),columns:Fe,hasMore:Qe}},Sr=async(e,t)=>{let r=await be(t.dataSourceId);if(!r)throw new u(400,"Invalid datasource");let o=await $(U(r,!0),r.dbType,e),a=Le(t.table,r);a.setLimit(2);for(let[c,m]of Object.entries(t.props))a.addWhere({value:[{value:m}],column:c});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}},Ir=async(e,t)=>{let r=await be(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=hr(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})},Er=async(e,t)=>{let r=await be(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=gr(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 be(e){return E.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var Cr=e=>{},sa=["--",";","DROP","drop"],Rr=([e,t])=>{t.mode!=="default"&&sa.forEach(r=>{if(t.value.includes(r))throw new u(400,"Invalid input value for "+e)})},Nr=e=>{if(!e.table)throw new u(400,"Table is required");Object.entries(e.values).forEach(Rr)},Ar=e=>{if(!e.table)throw new u(400,"Table is required");Object.entries(e.values).forEach(Rr)};var Or=g(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=f(t,Cr);return{data:await ge(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=p(t),a=x(t);return{data:await Sr(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:I("editor")},handler:async t=>{let r=f(t,Nr);return{data:await Er(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:I("editor")},handler:async t=>{let r=f(t,Ar);return{data:await Ir(t,r)}}})});var Pr=g(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:T.str("SERVER_VERSION")}}))});var Dr=g(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=p(t),o=await B.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:I("editor")},handler:async t=>b.transaction(async()=>{let r=t.user.id,o=f(t),a=w.create();a.id=r;let n=B.create(o);await B.save(n);let i=R.create({user:a,team:n});return await R.save(i),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:I("admin")},handler:async t=>{let{id:r}=p(t),{role:o,userId:a}=f(t,({role:i})=>{if(i==="owner")throw new u(400,"Only one owner is allowed")});if((await R.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new u(400,"Cannot change owner role");await R.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:I("admin")},handler:async t=>b.transaction(async()=>{let{id:r}=p(t),{userId:o}=x(t);if((await R.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new u(400,"Cannot delete team owner");await w.update(o,{currentTeam:null}),await R.delete({user:{id:o},team:{id:r}}),await w.delete({id:o})})})});var qe=P(require("bcryptjs")),te=async e=>{let t=await qe.default.genSalt(10);return qe.default.hash(e,t)};var vr=g(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=f(t);if(o.password&&(o.password=await te(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:I("admin")},handler:async t=>b.transaction(async()=>{let r=f(t),o=await te(r.password),a=await w.save(w.create({username:r.username,password:o})),n=await R.save(R.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await w.update(a.id,{currentTeam:{id:n.id}})})})});var xr=g(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await H.findOneBy({user:{id:r}});return o||(o=await H.save(H.create({user:{id:r}}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=f(t);if(!r.id)throw new u(400,"Settings id is required!");if(!(await H.update(r.id,r)).affected)throw new u(404,"You do not own these settings!");return{data:await H.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 _r=g(e=>{e.route({method:"post",url:"/",config:{requireRole:I("editor")},handler:async t=>{let r=f(t),o=await N.findOne({where:{id:r.queryId}});if(!o)throw new u(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 N.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:I("editor")},handler:async t=>{let{id:r}=p(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}=p(t),o=f(t,i=>{if(!i.name)throw new u(400,"Name is required")}),a=await _.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([_.update({id:r},{searchString:n}),N.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var Ur=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new u(400,"Either queryId or name and opts are required")};var Lr=require("typeorm");var Be=async()=>{let e=await S.maximum("orderIndex");return e!=null?e+1:0};function kr(e,t){return S.find({where:{team:{id:e},user:{id:t},archived:!1},select:["id","name","orderIndex"],order:{orderIndex:"ASC"}})}var qr=g(e=>{e.route({method:"get",url:"/",handler:async t=>{let{currentTeamId:r,id:o}=t.user;return{data:await kr(r,o)}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=p(t),{currentTeamId:o,id:a}=t.user,n=await S.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}=f(t,Ur),n,i,s=o;if(r)i=r.dataSourceId,n=r;else{let l=await N.findOne({where:{id:a},relations:{dataSource:!0}});if(!l)throw new u(404,"Query not Found");i=l.dataSource.id,n={table:l.opts.table,filters:l.opts.filters,joins:l.opts.joins,orderBy:l.opts.orderBy,columns:l.opts.columns,groupBy:l.opts.groupBy,searchAll:l.opts.searchAll,aggregations:l.opts.aggregations,dataSourceId:l.dataSource.id,page:0,size:50},o||(s=l.name)}let c=await Be();return{data:await S.save(S.create({name:s||new Date().toISOString(),opts:n||{},orderIndex:c,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}=p(t),o=f(t),a=await S.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&&S.update(r,{opts:o||{},searchString:j(o,a.name),updatedAt:new Date}),{data:{result:await ge(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}=p(t),o=f(t),a=await S.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 S.update(r,{...o,searchString:n}),{data:{id:r}}}}),e.route({method:"patch",url:"/:id/archive",handler:async t=>{let{id:r}=p(t),o=f(t),{currentTeamId:a,id:n}=t.user,i=await S.findOne({where:{id:r,user:{id:t.user.id}},select:["id","orderIndex"]});if(!i)throw new u(404,"Not Found");if(o.others||o.all){let c=ia(a,n,i.id,o);await S.update(c,{archived:!0})}else await S.update(r,{archived:!0});return{data:await kr(a,n)}}}),e.route({method:"patch",url:"/:id/restore",handler:async t=>{let{id:r}=p(t),o=await S.findOne({where:{id:r,user:{id:t.user.id}},select:["id","archived"]});if(!o)throw new u(404,"Not Found");if(!o.archived)throw new u(400,"This tab is not archived");let a=await Be();return await S.update(r,{archived:!1,orderIndex:a}),{data:{id:r}}}}),e.route({method:"delete",url:"/:id",handler:async t=>{let{id:r}=p(t),o=t.user.id;return await S.delete({id:r,user:{id:o}}),{data:!0}}})});function ia(e,t,r,o){let a={archived:!1,team:{id:e},user:{id:t}};return o.others&&(a.id=(0,Lr.Not)(r)),a}var Fr=require("node:crypto");var Br=require("node:crypto"),Qr={teamName:"Default Team",username:"admin"},ua=async()=>{let e=await B.findOneBy({});return e||B.save(B.create({name:Qr.teamName}))},we=async e=>{let t=await R.findOne({where:{role:"owner"},relations:{user:!0}});if(t)return t.user;let r=await ua(),o=await te(e?.password||(0,Br.randomBytes)(32).toString("hex")),a=await w.save(w.create({username:e?.name||Qr.username,password:o})),n=await R.save(R.create({user:a,team:r,role:"owner"}));return await w.update(a.id,{currentTeam:n}),a};var Se={setupAccessToken:void 0},Mr=()=>(Se.setupAccessToken=(0,Fr.randomBytes)(32).toString("hex"),Se.setupAccessToken),ca=e=>{if(!Se.setupAccessToken)throw new u(400,"Setup already performed");if(!e||e!==Se.setupAccessToken)throw new u(400,"Invalid setup access token")},W=async()=>D.skipAuth?!1:await w.count()<1,$r=async e=>{ca(e.setupAccessToken),await we({name:e.userName,password:e.userPassword})};var Wr=g(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:D.skipAuth,modeName:D.name,usesCustomDb:Ge(),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 W()?r.redirect("/setup"):r.sendFile("index.html")}),e.route({method:"get",url:"/setup",handler:async(t,r)=>await W()?r.sendFile("setup.html"):r.redirect("/")})});var Hr=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 Yr=g(e=>{e.route({method:"post",url:"/",config:{isPublic:!0},handler:async t=>{if(!await W())throw new u(400,"Setup has already been completed");let o=f(t,Hr);return await $r(o),{data:!0}}})});var ma=[[Wr,"/"],[bt,"/api/auth"],[Xt,"/api/data-sources"],[Zt,"/api/project"],[er,"/api/queries"],[Or,"/api/runner"],[Pr,"/api/status"],[Dr,"/api/teams"],[vr,"/api/users"],[xr,"/api/user-settings"],[_r,"/api/saved-queries"],[qr,"/api/workbench-tabs"],[Yr,"/api/setup"]],Gr=e=>{for(let[t,r]of ma)e.register(t,{prefix:r}),console.log("Registered "+r)};var la=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),da=async()=>R.findOne({where:{role:"owner"},relations:{user:!0,team:!0}}),pa=async e=>{let t=await da();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}},fa=async e=>{let t=e.headers.authorization;if(!t)throw new u(401,"Missing auth token");let[r,o]=t.split(" "),{userId:a}=await yt(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}},jr=async e=>{la(e)||(D.skipAuth?await pa(e):await fa(e))};var Kr=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Vr=e=>{e.addHook("onRequest",jr),e.addHook("onRequest",Vt),e.addHook("onResponse",Kr)};var zr=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 Jr=P(require("@fastify/cookie")),Xr=P(require("@fastify/cors"));var Zr=P(require("@fastify/static")),eo=require("node:path"),to=e=>{e.register(Jr.default,{}),e.register(Xr.default,{origin:J.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(Zr.default,{root:(0,eo.join)(__dirname,"web")})};(async function(){let t=(0,ro.default)({querystringParser:o=>oo.default.parse(o)});if(Ye(),to(t),Vr(t),Gr(t),zr(t),await t.after(),await ut(),t.listen({port:J.port,host:J.host},(o,a)=>{o&&(console.error(o),process.exit(1)),console.log(`Server listening at ${a}`)}),await W()){let o=Mr();console.log(`Setup access token:
62
- ${o}`),console.log("Use the above token to finish the setup process when opening the app for the first time.")}else await we()})();
61
+ )`).setParameter("dataSourceId",t).execute(),await e.delete(K,{dataSource:{id:t}})},ye=async(e,t)=>{let r=await e.find(q,{where:{datasource:{id:t}},select:["id"]});for(let o of r)await e.delete(M,{table:{id:o.id}}),await e.delete(q,o)};function Zo(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 Zt=async e=>{let t=await C.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 C.save(t),b.transaction(async r=>{let a=await(await Pt(k(t,!0),t.dbType)).inspectSchema();await ye(r,t.id);let n=Zo(a);for(let i of a){let s=await r.save(q,{datasource:{id:e},name:i.tableName});if(i.columns){let c=[];for(let m of i.columns)c.push(ce.create({table:{id:s.id},name:m.name,isPrimary:!!m.isPrimary,type:m.type,meta:{refs:m.ref,referencedBy:n.get(`${s.name}.${m.name}`)}}));await r.save(M,c)}}await r.save(F,{id:e,status:"READY",lastInspected:new Date})}).catch(r=>{console.error(r),C.save({id:e,status:"FAILED"})}),!0};var er=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=p(t),o=await C.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 C.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:I("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=f(t,It),n=C.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),i=await $(k(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:c,encrypted:m}=pe.encrypt(n.dbPassword);return n.dbPassword=m,n.dbPasswordIv=c,n.dbPasswordTag=s,{data:await C.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:I("admin")},handler:async t=>{let{id:r}=p(t),o=f(t),a=await C.findOneBy({id:r});if(!a)throw new u(404,"Data source not found");let n=C.merge(a,o);return await C.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:I("admin")},handler:async t=>b.transaction(async r=>{let{id:o}=p(t);await r.delete(z,{dataSource:{id:o}}),await Xt(r,o),await ye(r,o),await r.delete(F,{id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=p(t);return{data:{started:await Zt(o)}}}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=p(t);return{data:(await me.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 L=require("typeorm"),tr=h(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=p(t);return{data:await C.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=p(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,L.Raw)(y=>`LOWER(${y}) LIKE :search`,{search:`%${o.nameFilter.toLowerCase()}%`})}:void 0,c=await U.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"}}}),m=c.length>n;return m&&c.pop(),{data:c.map(y=>({name:y.query.name,id:y.query.id,updatedAt:y.query.updatedAt,savedQueryId:y.id,datasourceName:y.query.dataSource.name,datasourceType:y.query.dataSource.dbType})),hasMore:m}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=p(t),{search:o,size:a,selectedDataSources:n}=_(t),i=o.length>3?parseInt(a)||20:8,s={};n?.length&&(s.id=(0,L.In)(n));let[c,m,l]=await Promise.all([me.find({where:{name:(0,L.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}),S.find({where:{searchString:(0,L.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:"DESC"},take:i}),U.find({where:{searchString:(0,L.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:"DESC"},take:i})]),y=[];return c.forEach(d=>{y.push({name:d.name,id:d.id,dataSourceName:d.datasource?.name||"--",dataSourceId:d.datasource?.id||"--",type:"table"})}),m.forEach(d=>{y.push({name:d.name,id:d.id,dataSourceName:d.dataSource?.name||"--",dataSourceId:d.dataSource?.id||"--",type:"tab"})}),l.forEach(d=>{y.push({name:d.query.name,id:d.query.id,dataSourceName:d.query.dataSource?.name||"--",dataSourceId:d.query.dataSource?.id||"--",type:"query"})}),{data:y}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=p(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,L.Like)(`%${o.nameFilter}%`)),o.archived&&(s.archived=o.archived==="true");let c=await S.find({where:s,relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),m=!1;return c.length>n&&(c.pop(),m=!0),{data:c.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:m}}})});var rr=h(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=p(t),o=await N.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:I("editor")},handler:async t=>{let r=f(t),o=await C.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await N.save(N.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:I("editor")},handler:async t=>{let{id:r}=p(t),o=f(t);if(!(await N.update(r,o)).affected)throw new u(404,"Query not found");return{data:await N.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:I("editor")},handler:async t=>b.transaction(async()=>{let{id:r}=p(t);if(!(await N.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var or=e=>e&&fe(e)?"CONTAINS":"=",Le=(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.mode==="advanced"){let s=zt.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||or(i?.type),fn:o.fn})}else o.mode==="raw"?r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:"RAW",fn:o.fn}):r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:or(i?.type),fn:o.fn})}return r},ar=e=>{let t=[e.table];return e.joins&&e.joins.forEach(({table:r})=>t.push(r)),t},ke=e=>({column:e.value,fn:e.fn,distinct:e.distinct}),nr=(e,t,r)=>{let o=[];return t.length>0||r.length>0?o.push(...t.map(ke),...r.map(ke)):e.length>0&&o.push(...e.map(ke)),o},ea=e=>e.isPrimary&&e.table?.name?{table:e.table.name,field:e.name}:e?.meta?.refs,ta=e=>e?.meta?.referencedBy,sr=(e,t,r)=>t.map((o,a)=>{let n=o.table?r(o.table,o.column):void 0,i=n?ea(n):void 0,s=n?ta(n):void 0;return{...o,full:e[a].fn?e[a].column:o.full,type:n?.type,fn:e[a].fn,hidden:e[a].hidden,ref:i,referencedBy:s}}),ir=e=>{let t=[],r=[];for(let o of e)o.referencedBy?.forEach(a=>{t.push({id:[a.table,a.field,o.table,o.column].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"}),o.ref.table!==o.table&&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 qe=require("typeorm"),ur=new qe.DataSource({type:"mysql"}),cr=new qe.DataSource({type:"postgres"}),Y=e=>{switch(e){case"postgres":return cr.createQueryBuilder();case"mysql":return ur.createQueryBuilder();default:throw new Error("Unsupported database connection")}},Te={postgres:cr.driver,mysql:ur.driver};var ee=(e,t,r)=>{let{column:o,operator:a,value:n}=e,i="_"+t;switch(a){case"RAW":let s=" "+o+" ";return[`(${o} ${n[0].value.replace(/\s_\s/g,s)})`,{}];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(l=>l.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 mr=e=>{let t=Te[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 lr=["SUM","COUNT","AVG","MAX","MIN"],ra=["YEAR","MONTH","DAY",...lr],oa=ra.reduce((e,t)=>(e[t]=!0,e),{}),aa=lr.reduce((e,t)=>(e[t]=!0,e),{}),dr=e=>oa[e],pr=e=>aa[e];var ge=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,fr={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:ge,MAX:ge,MIN:ge,COUNT:ge};var he=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,yr={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:he,MAX:he,MIN:he,COUNT:he};var na=e=>{let t=[];return e.fn&&t.push(e.fn),e.distinct&&t.push("distinct"),t.push(e.column),t.join(" ")},sa=e=>{let t=mr(e),r=e==="postgres"?fr:yr;return o=>o.fn&&dr(o.fn)?r[o.fn](t(o.column),o.fn,o.distinct):t(o.column)};function Tr(e,t){let r=Y(t.dbType).from(e,e),o=!1,a=0,n=sa(t.dbType),i={};return{setColumns(s){s.forEach(c=>{let m=na(c);i[m]=m,r.addSelect(n(c),m)})},setLimit:s=>{r.limit(s),o=!0},setOffset(s){r.offset(s)},addOrderBy(s,c){r.addOrderBy(s,c)},addJoin({table:s,alias:c,on:m}){r.leftJoin(s,c||s,m)},addWhere(s){let[c,m]=ee({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andWhere(c,m)},addHaving(s){let[c,m]=ee({...s,operator:s.operator||"=",column:n(s)},++a,t.dbType);r.andHaving(c,m)},addGroupBy(s){r.addGroupBy(n(s))},hasAlias(s){return!!i[s]},build(){o||r.limit(50);let[s,c]=r.getQueryAndParameters();return{sql:s,params:c}}}}var gr=(e,t)=>{let r=Y(t.dbType).update(e),o=0;return{addWhere(a){let[n,i]=ee(a,++o,t.dbType);r.andWhere(n,i)},setParams(a){let n={};for(let[i,s]of Object.entries(a))s.mode==="raw"?n[i]=()=>s.value:n[i]=s.value;r.set(n)},build(){let[a,n]=r.getQueryAndParameters();return{sql:a,params:n}}}};var hr=(e,t)=>{let r=Y(t.dbType).insert().into(e);return{setValues(o){let a={};for(let[n,i]of Object.entries(o))i.mode==="raw"?a[n]=()=>i.value:a[n]=i.value;r.values([a])},build(){let[o,a]=r.getQueryAndParameters();return{sql:o,params:a}}}};var Be=Tr,br=gr,wr=hr;var Sr=require("typeorm"),Ir=async(e,t)=>{let r=await ce.find({where:{table:{name:(0,Sr.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,c)=>(s[c.full]=c.type,s),{});return{getAllColumns(){return o},hasColumn(s){return!!a[s]||s==="*"},getPrimaryKeyColumns(){return r.filter(s=>s.isPrimary).map(s=>({table:s.table.name,column:s.name,full:`${s.table.name}.${s.name}`}))},getAvailableJoins:()=>{let s=[],c=new Set(t);for(let m of r)if(m.meta?.referencedBy?.forEach(l=>{c.has(l.table)||s.push({id:[l.table,l.field,m.name,m.table.name].join("."),fromColumn:l.field,fromTable:l.table,toColumn:m.name,toTable:m.table.name,direction:"in"})}),m.meta?.refs){let l=m.meta.refs;c.has(l.table)||s.push({id:[m.name,m.table.name,l.table,l.field].join("."),fromColumn:m.name,fromTable:m.table.name,toColumn:l.field,toTable:l.table,direction:"out"})}return s},getColumnByName:(s,c)=>{for(let m of r)if(m.name===c&&m.table.name===s)return m}}};async function ia(e,t,r){return N.save(N.create({user:{id:e},team:{id:t},dataSource:{id:r.datasourceId},name:r.name,opts:r.opts}))}var be=async(e,t)=>{let{datasourceId:r,size:o=20,page:a}=t,{table:n,joins:i,groupBy:s,orderBy:c}=t.opts,m=await we(r);if(!m)throw new u(404,"Datasource not found");let l=nr(t.opts.columns,t.opts.groupBy,t.opts.aggregations),y=ar(t.opts),d=await Ir(r,y),A=d.getAllColumns(),v;l&&l.length>0?v=l:v=A.map(E=>({column:E.full})),v.forEach(E=>{if(!d.hasColumn(E.column))throw new u(400,`Invalid column ${E.column}`)});let so=s&&s.length>0||t.opts.aggregations&&t.opts.aggregations.length>0;if(l&&l.length>0&&!so){let E=new Set(v.map(oe=>oe.column)),Ee=d.getPrimaryKeyColumns();for(let oe of Ee)E.has(oe.full)||v.push({column:oe.full,hidden:!0})}let io=ia(e.user.id,e.user.currentTeamId,t),x=Be(n,m);x.setLimit(o+1),x.setOffset(o*a),x.setColumns(v),i&&i.forEach(x.addJoin),c.length>0&&c.forEach(({column:E,direction:Ee})=>{x.hasAlias(E)&&x.addOrderBy(Te[m.dbType].escape(E),Ee)}),s&&s.length>0&&s.forEach(E=>{d.hasColumn(E.value)&&x.addGroupBy({column:E.value,fn:E.fn,distinct:E.distinct})}),Le(t.opts.filters,d.getColumnByName).forEach(E=>{E.fn&&pr(E.fn)?x.addHaving(E):x.addWhere(E)});let{sql:uo,params:co}=x.build(),re=await(await $(k(m,!0),m.dbType,e)).executeQuery({sql:uo,params:co,type:"SELECT",allowBulkUpdate:!1}),Me=re.rows.length>o;Me&&re.rows.pop();let{id:mo}=await io,$e=sr(v,re.columns,d.getColumnByName),{hooks:lo,entities:po}=ir($e);return{...re,queryHistoryId:mo,tables:y,allColumns:A,availableHooks:lo,availableEntities:po,availableJoins:d.getAvailableJoins(),columns:$e,hasMore:Me}},Er=async(e,t)=>{let r=await we(t.dataSourceId);if(!r)throw new u(400,"Invalid datasource");let o=await $(k(r,!0),r.dbType,e),a=Be(t.table,r);a.setLimit(2);for(let[c,m]of Object.entries(t.props))a.addWhere({value:[{value:m}],column:c});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}},Cr=async(e,t)=>{let r=await we(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=br(t.table,r);o.setParams(t.values),Le(t.filters,()=>{}).forEach(s=>{o.addWhere(s)});let{sql:a,params:n}=o.build();return(await $(k(r,!0),r.dbType,e)).executeQuery({sql:a,params:n,type:"UPDATE",allowBulkUpdate:!1})},Rr=async(e,t)=>{let r=await we(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=wr(t.table,r);o.setValues(t.values);let{sql:a,params:n}=o.build();return(await $(k(r,!0),r.dbType,e)).executeQuery({sql:a,type:"INSERT",params:n,allowBulkUpdate:!1})};async function we(e){return C.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var Nr=e=>{},ua=["--",";","DROP","drop"],Ar=([e,t])=>{t.mode!=="default"&&ua.forEach(r=>{if(t.value.includes(r))throw new u(400,"Invalid input value for "+e)})},Pr=e=>{if(!e.table)throw new u(400,"Table is required");Object.entries(e.values).forEach(Ar)},Or=e=>{if(!e.table)throw new u(400,"Table is required");Object.entries(e.values).forEach(Ar)};var Dr=h(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=f(t,Nr);return{data:await be(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=p(t),a=_(t);return{data:await Er(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:I("editor")},handler:async t=>{let r=f(t,Pr);return{data:await Rr(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:I("editor")},handler:async t=>{let r=f(t,Or);return{data:await Cr(t,r)}}})});var vr=h(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:T.str("SERVER_VERSION")}}))});var xr=h(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=p(t),o=await B.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:I("editor")},handler:async t=>b.transaction(async()=>{let r=t.user.id,o=f(t),a=w.create();a.id=r;let n=B.create(o);await B.save(n);let i=R.create({user:a,team:n});return await R.save(i),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:I("admin")},handler:async t=>{let{id:r}=p(t),{role:o,userId:a}=f(t,({role:i})=>{if(i==="owner")throw new u(400,"Only one owner is allowed")});if((await R.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new u(400,"Cannot change owner role");await R.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:I("admin")},handler:async t=>b.transaction(async()=>{let{id:r}=p(t),{userId:o}=_(t);if((await R.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new u(400,"Cannot delete team owner");await w.update(o,{currentTeam:null}),await R.delete({user:{id:o},team:{id:r}}),await w.delete({id:o})})})});var Qe=O(require("bcryptjs")),te=async e=>{let t=await Qe.default.genSalt(10);return Qe.default.hash(e,t)};var _r=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=f(t);if(o.password&&(o.password=await te(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:I("admin")},handler:async t=>b.transaction(async()=>{let r=f(t),o=await te(r.password),a=await w.save(w.create({username:r.username,password:o})),n=await R.save(R.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await w.update(a.id,{currentTeam:{id:n.id}})})})});var Ur=h(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await H.findOneBy({user:{id:r}});return o||(o=await H.save(H.create({user:{id:r}}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=f(t);if(!r.id)throw new u(400,"Settings id is required!");if(!(await H.update(r.id,r)).affected)throw new u(404,"You do not own these settings!");return{data:await H.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 kr=h(e=>{e.route({method:"post",url:"/",config:{requireRole:I("editor")},handler:async t=>{let r=f(t),o=await N.findOne({where:{id:r.queryId}});if(!o)throw new u(400,"Query not found");let a=await U.save(U.create({isPersonal:!1,team:{id:t.user.currentTeamId},user:{id:t.user.id},query:{id:r.queryId},searchString:j(o.opts,r.name)}));return await N.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:I("editor")},handler:async t=>{let{id:r}=p(t);if(!(await U.delete({id:r})).affected)return{status:404,data:"Query not found"}}}),e.route({method:"patch",url:"/:id",handler:async t=>await b.transaction(async()=>{let{id:r}=p(t),o=f(t,i=>{if(!i.name)throw new u(400,"Name is required")}),a=await U.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([U.update({id:r},{searchString:n}),N.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var Lr=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new u(400,"Either queryId or name and opts are required")};var Br=require("typeorm");var Fe=async()=>{let e=await S.maximum("orderIndex");return e!=null?e+1:0};function qr(e,t){return S.find({where:{team:{id:e},user:{id:t},archived:!1},select:["id","name","orderIndex"],order:{orderIndex:"ASC"}})}var Qr=h(e=>{e.route({method:"get",url:"/",handler:async t=>{let{currentTeamId:r,id:o}=t.user;return{data:await qr(r,o)}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=p(t),{currentTeamId:o,id:a}=t.user,n=await S.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}=f(t,Lr),n,i,s=o;if(r)i=r.dataSourceId,n=r;else{let l=await N.findOne({where:{id:a},relations:{dataSource:!0}});if(!l)throw new u(404,"Query not Found");i=l.dataSource.id,n={table:l.opts.table,filters:l.opts.filters,joins:l.opts.joins,orderBy:l.opts.orderBy,columns:l.opts.columns,groupBy:l.opts.groupBy,searchAll:l.opts.searchAll,aggregations:l.opts.aggregations,dataSourceId:l.dataSource.id,page:0,size:50},o||(s=l.name)}let c=await Fe();return{data:await S.save(S.create({name:s||new Date().toISOString(),opts:n||{},orderIndex:c,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}=p(t),o=f(t),a=await S.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&&S.update(r,{opts:o||{},searchString:j(o,a.name),updatedAt:new Date}),{data:{result:await be(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}=p(t),o=f(t),a=await S.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 S.update(r,{...o,searchString:n}),{data:{id:r}}}}),e.route({method:"patch",url:"/:id/archive",handler:async t=>{let{id:r}=p(t),o=f(t),{currentTeamId:a,id:n}=t.user,i=await S.findOne({where:{id:r,user:{id:t.user.id}},select:["id","orderIndex"]});if(!i)throw new u(404,"Not Found");if(o.others||o.all){let c=ca(a,n,i.id,o);await S.update(c,{archived:!0})}else await S.update(r,{archived:!0});return{data:await qr(a,n)}}}),e.route({method:"patch",url:"/:id/restore",handler:async t=>{let{id:r}=p(t),o=await S.findOne({where:{id:r,user:{id:t.user.id}},select:["id","archived"]});if(!o)throw new u(404,"Not Found");if(!o.archived)throw new u(400,"This tab is not archived");let a=await Fe();return await S.update(r,{archived:!1,orderIndex:a}),{data:{id:r}}}}),e.route({method:"delete",url:"/:id",handler:async t=>{let{id:r}=p(t),o=t.user.id;return await S.delete({id:r,user:{id:o}}),{data:!0}}})});function ca(e,t,r,o){let a={archived:!1,team:{id:e},user:{id:t}};return o.others&&(a.id=(0,Br.Not)(r)),a}var $r=require("node:crypto");var Fr=require("node:crypto"),Mr={teamName:"Default Team",username:"admin"},ma=async()=>{let e=await B.findOneBy({});return e||B.save(B.create({name:Mr.teamName}))},Se=async e=>{let t=await R.findOne({where:{role:"owner"},relations:{user:!0}});if(t)return t.user;let r=await ma(),o=await te(e?.password||(0,Fr.randomBytes)(32).toString("hex")),a=await w.save(w.create({username:e?.name||Mr.username,password:o})),n=await R.save(R.create({user:a,team:r,role:"owner"}));return await w.update(a.id,{currentTeam:n}),a};var Ie={setupAccessToken:void 0},Wr=()=>(Ie.setupAccessToken=(0,$r.randomBytes)(32).toString("hex"),Ie.setupAccessToken),la=e=>{if(!Ie.setupAccessToken)throw new u(400,"Setup already performed");if(!e||e!==Ie.setupAccessToken)throw new u(400,"Invalid setup access token")},W=async()=>D.skipAuth?!1:await w.count()<1,Hr=async e=>{la(e.setupAccessToken),await Se({name:e.userName,password:e.userPassword})};var Gr=h(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:D.skipAuth,modeName:D.name,usesCustomDb:Ke(),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 W()?r.redirect("/setup"):r.sendFile("index.html")}),e.route({method:"get",url:"/setup",handler:async(t,r)=>await W()?r.sendFile("setup.html"):r.redirect("/")})});var Yr=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 jr=h(e=>{e.route({method:"post",url:"/",config:{isPublic:!0},handler:async t=>{if(!await W())throw new u(400,"Setup has already been completed");let o=f(t,Yr);return await Hr(o),{data:!0}}})});var da=[[Gr,"/"],[St,"/api/auth"],[er,"/api/data-sources"],[tr,"/api/project"],[rr,"/api/queries"],[Dr,"/api/runner"],[vr,"/api/status"],[xr,"/api/teams"],[_r,"/api/users"],[Ur,"/api/user-settings"],[kr,"/api/saved-queries"],[Qr,"/api/workbench-tabs"],[jr,"/api/setup"]],Kr=e=>{for(let[t,r]of da)e.register(t,{prefix:r}),console.log("Registered "+r)};var pa=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),fa=async()=>R.findOne({where:{role:"owner"},relations:{user:!0,team:!0}}),ya=async e=>{let t=await fa();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}},Ta=async e=>{let t=e.headers.authorization;if(!t)throw new u(401,"Missing auth token");let[r,o]=t.split(" "),{userId:a}=await gt(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}},Vr=async e=>{pa(e)||(D.skipAuth?await ya(e):await Ta(e))};var zr=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Jr=e=>{e.addHook("onRequest",Vr),e.addHook("onRequest",Jt),e.addHook("onResponse",zr)};var Xr=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 Zr=O(require("@fastify/cookie")),eo=O(require("@fastify/cors"));var to=O(require("@fastify/static")),ro=require("node:path"),oo=e=>{e.register(Zr.default,{}),e.register(eo.default,{origin:J.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(to.default,{root:(0,ro.join)(__dirname,"web")})};(async function(){let t=(0,ao.default)({querystringParser:o=>no.default.parse(o)});if(je(),oo(t),Jr(t),Kr(t),Xr(t),await t.after(),await mt(),t.listen({port:J.port,host:J.host},(o,a)=>{o&&(console.error(o),process.exit(1)),console.log(`Server listening at ${a}`)}),await W()){let o=Wr();console.log(`Setup access token:
62
+ ${o}`),console.log("Use the above token to finish the setup process when opening the app for the first time.")}else await Se()})();