@dataramen/cli 0.0.35 → 0.0.37

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.
@@ -0,0 +1 @@
1
+ "use strict";var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var t=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(r,e)=>{for(var a in e)s(r,a,{get:e[a],enumerable:!0})},l=(r,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of t(e))!p.call(r,n)&&n!==a&&s(r,n,{get:()=>e[n],enumerable:!(o=m(e,n))||o.enumerable});return r};var d=r=>l(s({},"__esModule",{value:!0}),r);var w={};c(w,{UsersManagement1755358316764:()=>i});module.exports=d(w);var u=require("typeorm"),i=class{name="UsersManagement1755358316764";async up(e){await e.addColumns("users",[new u.TableColumn({name:"username",type:"varchar",isUnique:!0}),new u.TableColumn({name:"password",type:"varchar"})])}async down(e){await e.dropColumns("users",["username","password"])}};0&&(module.exports={UsersManagement1755358316764});
@@ -1,9 +1,9 @@
1
- "use strict";var At=Object.create;var de=Object.defineProperty;var Ot=Object.getOwnPropertyDescriptor;var _t=Object.getOwnPropertyNames;var Dt=Object.getPrototypeOf,Pt=Object.prototype.hasOwnProperty;var Ut=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of _t(t))!Pt.call(e,a)&&a!==r&&de(e,a,{get:()=>t[a],enumerable:!(o=Ot(t,a))||o.enumerable});return e};var O=(e,t,r)=>(r=e!=null?At(Dt(e)):{},Ut(t||!e||!e.__esModule?de(r,"default",{value:e,enumerable:!0}):r,e));var G=require("dotenv"),Y=require("node:path"),pe=require("node:fs"),xt=(()=>{try{let e=(0,pe.readFileSync)((0,Y.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})();(0,G.config)({path:[(0,Y.join)(__dirname,"..","env",".env"),(0,Y.join)(__dirname,"..","env",".env.default")]});(0,G.populate)(process.env,{SERVER_VERSION:xt.version});var Mt=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],fe=()=>{let e=[];for(let t of Mt)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))};function vt(e,t=void 0){return process.env[e]||t}function Lt(e,t=void 0){let r=process.env[e];if(!r)return t;let o=Number(r);return!isNaN(o)&&r.trim()!==""?o:t}function Qt(e){return process.env[e]==="true"||process.env[e]==="TRUE"}var l={str:vt,num:Lt,bool:Qt};var wt=O(require("fastify")),St=O(require("@fastify/cors")),bt=O(require("@fastify/static"));var s=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var be=require("typeorm");var ye=require("typeorm");var y=l.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp";var te=new ye.EntitySchema({name:"DatabaseInspection",tableName:"db_inspection",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},tableName:{nullable:!0,type:String},columns:{type:"json",nullable:!0},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"}},relations:{datasource:{target:()=>"DataSource",type:"many-to-one",joinTable:!1,cascade:!0}}});var Te=require("typeorm");var re=new Te.EntitySchema({name:"Team",tableName:"teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"}},relations:{users:{type:"one-to-many",target:()=>"UsersToTeams",inverseSide:"team"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"team"},datasources:{type:"one-to-many",target:()=>"DataSource",inverseSide:"team"}}});var ge=require("typeorm");var oe=new ge.EntitySchema({name:"User",tableName:"users",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"}},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}}});var he=require("typeorm");var ae=new he.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"}},relations:{user:{type:"one-to-one",target:()=>"User",inverseSide:"settings",joinColumn:!0}}});var Ee=require("typeorm");var ne=new Ee.EntitySchema({name:"DataSource",tableName:"data_sources",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},dbUrl:{type:String},dbPort:{type:Number,nullable:!0},dbUser:{type:String},dbPassword:{type:String,nullable:!0,select:!1},dbPasswordIv:{type:String,nullable:!0,select:!1},dbPasswordTag:{type:String,nullable:!0,select:!1},dbType:{type:String},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},name:{type:String},description:{type:String,nullable:!0},dbDatabase:{type:String},dbSchema:{type:String,nullable:!0},allowInsert:{type:Boolean,default:!1},allowUpdate:{type:Boolean,default:!1},lastInspected:{type:y,nullable:!0,default:null},status:{type:String,nullable:!0}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"datasources",joinColumn:!0},inspections:{type:"one-to-many",target:()=>"DatabaseInspection",inverseSide:"datasource"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"dataSource"},owner:{type:"many-to-one",target:()=>"User",joinColumn:!0}}});var Re=O(require("node:os")),Ie=require("node:path");var we=require("typeorm");var se=new we.EntitySchema({name:"Query",tableName:"query",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},opts:{type:"json",default:"{}"},isTrash:{type:Boolean,default:!1,nullable:!0},createdAt:{type:y,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:y,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"queries",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",inverseSide:"datasources",joinColumn:!0}}});var Se=require("typeorm"),ie=new Se.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"}}});function Ft(){let e=l.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>",Re.default.homedir())),e}var S=new be.DataSource({type:l.str("APP_DB_TYPE"),database:Ft(),host:l.str("APP_DB_HOST"),username:l.str("APP_DB_USERNAME"),password:l.str("APP_DB_PASSWORD"),port:l.num("APP_DB_PORT"),schema:l.str("APP_DB_SCHEMA"),logging:l.bool("APP_DB_LOGGING"),migrationsRun:!0,migrations:[Ie.posix.join(__dirname,"migrations","*.js")],entities:[te,ne,re,oe,ie,ae,se]}),Ne=async()=>{if(!S.isInitialized)return S.initialize();throw new Error("Already initialized")},_=S.getRepository(te),f=S.getRepository(ne),x=S.getRepository(re),R=S.getRepository(oe),D=S.getRepository(ie),L=S.getRepository(ae),I=S.getRepository(se);var ue=O(require("node:fs/promises")),Ce=require("node:path"),Ae=O(require("node:os")),kt=Ae.default.homedir(),Oe=(0,Ce.join)(kt,".dataramen",".runtime","files"),_e=async()=>{await qt()||await ue.default.mkdir(Oe,{recursive:!0})};async function qt(){try{return(await ue.default.lstat(Oe)).isDirectory()}catch{return!1}}var E=e=>(t,r,o)=>{e(t),o()};var k=require("jose");var De=new TextEncoder,Pe=De.encode(l.str("JWT_SECRET")),Ue=De.encode(l.str("JWT_REFRESH_SECRET")),ce=async({userId:e})=>new k.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(Pe),le=async({userId:e})=>new k.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(Ue),xe=async(e,t)=>{try{let{payload:r}=await(0,k.jwtVerify)(e,t);if(!r.sub)throw new s(401,"Failed to verify access token");return{userId:r.sub}}catch(r){throw r instanceof s?r:r instanceof Error?new s(401,r.message):new s(401,"Failed to verify refresh token")}},Me=async e=>xe(e,Pe),ve=async e=>xe(e,Ue);var Bt=async()=>{let e=await x.save(x.create({name:"Personal"})),t=await R.save(R.create({})),r=await D.save(D.create({user:t,team:e,role:"admin"}));return await R.update(t.id,{currentTeam:r}),R.findOne({where:{}})},Le={httpOnly:!0,secure:l.bool("PROD"),sameSite:l.bool("PROD"),path:"/",maxAge:10*24*60*60},Qe=E(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let o=await R.findOne({where:{}});o||(o=await Bt());let[a,n]=await Promise.all([ce({userId:o?.id}),le({userId:o?.id})]);return r.setCookie("refreshToken",n,Le),{data:{accessToken:a}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies.refreshToken;if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await ve(o),[n,i]=await Promise.all([ce({userId:a}),le({userId:a})]);return r.setCookie("refreshToken",i,Le),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie("refreshToken",{path:"/"}),{data:!0})})});var w=(e,t)=>{let r=e.body;return t&&t(r),r},Q=(e,t)=>{let r=e.query;return t&&t(r),r},N=(e,t)=>{let r=e.params;return t&&t(r),r};var Fe=e=>{if(!e.dbUrl)throw new s(400,"url is required");if(!e.dbUser)throw new s(400,"user is required");if(!e.dbType)throw new s(400,"type is required");if(!e.name)throw new s(400,"name is required");if(!e.dbDatabase)throw new s(400,"database is required")};var qe=O(require("mysql2/promise"));var $t=({database:e,password:t,user:r,url:o})=>qe.default.createConnection({host:o,user:r,database:e,password:t}),Ht=async e=>{let t=`
1
+ "use strict";var Mt=Object.create;var Te=Object.defineProperty;var vt=Object.getOwnPropertyDescriptor;var Lt=Object.getOwnPropertyNames;var qt=Object.getPrototypeOf,Ft=Object.prototype.hasOwnProperty;var Qt=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Lt(t))!Ft.call(e,a)&&a!==r&&Te(e,a,{get:()=>t[a],enumerable:!(o=vt(t,a))||o.enumerable});return e};var A=(e,t,r)=>(r=e!=null?Mt(qt(e)):{},Qt(t||!e||!e.__esModule?Te(r,"default",{value:e,enumerable:!0}):r,e));var j=require("dotenv"),K=require("node:path"),he=require("node:fs"),kt=(()=>{try{let e=(0,he.readFileSync)((0,K.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(e)}catch{return{version:"0.0.0"}}})();(0,j.config)({path:[(0,K.join)(__dirname,"..","env",".env"),(0,K.join)(__dirname,"..","env",".env.default")]});(0,j.populate)(process.env,{SERVER_VERSION:kt.version});var Bt=["SYMM_ENCRYPTION_KEY","JWT_SECRET","JWT_REFRESH_SECRET"],ge=()=>{let e=[];for(let t of Bt)process.env[t]||e.push(t);if(e.length>0)throw new Error("Following env variables are required but not provided: "+e.join(", "))};function $t(e,t=void 0){return process.env[e]||t}function Ht(e,t=void 0){let r=process.env[e];if(!r)return t;let o=Number(r);return!isNaN(o)&&r.trim()!==""?o:t}function Yt(e){return process.env[e]==="true"||process.env[e]==="TRUE"}var m={str:$t,num:Ht,bool:Yt};var Wn=require("reflect-metadata"),At=A(require("fastify")),Ot=A(require("@fastify/cors")),_t=A(require("@fastify/static"));var s=class extends Error{constructor(r,o){super(o);this.status=r;this.message=o}};var Ce=require("typeorm");var we=require("typeorm");var T=m.str("APP_DB_TYPE")==="sqlite"?"datetime":"timestamp";var oe=new we.EntitySchema({name:"DatabaseInspection",tableName:"db_inspection",columns:{id:{type:String,unique:!0,primary:!0,generated:"uuid"},tableName:{nullable:!0,type:String},columns:{type:"json",nullable:!0},createdAt:{type:T,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:T,default:()=>"CURRENT_TIMESTAMP"}},relations:{datasource:{target:()=>"DataSource",type:"many-to-one",joinTable:!1,cascade:!0}}});var Ee=require("typeorm");var ae=new Ee.EntitySchema({name:"Team",tableName:"teams",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},createdAt:{type:T,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:T,default:()=>"CURRENT_TIMESTAMP"}},relations:{users:{type:"one-to-many",target:()=>"UsersToTeams",inverseSide:"team"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"team"},datasources:{type:"one-to-many",target:()=>"DataSource",inverseSide:"team"}}});var Se=require("typeorm");var ne=new Se.EntitySchema({name:"User",tableName:"users",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:T,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:T,default:()=>"CURRENT_TIMESTAMP"},username:{type:String,unique:!0},password:{type:String}},relations:{teams:{type:"one-to-many",target:()=>"UsersToTeams",inverseSide:"user"},settings:{type:"one-to-one",target:()=>"UserSettings",inverseSide:"user"},currentTeam:{type:"one-to-one",target:()=>"UsersToTeams",inverseSide:"user",joinColumn:!0}}});var Re=require("typeorm");var se=new Re.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},createdAt:{type:T,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:T,default:()=>"CURRENT_TIMESTAMP"}},relations:{user:{type:"one-to-one",target:()=>"User",inverseSide:"settings",joinColumn:!0}}});var be=require("typeorm");var ie=new be.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:T,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:T,default:()=>"CURRENT_TIMESTAMP"},name:{type:String},description:{type:String,nullable:!0},dbDatabase:{type:String},dbSchema:{type:String,nullable:!0},allowInsert:{type:Boolean,default:!1},allowUpdate:{type:Boolean,default:!1},lastInspected:{type:T,nullable:!0,default:null},status:{type:String,nullable:!0}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"datasources",joinColumn:!0},inspections:{type:"one-to-many",target:()=>"DatabaseInspection",inverseSide:"datasource"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"dataSource"},owner:{type:"many-to-one",target:()=>"User",joinColumn:!0}}});var Ae=A(require("node:os")),Oe=require("node:path");var Ne=require("typeorm");var ue=new Ne.EntitySchema({name:"Query",tableName:"query",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},opts:{type:"json",default:"{}"},isTrash:{type:Boolean,default:!1,nullable:!0},createdAt:{type:T,default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:T,default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"queries",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",inverseSide:"datasources",joinColumn:!0}}});var Ie=require("typeorm"),ce=new Ie.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"}}});function Gt(){let e=m.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>",Ae.default.homedir())),e}var S=new Ce.DataSource({type:m.str("APP_DB_TYPE"),database:Gt(),host:m.str("APP_DB_HOST"),username:m.str("APP_DB_USERNAME"),password:m.str("APP_DB_PASSWORD"),port:m.num("APP_DB_PORT"),schema:m.str("APP_DB_SCHEMA"),logging:m.bool("APP_DB_LOGGING"),migrationsRun:!0,migrations:[Oe.posix.join(__dirname,"migrations","*.js")],entities:[oe,ie,ae,ne,ce,se,ue]}),_e=async()=>{if(!S.isInitialized)return S.initialize();throw new Error("Already initialized")},_=S.getRepository(oe),f=S.getRepository(ie),U=S.getRepository(ae),h=S.getRepository(ne),I=S.getRepository(ce),L=S.getRepository(se),C=S.getRepository(ue);var me=A(require("node:fs/promises")),Pe=require("node:path"),De=A(require("node:os")),Kt=De.default.homedir(),Ue=(0,Pe.join)(Kt,".dataramen",".runtime","files"),xe=async()=>{await jt()||await me.default.mkdir(Ue,{recursive:!0})};async function jt(){try{return(await me.default.lstat(Ue)).isDirectory()}catch{return!1}}var R=e=>(t,r,o)=>{e(t),o()};var F=require("jose");var Me=new TextEncoder,ve=Me.encode(m.str("JWT_SECRET")),Le=Me.encode(m.str("JWT_REFRESH_SECRET")),le=async({userId:e})=>new F.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("1h").sign(ve),de=async({userId:e})=>new F.SignJWT({sub:e}).setProtectedHeader({alg:"HS256"}).setExpirationTime("10d").sign(Le),qe=async(e,t)=>{try{let{payload:r}=await(0,F.jwtVerify)(e,t);if(!r.sub)throw new s(401,"Failed to verify access token");return{userId:r.sub}}catch(r){throw r instanceof s?r:r instanceof Error?new s(401,r.message):new s(401,"Failed to verify refresh token")}},Fe=async e=>qe(e,ve),Qe=async e=>qe(e,Le);var y=(e,t)=>{let r=e.body;return t&&t(r),r},x=(e,t)=>{let r=e.query;return t&&t(r),r},b=(e,t)=>{let r=e.params;return t&&t(r),r};var Be=A(require("bcryptjs"));var ke=e=>{if(!e?.username)throw new s(400,"Username is required");if(!e?.password)throw new s(400,"Password is required")};var W="DATARAMEN_refresh_token",pe={httpOnly:!0,secure:m.bool("PROD"),sameSite:m.bool("PROD"),path:"/",maxAge:10*24*60*60},$e=R(e=>{e.route({method:"post",url:"/login",config:{isPublic:!0},handler:async(t,r)=>{let{username:o,password:a}=y(t,ke),n=await h.findOne({where:{username:o}});if(!n||!Be.default.compareSync(a,n.password))throw new s(401,"Invalid credentials");let[i,u]=await Promise.all([le({userId:n?.id}),de({userId:n?.id})]);return r.setCookie(W,u,pe),{data:{accessToken:i}}}}),e.route({method:"post",url:"/refresh",config:{isPublic:!0},handler:async(t,r)=>{let o=t.cookies[W];if(!o)return r.code(401).send({message:"Missing refresh token"});let{userId:a}=await Qe(o),[n,i]=await Promise.all([le({userId:a}),de({userId:a})]);return r.setCookie(W,i,pe),{data:{accessToken:n}}}}),e.route({method:"post",url:"/logout",config:{isPublic:!0},handler:async(t,r)=>(r.clearCookie(W,pe),{data:!0})})});var He=e=>{if(!e.dbUrl)throw new s(400,"url is required");if(!e.dbUser)throw new s(400,"user is required");if(!e.dbType)throw new s(400,"type is required");if(!e.name)throw new s(400,"name is required");if(!e.dbDatabase)throw new s(400,"database is required")};var Ge=A(require("mysql2/promise"));var Wt=({database:e,password:t,user:r,url:o})=>Ge.default.createConnection({host:o,user:r,database:e,password:t}),Vt=async e=>{let t=`
2
2
  SELECT 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=a.TABLE_NAME,i=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(i)}),o},Yt=async e=>{let t=`
6
+ `,[r]=await e.execute(t),o={};return r.forEach(a=>{let n=a.TABLE_NAME,i=a.COLUMN_NAME;o[n]||(o[n]=[]),o[n].push(i)}),o},Jt=async e=>{let t=`
7
7
  SELECT
8
8
  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},Gt=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await Yt(t),n=await Ht(t),i=o.map(async u=>{let m=Object.values(u)[0],c=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and table_name = '${m}'`,[T]=await t.query(c),g=a[m];return{columns:T.map(p=>({name:p.COLUMN_NAME,type:p.DATA_TYPE,isPrimary:n[m]?.includes(p.COLUMN_NAME),ref:g?.[p.COLUMN_NAME]?{table:g[p.COLUMN_NAME].refTable,field:g[p.COLUMN_NAME].refField}:void 0})).sort((p,h)=>p.isPrimary&&h.isPrimary?p.name.localeCompare(h.name):p.isPrimary?-1:1),createdAt:new Date,tableName:m,updatedAt:new Date}});return Promise.all(i)},ke=async(e,t,r)=>{try{console.log(`[MYSQL CONN] Query: ${e}`);let[o,a]=await t.query({sql:e,rowsAsArray:!0}),n=o?.constructor?.name;if(n==="ResultSetHeader"){let i=o;if(i.affectedRows>1&&r.allowBulkUpdate!==!0)throw new Error("[MYSQL CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i.affectedRows]],query:e}}else if(n==="Array"){let i=o;return{columns:a?.map(u=>({column:u.orgName||u.name,table:u.orgTable,alias:u.name,full:u.orgTable?u.orgTable+"."+u.orgName:u.name}))||[],rows:i,query:e}}throw new Error(`[MYSQL CONN] Unknown result type: ${n}`)}catch(o){throw console.error(o),o instanceof s?o:new s(400,o.message)}},jt=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}},Kt=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}},Be=async e=>{let t=await $t(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>Gt(e,t),executeQuery:(o,a)=>a.type==="SELECT"?Kt(t,()=>ke(o,t,a)):jt(t,()=>ke(o,t,a)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var He=O(require("pg"));var Wt=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new He.default.Client({host:o,user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},Vt=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},zt=async(e,t)=>{let o=(await t.query("SHOW TABLES"))[0],a=await Jt(t),n=await Vt(t),i=o.map(async u=>{let l=Object.values(u)[0],c=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${e.database}' and table_name = '${l}'`,[g]=await t.query(c),w=a[l];return{columns:g.map(p=>({name:p.COLUMN_NAME,type:p.DATA_TYPE,isPrimary:n[l]?.includes(p.COLUMN_NAME),ref:w?.[p.COLUMN_NAME]?{table:w[p.COLUMN_NAME].refTable,field:w[p.COLUMN_NAME].refField}:void 0})).sort((p,E)=>p.isPrimary&&E.isPrimary?p.name.localeCompare(E.name):p.isPrimary?-1:1),createdAt:new Date,tableName:l,updatedAt:new Date}});return Promise.all(i)},Ye=async(e,t,r)=>{try{console.log(`[MYSQL CONN] Query: ${e}`);let[o,a]=await t.query({sql:e,rowsAsArray:!0}),n=o?.constructor?.name;if(n==="ResultSetHeader"){let i=o;if(i.affectedRows>1&&r.allowBulkUpdate!==!0)throw new Error("[MYSQL CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i.affectedRows]],query:e}}else if(n==="Array"){let i=o;return{columns:a?.map(u=>({column:u.orgName||u.name,table:u.orgTable,alias:u.name,full:u.orgTable?u.orgTable+"."+u.orgName:u.name}))||[],rows:i,query:e}}throw new Error(`[MYSQL CONN] Unknown result type: ${n}`)}catch(o){throw console.error(o),o instanceof s?o:new s(400,o.message)}},Xt=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}},Zt=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}},Ke=async e=>{let t=await Wt(e),r=!1;return{dbType:"mysql",dataSource:e,inspectSchema:()=>zt(e,t),executeQuery:(o,a)=>a.type==="SELECT"?Zt(t,()=>Ye(o,t,a)):Xt(t,()=>Ye(o,t,a)),checkConnection:async()=>t.ping(),isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.destroy()}}};var We=A(require("pg"));var er=async({database:e,password:t,user:r,url:o,port:a})=>{let n=new We.default.Client({host:o,user:r,database:e,password:t,port:a,query_timeout:1e4});return await n.connect(),n},tr=async e=>{let r=await e.query(`
18
18
  SELECT
19
19
  kcu.table_name,
20
20
  kcu.column_name,
@@ -28,7 +28,7 @@
28
28
  tc.constraint_type = 'PRIMARY KEY'
29
29
  ORDER BY
30
30
  kcu.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},zt=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},rr=async e=>{let r=await e.query(`
32
32
  SELECT
33
33
  tc.table_name AS table_name,
34
34
  kcu.column_name AS field,
@@ -43,15 +43,15 @@
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},Jt=async(e,t)=>{let r=`SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = '${e.schema}'`,a=(await t.query(r)).rows,n=await zt(t),i=await Vt(t),u=a.map(async m=>{let c=Object.values(m)[0],T=`
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},or=async(e,t)=>{let r=`SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = '${e.schema}'`,a=(await t.query(r)).rows,n=await rr(t),i=await tr(t),u=a.map(async l=>{let c=Object.values(l)[0],g=`
47
47
  SELECT column_name, data_type
48
48
  FROM information_schema.columns
49
49
  WHERE
50
50
  table_name = '${c}' and
51
51
  table_schema = '${e.schema}'
52
- `,{rows:g}=await t.query(T),p=n[c];return{columns:g.map(h=>({name:h.column_name,type:h.data_type,isPrimary:i[c]?.includes(h.column_name),ref:p?.[h.column_name]?{table:p[h.column_name].refTable,field:p[h.column_name].refField}:void 0})).sort((h,b)=>h.isPrimary&&b.isPrimary?h.name.localeCompare(b.name):h.isPrimary?-1:1),createdAt:new Date,tableName:c,updatedAt:new Date}});return Promise.all(u)},Xt=async(e,t)=>{let r=`select relname, attname, concat(pg_class.oid, '-', attnum) as row_key
52
+ `,{rows:w}=await t.query(g),p=n[c];return{columns:w.map(E=>({name:E.column_name,type:E.data_type,isPrimary:i[c]?.includes(E.column_name),ref:p?.[E.column_name]?{table:p[E.column_name].refTable,field:p[E.column_name].refField}:void 0})).sort((E,N)=>E.isPrimary&&N.isPrimary?E.name.localeCompare(N.name):E.isPrimary?-1:1),createdAt:new Date,tableName:c,updatedAt:new Date}});return Promise.all(u)},ar=async(e,t)=>{let r=`select 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 25;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},$e=async(e,t,r)=>{try{console.log(`[PG CONN] Query: ${e}`);let{rows:o,fields:a,command:n,rowCount:i}=await t.query({text:e,rowMode:"array"});if(n==="UPDATE"||n==="INSERT"||n==="DELETE"){if(i!=null&&i>1&&r.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i]],query:e}}if(n==="SELECT"){let u=a.map(c=>`'${c.tableID}-${c.columnID}'`),m=await Xt(u,t);return{columns:a.map(c=>{let T=m[`${c.tableID}-${c.columnID}`];return{column:T?.column||c.name,alias:c.name,table:T?.table||"",full:T?T.table+"."+T.column:c.name}}),rows:o,query:e}}throw new Error(`[PG CONN] Unsupported command: ${n}`)}catch(o){throw o instanceof s?o:new s(400,o.message)}},Zt=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}},er=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}},Ye=async e=>{let t=await Wt(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:()=>Jt(e,t),executeQuery:(n,i)=>a(()=>i.type==="SELECT"?er(t,()=>$e(n,t,i)):Zt(t,()=>$e(n,t,i))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var M=async(e,t,r)=>{try{let o;if(t==="mysql")o=await Be(e);else if(t==="postgres")o=await Ye(e);else throw new s(500,`Connection manager for ${t} not found`);return r.__connections?r.__connections.push(o):r.__connections=[o],o}catch(o){throw console.error(o),o instanceof s?o:o?.code==="ECONNREFUSED"?new s(500,"Failed to connect to the database"):new s(500,o.message)}};var K=O(require("node:crypto"));var Ge="aes-256-gcm",tr=12,je=()=>{let e=l.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},rr=e=>{let t=K.default.randomBytes(tr),r=je(),o=K.default.createCipheriv(Ge,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")}},or=({encrypted:e,iv:t,tag:r})=>{let o=je(),a=K.default.createDecipheriv(Ge,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},W={encrypt:rr,decrypt:or};var v=(e,t=!1)=>{if(t){let r=W.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 C=(...e)=>(t,r,o)=>{if(!e.includes(t.user.currentTeamRole))throw new s(403,"You are not authorized to perform this action");o()};var Ke=E(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=N(t),o=await f.findOne({where:{id:r}});if(!o)throw new s(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=Q(t);return{data:await f.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",preHandler:[C("admin")],handler:async t=>{let{teamId:r,ownerId:o,...a}=w(t,Fe),n=f.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),i=await M(v(n),n.dbType,t);try{await i.checkConnection()}catch{throw new s(400,"Cannot connect to the database, please check datasource configuration")}let{tag:u,iv:m,encrypted:c}=W.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=m,n.dbPasswordTag=u,{data:await f.save(n)}}}),e.route({method:"put",url:"/:id",preHandler:[C("admin")],handler:async t=>{let{id:r}=N(t),o=w(t),a=await f.findOneBy({id:r});if(!a)throw new s(404,"Data source not found");let n=f.merge(a,o);return await f.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",preHandler:[C("admin")],handler:async(t,r)=>S.transaction(async()=>{let{id:o}=N(t);await Promise.all([_.delete({datasource:{id:o}}),I.delete({dataSource:{id:o}})]),await f.delete({id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=N(t),a=await f.findOne({where:{id:o},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!a)throw new Error("Data source not found");a.status="INSPECTING",await f.save(a);let i=await(await M(v(a,!0),a.dbType,t)).inspectSchema();await _.delete({datasource:{id:o}}),await _.insert(i.sort().map(u=>_.create({tableName:u.tableName,columns:u.columns,datasource:{id:o}}))),a.status="READY",a.lastInspected=new Date,await f.save(a)}}),e.route({method:"get",url:"/:id/inspections",handler:async(t,r)=>{let{id:o}=N(t);return{data:await _.find({where:{datasource:{id:o}}})}}})});var me=require("typeorm"),We=E(e=>{e.route({method:"get",url:"/team/:teamId/files",handler:async(t,r)=>{let{teamId:o}=N(t),a={where:{team:{id:o}},order:{name:"ASC"},select:{id:!0,name:!0,updatedAt:!0}},[n=[],i=[]]=await Promise.all([f.find(a),I.find({...a,where:{...a.where,isTrash:!1}})]);return{data:[...n.map(u=>({...u,type:"dataSource"})),...i.map(u=>({...u,type:"query"}))]}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=N(t),{search:o,size:a}=Q(t),n=(parseInt(a)||20)/2,[i,u]=await Promise.all([_.find({where:{tableName:(0,me.Like)(`%${o}%`),datasource:{team:{id:r}}},relations:{datasource:!0},select:{id:!0,tableName:!0,datasource:{name:!0,id:!0}},order:{tableName:"ASC"},take:n}),I.find({where:{name:(0,me.Like)(`%${o}%`),isTrash:!1,dataSource:{team:{id:r}}},relations:{dataSource:!0},select:{id:!0,name:!0,dataSource:{name:!0,id:!0}},order:{name:"ASC"},take:n})]),m=[];return i.forEach(c=>{m.push({name:c.tableName,id:c.id,dataSourceName:c.datasource?.name||"--",dataSourceId:c.datasource?.id||"--",type:"table"})}),u.forEach(c=>{m.push({name:c.name,id:c.id,dataSourceName:c.dataSource?.name||"--",dataSourceId:c.dataSource?.id||"--",type:"query"})}),{data:m}}})});function Ve(e,t=void 0){try{if(e){let r=e.split("&"),o={};for(let a of r){let n=a.split(":");o[n[0]]=n[1]}return o}}catch{}return t}var ze=require("typeorm");var Je=E(e=>{e.route({method:"get",url:"/",handler:async t=>{let{dataSourceId:r,teamId:o,limit:a,orderBy:n,name:i}=Q(t);if(!r&&!o)throw new s(400,"Either dsId or teamId is required");let u={isTrash:!1};return r&&(u.dataSource={id:r}),o&&(u.team={id:o}),i&&(u.name=(0,ze.Like)(`%${i}%`)),{data:await I.find({where:u,take:a,order:Ve(n,{createdAt:"DESC"})})}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=N(t),o=await I.findOne({where:{id:r},select:{dataSource:{id:!0}},relations:{dataSource:!0}});return o?{data:o}:{status:404,data:"Query not found"}}}),e.route({method:"post",url:"/",preHandler:[C("admin","editor")],handler:async t=>{let r=w(t),o=await f.findOne({where:{id:r.dataSourceId},relations:{team:!0}}),a=await I.save(I.create({name:r.name,isTrash:!1,opts:r.opts,team:{id:o?.team.id},dataSource:{id:r.dataSourceId}}));return console.log("Created query!"),{data:a}}}),e.route({method:"patch",url:"/:id",preHandler:[C("admin","editor")],handler:async t=>{let{id:r}=N(t),o=w(t);if(!(await I.update(r,o)).affected)throw new s(404,"Query not found");return{data:await I.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",preHandler:[C("admin","editor")],handler:async t=>S.transaction(async()=>{let{id:r}=N(t);if(!(await I.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var V=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},q={YEAR:e=>`EXTRACT(YEAR FROM ${e.value})`,MONTH:e=>`EXTRACT(MONTH FROM ${e.value})`,DAY:e=>`EXTRACT(DAY FROM ${e.value})`,SUM:e=>`COALESCE(SUM(${e.distinct===!0?"distinct ":""}${e.value}), 0)`,AVG:V,MAX:V,MIN:V,COUNT:V};var z=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},B={YEAR:e=>`YEAR(${e.value})`,MONTH:e=>`MONTH(${e.value})`,DAY:e=>`DAY(${e.value})`,SUM:e=>{let t=e.distinct===!0?"distinct ":"";return`coalesce(${e.fn}(${t}${e.value}), 0)`},AVG:z,MAX:z,MIN:z,COUNT:z};var Xe=["SUM","COUNT","AVG","MAX","MIN"],ar=["YEAR","MONTH","DAY",...Xe],nr=ar.reduce((e,t)=>(e[t]=!0,e),{}),sr=Xe.reduce((e,t)=>(e[t]=!0,e),{}),J=e=>nr[e],Ze=e=>sr[e],et=(e,t)=>e.fn&&J(e.fn)?(t==="postgres"?q:B)[e.fn](e):e.value;var X=e=>typeof e=="string",tt=e=>{let t="SELECT ";if(e.columns&&e.columns.length>0?t+=e.columns.join(", "):t+="*",e.table&&(t+=` FROM ${e.table}`),e.joins&&e.joins.length>0&&e.joins.forEach(r=>{t+=` ${r.type} JOIN ${r.table} ON ${r.on}`}),e.where&&(t+=` WHERE ${e.where}`),e.groupBy&&e.groupBy.length>0&&(t+=` GROUP BY ${e.groupBy.join(", ")}`),e.having&&(t+=` HAVING ${e.having}`),e.orderBy&&e.orderBy.length>0){let r=e.orderBy.reduce((a,n)=>(a[n.column]=n.direction,a),{}),o=Object.entries(r).map(([a,n])=>`${a} ${n}`);t+=` ORDER BY ${o.join(", ")}`}return e.limit!==void 0&&(t+=` LIMIT ${e.limit}`),e.offset!==void 0&&(t+=` OFFSET ${e.offset}`),t},$=(e,t)=>{let{column:r,operator:o,value:a,fn:n}=e,i=et({value:r,fn:n},t);switch(o){case"IS NULL":case"IS NOT NULL":return`${i} ${o}`;case"IN":case"NOT IN":let u=a?.map(p=>X(p.value)?`'${p.value}'`:p.value).join(", ");return`${i} ${o} (${u})`;case"LIKE":return`${i} ${t==="postgres"?"ILIKE":"LIKE"} '%${a?.[0].value}%'`;case"NOT LIKE":return`${i} ${t==="postgres"?"NOT ILIKE":"LIKE"} '%${a?.[0].value}%'`;default:let T=a?.[0],g;return X(T?.value)&&T?.isColumn!==!0?g=`'${T?.value}'`:g=T?.value,`${i} ${o} ${g}`}};var Z=class{constructor(t="mysql"){this.dialect=t,this.skeleton={type:"SELECT"}}addWhere(t){let r=$(t,this.dialect);if(this.skeleton.where){let o=t.connector||"AND";this.skeleton.where+=` ${o} ${r}`}else this.skeleton.where=r;return this}addWhereRaw(t,r="AND"){return this.skeleton.where?this.skeleton.where+=` ${r} ${t}`:this.skeleton.where=t,this}clearWhere(){return this.skeleton.where=void 0,this}addHaving(t){let r=$(t,this.dialect);if(this.skeleton.having){let o=t.connector||"AND";this.skeleton.having+=` ${o} ${r}`}else this.skeleton.having=r;return this}clearHaving(){return this.skeleton.having=void 0,this}addOrderBy(...t){return this.skeleton.orderBy||(this.skeleton.orderBy=[]),this.skeleton.orderBy.push(...t),this}clearOrderBy(){return this.skeleton.orderBy=void 0,this}setLimit(t){return this.skeleton.limit=t,this}setOffset(t){return this.skeleton.offset=t,this}addGroupBy(t){this.skeleton.groupBy||(this.skeleton.groupBy=[]);let r=this.skeleton.groupBy.findIndex(o=>o===t);return r>-1?this.skeleton.groupBy[r]=t:this.skeleton.groupBy.push(t),this}setTable(t){return this.skeleton.table=t,this}addJoin(...t){return this.skeleton.joins||(this.skeleton.joins=[]),this.skeleton.joins.push(...t),this}selectColumns(t){if(this.skeleton.type!=="SELECT")throw new Error("Column selection is only supported for SELECT queries");return this.skeleton.columns=t,this}toSQL(){return tt(this.skeleton)}};var nt=require("typeorm");var rt=[{value:"=",label:"equals"},{value:"<>",label:"not equal"},{value:">",label:"greater than"},{value:">=",label:"greater than or equal"},{value:"<",label:"less than"},{value:"<=",label:"less than or equal"},{value:"LIKE",label:"contains"},{value:"NOT LIKE",label:"not contains"},{value:"IN",label:"in list"},{value:"NOT IN",label:"not in list"},{value:"IS NULL",label:"is null"},{value:"IS NOT NULL",label:"is not null"}],ir=rt.reduce((e,t)=>(e[t.value]=t.label,e),{}),Sa=rt.reduce((e,t)=>(e[t.label]=t.value,e),{}),F=e=>e.map(t=>({label:ir[t],value:t})),ba=F(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),Ra=F(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL"]),Ia=F(["=","<>","IS NULL","IS NOT NULL"]),Na=F(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),Ca=F(["IS NULL","IS NOT NULL"]),Aa=F(["IN","NOT IN"]);var ot=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"];var Oa=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var at=e=>e.fn?e.distinct===!0?`${e.fn} distinct ${e.value}`:`${e.fn} ${e.value}`:e.value;var st=async(e,{table:t,datasourceId:r,filters:o,joins:a,orderBy:n,size:i,page:u,columns:m,groupBy:c,searchAll:T})=>{let g=await f.findOne({where:{id:r},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]}),p=[t],h=[];if(!g)throw new s(404,"Data source not found");let b=new Z(g.dbType);b.setTable(t),b.setLimit(i||20),b.setOffset(i*u),o?.forEach(d=>{d.fn&&Ze(d.fn)?b.addHaving(d):b.addWhere(d)}),a&&(b.addJoin(...a),a.forEach(d=>{p.push(d.table)})),n&&b.addOrderBy(...n.map(d=>({...d,column:mr(d.column,g.dbType)}))),c&&c.length>0&&c.forEach(d=>b.addGroupBy(lr(d,g.dbType)));let Ct=await _.find({where:{tableName:(0,nt.In)(p),datasource:{id:r}}});for(let d of Ct)if(d.columns)for(let U of d.columns)h.push({column:U.name,table:d.tableName||"",full:`${d.tableName}.${U.name}`,type:U.type});let H;if(m&&m.length>0?H=m.map(d=>cr(d,g.dbType)):H=h.map(d=>`${d.full} as "${d.full}"`),b.selectColumns(H),T){let d=h.filter(U=>ot.includes(U.type)&&H.some(ee=>ee.startsWith(U.full)));if(d.length>0){let U=d.map(ee=>`LOWER(${ee.full}) LIKE '%${T.toLowerCase()}%'`);b.addWhereRaw(`(${U.join(" OR ")})`,"AND")}}return{...await(await M(v(g,!0),g.dbType,e)).executeQuery(b.toSQL(),{type:"SELECT",allowBulkUpdate:!1}),tables:p,allColumns:h}},it=async(e,t)=>{let r=await f.findOne({where:{id:t.datasourceId},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate"]});if(!r)throw new s(404,"Data source not found");if(!r.allowUpdate)throw new s(403,"This datasource does not allow update operations");let o=t.values.map(({value:u,column:m})=>typeof u=="string"?u&&u.startsWith("=")?`${m}=${u.substring(1)}`:`${m}='${u}'`:`${m}='${u}'`).join(", "),a=t.filters.map(u=>$(u,r.dbType)).join(" AND "),n=`UPDATE ${t.table} SET ${o} WHERE ${a}`;return(await M(v(r,!0),r.dbType,e)).executeQuery(n,{type:"UPDATE",allowBulkUpdate:!1})},ut=async(e,t)=>{let r=await f.findOne({where:{id:t.datasourceId},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowInsert"]});if(!r)throw new s(404,"Data source not found");if(!r.allowInsert)throw new s(403,"This datasource does not allow insert operations");let{keys:o,values:a}=ur(t.values),n=`INSERT INTO ${t.table} (${o}) VALUES (${a})`;return(await M(v(r,!0),r.dbType,e)).executeQuery(n,{type:"INSERT",allowBulkUpdate:!1})},ur=e=>{let t=e.map(({column:o})=>o).join(", "),r=e.map(({value:o})=>typeof o=="string"?o&&o.startsWith("=")?o.substring(1):`'${o}'`:o).join(", ");return{keys:t,values:r}},cr=(e,t)=>{if(e.fn){if(J(e.fn))return`${(t==="postgres"?q:B)[e.fn](e)} as "${at(e)}"`;throw new Error("Function not allowed: "+e.fn)}return`${e.value} as "${e.value}"`},lr=(e,t)=>{if(e.fn){if(J(e.fn))return(t==="postgres"?q:B)[e.fn](e);throw new Error("Function not allowed: "+e.fn)}return e.value},mr=(e,t)=>t==="postgres"?`"${e}"`:t==="mysql"?`\`${e}\``:e;var ct=e=>{if(!e.table)throw new s(400,"Table is required")},dr=["--",";","DROP","drop"],lt=e=>{if(X(e.value)&&e.value.startsWith("=")){let t=e.value;dr.forEach(r=>{if(t.includes(r))throw new s(400,"Invalid input value for "+e.column)})}},mt=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(lt)},dt=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(lt)};var pt=E(e=>{e.route({method:"post",url:"/select",handler:async t=>{let r=w(t,ct);return{data:await st(t,r)}}}),e.route({method:"post",url:"/insert",preHandler:[C("admin","editor")],handler:async t=>{let r=w(t,mt);return{data:await ut(t,r)}}}),e.route({method:"post",url:"/update",preHandler:[C("admin","editor")],handler:async t=>{let r=w(t,dt);return{data:await it(t,r)}}})});var ft=E(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:l.str("SERVER_VERSION")}}))});var yt=E(e=>{e.route({method:"get",url:"/",handler:async(t,r)=>{let o=t.user.id;return{data:await x.find({where:{users:{user:{id:o}}}})}}}),e.route({method:"post",url:"/",preHandler:[C("admin","editor")],handler:async t=>S.transaction(async()=>{let r=t.user.id,o=w(t),a=R.create();a.id=r;let n=x.create(o);await x.save(n);let i=D.create({user:a,team:n});return await D.save(i),{data:n}})})});var Tt=E(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=await R.findOne({where:{id:t.user.id},relations:{currentTeam:{team:!0}}});if(!r)throw new s(404,"User not found");return{data:{id:r.id,teamId:r.currentTeam?.team.id,teamName:r.currentTeam?.team.name,teamRole:r.currentTeam?.role}}}}),e.route({method:"patch",url:"/",handler:async t=>{let r=t.user.id,o=w(t);if(!(await R.update(r,o)).affected)throw new s(404,"User not found");let n=await R.findOne({where:{id:r},relations:{currentTeam:{team:!0}}});return{data:{id:n?.id,teamId:n?.currentTeam?.team.id,teamName:n?.currentTeam?.team.name,teamRole:n?.currentTeam?.role}}}}),e.route({method:"put",url:"/team",handler:async t=>{let r=t.user.id,o=w(t),a=await D.findOneBy({user:{id:r},team:{id:o.teamId}});if(!a)throw new s(404,"User - Team association not found");await R.update(r,{currentTeam:a});let n=await R.findOne({where:{id:r},relations:{currentTeam:{team:!0}}});return{data:{id:n?.id,teamId:n?.currentTeam?.team.id,teamName:n?.currentTeam?.team.name,teamRole:n?.currentTeam?.role}}}})});var gt=E(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await L.findOneBy({user:{id:r}});return o||(o=await L.save(L.create({user:{id:r},model:"gpt-4o"}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=w(t);if(!r.id)throw new s(400,"Settings id is required!");if(!(await L.update(r.id,r)).affected)throw new s(404,"You do not own these settings!");return{data:await L.findOneBy({id:r.id})}}})});var Rt=require("node:path");var pr=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),ht=async e=>{if(pr(e))return;let t=e.headers.authorization;if(!t)throw new s(401,"Missing auth token");let[r,o]=t.split(" ");try{let{userId:a}=await Me(o),n=await D.findOneBy({user:{id:a}});if(!n)throw new s(401,"User is not part of a team");e.user={id:a,currentTeamRole:n.role}}catch{throw new s(401,"Unauthorized")}};var Et=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var It=O(require("@fastify/cookie")),A=(0,wt.default)(),Nt=l.num("PORT",4466),fr=l.bool("HOST")?"0.0.0.0":"127.0.0.1",yr=l.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),Tr=["https://app.dataramen.xyz","https://dataramen.xyz",`http://localhost:${Nt}`,...yr];function P(e,t){A.register(e,{prefix:t}),console.log("Registered "+t)}(async function(){fe(),await _e(),await A.register(It.default,{}),await A.register(St.default,{origin:(t,r)=>{!t||Tr.includes(t)?r(null,!0):r(new Error("Not allowed by CORS"),!1)},methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),await A.register(bt.default,{root:(0,Rt.join)(__dirname,"web")}),A.get("/",(t,r)=>{r.sendFile("index.html")}),A.addHook("onRequest",ht),A.addHook("onResponse",Et),P(Qe,"/api/auth"),P(Ke,"/api/data-sources"),P(We,"/api/project"),P(Je,"/api/queries"),P(pt,"/api/runner"),P(ft,"/api/status"),P(yt,"/api/teams"),P(Tt,"/api/users"),P(gt,"/api/user-settings"),A.setNotFoundHandler((t,r)=>{if(t.raw.url?.startsWith("/api/")){r.code(404).send({error:"API route not found"});return}r.sendFile("index.html")}),A.setErrorHandler((t,r,o)=>{if(t instanceof s){console.error(t),o.status(t.status).send({error:t.message});return}else console.error(t),o.status(500).send({error:"Internal Server Error"})}),await A.after(),await Ne(),A.listen({port:Nt,host:fr},(t,r)=>{t&&(console.error(t),process.exit(1)),console.log(`Server listening at ${r}`)})})();
57
+ limit 25;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},je=async(e,t,r)=>{try{console.log(`[PG CONN] Query: ${e}`);let{rows:o,fields:a,command:n,rowCount:i}=await t.query({text:e,rowMode:"array"});if(n==="UPDATE"||n==="INSERT"||n==="DELETE"){if(i!=null&&i>1&&r.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[i]],query:e}}if(n==="SELECT"){let u=a.map(c=>`'${c.tableID}-${c.columnID}'`),l=await ar(u,t);return{columns:a.map(c=>{let g=l[`${c.tableID}-${c.columnID}`];return{column:g?.column||c.name,alias:c.name,table:g?.table||"",full:g?g.table+"."+g.column:c.name}}),rows:o,query:e}}throw new Error(`[PG CONN] Unsupported command: ${n}`)}catch(o){throw o instanceof s?o:new s(400,o.message)}},nr=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}},sr=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 er(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:()=>or(e,t),executeQuery:(n,i)=>a(()=>i.type==="SELECT"?sr(t,()=>je(n,t,i)):nr(t,()=>je(n,t,i))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var M=async(e,t,r)=>{try{let o;if(t==="mysql")o=await Ke(e);else if(t==="postgres")o=await Ve(e);else throw new s(500,`Connection manager for ${t} not found`);return r.__connections?r.__connections.push(o):r.__connections=[o],o}catch(o){throw console.error(o),o instanceof s?o:o?.code==="ECONNREFUSED"?new s(500,"Failed to connect to the database"):new s(500,o.message)}};var V=A(require("node:crypto"));var Je="aes-256-gcm",ir=12,ze=()=>{let e=m.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},ur=e=>{let t=V.default.randomBytes(ir),r=ze(),o=V.default.createCipheriv(Je,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")}},cr=({encrypted:e,iv:t,tag:r})=>{let o=ze(),a=V.default.createDecipheriv(Je,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},J={encrypt:ur,decrypt:cr};var v=(e,t=!1)=>{if(t){let r=J.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 Xe=R(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=b(t),o=await f.findOne({where:{id:r}});if(!o)throw new s(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=x(t);return{data:await f.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:["admin"]},handler:async t=>{let{teamId:r,ownerId:o,...a}=y(t,He),n=f.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),i=await M(v(n),n.dbType,t);try{await i.checkConnection()}catch{throw new s(400,"Cannot connect to the database, please check datasource configuration")}let{tag:u,iv:l,encrypted:c}=J.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=l,n.dbPasswordTag=u,{data:await f.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:["admin"]},handler:async t=>{let{id:r}=b(t),o=y(t),a=await f.findOneBy({id:r});if(!a)throw new s(404,"Data source not found");let n=f.merge(a,o);return await f.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:["admin"]},handler:async(t,r)=>S.transaction(async()=>{let{id:o}=b(t);await Promise.all([_.delete({datasource:{id:o}}),C.delete({dataSource:{id:o}})]),await f.delete({id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=b(t),a=await f.findOne({where:{id:o},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!a)throw new Error("Data source not found");a.status="INSPECTING",await f.save(a);let i=await(await M(v(a,!0),a.dbType,t)).inspectSchema();await _.delete({datasource:{id:o}}),await _.insert(i.sort().map(u=>_.create({tableName:u.tableName,columns:u.columns,datasource:{id:o}}))),a.status="READY",a.lastInspected=new Date,await f.save(a)}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=b(t);return{data:await _.find({where:{datasource:{id:r}}})}}})});var fe=require("typeorm"),Ze=R(e=>{e.route({method:"get",url:"/team/:teamId/files",handler:async(t,r)=>{let{teamId:o}=b(t),a={where:{team:{id:o}},order:{name:"ASC"},select:{id:!0,name:!0,updatedAt:!0}},[n=[],i=[]]=await Promise.all([f.find(a),C.find({...a,where:{...a.where,isTrash:!1}})]);return{data:[...n.map(u=>({...u,type:"dataSource"})),...i.map(u=>({...u,type:"query"}))]}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=b(t),{search:o,size:a}=x(t),n=(parseInt(a)||20)/2,[i,u]=await Promise.all([_.find({where:{tableName:(0,fe.Like)(`%${o}%`),datasource:{team:{id:r}}},relations:{datasource:!0},select:{id:!0,tableName:!0,datasource:{name:!0,id:!0}},order:{tableName:"ASC"},take:n}),C.find({where:{name:(0,fe.Like)(`%${o}%`),isTrash:!1,dataSource:{team:{id:r}}},relations:{dataSource:!0},select:{id:!0,name:!0,dataSource:{name:!0,id:!0}},order:{name:"ASC"},take:n})]),l=[];return i.forEach(c=>{l.push({name:c.tableName,id:c.id,dataSourceName:c.datasource?.name||"--",dataSourceId:c.datasource?.id||"--",type:"table"})}),u.forEach(c=>{l.push({name:c.name,id:c.id,dataSourceName:c.dataSource?.name||"--",dataSourceId:c.dataSource?.id||"--",type:"query"})}),{data:l}}})});function et(e,t=void 0){try{if(e){let r=e.split("&"),o={};for(let a of r){let n=a.split(":");o[n[0]]=n[1]}return o}}catch{}return t}var tt=require("typeorm"),rt=R(e=>{e.route({method:"get",url:"/",handler:async t=>{let{dataSourceId:r,teamId:o,limit:a,orderBy:n,name:i}=x(t);if(!r&&!o)throw new s(400,"Either dsId or teamId is required");let u={isTrash:!1};return r&&(u.dataSource={id:r}),o&&(u.team={id:o}),i&&(u.name=(0,tt.Like)(`%${i}%`)),{data:await C.find({where:u,take:a,order:et(n,{createdAt:"DESC"})})}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=b(t),o=await C.findOne({where:{id:r},select:{dataSource:{id:!0}},relations:{dataSource:!0}});return o?{data:o}:{status:404,data:"Query not found"}}}),e.route({method:"post",url:"/",config:{requireRole:["admin","editor"]},handler:async t=>{let r=y(t),o=await f.findOne({where:{id:r.dataSourceId},relations:{team:!0}}),a=await C.save(C.create({name:r.name,isTrash:!1,opts:r.opts,team:{id:o?.team.id},dataSource:{id:r.dataSourceId}}));return console.log("Created query!"),{data:a}}}),e.route({method:"patch",url:"/:id",config:{requireRole:["admin","editor"]},handler:async t=>{let{id:r}=b(t),o=y(t);if(!(await C.update(r,o)).affected)throw new s(404,"Query not found");return{data:await C.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:["admin","editor"]},handler:async t=>S.transaction(async()=>{let{id:r}=b(t);if(!(await C.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var z=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},k={YEAR:e=>`EXTRACT(YEAR FROM ${e.value})`,MONTH:e=>`EXTRACT(MONTH FROM ${e.value})`,DAY:e=>`EXTRACT(DAY FROM ${e.value})`,SUM:e=>`COALESCE(SUM(${e.distinct===!0?"distinct ":""}${e.value}), 0)`,AVG:z,MAX:z,MIN:z,COUNT:z};var X=e=>{let t=e.distinct===!0?"distinct ":"";return`${e.fn}(${t}${e.value})`},B={YEAR:e=>`YEAR(${e.value})`,MONTH:e=>`MONTH(${e.value})`,DAY:e=>`DAY(${e.value})`,SUM:e=>{let t=e.distinct===!0?"distinct ":"";return`coalesce(${e.fn}(${t}${e.value}), 0)`},AVG:X,MAX:X,MIN:X,COUNT:X};var ot=["SUM","COUNT","AVG","MAX","MIN"],mr=["YEAR","MONTH","DAY",...ot],lr=mr.reduce((e,t)=>(e[t]=!0,e),{}),dr=ot.reduce((e,t)=>(e[t]=!0,e),{}),Z=e=>lr[e],at=e=>dr[e],nt=(e,t)=>e.fn&&Z(e.fn)?(t==="postgres"?k:B)[e.fn](e):e.value;var ee=e=>typeof e=="string",st=e=>{let t="SELECT ";if(e.columns&&e.columns.length>0?t+=e.columns.join(", "):t+="*",e.table&&(t+=` FROM ${e.table}`),e.joins&&e.joins.length>0&&e.joins.forEach(r=>{t+=` ${r.type} JOIN ${r.table} ON ${r.on}`}),e.where&&(t+=` WHERE ${e.where}`),e.groupBy&&e.groupBy.length>0&&(t+=` GROUP BY ${e.groupBy.join(", ")}`),e.having&&(t+=` HAVING ${e.having}`),e.orderBy&&e.orderBy.length>0){let r=e.orderBy.reduce((a,n)=>(a[n.column]=n.direction,a),{}),o=Object.entries(r).map(([a,n])=>`${a} ${n}`);t+=` ORDER BY ${o.join(", ")}`}return e.limit!==void 0&&(t+=` LIMIT ${e.limit}`),e.offset!==void 0&&(t+=` OFFSET ${e.offset}`),t},$=(e,t)=>{let{column:r,operator:o,value:a,fn:n}=e,i=nt({value:r,fn:n},t);switch(o){case"IS NULL":case"IS NOT NULL":return`${i} ${o}`;case"IN":case"NOT IN":let u=a?.map(p=>ee(p.value)?`'${p.value}'`:p.value).join(", ");return`${i} ${o} (${u})`;case"LIKE":return`${i} ${t==="postgres"?"ILIKE":"LIKE"} '%${a?.[0].value}%'`;case"NOT LIKE":return`${i} ${t==="postgres"?"NOT ILIKE":"LIKE"} '%${a?.[0].value}%'`;default:let g=a?.[0],w;return ee(g?.value)&&g?.isColumn!==!0?w=`'${g?.value}'`:w=g?.value,`${i} ${o} ${w}`}};var te=class{constructor(t="mysql"){this.dialect=t,this.skeleton={type:"SELECT"}}addWhere(t){let r=$(t,this.dialect);if(this.skeleton.where){let o=t.connector||"AND";this.skeleton.where+=` ${o} ${r}`}else this.skeleton.where=r;return this}addWhereRaw(t,r="AND"){return this.skeleton.where?this.skeleton.where+=` ${r} ${t}`:this.skeleton.where=t,this}clearWhere(){return this.skeleton.where=void 0,this}addHaving(t){let r=$(t,this.dialect);if(this.skeleton.having){let o=t.connector||"AND";this.skeleton.having+=` ${o} ${r}`}else this.skeleton.having=r;return this}clearHaving(){return this.skeleton.having=void 0,this}addOrderBy(...t){return this.skeleton.orderBy||(this.skeleton.orderBy=[]),this.skeleton.orderBy.push(...t),this}clearOrderBy(){return this.skeleton.orderBy=void 0,this}setLimit(t){return this.skeleton.limit=t,this}setOffset(t){return this.skeleton.offset=t,this}addGroupBy(t){this.skeleton.groupBy||(this.skeleton.groupBy=[]);let r=this.skeleton.groupBy.findIndex(o=>o===t);return r>-1?this.skeleton.groupBy[r]=t:this.skeleton.groupBy.push(t),this}setTable(t){return this.skeleton.table=t,this}addJoin(...t){return this.skeleton.joins||(this.skeleton.joins=[]),this.skeleton.joins.push(...t),this}selectColumns(t){if(this.skeleton.type!=="SELECT")throw new Error("Column selection is only supported for SELECT queries");return this.skeleton.columns=t,this}toSQL(){return st(this.skeleton)}};var mt=require("typeorm");var it=[{value:"=",label:"equals"},{value:"<>",label:"not equal"},{value:">",label:"greater than"},{value:">=",label:"greater than or equal"},{value:"<",label:"less than"},{value:"<=",label:"less than or equal"},{value:"LIKE",label:"contains"},{value:"NOT LIKE",label:"not contains"},{value:"IN",label:"in list"},{value:"NOT IN",label:"not in list"},{value:"IS NULL",label:"is null"},{value:"IS NOT NULL",label:"is not null"}],pr=it.reduce((e,t)=>(e[t.value]=t.label,e),{}),_a=it.reduce((e,t)=>(e[t.label]=t.value,e),{}),q=e=>e.map(t=>({label:pr[t],value:t})),Pa=q(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),Da=q(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL"]),Ua=q(["=","<>","IS NULL","IS NOT NULL"]),xa=q(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),Ma=q(["IS NULL","IS NOT NULL"]),va=q(["IN","NOT IN"]);var ut=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"];var La=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var ct=e=>e.fn?e.distinct===!0?`${e.fn} distinct ${e.value}`:`${e.fn} ${e.value}`:e.value;var lt=async(e,{table:t,datasourceId:r,filters:o,joins:a,orderBy:n,size:i,page:u,columns:l,groupBy:c,searchAll:g})=>{let w=await f.findOne({where:{id:r},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]}),p=[t],E=[];if(!w)throw new s(404,"Data source not found");let N=new te(w.dbType);N.setTable(t),N.setLimit(i||20),N.setOffset(i*u),o?.forEach(d=>{d.fn&&at(d.fn)?N.addHaving(d):N.addWhere(d)}),a&&(N.addJoin(...a),a.forEach(d=>{p.push(d.table)})),n&&N.addOrderBy(...n.map(d=>({...d,column:hr(d.column,w.dbType)}))),c&&c.length>0&&c.forEach(d=>N.addGroupBy(Tr(d,w.dbType)));let xt=await _.find({where:{tableName:(0,mt.In)(p),datasource:{id:r}}});for(let d of xt)if(d.columns)for(let D of d.columns)E.push({column:D.name,table:d.tableName||"",full:`${d.tableName}.${D.name}`,type:D.type});let G;if(l&&l.length>0?G=l.map(d=>yr(d,w.dbType)):G=E.map(d=>`${d.full} as "${d.full}"`),N.selectColumns(G),g){let d=E.filter(D=>ut.includes(D.type)&&G.some(re=>re.startsWith(D.full)));if(d.length>0){let D=d.map(re=>`LOWER(${re.full}) LIKE '%${g.toLowerCase()}%'`);N.addWhereRaw(`(${D.join(" OR ")})`,"AND")}}return{...await(await M(v(w,!0),w.dbType,e)).executeQuery(N.toSQL(),{type:"SELECT",allowBulkUpdate:!1}),tables:p,allColumns:E}},dt=async(e,t)=>{let r=await f.findOne({where:{id:t.datasourceId},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate"]});if(!r)throw new s(404,"Data source not found");if(!r.allowUpdate)throw new s(403,"This datasource does not allow update operations");let o=t.values.map(({value:u,column:l})=>typeof u=="string"?u&&u.startsWith("=")?`${l}=${u.substring(1)}`:`${l}='${u}'`:`${l}='${u}'`).join(", "),a=t.filters.map(u=>$(u,r.dbType)).join(" AND "),n=`UPDATE ${t.table} SET ${o} WHERE ${a}`;return(await M(v(r,!0),r.dbType,e)).executeQuery(n,{type:"UPDATE",allowBulkUpdate:!1})},pt=async(e,t)=>{let r=await f.findOne({where:{id:t.datasourceId},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowInsert"]});if(!r)throw new s(404,"Data source not found");if(!r.allowInsert)throw new s(403,"This datasource does not allow insert operations");let{keys:o,values:a}=fr(t.values),n=`INSERT INTO ${t.table} (${o}) VALUES (${a})`;return(await M(v(r,!0),r.dbType,e)).executeQuery(n,{type:"INSERT",allowBulkUpdate:!1})},fr=e=>{let t=e.map(({column:o})=>o).join(", "),r=e.map(({value:o})=>typeof o=="string"?o&&o.startsWith("=")?o.substring(1):`'${o}'`:o).join(", ");return{keys:t,values:r}},yr=(e,t)=>{if(e.fn){if(Z(e.fn))return`${(t==="postgres"?k:B)[e.fn](e)} as "${ct(e)}"`;throw new Error("Function not allowed: "+e.fn)}return`${e.value} as "${e.value}"`},Tr=(e,t)=>{if(e.fn){if(Z(e.fn))return(t==="postgres"?k:B)[e.fn](e);throw new Error("Function not allowed: "+e.fn)}return e.value},hr=(e,t)=>t==="postgres"?`"${e}"`:t==="mysql"?`\`${e}\``:e;var ft=e=>{if(!e.table)throw new s(400,"Table is required")},gr=["--",";","DROP","drop"],yt=e=>{if(ee(e.value)&&e.value.startsWith("=")){let t=e.value;gr.forEach(r=>{if(t.includes(r))throw new s(400,"Invalid input value for "+e.column)})}},Tt=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(yt)},ht=e=>{if(!e.table)throw new s(400,"Table is required");e.values.forEach(yt)};var gt=R(e=>{e.route({method:"post",url:"/select",handler:async t=>{let r=y(t,ft);return{data:await lt(t,r)}}}),e.route({method:"post",url:"/insert",config:{requireRole:["admin","editor"]},handler:async t=>{let r=y(t,Tt);return{data:await pt(t,r)}}}),e.route({method:"post",url:"/update",config:{requireRole:["admin","editor"]},handler:async t=>{let r=y(t,ht);return{data:await dt(t,r)}}})});var wt=R(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:m.str("SERVER_VERSION")}}))});var Et=R(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=b(t),o=await U.findOne({where:{id:r},relations:{users:{user:!0}}});if(!o)throw new s(404,"Team not found");return{data:o.users.map(a=>({role:a.role,id:a.user.id,name:a.user.username}))}}}),e.route({method:"post",url:"/",config:{requireRole:["admin","editor"]},handler:async t=>S.transaction(async()=>{let r=t.user.id,o=y(t),a=h.create();a.id=r;let n=U.create(o);await U.save(n);let i=I.create({user:a,team:n});return await I.save(i),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:["admin"]},handler:async t=>{let{id:r}=b(t),{role:o,userId:a}=y(t);await I.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:["admin"]},handler:async t=>S.transaction(async()=>{let{id:r}=b(t),{userId:o}=x(t);await h.update(o,{currentTeam:null}),await I.delete({user:{id:o},team:{id:r}}),await h.delete({id:r})})})});var ye=A(require("bcryptjs")),H=async e=>{let t=await ye.default.genSalt(10);return ye.default.hash(e,t)};var St=R(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=await h.findOne({where:{id:t.user.id},relations:{currentTeam:{team:!0}}});if(!r)throw new s(404,"User not found");return{data:{id:r.id,teamId:r.currentTeam?.team.id,teamName:r.currentTeam?.team.name,teamRole:r.currentTeam?.role,username:r.username}}}}),e.route({method:"patch",url:"/",handler:async t=>{let r=t.user.id,o=y(t);if(o.password&&(o.password=await H(o.password)),!(await h.update(r,o)).affected)throw new s(404,"User not found");let n=await h.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:"/",handler:async t=>S.transaction(async()=>{let r=y(t),o=await H(r.password),a=await h.save(h.create({username:r.username,password:o})),n=await I.save(I.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await h.update(a.id,{currentTeam:{id:n.id}})})})});var Rt=R(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await L.findOneBy({user:{id:r}});return o||(o=await L.save(L.create({user:{id:r}}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=y(t);if(!r.id)throw new s(400,"Settings id is required!");if(!(await L.update(r.id,r)).affected)throw new s(404,"You do not own these settings!");return{data:await L.findOneBy({id:r.id})}}})});var Pt=require("node:path");var wr=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),bt=async e=>{if(wr(e))return;let t=e.headers.authorization;if(!t)throw new s(401,"Missing auth token");let[r,o]=t.split(" ");try{let{userId:a}=await Fe(o),n=await I.findOneBy({user:{id:a}});if(!n)throw new s(401,"User is not part of a team");e.user={id:a,currentTeamRole:n.role}}catch{throw new s(401,"Unauthorized")}};var Nt=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Dt=A(require("@fastify/cookie"));var Y={teamName:"Default Team",username:"admin",password:"admin"},Er=async()=>{let e=await U.findOne({});return e||U.save(U.create({name:Y.teamName}))},It=async()=>{let e=await h.findOne({where:{username:Y.username}});if(e)return e;let t=await Er(),r=await H(Y.password),o=await h.save(h.create({username:Y.username,password:r})),a=await I.save(I.create({user:o,team:t,role:"admin"}));return await h.update(o.id,{currentTeam:a}),h.findOne({where:{username:Y.username}})};var Ct=async e=>{let t=e.routeOptions.config.requireRole;if(t&&!t.includes(e.user.currentTeamRole))throw new s(403,"You are not authorized to perform this action")};var O=(0,At.default)(),Ut=m.num("PORT",4466),Sr=m.bool("HOST")?"0.0.0.0":"127.0.0.1",Rr=m.str("ALLOWED_ORIGINS","").split(",").map(e=>e.trim()),br=["https://app.dataramen.xyz","https://dataramen.xyz",`http://localhost:${Ut}`,...Rr];function P(e,t){O.register(e,{prefix:t}),console.log("Registered "+t)}(async function(){ge(),await xe(),await O.register(Dt.default,{}),await O.register(Ot.default,{origin:(t,r)=>{!t||br.includes(t)?r(null,!0):r(new Error("Not allowed by CORS"),!1)},methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),await O.register(_t.default,{root:(0,Pt.join)(__dirname,"web")}),O.get("/",(t,r)=>{r.sendFile("index.html")}),O.addHook("onRequest",bt),O.addHook("onRequest",Ct),O.addHook("onResponse",Nt),P($e,"/api/auth"),P(Xe,"/api/data-sources"),P(Ze,"/api/project"),P(rt,"/api/queries"),P(gt,"/api/runner"),P(wt,"/api/status"),P(Et,"/api/teams"),P(St,"/api/users"),P(Rt,"/api/user-settings"),O.setNotFoundHandler((t,r)=>{if(t.raw.url?.startsWith("/api/")){r.code(404).send({error:"API route not found"});return}r.sendFile("index.html")}),O.setErrorHandler((t,r,o)=>{if(console.error(t),t instanceof s){o.status(t.status).send({error:t.message});return}else o.status(500).send({error:"Internal Server Error"})}),await O.after(),await _e(),await It(),O.listen({port:Ut,host:Sr},(t,r)=>{t&&(console.error(t),process.exit(1)),console.log(`Server listening at ${r}`)})})();