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