@dataramen/cli 0.0.14 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/README.md +1 -1
- package/dist/code/proxy.js +5 -5
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 🍜 Data Ramen CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Your cozy corner for exploring and working with SQL databases — no query writing required (unless you want to).
|
|
4
4
|
|
|
5
5
|
Data Ramen CLI lets you launch a powerful, local database exploration app that connects effortlessly to MySQL and PostgreSQL databases. Browse schemas, follow relationships, insert data, and even write raw SQL — all from your browser.
|
|
6
6
|
|
package/dist/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 🍜 Data Ramen CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Your cozy corner for exploring and working with SQL databases — no query writing required (unless you want to).
|
|
4
4
|
|
|
5
5
|
Data Ramen CLI lets you launch a powerful, local database exploration app that connects effortlessly to MySQL and PostgreSQL databases. Browse schemas, follow relationships, insert data, and even write raw SQL — all from your browser.
|
|
6
6
|
|
package/dist/code/proxy.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var ot=Object.create;var re=Object.defineProperty;var nt=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var ut=Object.getPrototypeOf,ct=Object.prototype.hasOwnProperty;var Q=(a,e)=>()=>(e||a((e={exports:{}}).exports,e),e.exports);var dt=(a,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of it(e))!ct.call(a,s)&&s!==t&&re(a,s,{get:()=>e[s],enumerable:!(r=nt(e,s))||r.enumerable});return a};var O=(a,e,t)=>(t=a!=null?ot(ut(a)):{},dt(e||!a||!a.__esModule?re(t,"default",{value:a,enumerable:!0}):t,a));var ke=Q(De=>{"use strict";Object.defineProperty(De,"__esModule",{value:!0})});var qe=Q(W=>{"use strict";Object.defineProperty(W,"__esModule",{value:!0});W.isString=void 0;var Pt=a=>typeof a=="string";W.isString=Pt});var Le=Q(D=>{"use strict";Object.defineProperty(D,"__esModule",{value:!0});D.SQLManipulator=D.SQLBuilder=D.SQLParser=void 0;var Me=qe(),j=class{constructor(e="mysql"){this.dialect=e}parse(e){let r=e.trim().replace(/;$/,"").replace(/\s+/g," "),s=r.toUpperCase(),o;if(s.startsWith("SELECT"))o=this.parseSelect(r);else if(s.startsWith("INSERT"))o=this.parseInsert(r);else if(s.startsWith("UPDATE"))o=this.parseUpdate(r);else if(s.startsWith("DELETE"))o=this.parseDelete(r);else throw new Error("Unsupported SQL statement type");return o.parameters=this.extractParameters(r),o}extractParameters(e){let t=/:(\w+)/g,r=[],s;for(;(s=t.exec(e))!==null;){let o=s[1];r.includes(o)||r.push(o)}return r}parseSelect(e){let t={type:"SELECT"},{cleanedSQL:r,subqueries:s}=this.extractSubqueries(e),o=r.match(/SELECT\s+(.*?)\s+FROM/i);if(o){let p=o[1].trim();t.columns=p==="*"?["*"]:this.parseColumns(p)}let n=r.match(/FROM\s+([^\s]+)(?:\s|$)/i);if(n&&(t.table=n[1]),!t.table){let p=r.match(/FROM\s+([^\s]+)(?:\s+(?:AS\s+)?([^\s]+))?(?:\s+(?:WHERE|JOIN|INNER|LEFT|RIGHT|FULL|GROUP|ORDER|LIMIT|OFFSET|HAVING)|$)/i);p&&(t.table=p[1])}t.joins=this.parseJoins(r);let u=r.match(/WHERE\s+(.*?)(?:\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/i);u&&(t.where=this.restoreSubqueries(u[1].trim(),s));let i=r.match(/ORDER\s+BY\s+(.*?)(?:\s+LIMIT|\s+OFFSET|$)/i);i&&(t.orderBy=this.parseOrderBy(i[1]));let d=r.match(/GROUP\s+BY\s+(.*?)(?:\s+HAVING|\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/i);d&&(t.groupBy=this.parseColumns(d[1]));let l=r.match(/HAVING\s+(.*?)(?:\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/i);l&&(t.having=this.restoreSubqueries(l[1].trim(),s));let T=r.match(/LIMIT\s+(\d+)/i);T&&(t.limit=parseInt(T[1]));let m=r.match(/OFFSET\s+(\d+)/i);return m&&(t.offset=parseInt(m[1])),t}parseColumns(e){let t=[],r="",s=!1,o="",n=0;for(let u=0;u<e.length;u++){let i=e[u];!s&&(i==='"'||i==="'")?(s=!0,o=i,r+=i):s&&i===o?u+1<e.length&&e[u+1]===o?(r+=i+i,u++):(s=!1,o="",r+=i):!s&&i==="("?(n++,r+=i):!s&&i===")"?(n--,r+=i):!s&&i===","&&n===0?(t.push(r.trim()),r=""):r+=i}return r.trim()&&t.push(r.trim()),t}extractSubqueries(e){let t=new Map,r=e,s=0,o=/\(([^()]*(?:SELECT|INSERT|UPDATE|DELETE)[^()]*(?:\([^()]*\)[^()]*)*)\)/gi,n=!0;for(;n;)n=!1,r=r.replace(o,(u,i)=>{if(/\b(SELECT|INSERT|UPDATE|DELETE)\b/i.test(i)){let d=`__SUBQUERY_${s}__`;return t.set(d,u),s++,n=!0,d}return u});return{cleanedSQL:r,subqueries:t}}restoreSubqueries(e,t){let r=e;return t.forEach((s,o)=>{r=r.replace(new RegExp(o,"g"),s)}),r}parseJoins(e){let t=[],r=/((?:INNER|LEFT|RIGHT|FULL)?\s*JOIN)\s+(\w+(?:\s+\w+)?)\s+ON\s+(.*?)(?=\s+(?:INNER|LEFT|RIGHT|FULL)?\s*JOIN|\s+WHERE|\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/gi,s;for(;(s=r.exec(e))!==null;){let o=s[1].trim().toUpperCase(),n=s[2].trim(),u=s[3].trim(),i=n.split(/\s+/),d=i[0],l=i.length>1?i[1]:void 0,T;o.includes("LEFT")?T="LEFT":o.includes("RIGHT")?T="RIGHT":o.includes("FULL")?T="FULL":T="INNER",t.push({type:T,table:d,alias:l,on:u})}return t.length>0?t:[]}parseInsert(e){let t={type:"INSERT"},r=e.match(/INSERT\s+INTO\s+(\w+)\s*\(([^)]+(?:\([^)]*\)[^)]*)*)\)\s*VALUES\s*\((.+)\)\s*;?$/i);return r&&(t.table=r[1],t.columns=this.parseColumns(r[2]),t.values=this.parseColumns(r[3])),t}parseUpdate(e){let t={type:"UPDATE"},r=e.match(/UPDATE\s+(\w+)\s+SET\s+(.*?)(?:\s+WHERE|$)/i);r&&(t.table=r[1],t.set=this.parseSetClause(r[2]));let s=e.match(/WHERE\s+(.*?)$/i);return s&&(t.where=s[1].trim()),t}parseDelete(e){let t={type:"DELETE"},r=e.match(/DELETE\s+FROM\s+(\w+)(?:\s+WHERE\s+(.*?))?$/i);return r&&(t.table=r[1],r[2]&&(t.where=r[2].trim())),t}parseOrderBy(e){return e.split(",").map(r=>{let s=r.trim().split(" "),o=s.pop();return o==="DESC"||o==="desc"?{column:s.join(" "),direction:"DESC"}:o==="ASC"||o==="asc"?{column:s.join(" "),direction:"ASC"}:{column:s.join(" ")+" "+o,direction:"ASC"}})}parseSetClause(e){let t={};return this.parseColumns(e).forEach(s=>{let o=s.indexOf("=");if(o>0){let n=s.substring(0,o).trim(),u=s.substring(o+1).trim();t[n]=u}}),t}};D.SQLParser=j;var F=class{constructor(e,t="mysql"){this.parsed={...e},this.dialect=t}build(){switch(this.parsed.type){case"SELECT":return this.buildSelect();case"INSERT":return this.buildInsert();case"UPDATE":return this.buildUpdate();case"DELETE":return this.buildDelete();default:throw new Error("Unsupported SQL type")}}buildSelect(){let e="SELECT ";if(this.parsed.columns&&this.parsed.columns.length>0?e+=this.parsed.columns.join(", "):e+="*",this.parsed.table&&(e+=` FROM ${this.parsed.table}`),this.parsed.joins&&this.parsed.joins.length>0&&this.parsed.joins.forEach(t=>{e+=` ${t.type} JOIN ${t.table} ON ${t.on}`}),this.parsed.where&&(e+=` WHERE ${this.parsed.where}`),this.parsed.groupBy&&this.parsed.groupBy.length>0&&(e+=` GROUP BY ${this.parsed.groupBy.join(", ")}`),this.parsed.having&&(e+=` HAVING ${this.parsed.having}`),this.parsed.orderBy&&this.parsed.orderBy.length>0){let t=this.parsed.orderBy.reduce((s,o)=>(s[o.column]=o.direction,s),{}),r=Object.entries(t).map(([s,o])=>`${s} ${o}`);e+=` ORDER BY ${r.join(", ")}`}return this.parsed.limit!==void 0&&(e+=` LIMIT ${this.parsed.limit}`),this.parsed.offset!==void 0&&(this.dialect==="mysql"?e+=` OFFSET ${this.parsed.offset}`:e+=` OFFSET ${this.parsed.offset}`),e}buildInsert(){if(!this.parsed.table||!this.parsed.columns||!this.parsed.values)throw new Error("Invalid INSERT statement data");let e=this.parsed.columns.join(", "),t=this.parsed.values.join(", ");return`INSERT INTO ${this.parsed.table} (${e}) VALUES (${t})`}buildUpdate(){if(!this.parsed.table||!this.parsed.set)throw new Error("Invalid UPDATE statement data");let e=Object.entries(this.parsed.set).map(([r,s])=>`${r} = ${s}`),t=`UPDATE ${this.parsed.table} SET ${e.join(", ")}`;return this.parsed.where&&(t+=` WHERE ${this.parsed.where}`),t}buildDelete(){if(!this.parsed.table)throw new Error("Invalid DELETE statement data");let e=`DELETE FROM ${this.parsed.table}`;return this.parsed.where&&(e+=` WHERE ${this.parsed.where}`),e}};D.SQLBuilder=F;var te=class{constructor(e="mysql",t){this.dialect=e,this.parser=new j(e),this.parsed=t==="SELECT"?{type:"SELECT"}:this.parser.parse(t),this.parameters={}}setParameter(e,t){return this.parameters[e]=t,this}setParameters(e){return this.parameters={...this.parameters,...e},this}getParameter(e){return this.parameters[e]}getParameters(){return{...this.parameters}}clearParameters(){return this.parameters={},this}getRequiredParameters(){return this.parsed.parameters||[]}getMissingParameters(){let e=this.getRequiredParameters(),t=Object.keys(this.parameters);return e.filter(r=>!t.includes(r))}addWhereWithParam(e,t,r,s="AND"){let o=this.buildWhereConditionWithParam(e,t,r);return this.parsed.where?this.parsed.where+=` ${s} ${o}`:this.parsed.where=o,this.parsed.parameters||(this.parsed.parameters=[]),this.parsed.parameters.includes(r)||this.parsed.parameters.push(r),this}addWhere(e){let t=this.buildWhereCondition(e);if(this.parsed.where){let r=e.connector||"AND";this.parsed.where+=` ${r} ${t}`}else this.parsed.where=t;return this}addWhereRaw(e,t="AND"){return this.parsed.where?this.parsed.where+=` ${t} ${e}`:this.parsed.where=e,this}clearWhere(){return this.parsed.where=void 0,this}addOrderBy(...e){return this.parsed.orderBy||(this.parsed.orderBy=[]),this.parsed.orderBy.push(...e),this}clearOrderBy(){return this.parsed.orderBy=void 0,this}setLimit(e){return this.parsed.limit=e,this}setOffset(e){return this.parsed.offset=e,this}addGroupBy(e){this.parsed.groupBy||(this.parsed.groupBy=[]);let t=this.parsed.groupBy.findIndex(r=>r===e);return t>-1?this.parsed.groupBy[t]=e:this.parsed.groupBy.push(e),this}setHaving(e){return this.parsed.having=e,this}setTable(e){return this.parsed.table=e,this}addJoin(...e){if(this.parsed.type!=="SELECT")throw new Error("JOIN operations are only supported for SELECT queries");return this.parsed.joins||(this.parsed.joins=[]),this.parsed.joins.push(...e),this}selectColumns(e){if(this.parsed.type!=="SELECT")throw new Error("Column selection is only supported for SELECT queries");return this.parsed.columns=e,this}toSQL(e=!1,t=!1){let s=new F(this.parsed,this.dialect).build();return e&&(s=this.substituteParameters(s)),t&&(s+=";"),s}toParameterizedSQL(e=!1){let r=new F(this.parsed,this.dialect).build();return e?r+";":r}toExecutableSQL(e=!1){return this.toSQL(!0,e)}substituteParameters(e){let t=e;return Object.entries(this.parameters).forEach(([r,s])=>{let o=new RegExp(`:${r}\\b`,"g"),n=this.formatParameterValue(s);t=t.replace(o,n)}),t}formatParameterValue(e){return e==null?"NULL":typeof e=="string"?e:typeof e=="boolean"?this.dialect==="postgres"?e?"TRUE":"FALSE":e?"1":"0":Array.isArray(e)?`(${e.map(r=>this.formatParameterValue(r)).join(", ")})`:e instanceof Date?`'${e.toISOString().slice(0,19).replace("T"," ")}'`:String(e)}buildWhereConditionWithParam(e,t,r){switch(t){case"IS NULL":case"IS NOT NULL":return`${e} ${t}`;case"IN":case"NOT IN":return`${e} ${t} :${r}`;default:return`${e} ${t} :${r}`}}getParsed(){return{...this.parsed}}buildWhereCondition(e){let{column:t,operator:r,value:s}=e;switch(r){case"IS NULL":case"IS NOT NULL":return`${t} ${r}`;case"IN":case"NOT IN":let o=s?.map(i=>(0,Me.isString)(i)?`'${i}'`:i).join(", ");return`${t} ${r} (${o})`;default:let n=s?.[0],u;return(0,Me.isString)(n?.value)&&n?.isColumn!==!0?u=`'${n?.value}'`:u=n?.value,`${t} ${r} ${u}`}}};D.SQLManipulator=te});var xe=Q(k=>{"use strict";var Ot=k&&k.__createBinding||(Object.create?function(a,e,t,r){r===void 0&&(r=t);var s=Object.getOwnPropertyDescriptor(e,t);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(a,r,s)}:function(a,e,t,r){r===void 0&&(r=t),a[r]=e[t]}),Ue=k&&k.__exportStar||function(a,e){for(var t in a)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Ot(e,a,t)};Object.defineProperty(k,"__esModule",{value:!0});Ue(ke(),k);Ue(Le(),k)});var v=require("dotenv"),$=require("node:path"),ae=require("node:fs"),mt=(()=>{try{let a=(0,ae.readFileSync)((0,$.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(a)}catch{return{version:"0.0.0"}}})();(0,v.config)({path:[(0,$.join)(__dirname,"..","env",".env"),(0,$.join)(__dirname,"..","env",".env.default")]});(0,v.populate)(process.env,{SERVER_VERSION:mt.version});var tt=O(require("fastify")),rt=O(require("@fastify/cors"));var c=class extends Error{constructor(t,r){super(r);this.status=t;this.message=r}};var me=require("typeorm");var se=require("typeorm"),H=new se.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 oe=require("typeorm"),Y=new oe.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:"many-to-many",target:()=>"User",inverseSide:"teams"},workbooks:{type:"one-to-many",target:()=>"Workbook",inverseSide:"team"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"team"},datasources:{type:"one-to-many",target:()=>"DataSource",inverseSide:"team"}}});var ne=require("typeorm"),G=new ne.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:"many-to-many",target:()=>"Team",inverseSide:"users",joinTable:!0},settings:{type:"one-to-one",target:()=>"UserSettings",inverseSide:"user",joinColumn:!0},currentTeam:{type:"many-to-one",target:()=>"Team",joinColumn:!0}}});var ie=require("typeorm"),V=new ie.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},openAiToken:{type:String,nullable:!0},model:{type:String,default:"gpt-3.5-turbo"},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 ue=require("typeorm"),z=new ue.EntitySchema({name:"Workbook",tableName:"workbooks",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},path:{type:"uuid",generated:"uuid"},isTrash:{type:"boolean",default:!1},createdAt:{type:"datetime",default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:"datetime",default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"workbooks",joinColumn:!0}}});var ce=require("typeorm"),K=new ce.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},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},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 pe=O(require("os"));var de=require("typeorm"),J=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:"workbooks",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",inverseSide:"queries",joinColumn:!0}}});function pt(){let a=process.env.TYPEORM_DATABASE;if(!a)throw new Error("Bad value for TYPEORM_DATABASE. Please check your config!");return a.startsWith("<home>")&&(a=a.replace("<home>",pe.default.homedir())),a}var E=new me.DataSource({type:process.env.TYPEORM_CONNECTION,database:pt(),synchronize:process.env.TYPEORM_SYNCHRONIZE==="true",host:process.env.TYPEORM_HOST,username:process.env.TYPEORM_USERNAME,password:process.env.TYPEORM_PASSWORD,port:process.env.TYPEORM_PORT?parseInt(process.env.TYPEORM_PORT):void 0,logging:process.env.TYPEORM_LOGGING==="true",entities:[H,K,Y,G,V,z,J]}),le=async()=>{if(!E.isInitialized)return E.initialize();throw new Error("Already initialized")},C=E.getRepository(H),g=E.getRepository(K),q=E.getRepository(Y),I=E.getRepository(G),P=E.getRepository(V),S=E.getRepository(z),b=E.getRepository(J);var x=O(require("node:fs/promises")),Z=require("node:path"),fe=O(require("node:os")),lt=fe.default.homedir(),X=(0,Z.join)(lt,".dataramen",".runtime","files"),ye=a=>(0,Z.join)(X,a),he=async a=>x.default.readFile(ye(a),{encoding:"utf8"}),ge=async(a,e)=>x.default.writeFile(ye(a),e,{encoding:"utf8"});var Te=async()=>{await ft()||await x.default.mkdir(X,{recursive:!0})};async function ft(){try{return(await x.default.lstat(X)).isDirectory()}catch{return!1}}var f=a=>(e,t,r)=>{a(e),r()};var Ee=f(a=>{a.post("/workbook",async e=>({data:""}))});var y=(a,e)=>{let t=a.body;return e&&e(t),t},N=(a,e)=>{let t=a.query;return e&&e(t),t},h=(a,e)=>{let t=a.params;return e&&e(t),t};var _=a=>a.headers["phoenix-user-id"];var we=a=>{if(!a.dbUrl)throw new c(400,"url is required");if(!a.dbUser)throw new c(400,"user is required");if(!a.dbType)throw new c(400,"type is required");if(!a.name)throw new c(400,"name is required");if(!a.dbDatabase)throw new c(400,"database is required")};var be=O(require("mysql2/promise"));var ht=({dbDatabase:a,dbPassword:e,dbUser:t,dbUrl:r})=>be.default.createConnection({host:r,user:t,database:a,password:e}),gt=async a=>{let e=`
|
|
1
|
+
"use strict";var ot=Object.create;var ae=Object.defineProperty;var nt=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var ut=Object.getPrototypeOf,ct=Object.prototype.hasOwnProperty;var Q=(a,e)=>()=>(e||a((e={exports:{}}).exports,e),e.exports);var dt=(a,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of it(e))!ct.call(a,s)&&s!==t&&ae(a,s,{get:()=>e[s],enumerable:!(r=nt(e,s))||r.enumerable});return a};var N=(a,e,t)=>(t=a!=null?ot(ut(a)):{},dt(e||!a||!a.__esModule?ae(t,"default",{value:a,enumerable:!0}):t,a));var qe=Q(ke=>{"use strict";Object.defineProperty(ke,"__esModule",{value:!0})});var Me=Q(W=>{"use strict";Object.defineProperty(W,"__esModule",{value:!0});W.isString=void 0;var Pt=a=>typeof a=="string";W.isString=Pt});var Ue=Q(D=>{"use strict";Object.defineProperty(D,"__esModule",{value:!0});D.SQLManipulator=D.SQLBuilder=D.SQLParser=void 0;var Le=Me(),j=class{constructor(e="mysql"){this.dialect=e}parse(e){let r=e.trim().replace(/;$/,"").replace(/\s+/g," "),s=r.toUpperCase(),o;if(s.startsWith("SELECT"))o=this.parseSelect(r);else if(s.startsWith("INSERT"))o=this.parseInsert(r);else if(s.startsWith("UPDATE"))o=this.parseUpdate(r);else if(s.startsWith("DELETE"))o=this.parseDelete(r);else throw new Error("Unsupported SQL statement type");return o.parameters=this.extractParameters(r),o}extractParameters(e){let t=/:(\w+)/g,r=[],s;for(;(s=t.exec(e))!==null;){let o=s[1];r.includes(o)||r.push(o)}return r}parseSelect(e){let t={type:"SELECT"},{cleanedSQL:r,subqueries:s}=this.extractSubqueries(e),o=r.match(/SELECT\s+(.*?)\s+FROM/i);if(o){let m=o[1].trim();t.columns=m==="*"?["*"]:this.parseColumns(m)}let n=r.match(/FROM\s+([^\s]+)(?:\s|$)/i);if(n&&(t.table=n[1]),!t.table){let m=r.match(/FROM\s+([^\s]+)(?:\s+(?:AS\s+)?([^\s]+))?(?:\s+(?:WHERE|JOIN|INNER|LEFT|RIGHT|FULL|GROUP|ORDER|LIMIT|OFFSET|HAVING)|$)/i);m&&(t.table=m[1])}t.joins=this.parseJoins(r);let u=r.match(/WHERE\s+(.*?)(?:\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/i);u&&(t.where=this.restoreSubqueries(u[1].trim(),s));let i=r.match(/ORDER\s+BY\s+(.*?)(?:\s+LIMIT|\s+OFFSET|$)/i);i&&(t.orderBy=this.parseOrderBy(i[1]));let d=r.match(/GROUP\s+BY\s+(.*?)(?:\s+HAVING|\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/i);d&&(t.groupBy=this.parseColumns(d[1]));let l=r.match(/HAVING\s+(.*?)(?:\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/i);l&&(t.having=this.restoreSubqueries(l[1].trim(),s));let T=r.match(/LIMIT\s+(\d+)/i);T&&(t.limit=parseInt(T[1]));let p=r.match(/OFFSET\s+(\d+)/i);return p&&(t.offset=parseInt(p[1])),t}parseColumns(e){let t=[],r="",s=!1,o="",n=0;for(let u=0;u<e.length;u++){let i=e[u];!s&&(i==='"'||i==="'")?(s=!0,o=i,r+=i):s&&i===o?u+1<e.length&&e[u+1]===o?(r+=i+i,u++):(s=!1,o="",r+=i):!s&&i==="("?(n++,r+=i):!s&&i===")"?(n--,r+=i):!s&&i===","&&n===0?(t.push(r.trim()),r=""):r+=i}return r.trim()&&t.push(r.trim()),t}extractSubqueries(e){let t=new Map,r=e,s=0,o=/\(([^()]*(?:SELECT|INSERT|UPDATE|DELETE)[^()]*(?:\([^()]*\)[^()]*)*)\)/gi,n=!0;for(;n;)n=!1,r=r.replace(o,(u,i)=>{if(/\b(SELECT|INSERT|UPDATE|DELETE)\b/i.test(i)){let d=`__SUBQUERY_${s}__`;return t.set(d,u),s++,n=!0,d}return u});return{cleanedSQL:r,subqueries:t}}restoreSubqueries(e,t){let r=e;return t.forEach((s,o)=>{r=r.replace(new RegExp(o,"g"),s)}),r}parseJoins(e){let t=[],r=/((?:INNER|LEFT|RIGHT|FULL)?\s*JOIN)\s+(\w+(?:\s+\w+)?)\s+ON\s+(.*?)(?=\s+(?:INNER|LEFT|RIGHT|FULL)?\s*JOIN|\s+WHERE|\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|\s+OFFSET|$)/gi,s;for(;(s=r.exec(e))!==null;){let o=s[1].trim().toUpperCase(),n=s[2].trim(),u=s[3].trim(),i=n.split(/\s+/),d=i[0],l=i.length>1?i[1]:void 0,T;o.includes("LEFT")?T="LEFT":o.includes("RIGHT")?T="RIGHT":o.includes("FULL")?T="FULL":T="INNER",t.push({type:T,table:d,alias:l,on:u})}return t.length>0?t:[]}parseInsert(e){let t={type:"INSERT"},r=e.match(/INSERT\s+INTO\s+(\w+)\s*\(([^)]+(?:\([^)]*\)[^)]*)*)\)\s*VALUES\s*\((.+)\)\s*;?$/i);return r&&(t.table=r[1],t.columns=this.parseColumns(r[2]),t.values=this.parseColumns(r[3])),t}parseUpdate(e){let t={type:"UPDATE"},r=e.match(/UPDATE\s+(\w+)\s+SET\s+(.*?)(?:\s+WHERE|$)/i);r&&(t.table=r[1],t.set=this.parseSetClause(r[2]));let s=e.match(/WHERE\s+(.*?)$/i);return s&&(t.where=s[1].trim()),t}parseDelete(e){let t={type:"DELETE"},r=e.match(/DELETE\s+FROM\s+(\w+)(?:\s+WHERE\s+(.*?))?$/i);return r&&(t.table=r[1],r[2]&&(t.where=r[2].trim())),t}parseOrderBy(e){return e.split(",").map(r=>{let s=r.trim().split(" "),o=s.pop();return o==="DESC"||o==="desc"?{column:s.join(" "),direction:"DESC"}:o==="ASC"||o==="asc"?{column:s.join(" "),direction:"ASC"}:{column:s.join(" ")+" "+o,direction:"ASC"}})}parseSetClause(e){let t={};return this.parseColumns(e).forEach(s=>{let o=s.indexOf("=");if(o>0){let n=s.substring(0,o).trim(),u=s.substring(o+1).trim();t[n]=u}}),t}};D.SQLParser=j;var F=class{constructor(e,t="mysql"){this.parsed={...e},this.dialect=t}build(){switch(this.parsed.type){case"SELECT":return this.buildSelect();case"INSERT":return this.buildInsert();case"UPDATE":return this.buildUpdate();case"DELETE":return this.buildDelete();default:throw new Error("Unsupported SQL type")}}buildSelect(){let e="SELECT ";if(this.parsed.columns&&this.parsed.columns.length>0?e+=this.parsed.columns.join(", "):e+="*",this.parsed.table&&(e+=` FROM ${this.parsed.table}`),this.parsed.joins&&this.parsed.joins.length>0&&this.parsed.joins.forEach(t=>{e+=` ${t.type} JOIN ${t.table} ON ${t.on}`}),this.parsed.where&&(e+=` WHERE ${this.parsed.where}`),this.parsed.groupBy&&this.parsed.groupBy.length>0&&(e+=` GROUP BY ${this.parsed.groupBy.join(", ")}`),this.parsed.having&&(e+=` HAVING ${this.parsed.having}`),this.parsed.orderBy&&this.parsed.orderBy.length>0){let t=this.parsed.orderBy.reduce((s,o)=>(s[o.column]=o.direction,s),{}),r=Object.entries(t).map(([s,o])=>`${s} ${o}`);e+=` ORDER BY ${r.join(", ")}`}return this.parsed.limit!==void 0&&(e+=` LIMIT ${this.parsed.limit}`),this.parsed.offset!==void 0&&(this.dialect==="mysql"?e+=` OFFSET ${this.parsed.offset}`:e+=` OFFSET ${this.parsed.offset}`),e}buildInsert(){if(!this.parsed.table||!this.parsed.columns||!this.parsed.values)throw new Error("Invalid INSERT statement data");let e=this.parsed.columns.join(", "),t=this.parsed.values.join(", ");return`INSERT INTO ${this.parsed.table} (${e}) VALUES (${t})`}buildUpdate(){if(!this.parsed.table||!this.parsed.set)throw new Error("Invalid UPDATE statement data");let e=Object.entries(this.parsed.set).map(([r,s])=>`${r} = ${s}`),t=`UPDATE ${this.parsed.table} SET ${e.join(", ")}`;return this.parsed.where&&(t+=` WHERE ${this.parsed.where}`),t}buildDelete(){if(!this.parsed.table)throw new Error("Invalid DELETE statement data");let e=`DELETE FROM ${this.parsed.table}`;return this.parsed.where&&(e+=` WHERE ${this.parsed.where}`),e}};D.SQLBuilder=F;var re=class{constructor(e="mysql",t){this.dialect=e,this.parser=new j(e),this.parsed=t==="SELECT"?{type:"SELECT"}:this.parser.parse(t),this.parameters={}}setParameter(e,t){return this.parameters[e]=t,this}setParameters(e){return this.parameters={...this.parameters,...e},this}getParameter(e){return this.parameters[e]}getParameters(){return{...this.parameters}}clearParameters(){return this.parameters={},this}getRequiredParameters(){return this.parsed.parameters||[]}getMissingParameters(){let e=this.getRequiredParameters(),t=Object.keys(this.parameters);return e.filter(r=>!t.includes(r))}addWhereWithParam(e,t,r,s="AND"){let o=this.buildWhereConditionWithParam(e,t,r);return this.parsed.where?this.parsed.where+=` ${s} ${o}`:this.parsed.where=o,this.parsed.parameters||(this.parsed.parameters=[]),this.parsed.parameters.includes(r)||this.parsed.parameters.push(r),this}addWhere(e){let t=this.buildWhereCondition(e);if(this.parsed.where){let r=e.connector||"AND";this.parsed.where+=` ${r} ${t}`}else this.parsed.where=t;return this}addWhereRaw(e,t="AND"){return this.parsed.where?this.parsed.where+=` ${t} ${e}`:this.parsed.where=e,this}clearWhere(){return this.parsed.where=void 0,this}addOrderBy(...e){return this.parsed.orderBy||(this.parsed.orderBy=[]),this.parsed.orderBy.push(...e),this}clearOrderBy(){return this.parsed.orderBy=void 0,this}setLimit(e){return this.parsed.limit=e,this}setOffset(e){return this.parsed.offset=e,this}addGroupBy(e){this.parsed.groupBy||(this.parsed.groupBy=[]);let t=this.parsed.groupBy.findIndex(r=>r===e);return t>-1?this.parsed.groupBy[t]=e:this.parsed.groupBy.push(e),this}setHaving(e){return this.parsed.having=e,this}setTable(e){return this.parsed.table=e,this}addJoin(...e){if(this.parsed.type!=="SELECT")throw new Error("JOIN operations are only supported for SELECT queries");return this.parsed.joins||(this.parsed.joins=[]),this.parsed.joins.push(...e),this}selectColumns(e){if(this.parsed.type!=="SELECT")throw new Error("Column selection is only supported for SELECT queries");return this.parsed.columns=e,this}toSQL(e=!1,t=!1){let s=new F(this.parsed,this.dialect).build();return e&&(s=this.substituteParameters(s)),t&&(s+=";"),s}toParameterizedSQL(e=!1){let r=new F(this.parsed,this.dialect).build();return e?r+";":r}toExecutableSQL(e=!1){return this.toSQL(!0,e)}substituteParameters(e){let t=e;return Object.entries(this.parameters).forEach(([r,s])=>{let o=new RegExp(`:${r}\\b`,"g"),n=this.formatParameterValue(s);t=t.replace(o,n)}),t}formatParameterValue(e){return e==null?"NULL":typeof e=="string"?e:typeof e=="boolean"?this.dialect==="postgres"?e?"TRUE":"FALSE":e?"1":"0":Array.isArray(e)?`(${e.map(r=>this.formatParameterValue(r)).join(", ")})`:e instanceof Date?`'${e.toISOString().slice(0,19).replace("T"," ")}'`:String(e)}buildWhereConditionWithParam(e,t,r){switch(t){case"IS NULL":case"IS NOT NULL":return`${e} ${t}`;case"IN":case"NOT IN":return`${e} ${t} :${r}`;default:return`${e} ${t} :${r}`}}getParsed(){return{...this.parsed}}buildWhereCondition(e){let{column:t,operator:r,value:s}=e;switch(r){case"IS NULL":case"IS NOT NULL":return`${t} ${r}`;case"IN":case"NOT IN":let o=s?.map(i=>(0,Le.isString)(i.value)?`'${i.value}'`:i.value).join(", ");return`${t} ${r} (${o})`;default:let n=s?.[0],u;return(0,Le.isString)(n?.value)&&n?.isColumn!==!0?u=`'${n?.value}'`:u=n?.value,`${t} ${r} ${u}`}}};D.SQLManipulator=re});var Fe=Q(k=>{"use strict";var Nt=k&&k.__createBinding||(Object.create?function(a,e,t,r){r===void 0&&(r=t);var s=Object.getOwnPropertyDescriptor(e,t);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(a,r,s)}:function(a,e,t,r){r===void 0&&(r=t),a[r]=e[t]}),xe=k&&k.__exportStar||function(a,e){for(var t in a)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Nt(e,a,t)};Object.defineProperty(k,"__esModule",{value:!0});xe(qe(),k);xe(Ue(),k)});var v=require("dotenv"),$=require("node:path"),se=require("node:fs"),mt=(()=>{try{let a=(0,se.readFileSync)((0,$.join)(__dirname,"..","package.json"),"utf8");return JSON.parse(a)}catch{return{version:"0.0.0"}}})();(0,v.config)({path:[(0,$.join)(__dirname,"..","env",".env"),(0,$.join)(__dirname,"..","env",".env.default")]});(0,v.populate)(process.env,{SERVER_VERSION:mt.version});var rt=N(require("fastify")),at=N(require("@fastify/cors"));var c=class extends Error{constructor(t,r){super(r);this.status=t;this.message=r}};var pe=require("typeorm");var oe=require("typeorm"),Y=new oe.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 ne=require("typeorm"),G=new ne.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:"many-to-many",target:()=>"User",inverseSide:"teams"},workbooks:{type:"one-to-many",target:()=>"Workbook",inverseSide:"team"},queries:{type:"one-to-many",target:()=>"Query",inverseSide:"team"},datasources:{type:"one-to-many",target:()=>"DataSource",inverseSide:"team"}}});var ie=require("typeorm"),V=new ie.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:"many-to-many",target:()=>"Team",inverseSide:"users",joinTable:!0},settings:{type:"one-to-one",target:()=>"UserSettings",inverseSide:"user",joinColumn:!0},currentTeam:{type:"many-to-one",target:()=>"Team",joinColumn:!0}}});var ue=require("typeorm"),z=new ue.EntitySchema({name:"UserSettings",tableName:"user_settings",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},openAiToken:{type:String,nullable:!0},model:{type:String,default:"gpt-3.5-turbo"},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 ce=require("typeorm"),K=new ce.EntitySchema({name:"Workbook",tableName:"workbooks",columns:{id:{type:"uuid",primary:!0,generated:"uuid"},name:{type:String},path:{type:"uuid",generated:"uuid"},isTrash:{type:"boolean",default:!1},createdAt:{type:"datetime",default:()=>"CURRENT_TIMESTAMP"},updatedAt:{type:"datetime",default:()=>"CURRENT_TIMESTAMP",onUpdate:"CURRENT_TIMESTAMP"}},relations:{team:{type:"many-to-one",target:()=>"Team",inverseSide:"workbooks",joinColumn:!0}}});var de=require("typeorm"),J=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},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},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 le=N(require("os"));var me=require("typeorm"),Z=new me.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:"workbooks",joinColumn:!0},dataSource:{type:"many-to-one",target:()=>"DataSource",inverseSide:"queries",joinColumn:!0}}});function pt(){let a=process.env.TYPEORM_DATABASE;if(!a)throw new Error("Bad value for TYPEORM_DATABASE. Please check your config!");return a.startsWith("<home>")&&(a=a.replace("<home>",le.default.homedir())),a}var w=new pe.DataSource({type:process.env.TYPEORM_CONNECTION,database:pt(),synchronize:process.env.TYPEORM_SYNCHRONIZE==="true",host:process.env.TYPEORM_HOST,username:process.env.TYPEORM_USERNAME,password:process.env.TYPEORM_PASSWORD,port:process.env.TYPEORM_PORT?parseInt(process.env.TYPEORM_PORT):void 0,logging:process.env.TYPEORM_LOGGING==="true",entities:[Y,J,G,V,z,K,Z]}),fe=async()=>{if(!w.isInitialized)return w.initialize();throw new Error("Already initialized")},C=w.getRepository(Y),g=w.getRepository(J),q=w.getRepository(G),I=w.getRepository(V),P=w.getRepository(z),b=w.getRepository(K),R=w.getRepository(Z);var x=N(require("node:fs/promises")),X=require("node:path"),ye=N(require("node:os")),lt=ye.default.homedir(),ee=(0,X.join)(lt,".dataramen",".runtime","files"),he=a=>(0,X.join)(ee,a),ge=async a=>x.default.readFile(he(a),{encoding:"utf8"}),Te=async(a,e)=>x.default.writeFile(he(a),e,{encoding:"utf8"});var Ee=async()=>{await ft()||await x.default.mkdir(ee,{recursive:!0})};async function ft(){try{return(await x.default.lstat(ee)).isDirectory()}catch{return!1}}var f=a=>(e,t,r)=>{a(e),r()};var we=f(a=>{a.post("/workbook",async e=>({data:""}))});var y=(a,e)=>{let t=a.body;return e&&e(t),t},O=(a,e)=>{let t=a.query;return e&&e(t),t},h=(a,e)=>{let t=a.params;return e&&e(t),t};var _=a=>a.headers["phoenix-user-id"];var Se=a=>{if(!a.dbUrl)throw new c(400,"url is required");if(!a.dbUser)throw new c(400,"user is required");if(!a.dbType)throw new c(400,"type is required");if(!a.name)throw new c(400,"name is required");if(!a.dbDatabase)throw new c(400,"database is required")};var Re=N(require("mysql2/promise"));var ht=({dbDatabase:a,dbPassword:e,dbUser:t,dbUrl:r})=>Re.default.createConnection({host:r,user:t,database:a,password:e}),gt=async a=>{let e=`
|
|
2
2
|
SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION
|
|
3
3
|
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
|
4
4
|
WHERE CONSTRAINT_NAME = 'PRIMARY'
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
WHERE
|
|
15
15
|
REFERENCED_TABLE_NAME IS NOT NULL
|
|
16
16
|
AND CONSTRAINT_SCHEMA = DATABASE();
|
|
17
|
-
`,[t]=await a.execute(e),r={};return Array.isArray(t)&&t.forEach(s=>{r[s.table_name]||(r[s.table_name]={}),r[s.table_name][s.field]={refTable:s.referenced_table,refField:s.referenced_field}}),r},Et=async(a,e)=>{let r=(await e.query("SHOW TABLES"))[0],s=await Tt(e),o=await gt(e),n=r.map(async u=>{let i=Object.values(u)[0],d=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${a.dbDatabase}' and table_name = '${i}'`,[l]=await e.query(d),T=s[i];return{columns:l.map(
|
|
17
|
+
`,[t]=await a.execute(e),r={};return Array.isArray(t)&&t.forEach(s=>{r[s.table_name]||(r[s.table_name]={}),r[s.table_name][s.field]={refTable:s.referenced_table,refField:s.referenced_field}}),r},Et=async(a,e)=>{let r=(await e.query("SHOW TABLES"))[0],s=await Tt(e),o=await gt(e),n=r.map(async u=>{let i=Object.values(u)[0],d=`select COLUMN_NAME, DATA_TYPE from information_schema.columns where table_schema = '${a.dbDatabase}' and table_name = '${i}'`,[l]=await e.query(d),T=s[i];return{columns:l.map(p=>({name:p.COLUMN_NAME,type:p.DATA_TYPE,isPrimary:o[i]?.includes(p.COLUMN_NAME),ref:T?.[p.COLUMN_NAME]?{table:T[p.COLUMN_NAME].refTable,field:T[p.COLUMN_NAME].refField}:void 0})).sort((p,m)=>p.isPrimary&&m.isPrimary?p.name.localeCompare(m.name):p.isPrimary?-1:1),createdAt:new Date,tableName:i,updatedAt:new Date}});return Promise.all(n)},be=async(a,e,t)=>{try{console.log(`[MYSQL CONN] Query: ${a}`);let[r,s]=await e.query({sql:a,rowsAsArray:!0}),o=r?.constructor?.name;if(o==="ResultSetHeader"){let n=r;if(n.affectedRows>3&&t.allowBulkUpdate!==!0)throw new Error("[MYSQL CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[n.affectedRows]],query:a}}else if(o==="Array"){let n=r;return{columns:s?.map(u=>({column:u.orgName||u.name,table:u.orgTable,alias:u.name,full:u.orgTable?u.orgTable+"."+u.orgName:u.name}))||[],rows:n,query:a}}throw new Error(`[MYSQL CONN] Unknown result type: ${o}`)}catch(r){throw console.error(r),r instanceof c?r:new c(400,r.message)}},wt=async(a,e)=>{await a.beginTransaction();try{let t=await e();return await a.commit(),console.log("[MYSQL CONN] Commit"),t}catch(t){throw await a.rollback(),console.warn(t.message),console.log("[MYSQL CONN] Rollback"),t}},Ie=async a=>{let e=await ht(a),t=!1;return{dbType:"mysql",dataSource:a,inspectSchema:()=>Et(a,e),executeQuery:(r,s)=>s.type==="SELECT"?be(r,e,s):wt(e,()=>be(r,e,s)),checkConnection:async()=>e.ping(),isClosed:()=>t,close:async()=>{if(!t)return t=!0,e.destroy()}}};var Ae=N(require("pg"));var St=async({dbDatabase:a,dbPassword:e,dbUser:t,dbUrl:r,dbPort:s})=>{let o=new Ae.default.Client({host:r,user:t,database:a,password:e,port:s,query_timeout:1e4});return await o.connect(),o},bt=async a=>{let t=await a.query(`
|
|
18
18
|
SELECT
|
|
19
19
|
kcu.table_name,
|
|
20
20
|
kcu.column_name,
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
WHERE
|
|
50
50
|
table_name = '${d}' and
|
|
51
51
|
table_schema = '${a.dbSchema}'
|
|
52
|
-
`,{rows:T}=await e.query(l),
|
|
52
|
+
`,{rows:T}=await e.query(l),p=o[d];return{columns:T.map(m=>({name:m.column_name,type:m.data_type,isPrimary:n[d]?.includes(m.column_name),ref:p?.[m.column_name]?{table:p[m.column_name].refTable,field:p[m.column_name].refField}:void 0})).sort((m,E)=>m.isPrimary&&E.isPrimary?m.name.localeCompare(E.name):m.isPrimary?-1:1),createdAt:new Date,tableName:d,updatedAt:new Date}});return Promise.all(u)},Ct=async(a,e)=>{let t=`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 (${a.join(", ")})
|
|
57
|
-
limit 25;`;return(await e.query(t)).rows.reduce((s,o)=>(s[o.row_key]={table:o.relname,column:o.attname},s),{})},
|
|
57
|
+
limit 25;`;return(await e.query(t)).rows.reduce((s,o)=>(s[o.row_key]={table:o.relname,column:o.attname},s),{})},Ce=async(a,e,t)=>{try{console.log(`[PG CONN] Query: ${a}`);let{rows:r,fields:s,command:o,rowCount:n}=await e.query({text:a,rowMode:"array"});if(o==="UPDATE"||o==="INSERT"||o==="DELETE"){if(n!=null&&n>3&&t.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[n]],query:a}}if(o==="SELECT"){let u=s.map(d=>`'${d.tableID}-${d.columnID}'`),i=await Ct(u,e);return{columns:s.map(d=>{let l=i[`${d.tableID}-${d.columnID}`];return{column:l?.column||d.name,alias:d.name,table:l?.table||"",full:l?l.table+"."+l.column:d.name}}),rows:r,query:a}}throw new Error(`[PG CONN] Unsupported command: ${o}`)}catch(r){throw r instanceof c?r:new c(400,r.message)}},At=async(a,e)=>{await a.query("BEGIN");try{let t=await e();return await a.query("COMMIT"),console.log("[PG CONN] Commit"),t}catch(t){throw await a.query("ROLLBACK"),console.log("[PG CONN] Rollback"),t}},Pe=async a=>{let e=await St(a),t=!1,r=!1,s=async o=>(r||await e.query(`SET search_path TO ${a.dbSchema}`),o());return{dbType:"postgres",dataSource:a,inspectSchema:()=>It(a,e),executeQuery:(o,n)=>s(()=>n.type==="SELECT"?Ce(o,e,n):At(e,()=>Ce(o,e,n))),checkConnection:async()=>{},isClosed:()=>t,close:async()=>{if(!t)return t=!0,e.end()}}};var M=async(a,e)=>{try{let t;if(a.dbType==="mysql")t=await Ie(a);else if(a.dbType==="postgres")t=await Pe(a);else throw new c(500,`Connection manager for ${a.dbType} not found`);return e.__connections?e.__connections.push(t):e.__connections=[t],t}catch(t){throw console.error(t),t instanceof c?t:t?.code==="ECONNREFUSED"?new c(500,"Failed to connect to the database"):new c(500,t.message)}};var Ne=f(a=>{a.get("/:id",async e=>{let{id:t}=h(e),r=await g.findOne({where:{id:t}});if(!r)throw new c(404,"Data source not found");return{data:r}}),a.get("/",async e=>{let{teamId:t}=O(e);return{data:await g.find({where:{team:{id:t}},order:{createdAt:"DESC"}})}}),a.post("/",async(e,t)=>{let{teamId:r,ownerId:s,...o}=y(e,Se),n=g.create({...o,team:{id:r},owner:{id:s}}),u=await M(n,e);try{await u.checkConnection()}catch{throw new c(400,"Cannot connect to the database, please check datasource configuration")}return{data:await g.save(n)}}),a.put("/:id",async(e,t)=>{let{id:r}=h(e),s=y(e),o=await g.findOneBy({id:r});if(!o)throw new c(404,"Data source not found");let n=g.merge(o,s);return await g.save(n),{data:n}}),a.delete("/:id",async(e,t)=>w.transaction(async()=>{let{id:r}=h(e);await Promise.all([C.delete({datasource:{id:r}}),R.delete({dataSource:{id:r}})]),await g.delete({id:r})})),a.post("/:id/inspect",async(e,t)=>{let{id:r}=h(e),s=await g.findOneBy({id:r});if(!s)throw new Error("Data source not found");s.status="INSPECTING",await g.save(s);let n=await(await M(s,e)).inspectSchema();await C.delete({datasource:{id:r}}),await C.insert(n.sort().map(u=>C.create({tableName:u.tableName,columns:u.columns,datasource:{id:r}}))),s.status="READY",s.lastInspected=new Date,await g.save(s)}),a.get("/:id/inspections",async(e,t)=>{let{id:r}=h(e);return{data:await C.find({where:{datasource:{id:r}}})}})});var te=require("typeorm"),Oe=f(a=>{a.get("/team/:teamId/files",async(e,t)=>{let{teamId:r}=h(e),s={where:{team:{id:r}},order:{name:"ASC"},select:{id:!0,name:!0,updatedAt:!0}},[o=[],n=[],u=[]]=await Promise.all([g.find(s),b.find({...s,where:{...s.where,isTrash:!1}}),R.find({...s,where:{...s.where,isTrash:!1}})]);return{data:[...o.map(i=>({...i,type:"dataSource"})),...n.map(i=>({...i,type:"workbook"})),...u.map(i=>({...i,type:"query"}))]}}),a.get("/team/:teamId/trash",async e=>{let{teamId:t}=h(e);return{data:await w.query(`
|
|
58
58
|
select id, name, updatedAt
|
|
59
59
|
from workbooks
|
|
60
60
|
where teamId = '${t}' AND (isTrash = true OR isTrash IS NULL)
|
|
61
61
|
order by name asc
|
|
62
62
|
limit 100;
|
|
63
|
-
`)}}),a.get("/team/:teamId/query",async e=>{let{teamId:t}=h(e),{search:r,size:s}=
|
|
63
|
+
`)}}),a.get("/team/:teamId/query",async e=>{let{teamId:t}=h(e),{search:r,size:s}=O(e),o=(parseInt(s)||20)/2,[n,u]=await Promise.all([C.find({where:{tableName:(0,te.Like)(`%${r}%`),datasource:{team:{id:t}}},relations:{datasource:!0},select:{id:!0,tableName:!0,datasource:{name:!0,id:!0}},order:{tableName:"ASC"},take:o}),R.find({where:{name:(0,te.Like)(`%${r}%`),isTrash:!1,dataSource:{team:{id:t}}},relations:{dataSource:!0},select:{id:!0,name:!0,dataSource:{name:!0,id:!0}},order:{name:"ASC"},take:o})]),i=[];return n.forEach(d=>{i.push({name:d.tableName,id:d.id,dataSourceName:d.datasource?.name||"--",dataSourceId:d.datasource?.id||"--",type:"table"})}),u.forEach(d=>{i.push({name:d.name,id:d.id,dataSourceName:d.dataSource?.name||"--",dataSourceId:d.dataSource?.id||"--",type:"query"})}),{data:i}})});function B(a,e=void 0){try{if(a){let t=a.split("&"),r={};for(let s of t){let o=s.split(":");r[o[0]]=o[1]}return r}}catch{}return e}var _e=require("typeorm"),De=f(a=>{a.get("/",async e=>{let{dataSourceId:t,teamId:r,limit:s,orderBy:o,name:n}=O(e);if(!t&&!r)throw new c(400,"Either dsId or teamId is required");let u={isTrash:!1};return t&&(u.dataSource={id:t}),r&&(u.team={id:r}),n&&(u.name=(0,_e.Like)(`%${n}%`)),{data:await R.find({where:u,take:s,order:B(o,{createdAt:"DESC"})})}}),a.get("/:id",async e=>{let{id:t}=h(e),r=await R.findOne({where:{id:t},select:{dataSource:{id:!0}},relations:{dataSource:!0}});return r?{data:r}:{status:404,data:"Query not found"}}),a.post("/",async e=>{let t=y(e),r=await g.findOne({where:{id:t.dataSourceId},relations:{team:!0}});return{data:await R.save(R.create({name:t.name,isTrash:!1,opts:t.opts,team:{id:r?.team.id},dataSource:{id:t.dataSourceId}}))}}),a.patch("/:id",async e=>{let{id:t}=h(e),r=y(e);if(!(await R.update(t,r)).affected)throw new c(404,"Workbook not found");return{data:await R.findOneBy({id:t})}}),a.delete("/:id",async e=>w.transaction(async()=>{let{id:t}=h(e);if(!(await R.delete({id:t})).affected)return{status:404,data:"Workbook not found"}}))});var Be=N(Fe()),We=require("typeorm");function Qe(a,e,t){return`${a.replace(/;\s*$/,"").trim()} LIMIT ${e} OFFSET ${t}`}function $e(a,e){return a.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(t,r)=>{if(!(r in e))throw new Error(`Missing value for SQL variable: ${r}`);return String(e[r])})}function ve(a){let t=a.replace(/--.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").trim().match(/^\s*(\(?\s*)*([a-zA-Z]+)/);if(!t)throw new c(400,"Failed to detect query type");return t[2].toUpperCase()}function Ot(a){return a||20}function _t(a){return a||0}function Dt(a){return a.includes(" ")&&!a.startsWith("'")?`\`${a}\``:a}var je=async(a,{table:e,variables:t,datasourceId:r,filters:s,joins:o,orderBy:n,size:u,page:i,columns:d,groupBy:l})=>{let T=await g.findOneBy({id:r}),p=[],m=[];if(!T)throw new c(404,"Data source not found");let E=new Be.SQLManipulator(T.dbType,"SELECT");if(E.setTable(e),t&&E.setParameters(t),E.getParsed().type!=="SELECT")throw new c(400,"Only SELECT queries are allowed in this endpoint");E.setLimit(u||20),E.setOffset(u*i),s?.forEach(S=>{E.addWhere(kt(S))}),o&&E.addJoin(...o),n&&E.addOrderBy(...n.map(S=>({...S,column:Dt(S.column)}))),l&&l.length>0&&l.forEach(S=>E.addGroupBy(S));let U=E.getParsed();U.table&&p.push(U.table),U.joins&&U.joins.length>0&&U.joins.forEach(S=>{p.push(S.table)});let st=await C.find({where:{tableName:(0,We.In)(p),datasource:{id:r}}});for(let S of st)if(S.columns)for(let H of S.columns)m.push({column:H.name,table:S.tableName||"",full:`${S.tableName}.${H.name}`,type:H.type});return d&&d.length>0?E.selectColumns(d):E.selectColumns(m.map(S=>S.full)),{...await(await M(T,a)).executeQuery(E.toExecutableSQL(),{type:E.getParsed().type,allowBulkUpdate:!1}),tables:p,allColumns:m}},He=async(a,{sql:e,variables:t,datasourceId:r,size:s,page:o})=>{let n=await g.findOneBy({id:r});if(!n)throw new c(404,"Data source not found");let u=ve(e),i=e;if(u==="SELECT"){if(i.match(/LIMIT|OFFSET/ig))throw new c(400,"Queries are automatically paginated, do not use LIMIT and/or OFFSET");let l=Ot(s);i=Qe(i,l,l*_t(o))}return t&&(i=$e(i,t)),(await M(n,a)).executeQuery(i,{type:u,allowBulkUpdate:!1})};function kt(a){let e={...a};switch(e.operator){case"IS NULL":case"IS NOT NULL":e.value=void 0;break;case"LIKE":case"ILIKE":case"NOT LIKE":case"NOT ILIKE":e.value=e.value?.map(t=>({isColumn:t?.isColumn,value:`%${t?.value}%`}));break}return e}var Ye=f(a=>{a.post("/sql",async e=>{let t=y(e);return{data:await je(e,t)}}),a.post("/raw",async e=>{let t=y(e);return{data:await He(e,t)}})});var Ge=require("node:child_process"),Ve=f(a=>{a.get("/",async(e,t)=>({data:{active:!0,version:process.env.SERVER_VERSION}})),a.get("/logs",async()=>{(0,Ge.spawn)(`echo "${process.env.SERVER_VERSION}"`)})});var ze=f(a=>{a.get("/",async(e,t)=>{let r=_(e);return{data:await q.find({where:{users:{id:r}}})}}),a.post("/",async(e,t)=>w.transaction(async()=>{let r=_(e),s=y(e),o=I.create();o.id=r;let n=q.create(s);return n.users=[o],await q.save(n),{data:n}}))});var Ke=async a=>({email:"local@localhost",sub:"local"});async function Je(){let a=q.create({name:"Personal"}),e=await I.save(I.create({}));return a.users=[e],await q.save(a),await I.update(e.id,{currentTeam:{id:a.id}}),I.findOne({where:{},relations:{currentTeam:!0}})}var Ze=f(a=>{a.post("/register",async(e,t)=>{let r=await Ke(e);if(!r?.email||!r?.sub)throw new c(400,"Invalid token");return{data:await Je()}}),a.get("/",async(e,t)=>{let r=await I.findOne({where:{},relations:{currentTeam:!0}});return r?{data:r}:{data:await Je()}}),a.put("/",async(e,t)=>{let r=_(e),s=y(e);if(!(await I.update(r,s)).affected)throw new c(404,"User not found");return{data:I.findOneBy({id:r})}}),a.put("/team",async(e,t)=>{let r=_(e),s=y(e);return await I.update(r,{currentTeam:{id:s.teamId}}),{data:await I.findOne({where:{id:r},relations:{currentTeam:!0}})}})});var qt="********************************************",Xe=a=>a.slice(0,4)+qt+a.slice(a.length-4);function Mt(a){let e=P.create(a);return a.openAiToken&&(e.openAiToken=Xe(a.openAiToken)),e}var et=f(a=>{a.get("/",async e=>{let t=_(e),r=await P.findOneBy({user:{id:t}});return r||(r=await P.save(P.create({user:{id:t},model:"gpt-4o"}))),{data:Mt(r)}}),a.patch("/",async e=>{let{settings:t}=y(e);if(!t.id)throw new c(400,"Settings id is required!");if(!(await P.update(t.id,t)).affected)throw new c(404,"You do not own these settings!");return{data:await P.findOneBy({id:t.id})}})});var tt=f(a=>{a.get("/",async e=>{let{dsId:t,teamId:r,limit:s,orderBy:o}=O(e);if(!t&&!r)throw new c(400,"Either dsId or teamId is required");return{data:await b.find({where:{team:{id:r},isTrash:!1},take:s,order:B(o,{createdAt:"DESC"})})}}),a.get("/:id",async e=>{let{id:t}=h(e),r=await b.findOneBy({id:t});return r?{data:r}:{status:404,data:"Workbook not found"}}),a.post("/",async e=>{let t=y(e);return{data:await b.save(b.create({name:t.name,isTrash:!1,team:{id:t.teamId}}))}}),a.patch("/:id",async e=>{let{id:t}=h(e),r=y(e);if(!(await b.update(t,r)).affected)throw new c(404,"Workbook not found");return{data:await b.findOneBy({id:t})}}),a.delete("/:id",async e=>{let{id:t}=h(e);if(!(await b.delete({id:t})).affected)return{status:404,data:"Workbook not found"}}),a.get("/:id/content",async e=>{let{id:t}=h(e),r=await b.findOneBy({id:t});if(!r)throw new c(404,"Workbook not found");try{let s=await ge(r?.path);if(s)return{data:s}}catch{}return{data:""}}),a.patch("/:id/content",async e=>{let{id:t}=h(e),r=y(e),s=await b.findOneBy({id:t});if(!s?.path)throw new c(404,"Workbook not found");await Te(s?.path,r.content),await b.update(s.id,{updatedAt:new Date})})});var L=(0,rt.default)(),Lt=process.env.PORT?parseInt(process.env.PORT):4466;function A(a,e){L.register(a,{prefix:e}),console.log("Registered "+e)}async function Ut(){await Ee(),A(we,"/api/chat"),A(Ne,"/api/data-sources"),A(Oe,"/api/project"),A(De,"/api/queries"),A(Ye,"/api/runner"),A(Ve,"/api/status"),A(ze,"/api/teams"),A(Ze,"/api/users"),A(et,"/api/user-settings"),A(tt,"/api/workbooks"),L.register(at.default,{origin:"*",methods:"*"}),L.addHook("onResponse",async a=>{a.__connections&&a.__connections.forEach(e=>{e.close()})}),L.setErrorHandler((a,e,t)=>{if(a instanceof c){console.error(a),t.status(a.status).send({error:a.message});return}else console.error(a),t.status(500).send({error:"Internal Server Error"})}),await L.after(),await fe(),L.listen({port:Lt,host:"0.0.0.0"},(a,e)=>{a&&(console.error(a),process.exit(1)),console.log(`Server listening at ${e}`)})}Ut();
|
package/dist/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@dataramen/local-server","version":"0.0.
|
|
1
|
+
{"name":"@dataramen/local-server","version":"0.0.38","license":"MIT","main":"code/proxy.js","dependencies":{"@fastify/cors":"^11.0.1","dotenv":"^16.5.0","fast-glob":"^3.3.3","fastify":"^5.3.2","mysql2":"^3.14.1","pg":"^8.15.6","sqlite3":"^5.1.7","typeorm":"^0.3.23"},"devDependencies":{"fs-extra":"^11.3.0","yargs":"^18.0.0","yocto-spinner":"^1.0.0"}}
|