db-studio 1.9.4 → 1.9.6
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 +5 -5
- package/dist/index.js +20 -20
- package/dist/index.js.map +1 -1
- package/dist/web-dist/assets/_pathlessLayout-BByrt-IV.js +2 -0
- package/dist/web-dist/assets/{_pathlessLayout-DhK1pVQZ.js.map → _pathlessLayout-BByrt-IV.js.map} +1 -1
- package/dist/web-dist/assets/{_queryId-PHL0xcKj.js → _queryId-cyxa5wMS.js} +1 -1
- package/dist/web-dist/assets/{_queryId-PHL0xcKj.js.map → _queryId-cyxa5wMS.js.map} +1 -1
- package/dist/web-dist/assets/{_table-Ud147_vw.js → _table-B0yPxctF.js} +1 -1
- package/dist/web-dist/assets/{_table-Ud147_vw.js.map → _table-B0yPxctF.js.map} +1 -1
- package/dist/web-dist/assets/{_table-CThT7wMT.js → _table-DwIZYs3U.js} +1 -1
- package/dist/web-dist/assets/{_table-CThT7wMT.js.map → _table-DwIZYs3U.js.map} +1 -1
- package/dist/web-dist/assets/{format-cell-value-DG6WpZw_.js → format-cell-value-BDLw73u3.js} +6 -6
- package/dist/web-dist/assets/format-cell-value-BDLw73u3.js.map +1 -0
- package/dist/web-dist/assets/index-DRNEODC_.js +86 -0
- package/dist/web-dist/assets/index-DRNEODC_.js.map +1 -0
- package/dist/web-dist/assets/{queries.store-DruKauzK.js → queries.store-DvaENLe7.js} +1 -1
- package/dist/web-dist/assets/{queries.store-DruKauzK.js.map → queries.store-DvaENLe7.js.map} +1 -1
- package/dist/web-dist/assets/{query-runner-Db56mYGQ.js → query-runner-D4jp77L6.js} +2 -2
- package/dist/web-dist/assets/{query-runner-Db56mYGQ.js.map → query-runner-D4jp77L6.js.map} +1 -1
- package/dist/web-dist/assets/{runner-DAA3MnAn.js → runner-EqOuNKQH.js} +1 -1
- package/dist/web-dist/assets/{runner-DAA3MnAn.js.map → runner-EqOuNKQH.js.map} +1 -1
- package/dist/web-dist/assets/{tanstack-C38qytx8.js → tanstack-BfO3BbGk.js} +5 -5
- package/dist/web-dist/assets/tanstack-BfO3BbGk.js.map +1 -0
- package/dist/web-dist/index.html +3 -3
- package/package.json +1 -1
- package/dist/web-dist/assets/_pathlessLayout-DhK1pVQZ.js +0 -2
- package/dist/web-dist/assets/format-cell-value-DG6WpZw_.js.map +0 -1
- package/dist/web-dist/assets/index-GnOMl7Md.js +0 -86
- package/dist/web-dist/assets/index-GnOMl7Md.js.map +0 -1
- package/dist/web-dist/assets/tanstack-C38qytx8.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var Da=Object.defineProperty;var E=(a,e)=>()=>(a&&(e=a(a=0)),e);var pr=(a,e)=>{for(var t in e)Da(a,t,{get:e[t],enumerable:!0})};var fr=E(()=>{"use strict"});var br=E(()=>{"use strict"});var yr=E(()=>{"use strict"});var hr,gr,we,Tr=E(()=>{"use strict";hr=globalThis.process?.env,gr=hr?.NODE_ENV,we={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.dbstudio.localhost",IS_DEV:gr==="development",PROXY_URL:hr?.DB_STUDIO_PROXY_URL??(gr==="development"?"https://proxy.dbstudio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var Er=E(()=>{"use strict"});var Cr,wt=E(()=>{"use strict";Cr={AUTHOR:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",AUTHOR_NAME:"H\xFCsam",AUTHOR_AVATAR:"/avocado.png",AUTHOR_USERNAME:"husamql3",AUTHOR_GITHUB_LINK:"https://github.com/husamql3",SITE_DESCRIPTION:"The modern pgAdmin alternative that works with every database.",SITE_KEYWORDS:["pgadmin alternative","database client","database gui","database browser","sql editor","postgresql client","mysql client","table editor","ai sql","er diagram"],SITE_TITLE:"dbstudio",SITE_NAME:"dbstudio.sh",SITE_URL:"https://dbstudio.sh",SITE_X_LINK:"https://x.com/dbstudio_sh",SITE_GITHUB_LINK:"https://github.com/husamql3/db-studio",SITE_GITHUB_NEW_ISSUE_LINK:"https://github.com/husamql3/db-studio/issues/new/choose",SITE_DOCS_LINK:"https://dbstudio.sh/docs",SITE_CHANGELOG_LINK:"https://dbstudio.sh/changelog",SITE_ROADMAP_LINK:"https://dbstudio.sh/roadmap",SITE_IMAGE:"https://dbstudio.sh/og-image.png",SITE_IMAGE_WIDTH:"1200",SITE_IMAGE_HEIGHT:"630",SITE_IMAGE_ALT:"dbstudio.sh \u2013 Modern database management studio",SITE_COLOR:"#1447e6"}});var wr=E(()=>{"use strict"});var Ze=E(()=>{"use strict";fr();br();yr();Tr();Er();wt();wr()});import{HTTPException as Va}from"hono/http-exception";function q(a){return se.get(a)}var At,se,Re=E(()=>{"use strict";At=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new Va(400,{message:`Unsupported database type: "${e}". Supported types: ${this.getSupportedTypes().join(", ")}`});return t}has(e){return this.adapters.has(e)}getSupportedTypes(){return[...this.adapters.keys()]}},se=new At});import{HTTPException as Oe}from"hono/http-exception";import{DatabaseError as Wa}from"pg";function J(a){throw new Oe(501,{message:`${a} is not implemented for this database type`})}var oe,De=E(()=>{"use strict";oe=class{wrapError(e){if(e instanceof Oe)return e;if(e instanceof Error){let t=e;return t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"||t.code==="ETIMEDOUT"||t.code==="ER_ACCESS_DENIED_ERROR"||t.code==="ER_BAD_HOST_ERROR"||t.code==="ECONNRESET"||t.errno===1045||t.errno===2003||t.errno===2002||e.message.includes("ECONNREFUSED")||e.message.includes("connection refused")||e.message.includes("timeout expired")||e.message.includes("Connection terminated")||e.message.includes("MongoNetworkError")||e.message.includes("MongoServerSelectionError")||e.message.includes("Login failed")||e.message.startsWith("NOAUTH")||e.message.startsWith("WRONGPASS")||e.message.startsWith("LOADING")||e.message.startsWith("BUSY")||e.message.startsWith("READONLY")||e.message.startsWith("CLUSTERDOWN")||e.message.includes("Redis cluster mode is not supported")||e instanceof Wa&&e.code?.startsWith("08")?new Oe(503,{message:e.message}):new Oe(500,{message:e.message})}return new Oe(500,{message:"Internal server error"})}encodeCursor(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}decodeCursor(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}normalizeRow(e){let t={};for(let[r,n]of Object.entries(e))t[r]=n;return t}async getTableData(e){try{let{db:t,limit:r=50,direction:n="asc"}=e,o=this.buildTableDataQuery(e),s=await this.runQuery(t,o.countSql,o.countValues),c=Number(s[0]?.total??0),i=await this.runQuery(t,o.sql,o.values),l=i.length>r;l&&(i=i.slice(0,r));let u=this.normalizeRows(i);n==="desc"&&(u=u.reverse());let{nextCursor:m,prevCursor:p}=this.buildCursors(e,u,l);return{data:u,meta:{limit:r,total:c,hasNextPage:n==="asc"?l:!!e.cursor,hasPreviousPage:n==="asc"?!!e.cursor:l,nextCursor:m,prevCursor:p}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=`SELECT * FROM ${this.quoteIdentifier(e)}`,n=await this.runQuery(t,r,[]);if(!n||n.length===0)throw new Oe(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(n[0]),rows:n}}catch(r){throw this.wrapError(r)}}getDatabasesList(){return J("getDatabasesList")}getCurrentDatabase(){return J("getCurrentDatabase")}getDatabaseConnectionInfo(){return J("getDatabaseConnectionInfo")}getTablesList(e){return J("getTablesList")}createTable(e){return J("createTable")}deleteTable(e){return J("deleteTable")}getTableSchema(e){return J("getTableSchema")}getTableColumns(e){return J("getTableColumns")}addColumn(e){return J("addColumn")}deleteColumn(e){return J("deleteColumn")}alterColumn(e){return J("alterColumn")}renameColumn(e){return J("renameColumn")}addRecord(e){return J("addRecord")}updateRecords(e){return J("updateRecords")}deleteRecords(e){return J("deleteRecords")}forceDeleteRecords(e){return J("forceDeleteRecords")}bulkInsertRecords(e){return J("bulkInsertRecords")}executeQuery(e){return J("executeQuery")}}});import za from"better-sqlite3";import{Redis as Ya}from"ioredis";import{MongoClient as Ga,ObjectId as Dt}from"mongodb";import Qa from"mssql";import{createPool as Ja}from"mysql2/promise";import{Pool as xr}from"pg";var _t,be,vr,kr,qr,Le,Ur,Fr,Br,jr,Hr,Kr,rt,nt,Pe=E(()=>{"use strict";_t=class{pgPools=new Map;mysqlPools=new Map;mssqlPools=new Map;mongoClient=null;sqliteDb=null;redisClients=new Map;redisClusterChecked=!1;baseConfig=null;initError=null;constructor(){try{this.initializeBaseConfig()}catch(e){this.initError=e instanceof Error?e:new Error(String(e))}}detectDbType(e){let t=e.protocol.replace(":","");switch(t){case"postgres":case"postgresql":return"pg";case"mysql":case"mysql2":return"mysql";case"mssql":case"sqlserver":return"mssql";case"mongodb":case"mongodb+srv":return"mongodb";case"sqlite":return"sqlite";default:throw new Error(`Unsupported database type: ${t}. Supported types: PostgreSQL (postgres://), MySQL (mysql://), SQL Server (mssql://), MongoDB (mongodb://), SQLite (sqlite://).`)}}initializeBaseConfig(){let e=process.env.DATABASE_URL;if(!e)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");if(e.startsWith("sqlite://")){this.baseConfig={url:e,host:"localhost",port:0,user:"",password:"",dbType:"sqlite"};return}try{let t=new URL(e),r=this.detectDbType(t),n=r==="mysql"?3306:r==="mssql"?1433:r==="mongodb"?27017:r==="redis"?6379:5432;this.baseConfig={url:e,host:t.hostname,port:Number.parseInt(t.port,10)||n,user:t.username,password:t.password,dbType:r}}catch(t){throw new Error(t instanceof Error?t.message:String(t))}}getDbType(){if(this.initError)throw this.initError;if(!this.baseConfig)throw new Error("Base configuration not initialized");return this.baseConfig.dbType}buildConnectionString(e){if(this.initError)throw this.initError;if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType==="sqlite")return this.baseConfig.url;e||(e=new URL(this.baseConfig.url).pathname.slice(1));try{let t=new URL(this.baseConfig.url);return t.pathname=`/${e}`,t.toString()}catch(t){throw new Error(`Failed to build connection string for database "${e}": ${t instanceof Error?t.message:String(t)}`)}}getSqliteDb(){if(!this.baseConfig||this.baseConfig.dbType!=="sqlite")throw new Error("DATABASE_URL is not a sqlite:// connection");if(!this.sqliteDb){let e=this.baseConfig.url.replace(/^sqlite:\/\//,""),t=new za(e);t.pragma("journal_mode = WAL"),t.pragma("foreign_keys = ON"),this.sqliteDb=t}return this.sqliteDb}closeSqliteDb(){this.sqliteDb&&(this.sqliteDb.close(),this.sqliteDb=null)}getPgPool(e){let t=this.buildConnectionString(e);if(!this.pgPools.has(t)){let r={connectionString:t,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:2e3},n=new xr(r);n.on("error",o=>{}),this.pgPools.set(t,n)}return this.pgPools.get(t)??new xr({connectionString:t})}getMysqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mysqlPools.has(t)){let n=new URL(t).pathname.slice(1),o=Ja({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:n||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(t,o)}return this.mysqlPools.get(t)}async getMssqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mssqlPools.has(t)){let n=new URL(t).pathname.slice(1),o={server:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:n||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},s=await new Qa.ConnectionPool(o).connect();s.on("error",c=>{}),this.mssqlPools.set(t,s)}return this.mssqlPools.get(t)}getPool(e){return this.getPgPool(e)}async closePgPool(e){let t=this.pgPools.get(e);t&&(await t.end(),this.pgPools.delete(e))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e))}async closePool(e){if(this.baseConfig?.dbType==="sqlite"&&e===this.baseConfig.url){this.closeSqliteDb();return}await this.closePgPool(e),await this.closeMysqlPool(e),await this.closeMssqlPool(e)}async closePoolByDatabase(e){if(this.baseConfig?.dbType==="sqlite"){this.closeSqliteDb();return}let t=this.buildConnectionString(e);await this.closePool(t)}async getMongoClient(){if(!this.mongoClient){if(!this.baseConfig)throw new Error("Base configuration not initialized");let e=new Ga(this.baseConfig.url);try{await e.connect(),this.mongoClient=e}catch(t){try{await e.close()}catch{}throw t}}return this.mongoClient}getMongoDbName(){if(!this.baseConfig)throw new Error("Base configuration not initialized");return new URL(this.baseConfig.url).pathname?.replace(/^\//,"")||"admin"}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType!=="redis")throw new Error("DATABASE_URL is not a redis:// connection");let t=e??this.getRedisDefaultDb(),r=this.redisClients.get(t);if(r)return r;let n=new URL(this.baseConfig.url),o={host:this.baseConfig.host,port:this.baseConfig.port,db:t,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};this.baseConfig.user&&(o.username=decodeURIComponent(this.baseConfig.user)),this.baseConfig.password&&(o.password=decodeURIComponent(this.baseConfig.password)),n.protocol==="rediss:"&&(o.tls={});let s=new Ya(o);try{if(await s.connect(),!this.redisClusterChecked){let c=await s.info("server");if(/^redis_mode:cluster\b/m.test(c))throw await s.quit().catch(()=>{}),new Error("Redis cluster mode is not supported. Use a single-node redis:// connection.");this.redisClusterChecked=!0}}catch(c){throw await s.quit().catch(()=>{}),c}return this.redisClients.set(t,s),s}getRedisDefaultDb(){if(!this.baseConfig)return 0;try{let t=new URL(this.baseConfig.url).pathname.replace(/^\//,"");if(!t)return 0;let r=Number.parseInt(t,10);return Number.isFinite(r)?r:0}catch{return 0}}async closeAll(){let e=Array.from(this.pgPools.entries()).map(async([o,s])=>{await s.end()}),t=Array.from(this.mysqlPools.entries()).map(async([o,s])=>{await s.end()}),r=Array.from(this.mssqlPools.entries()).map(async([o,s])=>{await s.close()});await Promise.all([...e,...t,...r]),this.pgPools.clear(),this.mysqlPools.clear(),this.mssqlPools.clear(),this.mongoClient&&(await this.mongoClient.close(),this.mongoClient=null),this.closeSqliteDb();let n=Array.from(this.redisClients.entries()).map(async([o,s])=>{await s.quit().catch(()=>{})});await Promise.all(n),this.redisClients.clear(),this.redisClusterChecked=!1}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys()),...Array.from(this.mssqlPools.keys())]}},be=new _t,vr=a=>be.getPgPool(a),kr=a=>be.getMysqlPool(a),qr=async a=>be.getMssqlPool(a),Le=()=>be.getDbType(),Ur=()=>be.getSqliteDb(),Fr=()=>be.getMongoClient(),Br=()=>be.getMongoDbName(),jr=a=>be.getMongoDb(a),Hr=a=>be.getRedisClient(a),Kr=()=>be.getRedisDefaultDb(),rt=a=>typeof a=="string"&&Dt.isValid(a),nt=a=>typeof a=="string"&&Dt.isValid(a)?new Dt(a):a});var z,H,B,G,$t,Ot,ee,le,Me,_e=E(()=>{"use strict";Pe();z=a=>vr(a),H=a=>kr(a),B=a=>qr(a),G=()=>Ur(),$t=()=>Fr(),Ot=()=>Br(),ee=a=>jr(a),le=a=>Hr(a),Me=()=>Kr()});function Se(){let a=process.env.DATABASE_URL;if(!a)return{host:"localhost",port:5432};try{let e=new URL(a),t=e.protocol.replace(":",""),r=t==="mongodb"||t==="mongodb+srv"?27017:t==="mssql"||t==="sqlserver"?1433:t==="mysql"||t==="mysql2"?3306:5432;return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||r}}catch{return{host:"localhost",port:5432}}}var He=E(()=>{"use strict"});function Vr(a){if(!a||a.length===0)return{};let e=[];for(let t of a){let r=t.columnName,n=Za(t.value),o=t.operator.toLowerCase();if(r)switch(o){case"=":e.push({[r]:n});break;case"!=":e.push({[r]:{$ne:n}});break;case">":e.push({[r]:{$gt:n}});break;case">=":e.push({[r]:{$gte:n}});break;case"<":e.push({[r]:{$lt:n}});break;case"<=":e.push({[r]:{$lte:n}});break;case"is":e.push({[r]:n});break;case"is not":e.push({[r]:{$ne:n}});break;case"like":e.push({[r]:{$regex:at(String(n)),$options:""}});break;case"not like":e.push({[r]:{$not:{$regex:at(String(n)),$options:""}}});break;case"ilike":e.push({[r]:{$regex:at(String(n)),$options:"i"}});break;case"not ilike":e.push({[r]:{$not:{$regex:at(String(n)),$options:"i"}}});break;default:e.push({[r]:n});break}}return e.length?{$and:e}:{}}function Lt(a,e){return a?Array.isArray(a)?a.length===0?{_id:1}:Object.fromEntries(a.map(t=>[t.columnName,t.direction==="desc"?-1:1])):typeof a=="string"&&a.length>0?{[a]:e==="desc"?-1:1}:{_id:1}:{_id:1}}function Pt(a){return Buffer.from(JSON.stringify({offset:a})).toString("base64url")}function Wr(a){if(!a)return 0;try{let e=JSON.parse(Buffer.from(a,"base64url").toString("utf-8"));return typeof e.offset=="number"?e.offset:0}catch{return 0}}var at,Za,zr=E(()=>{"use strict";Pe();at=a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Za=a=>{let e=a.trim();if(e==="null")return null;if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return!Number.isNaN(t)&&e!==""?t:rt(e)?nt(e):e}});import{HTTPException as v}from"hono/http-exception";var Mt,Ie,eo,to,Yr,Ke,ro,Gr,no,ao,oo,xe,ot,Qr=E(()=>{"use strict";De();_e();Pe();He();zr();Mt=a=>a instanceof Date?a.toISOString():typeof a=="bigint"?a.toString():a&&typeof a=="object"?"_bsontype"in a&&a._bsontype==="ObjectId"?a.toHexString():Array.isArray(a)?a.map(e=>Mt(e)):Object.fromEntries(Object.entries(a).map(([e,t])=>[e,Mt(t)])):a,Ie=a=>Mt(a),eo=a=>a instanceof Date?"date":a&&typeof a=="object"?Array.isArray(a)?"array":"_bsontype"in a?"text":"json":typeof a=="boolean"?"boolean":typeof a=="number"||typeof a=="bigint"?"number":"text",to=a=>{switch(a){case"number":return"numeric";case"boolean":return"boolean";case"json":return"json";case"date":return"date";case"array":return"array";case"enum":return"enum";default:return"text"}},Yr=a=>typeof a=="string"&&rt(a),Ke=a=>nt(a),ro=a=>{if(!Number.isFinite(a))return"n/a";let e=["B","KB","MB","GB","TB"],t=a,r=0;for(;t>=1024&&r<e.length-1;)t/=1024,r++;return`${t.toFixed(1)} ${e[r]}`},Gr=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),no=a=>{let e=a.trim();if(Gr.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},ao=a=>{if(a==null)return"null";if(a instanceof Date)return"date";if(typeof a=="boolean")return"bool";if(typeof a=="number")return Number.isInteger(a)?"int":"double";if(typeof a=="bigint")return"long";if(Array.isArray(a))return"array";if(typeof a=="object"){let e=a._bsontype;return e==="ObjectId"?"objectId":e==="Decimal128"?"decimal":e==="Binary"?"binData":e==="Timestamp"?"timestamp":e?e.toLowerCase():"object"}return"string"},oo=(a,e)=>{if(a!=null&&a.trim()!=="")try{return JSON.parse(a)}catch{return a}switch(e){case"string":return"";case"int":case"long":case"double":case"decimal":return 0;case"bool":return!1;case"array":return[];case"object":return{};case"date":return new Date;default:return null}},xe=a=>{if(a._id&&typeof a._id=="string")return{...a,_id:Ke(a._id)};if(a._id&&typeof a._id=="object"){let e=a._id;if(Array.isArray(e.$in))return{...a,_id:{...e,$in:e.$in.map(t=>typeof t=="string"?Ke(t):t)}};if(Array.isArray(e.$nin))return{...a,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?Ke(t):t)}}}return a},ot=class extends oe{runQuery(){throw new v(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new v(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(Ie(t)))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"int":case"long":case"double":case"decimal":return"number";case"bool":return"boolean";case"date":return"date";case"array":return"array";case"object":return"json";default:return"text"}}mapFromUniversalType(e){switch(e){case"number":return"double";case"boolean":return"bool";case"date":return"date";case"array":return"array";case"json":return"object";default:return"string"}}wrapError(e){if(e instanceof v)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new v(503,{message:e.message})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:r,cursor:n,limit:o,direction:s="asc",sort:c,order:i,filters:l}=e,m=(await ee(r)).collection(t),p=Vr(l??[]),d=Lt(c??"",i),f=o&&o>0?o:50,b=Wr(n),g=Number.isFinite(b)&&b>=0?b:0,h=s==="desc"?Math.max(g-f,0):g,[C,R]=await Promise.all([m.countDocuments(p),m.find(p).sort(d).skip(h).limit(f).toArray()]),N=R.map(S=>Ie(S)),w=h+f,T=Math.max(h-f,0);return{data:N,meta:{limit:f,total:C,hasNextPage:w<C,hasPreviousPage:h>0,nextCursor:w<C?Pt(w):null,prevCursor:h>0?Pt(T):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let s=(await(await ee(t)).collection(e).find({}).limit(1e4).toArray()).map(i=>Ie(i));return{cols:Array.from(new Set(s.flatMap(i=>Object.keys(i)))),rows:s}}catch(r){throw this.wrapError(r)}}async getDatabasesList(){try{let n=(await(await $t()).db().admin().listDatabases()).databases??[];if(!n[0])throw new v(500,{message:"No databases returned from MongoDB"});return n.map(o=>({name:o.name,size:ro(o.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:Ot()}}async getDatabaseConnectionInfo(){try{let t=(await $t()).db().admin(),r=Se(),n={};try{n=await t.serverStatus()}catch{}return{host:r.host,port:r.port,user:"n/a",database:Ot(),version:n.version??"unknown",active_connections:n.connections?.current??0,max_connections:(n.connections?.current??0)+(n.connections?.available??0)}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=await ee(e),r=await t.listCollections().toArray(),n=[];for(let o of r){let s=await t.collection(o.name).estimatedDocumentCount();n.push({tableName:o.name,rowCount:s})}return n}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){try{let r=e?.tableName??"",n=await ee(t);if((await n.listCollections({name:r}).toArray()).length>0)throw new v(400,{message:`Collection "${r}" already exists`});let s=e?.fields??[];if(s.length===0){await n.createCollection(r);return}let c={},i=[];for(let l of s){let u=no(l.columnType);if(!Gr.has(u))throw new v(400,{message:`Unsupported MongoDB BSON type "${l.columnType}" for field "${l.columnName}"`});l.isArray?c[l.columnName]={bsonType:"array",...u!=="array"?{items:{bsonType:u}}:{}}:c[l.columnName]={bsonType:u},l.isNullable||i.push(l.columnName)}await n.createCollection(r,{validator:{$jsonSchema:{bsonType:"object",required:i,properties:c,additionalProperties:!0}},validationAction:"error"})}catch(r){throw this.wrapError(r)}}async deleteTable({tableName:e,db:t}){try{let n=(await ee(t)).collection(e),o=await n.estimatedDocumentCount();return await n.drop(),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async getTableSchema({tableName:e,db:t}){try{let r=await ee(t);if((await r.listCollections({name:e}).toArray()).length===0)throw new v(404,{message:`Collection "${e}" does not exist`});let o=r.collection(e),s=await o.find({}).limit(200).toArray(),c=await o.estimatedDocumentCount(),i=new Map,l=new Map;for(let d of s)for(let[f,b]of Object.entries(d)){let g=ao(b);i.has(f)||(i.set(f,new Set),l.set(f,0)),i.get(f)?.add(g),l.set(f,(l.get(f)??0)+1)}let u={},m=[];for(let[d,f]of i.entries()){let b=l.get(d)??0,g=Array.from(f).filter(C=>C!=="null"),h=f.has("null")||b<s.length;b===s.length&&s.length>0&&!h&&m.push(d),u[d]=g.length===1?{bsonType:h?[g[0],"null"]:g[0]}:{bsonType:h?[...g,"null"]:g}}let p={collection:e,estimatedDocumentCount:c,sampledDocuments:s.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(p,null,2)}catch(r){throw this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let o=await(await ee(t)).collection(e).find({}).limit(200).toArray(),s=o.length,c=new Map,i=(l,u)=>{let m=eo(u);if(!c.has(l))c.set(l,{types:new Set([m]),nullable:!1,presentCount:1});else{let p=c.get(l);p.types.add(m),p.presentCount+=1}};for(let l of o)for(let[u,m]of Object.entries(l)){if(m==null){if(!c.has(u))c.set(u,{types:new Set(["text"]),nullable:!0,presentCount:1});else{let p=c.get(u);p.nullable=!0,p.presentCount+=1}continue}i(u,m)}if(s>0)for(let l of c.values())l.presentCount<s&&(l.nullable=!0);return c.has("_id")||c.set("_id",{types:new Set(["text"]),nullable:!1,presentCount:s}),Array.from(c.entries()).map(([l,u])=>{let m=u.types.values().next().value??"text";return{columnName:l,dataType:m,dataTypeLabel:to(m),isNullable:u.nullable,columnDefault:null,isPrimaryKey:l==="_id",isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}})}catch(r){throw this.wrapError(r)}}async addColumn(e){try{let{tableName:t,columnName:r,columnType:n,defaultValue:o,isNullable:s,db:c}=e,i=await ee(c),l=await i.listCollections({name:t}).toArray();if(l.length===0)throw new v(404,{message:`Collection "${t}" does not exist`});if(await i.collection(t).findOne({[r]:{$exists:!0}}))throw new v(409,{message:`Field "${r}" already exists in collection "${t}"`});let m=oo(o,n);await i.collection(t).updateMany({},{$set:{[r]:m}});let d=l[0].options?.validator?.$jsonSchema??{},f={...d.properties??{},[r]:{bsonType:s?[n,"null"]:n}},b=[...d.required??[]];!s&&!b.includes(r)&&b.push(r),await i.command({collMod:t,validator:{$jsonSchema:{...d,bsonType:"object",properties:f,...b.length>0?{required:b}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{return{deletedCount:(await(await ee(r)).collection(e).updateMany({},{$unset:{[t]:""}})).modifiedCount}}catch(n){throw this.wrapError(n)}}async alterColumn(e){try{let{tableName:t,columnName:r,columnType:n,isNullable:o,db:s}=e,c=await ee(s),i=await c.listCollections({name:t}).toArray();if(i.length===0)throw new v(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new v(400,{message:'Cannot alter the "_id" field'});let u=i[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},p=[...u.required??[]];m[r]={bsonType:o?[n,"null"]:n};let d=p.indexOf(r);!o&&d===-1?p.push(r):o&&d!==-1&&p.splice(d,1),await c.command({collMod:t,validator:{$jsonSchema:{...u,bsonType:"object",properties:m,...p.length>0?{required:p}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async renameColumn(e){try{let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=await ee(o);if((await s.listCollections({name:t}).toArray()).length===0)throw new v(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new v(400,{message:'Cannot rename the "_id" field'});if(!await s.collection(t).findOne({[r]:{$exists:!0}}))throw new v(404,{message:`Field "${r}" does not exist in collection "${t}"`});if(await s.collection(t).findOne({[n]:{$exists:!0}}))throw new v(409,{message:`Field "${n}" already exists in collection "${t}"`});await s.collection(t).updateMany({[r]:{$exists:!0}},{$rename:{[r]:n}})}catch(t){throw this.wrapError(t)}}async addRecord({db:e,params:t}){try{let{tableName:r,data:n}=t,s=(await ee(e)).collection(r),c=Ie(n);if((c._id===""||c._id===null)&&delete c._id,!(await s.insertOne(c)).insertedId)throw new v(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:n,primaryKey:o}=t,c=(await ee(e)).collection(r),i=0,l=o||"_id",u=new Map;for(let m of n){let p=m.rowData[l];if(p==null)throw new v(400,{message:`Primary key "${l}" not found in row data.`});u.has(p)||u.set(p,{}),u.get(p)[m.columnName]=m.value}for(let[m,p]of u.entries()){let d=l==="_id"&&Yr(m)?Ke(m):m,f=await c.updateOne({[l]:d},{$set:p});if(f.matchedCount===0)throw new v(404,{message:`Record with ${l} = ${String(m)} not found in "${r}"`});i+=f.modifiedCount}return{updatedCount:i}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:n}=e,s=(await ee(n)).collection(t),c=r[0]?.columnName??"_id",i=r.map(u=>c==="_id"&&Yr(u.value)?Ke(u.value):u.value);return{deletedCount:(await s.deleteMany({[c]:{$in:i}})).deletedCount??0}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:r,db:n}=e;if(!r||r.length===0)throw new v(400,{message:"At least one record is required"});let s=(await ee(n)).collection(t),c=r.map(l=>{let u=Ie(l);return(u._id===""||u._id===null)&&delete u._id,u}),i=await s.insertMany(c,{ordered:!1});return{success:!0,message:`Successfully inserted ${i.insertedCount} record${i.insertedCount!==1?"s":""}`,successCount:i.insertedCount,failureCount:r.length-i.insertedCount}}catch(t){throw this.wrapError(t)}}async executeQuery({query:e,db:t}){try{if(!e?.trim())throw new v(400,{message:"Query is required"});let r;try{r=JSON.parse(e)}catch{throw new v(400,{message:"Mongo query must be valid JSON"})}if(!r.collection||!r.operation)throw new v(400,{message:"Mongo query must include collection and operation"});let o=(await ee(t)).collection(r.collection),s=performance.now(),c=[],i=0,l;switch(r.operation){case"find":{let d=xe(r.filter??{}),f=o.find(d,r.options??{});f.sort(r.sort??Lt("",void 0)),r.skip&&f.skip(r.skip),r.limit&&f.limit(r.limit),c=await f.toArray(),i=c.length;break}case"aggregate":{c=await o.aggregate(r.pipeline??[],r.options??{}).toArray(),i=c.length;break}case"insertOne":{let d=r.document;if(!d)throw new v(400,{message:"document is required"});i=(await o.insertOne(d)).insertedId?1:0,l="OK";break}case"insertMany":{let d=r.document;if(!Array.isArray(d))throw new v(400,{message:"document array is required"});i=(await o.insertMany(d)).insertedCount??0,l="OK";break}case"updateOne":{let d=xe(r.filter??{});if(!r.update)throw new v(400,{message:"update is required"});let f=await o.updateOne(d,r.update,r.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"updateMany":{let d=xe(r.filter??{});if(!r.update)throw new v(400,{message:"update is required"});let f=await o.updateMany(d,r.update,r.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"deleteOne":{let d=xe(r.filter??{});i=(await o.deleteOne(d,r.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let d=xe(r.filter??{});i=(await o.deleteMany(d,r.options??{})).deletedCount??0,l="OK";break}case"count":{let d=xe(r.filter??{});i=await o.countDocuments(d),c=[{count:i}],l="OK";break}default:throw new v(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-s,m=c.map(d=>Ie(d));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:i,duration:u,message:l}}catch(r){throw this.wrapError(r)}}}});import{z as ve}from"zod";var D,Jr,Ve,so,io,ce,ue=E(()=>{"use strict";D=ve.object({db:ve.string("Database name is required")}),Jr=["pg","mysql","mssql","mongodb","sqlite"],Ve=ve.enum(Jr,{message:"Invalid database type"}),so=D.extend({dbType:Ve}),io=ve.object({dbType:Ve}),ce=ve.object({tableName:ve.string("Table name is required")})});import{z as ye}from"zod";var me,lo,co,Xr=E(()=>{"use strict";ue();me=ye.object({columnName:ye.string("Column name is required"),columnType:ye.string("Column type is required"),defaultValue:ye.string().optional(),isPrimaryKey:ye.boolean().default(!1),isNullable:ye.boolean().default(!1),isUnique:ye.boolean().default(!1),isIdentity:ye.boolean().default(!1),isArray:ye.boolean().default(!1)}),lo=ce,co=ye.object({db:D.shape.db,tableName:ce.shape.tableName,columnName:me.shape.columnName,columnType:me.shape.columnType,defaultValue:me.shape.defaultValue,isPrimaryKey:me.shape.isPrimaryKey,isNullable:me.shape.isNullable,isUnique:me.shape.isUnique,isIdentity:me.shape.isIdentity,isArray:me.shape.isArray})});import{z as We}from"zod";var It,Zr=E(()=>{"use strict";It=We.object({tableName:We.string("Table name is required"),data:We.record(We.string("Column name is required"),We.any())})});import{z as de}from"zod";var xt,te,uo,mo,st=E(()=>{"use strict";ue();xt=D.extend({cascade:de.string().optional().transform(a=>a==="true")}),te=de.object({tableName:de.string("Table name is required"),columnName:de.string("Column name is required")}),uo=de.object({db:D.shape.db,tableName:te.shape.tableName,columnName:te.shape.columnName,cascade:de.boolean().optional()}),mo=de.object({message:de.string("Message is required"),tableName:de.string("Table name is required"),columnName:de.string("Column name is required"),deletedCount:de.number("Deleted count is required").default(0)})});import{z as ze}from"zod";var ke,po,fo,en=E(()=>{"use strict";ue();st();ke=ze.object({columnType:ze.string("Column type is required"),isNullable:ze.boolean(),defaultValue:ze.string().nullable().optional()}),po=te,fo=ze.object({db:D.shape.db,tableName:te.shape.tableName,columnName:te.shape.columnName,columnType:ke.shape.columnType,isNullable:ke.shape.isNullable,defaultValue:ke.shape.defaultValue})});var tn=E(()=>{"use strict"});import{z as qe}from"zod";var vt,rn=E(()=>{"use strict";vt=qe.object({tableName:qe.string().min(1,"Table name is required"),records:qe.array(qe.record(qe.string(),qe.any())).min(1,"At least one record is required")})});import{z as pe}from"zod";var bo,kt,nn=E(()=>{"use strict";ue();bo=pe.object({type:pe.string(),content:pe.string().optional()}).passthrough(),kt=pe.object({messages:pe.array(pe.object({id:pe.string(),role:pe.enum(["user","assistant","system","tool"]),parts:pe.array(bo)}).passthrough()),data:pe.object({conversationId:pe.string().optional(),db:D.shape.db})})});var an=E(()=>{"use strict"});import{z as ie}from"zod";var yo,on,U,go,sn,ho,qt=E(()=>{"use strict";yo=["text","boolean","number","enum","json","date","array"],on=ie.enum(yo),U={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},go=["int","bigint","smallint","numeric","float","double","money","tinyint","mediumint","bit","boolean","text","varchar","char","tinytext","mediumtext","longtext","json","jsonb","xml","uuid","date","time","timestamp","timestamptz","interval","datetime","year","bytea","inet","cidr","macaddr","macaddr8","point","line","polygon","binary","varbinary","blob","tinyblob","mediumblob","longblob","array","enum","set"],sn=ie.enum(go),ho=ie.object({columnName:ie.string(),dataType:on,dataTypeLabel:sn,isNullable:ie.boolean(),columnDefault:ie.string().nullable(),isPrimaryKey:ie.boolean(),isForeignKey:ie.boolean(),referencedTable:ie.string().nullable(),referencedColumn:ie.string().nullable(),enumValues:ie.array(ie.string()).nullable()})});function it(a){let e=a?.toLowerCase().trim()||"";return e.includes("[]")||e==="date"||e==="time"||e==="time without time zone"||e.startsWith("time(")||e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")||e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?U.date:e==="integer"||e==="int"||e==="int4"||e==="bigint"||e==="int8"||e==="smallint"||e==="int2"||e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")||e==="real"||e==="float4"||e==="double precision"||e==="float8"||e==="float"||e==="serial"||e==="serial4"||e==="bigserial"||e==="serial8"||e==="money"?U.number:e==="boolean"||e==="bool"?U.boolean:e==="json"||e==="jsonb"?U.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?U.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")||e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"||e==="uuid"||e==="interval"||e.startsWith("interval")||e==="bytea"||e==="point"||e==="line"||e==="polygon"||e==="inet"||e==="cidr"||e==="macaddr"||e==="macaddr8"?U.text:U.text}function Ut(a){if(!a)return y.text;let e=a.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?y.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?y.bigint:e==="smallint"||e==="int2"?y.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?y.numeric:e==="real"||e==="float4"?y.float:e==="double precision"||e==="float8"||e==="float"?y.double:e==="money"?y.money:e==="boolean"||e==="bool"?y.boolean:e==="text"?y.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?y.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?y.char:e==="json"?y.json:e==="jsonb"?y.jsonb:e==="xml"?y.xml:e==="uuid"?y.uuid:e==="date"?y.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?y.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?y.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?y.timestamptz:e==="interval"||e.startsWith("interval")?y.interval:e==="bytea"?y.bytea:e==="inet"?y.inet:e==="cidr"?y.cidr:e==="macaddr"?y.macaddr:e==="macaddr8"?y.macaddr8:e==="point"?y.point:e==="line"?y.line:e==="polygon"?y.polygon:e.startsWith("array")||e.includes("[]")?y.text:e.startsWith("user-defined")||e==="enum"?y.enum:y.text}function lt(a,e){let t=a?.toLowerCase().trim()||"",r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?U.boolean:t==="tinyint"||t==="smallint"||t==="mediumint"||t==="int"||t==="integer"||t==="bigint"||t==="decimal"||t==="numeric"||t==="float"||t==="double"||t==="real"||t==="bit"?U.number:t==="boolean"||t==="bool"?U.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?U.date:t==="json"?U.json:t==="enum"||t==="set"?U.enum:U.text}function Ft(a,e){if(!a)return y.text;let t=a.toLowerCase().trim(),r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?y.boolean:t==="tinyint"?y.tinyint:t==="smallint"?y.smallint:t==="mediumint"?y.mediumint:t==="int"||t==="integer"?y.int:t==="bigint"?y.bigint:t==="decimal"||t==="numeric"?y.numeric:t==="float"||t==="real"?y.float:t==="double"?y.double:t==="bit"?y.bit:t==="boolean"||t==="bool"?y.boolean:t==="char"?y.char:t==="varchar"?y.varchar:t==="tinytext"?y.tinytext:t==="text"?y.text:t==="mediumtext"?y.mediumtext:t==="longtext"?y.longtext:t==="binary"?y.binary:t==="varbinary"?y.varbinary:t==="tinyblob"?y.tinyblob:t==="blob"?y.blob:t==="mediumblob"?y.mediumblob:t==="longblob"?y.longblob:t==="json"?y.json:t==="date"?y.date:t==="time"?y.time:t==="datetime"?y.datetime:t==="timestamp"?y.timestamp:t==="year"?y.year:t==="enum"?y.enum:t==="set"?y.set:y.text}function ct(a){let e=a?.toLowerCase().trim()||"";return e==="tinyint"||e==="smallint"||e==="int"||e==="bigint"||e==="decimal"||e==="numeric"||e==="float"||e==="real"||e==="money"||e==="smallmoney"?U.number:e==="bit"?U.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?U.date:e==="json"?U.json:U.text}function Bt(a){if(!a)return y.text;let e=a.toLowerCase().trim();return e==="tinyint"?y.tinyint:e==="smallint"?y.smallint:e==="int"?y.int:e==="bigint"?y.bigint:e==="decimal"||e==="numeric"?y.numeric:e==="float"||e==="real"?y.float:e==="money"||e==="smallmoney"?y.money:e==="bit"?y.boolean:e==="char"?y.char:e==="varchar"?y.varchar:e==="text"?y.text:e==="nchar"?y.char:e==="nvarchar"?y.varchar:e==="ntext"?y.text:e==="binary"?y.binary:e==="varbinary"?y.varbinary:e==="image"?y.blob:e==="uniqueidentifier"?y.uuid:e==="date"?y.date:e==="time"?y.time:e==="datetime"||e==="datetime2"||e==="smalldatetime"?y.datetime:e==="datetimeoffset"?y.timestamptz:e==="json"?y.json:e==="xml"?y.xml:y.text}function ut(a){let e=a?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?U.boolean:e==="json"?U.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?U.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?U.number:U.text}function jt(a){let e=a?.toLowerCase().trim()||"";return e==="integer"||e==="int"?y.int:e==="bigint"||e.startsWith("bigint(")?y.bigint:e==="smallint"||e.startsWith("smallint(")?y.smallint:e==="tinyint"||e.startsWith("tinyint(")?y.tinyint:e==="mediumint"||e.startsWith("mediumint(")?y.mediumint:e.includes("int")?y.int:e==="real"||e==="float"||e.startsWith("float(")?y.float:e==="double"||e==="double precision"||e.startsWith("double(")?y.double:e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?y.numeric:e==="boolean"||e==="bool"?y.boolean:e==="text"||e==="clob"?y.text:e==="varchar"||e.startsWith("varchar(")?y.varchar:e==="char"||e.startsWith("char(")?y.char:e==="json"?y.json:e==="date"?y.date:e==="time"?y.time:e==="datetime"?y.datetime:e==="timestamp"?y.timestamp:e==="blob"?y.blob:y.text}var y,ln=E(()=>{"use strict";qt();y={int:"int",bigint:"bigint",smallint:"smallint",numeric:"numeric",float:"float",double:"double",money:"money",tinyint:"tinyint",mediumint:"mediumint",bit:"bit",boolean:"boolean",text:"text",varchar:"varchar",char:"char",tinytext:"tinytext",mediumtext:"mediumtext",longtext:"longtext",json:"json",jsonb:"jsonb",xml:"xml",uuid:"uuid",date:"date",time:"time",timestamp:"timestamp",timestamptz:"timestamptz",interval:"interval",datetime:"datetime",year:"year",bytea:"bytea",inet:"inet",cidr:"cidr",macaddr:"macaddr",macaddr8:"macaddr8",point:"point",line:"line",polygon:"polygon",binary:"binary",varbinary:"varbinary",blob:"blob",tinyblob:"tinyblob",mediumblob:"mediumblob",longblob:"longblob",array:"array",enum:"enum",set:"set"}});import{z as X}from"zod";var cn,Ht,un,mn,Kt,dn=E(()=>{"use strict";cn=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],Ht=X.enum(cn),un=X.object({columnName:X.string("Column name is required"),columnType:X.string("Column type is required"),defaultValue:X.string().optional(),isPrimaryKey:X.boolean().default(!1),isNullable:X.boolean().default(!1),isUnique:X.boolean().default(!1),isIdentity:X.boolean().default(!1),isArray:X.boolean().default(!1)}),mn=X.object({columnName:X.string("Column name is required"),referencedTable:X.string("Referenced table is required"),referencedColumn:X.string("Referenced column is required"),onUpdate:Ht.default("NO ACTION"),onDelete:Ht.default("NO ACTION")}),Kt=X.object({tableName:X.string("Table name is required"),fields:X.array(un).min(1,"At least one field is required"),foreignKeys:X.array(mn).optional()})});import{z as re}from"zod";var pn,To,Eo,fn=E(()=>{"use strict";ue();pn=re.object({name:re.string("Name is required"),size:re.string("Size is required"),owner:re.string("Owner is required"),encoding:re.string("Encoding is required")}),To=re.object({databases:re.array(pn),dbType:Ve}),Eo=re.object({version:re.string("Version is required"),database:re.string("Database is required"),user:re.string("User is required"),host:re.string("Host is required").nullable(),port:re.number("Port is required").nullable(),active_connections:re.coerce.number("Active connections is required"),max_connections:re.coerce.number("Max connections is required")})});var bn=E(()=>{"use strict"});import{z as Ue}from"zod";var mt,yn=E(()=>{"use strict";mt=Ue.object({tableName:Ue.string("Table name is required"),primaryKeys:Ue.array(Ue.object({columnName:Ue.string("Column name is required"),value:Ue.any()})).min(1,"At least one primary key is required")})});import{z as Co}from"zod";var Vt,gn=E(()=>{"use strict";ue();Vt=D.extend({cascade:Co.string().optional().transform(a=>a==="true")})});import{z as hn}from"zod";var Wt,Tn=E(()=>{"use strict";Wt=hn.object({query:hn.string("Query is required")})});import{z as wo}from"zod";var En,zt,Cn=E(()=>{"use strict";ue();En=["csv","xlsx","json"],zt=D.extend({format:wo.enum(En,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});var wn=E(()=>{"use strict"});import{z as Yt}from"zod";var dt,Ro,So,Rn=E(()=>{"use strict";ue();st();dt=Yt.object({newColumnName:Yt.string("New column name is required")}),Ro=te,So=Yt.object({db:D.shape.db,tableName:te.shape.tableName,columnName:te.shape.columnName,newColumnName:dt.shape.newColumnName})});import{z as F}from"zod";var No,Ye,Ao,Sn,Do,Gt,Nn=E(()=>{"use strict";ue();No=F.object({columnName:F.string(),operator:F.string(),value:F.string()}),Ye=["asc","desc"],Ao=F.object({columnName:F.string(),direction:F.enum(Ye)}),Sn=F.object({limit:F.number(),total:F.number(),hasNextPage:F.boolean(),hasPreviousPage:F.boolean(),nextCursor:F.string().nullable(),prevCursor:F.string().nullable()}),Do=F.object({data:F.array(F.record(F.string(),F.unknown())),meta:Sn}),Gt=F.object({db:D.shape.db,cursor:F.string().optional(),limit:F.string().optional().default("50").transform(Number),direction:F.enum(Ye).optional().default(Ye[0]),sort:F.string().optional().transform(a=>{if(!a)return"";try{let e=JSON.parse(a);return Array.isArray(e)?e:a}catch{return a}}),order:F.enum(Ye).optional(),filters:F.string().optional().transform(a=>{if(!a)return[];try{return JSON.parse(a)}catch{return[]}})})});import{z as pt}from"zod";var _o,An=E(()=>{"use strict";_o=pt.object({tableName:pt.string("Table name is required"),schemaName:pt.string().optional(),rowCount:pt.coerce.number("Row count is required")})});import{z as Dn}from"zod";var $o,_n=E(()=>{"use strict";$o=Dn.object({schema:Dn.string()})});import{z as ge}from"zod";var Qt,$n=E(()=>{"use strict";Qt=ge.object({tableName:ge.string("Table name is required"),primaryKey:ge.string("Primary key is required").default("id"),updates:ge.array(ge.object({rowData:ge.record(ge.string("Column name is required"),ge.any()),columnName:ge.string("Column name is required"),value:ge.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var On={};pr(On,{DATABASE_TYPES:()=>Jr,DataTypes:()=>U,FOREIGN_KEY_ACTIONS:()=>cn,FORMAT_TYPES:()=>En,StandardizedDataType:()=>y,addColumnParamSchema:()=>lo,addColumnParamsSchema:()=>co,addColumnSchema:()=>me,addRecordSchema:()=>It,alterColumnParamSchema:()=>po,alterColumnParamsSchema:()=>fo,alterColumnSchema:()=>ke,bulkInsertRecordsSchema:()=>vt,chatSchema:()=>kt,columnInfoSchema:()=>ho,connectionInfoSchema:()=>Eo,createTableSchema:()=>Kt,currentDatabaseSchema:()=>so,dataTypesSchema:()=>on,databaseInfoSchema:()=>pn,databaseListSchema:()=>To,databaseSchema:()=>D,databaseTypeParamSchema:()=>io,databaseTypeSchema:()=>Ve,deleteColumnParamSchema:()=>te,deleteColumnParamsSchema:()=>uo,deleteColumnQuerySchema:()=>xt,deleteColumnSuccessResponseSchema:()=>mo,deleteRecordSchema:()=>mt,deleteTableQuerySchema:()=>Vt,executeQuerySchema:()=>Wt,exportTableSchema:()=>zt,fieldDataSchema:()=>un,filterSchema:()=>No,foreignKeyActionSchema:()=>Ht,foreignKeyDataSchema:()=>mn,mapMssqlToDataType:()=>ct,mapMysqlToDataType:()=>lt,mapPostgresToDataType:()=>it,mapSqliteToDataType:()=>ut,renameColumnParamSchema:()=>Ro,renameColumnParamsSchema:()=>So,renameColumnSchema:()=>dt,sortDirections:()=>Ye,sortSchema:()=>Ao,standardizeDataTypeLabel:()=>Ut,standardizeMssqlDataTypeLabel:()=>Bt,standardizeMysqlDataTypeLabel:()=>Ft,standardizeSqliteDataTypeLabel:()=>jt,standardizedDataTypeSchema:()=>sn,tableDataMetaSchema:()=>Sn,tableDataQuerySchema:()=>Gt,tableDataResultSchema:()=>Do,tableInfoSchema:()=>_o,tableNameSchema:()=>ce,tableSchemaResultSchema:()=>$o,updateRecordsSchema:()=>Qt});var he=E(()=>{"use strict";Xr();Zr();en();tn();rn();nn();an();ln();qt();dn();ue();fn();bn();st();yn();gn();Tn();Cn();wn();Rn();Nn();An();_n();$n()});function Jt(a,e=0){if(a.length===0)return{clause:"",values:[],nextIdx:e};let t=[],r=[],n=e;for(let o of a){let s=`[${o.columnName}]`;switch(o.operator){case"=":case"!=":case">":case">=":case"<":case"<=":t.push(`${s} ${o.operator} @p${n}`),r.push(o.value),n++;break;case"is":o.value.toLowerCase()==="null"?t.push(`${s} IS NULL`):(t.push(`${s} = @p${n}`),r.push(o.value),n++);break;case"is not":o.value.toLowerCase()==="null"?t.push(`${s} IS NOT NULL`):(t.push(`${s} != @p${n}`),r.push(o.value),n++);break;case"like":case"ilike":t.push(`${s} LIKE @p${n}`),r.push(o.value),n++;break;case"not like":case"not ilike":t.push(`${s} NOT LIKE @p${n}`),r.push(o.value),n++;break;default:break}}return t.length===0?{clause:"",values:[],nextIdx:e}:{clause:`WHERE ${t.join(" AND ")}`,values:r,nextIdx:n}}function Xt(a,e){return Array.isArray(a)?a.length===0?"":`ORDER BY ${a.map(t=>`[${t.columnName}] ${t.direction.toUpperCase()}`).join(", ")}`:a&&typeof a=="string"?`ORDER BY [${a}] ${e?.toUpperCase()||"ASC"}`:""}function Zt(a,e){if(e)return"NVARCHAR(MAX)";let t=a.toLowerCase().trim();return{serial:"INT IDENTITY(1,1)",serial4:"INT IDENTITY(1,1)",bigserial:"BIGINT IDENTITY(1,1)",serial8:"BIGINT IDENTITY(1,1)",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",tinyint:"TINYINT",numeric:"NUMERIC",decimal:"DECIMAL",real:"REAL",float4:"REAL",float:"FLOAT","double precision":"FLOAT",float8:"FLOAT",money:"MONEY",boolean:"BIT",bool:"BIT",text:"NVARCHAR(MAX)",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"UNIQUEIDENTIFIER",json:"NVARCHAR(MAX)",jsonb:"NVARCHAR(MAX)",xml:"XML",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME2","timestamp without time zone":"DATETIME2","timestamp with time zone":"DATETIMEOFFSET",timestamptz:"DATETIMEOFFSET",interval:"VARCHAR(255)",bytea:"VARBINARY(MAX)",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)"}[t]||a.toUpperCase()}function er(a,e){let t=a.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("newid()")?e.toUpperCase().includes("UNIQUEIDENTIFIER")?"NEWID()":null:t.includes("getdate")||t.includes("current_timestamp")?"GETDATE()":a.trim():t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":a.trim()}function Ln(a,e={}){let t=Zt(a.columnType,a.isArray??!1),r=`[${a.columnName}] ${t}`;if(a.isIdentity&&!t.includes("IDENTITY")&&(r+=" IDENTITY(1,1)"),!a.isNullable&&!a.isPrimaryKey&&(r+=" NOT NULL"),a.defaultValue?.trim()&&!t.includes("IDENTITY")){let n=er(a.defaultValue,t);n!==null&&(r+=` DEFAULT ${n}`)}return e.includeUnique&&a.isUnique&&!a.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&a.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var Pn=E(()=>{"use strict"});import{HTTPException as I}from"hono/http-exception";var Oo,Lo,ft,Mn=E(()=>{"use strict";he();De();_e();He();Pn();Oo=547,Lo=3726,ft=class extends oe{async runQuery(e,t,r){let o=(await B(e)).request();return r.forEach((c,i)=>{o.input(`p${i}`,c)}),(await o.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return ct(e)}mapFromUniversalType(e){return{text:"NVARCHAR(MAX)",number:"INT",boolean:"BIT",json:"NVARCHAR(MAX)",date:"DATETIME2",array:"NVARCHAR(MAX)",enum:"NVARCHAR(255)"}[e]??"NVARCHAR(MAX)"}buildTableDataQuery(e){let{tableName:t,filters:r=[],sort:n=[],order:o="asc",limit:s=50,cursor:c}=e,{clause:i,values:l,nextIdx:u}=Jt(r,0),m=Xt(n,o)||"ORDER BY (SELECT NULL)",p=c?this.decodeOffsetCursor(c):0,d=`SELECT * FROM [${t}] ${i} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,f=[...l,p,s+1],b=`SELECT COUNT(*) as total FROM [${t}] ${i}`;return{sql:d,values:f,countSql:b,countValues:l}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){let{cursor:n,limit:o=50}=e,s=n?this.decodeOffsetCursor(n):0;return{nextCursor:r?this.makeCursor(s+o):null,prevCursor:s>0?this.makeCursor(Math.max(0,s-o)):null}}async getTableData(e){try{let{tableName:t,db:r,limit:n=50,sort:o=[],order:s="asc",cursor:c,filters:i=[]}=e,l=await B(r),u=c?this.decodeOffsetCursor(c):0,{clause:m,values:p,nextIdx:d}=Jt(i,0),f=Xt(o,s)||"ORDER BY (SELECT NULL)",b=l.request();p.forEach((T,S)=>{b.input(`p${S}`,T)});let g=await b.query(`SELECT COUNT(*) as total FROM [${t}] ${m}`),h=Number(g.recordset[0]?.total??0),C=l.request();p.forEach((T,S)=>{C.input(`p${S}`,T)}),C.input(`p${d}`,u),C.input(`p${d+1}`,n+1);let N=(await C.query(`SELECT * FROM [${t}] ${m} ${f} OFFSET @p${d} ROWS FETCH NEXT @p${d+1} ROWS ONLY`)).recordset,w=N.length>n;return w&&(N=N.slice(0,n)),{data:N,meta:{limit:n,total:h,hasNextPage:w,hasPreviousPage:u>0,nextCursor:w?this.makeCursor(u+n):null,prevCursor:u>0?this.makeCursor(Math.max(0,u-n)):null}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){let t=await(await B()).request().query(`
|
|
2
|
+
var _a=Object.defineProperty;var E=(a,e)=>()=>(a&&(e=a(a=0)),e);var fr=(a,e)=>{for(var t in e)_a(a,t,{get:e[t],enumerable:!0})};var br=E(()=>{"use strict"});var yr=E(()=>{"use strict"});var gr=E(()=>{"use strict"});var Tr,hr,be,Er=E(()=>{"use strict";Tr=globalThis.process?.env,hr=Tr?.NODE_ENV,be={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.dbstudio.localhost",API_PREFIX:"/api",IS_DEV:hr==="development",PROXY_URL:Tr?.DB_STUDIO_PROXY_URL??(hr==="development"?"https://proxy.dbstudio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var Cr=E(()=>{"use strict"});var wr,Rt=E(()=>{"use strict";wr={AUTHOR:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",AUTHOR_NAME:"H\xFCsam",AUTHOR_AVATAR:"/avocado.png",AUTHOR_USERNAME:"husamql3",AUTHOR_GITHUB_LINK:"https://github.com/husamql3",SITE_DESCRIPTION:"The modern pgAdmin alternative that works with every database.",SITE_KEYWORDS:["pgadmin alternative","database client","database gui","database browser","sql editor","postgresql client","mysql client","table editor","ai sql","er diagram"],SITE_TITLE:"dbstudio",SITE_NAME:"dbstudio.sh",SITE_URL:"https://dbstudio.sh",SITE_X_LINK:"https://x.com/dbstudio_sh",SITE_GITHUB_LINK:"https://github.com/husamql3/db-studio",SITE_GITHUB_NEW_ISSUE_LINK:"https://github.com/husamql3/db-studio/issues/new/choose",SITE_DOCS_LINK:"https://dbstudio.sh/docs",SITE_CHANGELOG_LINK:"https://dbstudio.sh/changelog",SITE_ROADMAP_LINK:"https://dbstudio.sh/roadmap",SITE_IMAGE:"https://dbstudio.sh/og-image.png",SITE_IMAGE_WIDTH:"1200",SITE_IMAGE_HEIGHT:"630",SITE_IMAGE_ALT:"dbstudio.sh \u2013 Modern database management studio",SITE_COLOR:"#1447e6"}});var Rr=E(()=>{"use strict"});var Ke=E(()=>{"use strict";br();yr();gr();Er();Cr();Rt();Rr()});import{HTTPException as Wa}from"hono/http-exception";function q(a){return se.get(a)}var Dt,se,Re=E(()=>{"use strict";Dt=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new Wa(400,{message:`Unsupported database type: "${e}". Supported types: ${this.getSupportedTypes().join(", ")}`});return t}has(e){return this.adapters.has(e)}getSupportedTypes(){return[...this.adapters.keys()]}},se=new Dt});import{HTTPException as Pe}from"hono/http-exception";import{DatabaseError as za}from"pg";function J(a){throw new Pe(501,{message:`${a} is not implemented for this database type`})}var oe,De=E(()=>{"use strict";oe=class{wrapError(e){if(e instanceof Pe)return e;if(e instanceof Error){let t=e;return t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"||t.code==="ETIMEDOUT"||t.code==="ER_ACCESS_DENIED_ERROR"||t.code==="ER_BAD_HOST_ERROR"||t.code==="ECONNRESET"||t.errno===1045||t.errno===2003||t.errno===2002||e.message.includes("ECONNREFUSED")||e.message.includes("connection refused")||e.message.includes("timeout expired")||e.message.includes("Connection terminated")||e.message.includes("MongoNetworkError")||e.message.includes("MongoServerSelectionError")||e.message.includes("Login failed")||e.message.startsWith("NOAUTH")||e.message.startsWith("WRONGPASS")||e.message.startsWith("LOADING")||e.message.startsWith("BUSY")||e.message.startsWith("READONLY")||e.message.startsWith("CLUSTERDOWN")||e.message.includes("Redis cluster mode is not supported")||e instanceof za&&e.code?.startsWith("08")?new Pe(503,{message:e.message}):new Pe(500,{message:e.message})}return new Pe(500,{message:"Internal server error"})}encodeCursor(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}decodeCursor(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}normalizeRow(e){let t={};for(let[r,n]of Object.entries(e))t[r]=n;return t}async getTableData(e){try{let{db:t,limit:r=50,direction:n="asc"}=e,o=this.buildTableDataQuery(e),s=await this.runQuery(t,o.countSql,o.countValues),c=Number(s[0]?.total??0),i=await this.runQuery(t,o.sql,o.values),l=i.length>r;l&&(i=i.slice(0,r));let u=this.normalizeRows(i);n==="desc"&&(u=u.reverse());let{nextCursor:m,prevCursor:p}=this.buildCursors(e,u,l);return{data:u,meta:{limit:r,total:c,hasNextPage:n==="asc"?l:!!e.cursor,hasPreviousPage:n==="asc"?!!e.cursor:l,nextCursor:m,prevCursor:p}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=`SELECT * FROM ${this.quoteIdentifier(e)}`,n=await this.runQuery(t,r,[]);if(!n||n.length===0)throw new Pe(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(n[0]),rows:n}}catch(r){throw this.wrapError(r)}}getDatabasesList(){return J("getDatabasesList")}getCurrentDatabase(){return J("getCurrentDatabase")}getDatabaseConnectionInfo(){return J("getDatabaseConnectionInfo")}getTablesList(e){return J("getTablesList")}createTable(e){return J("createTable")}deleteTable(e){return J("deleteTable")}getTableSchema(e){return J("getTableSchema")}getTableColumns(e){return J("getTableColumns")}addColumn(e){return J("addColumn")}deleteColumn(e){return J("deleteColumn")}alterColumn(e){return J("alterColumn")}renameColumn(e){return J("renameColumn")}addRecord(e){return J("addRecord")}updateRecords(e){return J("updateRecords")}deleteRecords(e){return J("deleteRecords")}forceDeleteRecords(e){return J("forceDeleteRecords")}bulkInsertRecords(e){return J("bulkInsertRecords")}executeQuery(e){return J("executeQuery")}}});import Ya from"better-sqlite3";import{Redis as Ga}from"ioredis";import{MongoClient as Qa,ObjectId as _t}from"mongodb";import Ja from"mssql";import{createPool as Xa}from"mysql2/promise";import{Pool as vr}from"pg";var $t,ye,kr,qr,Ur,Le,Fr,Br,jr,Hr,Kr,Vr,nt,at,Me=E(()=>{"use strict";$t=class{pgPools=new Map;mysqlPools=new Map;mssqlPools=new Map;mongoClient=null;sqliteDb=null;redisClients=new Map;redisClusterChecked=!1;baseConfig=null;initError=null;constructor(){try{this.initializeBaseConfig()}catch(e){this.initError=e instanceof Error?e:new Error(String(e))}}detectDbType(e){let t=e.protocol.replace(":","");switch(t){case"postgres":case"postgresql":return"pg";case"mysql":case"mysql2":return"mysql";case"mssql":case"sqlserver":return"mssql";case"mongodb":case"mongodb+srv":return"mongodb";case"sqlite":return"sqlite";default:throw new Error(`Unsupported database type: ${t}. Supported types: PostgreSQL (postgres://), MySQL (mysql://), SQL Server (mssql://), MongoDB (mongodb://), SQLite (sqlite://).`)}}initializeBaseConfig(){let e=process.env.DATABASE_URL;if(!e)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");if(e.startsWith("sqlite://")){this.baseConfig={url:e,host:"localhost",port:0,user:"",password:"",dbType:"sqlite"};return}try{let t=new URL(e),r=this.detectDbType(t),n=r==="mysql"?3306:r==="mssql"?1433:r==="mongodb"?27017:r==="redis"?6379:5432;this.baseConfig={url:e,host:t.hostname,port:Number.parseInt(t.port,10)||n,user:t.username,password:t.password,dbType:r}}catch(t){throw new Error(t instanceof Error?t.message:String(t))}}getDbType(){if(this.initError)throw this.initError;if(!this.baseConfig)throw new Error("Base configuration not initialized");return this.baseConfig.dbType}buildConnectionString(e){if(this.initError)throw this.initError;if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType==="sqlite")return this.baseConfig.url;e||(e=new URL(this.baseConfig.url).pathname.slice(1));try{let t=new URL(this.baseConfig.url);return t.pathname=`/${e}`,t.toString()}catch(t){throw new Error(`Failed to build connection string for database "${e}": ${t instanceof Error?t.message:String(t)}`)}}getSqliteDb(){if(!this.baseConfig||this.baseConfig.dbType!=="sqlite")throw new Error("DATABASE_URL is not a sqlite:// connection");if(!this.sqliteDb){let e=this.baseConfig.url.replace(/^sqlite:\/\//,""),t=new Ya(e);t.pragma("journal_mode = WAL"),t.pragma("foreign_keys = ON"),this.sqliteDb=t}return this.sqliteDb}closeSqliteDb(){this.sqliteDb&&(this.sqliteDb.close(),this.sqliteDb=null)}getPgPool(e){let t=this.buildConnectionString(e);if(!this.pgPools.has(t)){let r={connectionString:t,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:2e3},n=new vr(r);n.on("error",o=>{}),this.pgPools.set(t,n)}return this.pgPools.get(t)??new vr({connectionString:t})}getMysqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mysqlPools.has(t)){let n=new URL(t).pathname.slice(1),o=Xa({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:n||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(t,o)}return this.mysqlPools.get(t)}async getMssqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mssqlPools.has(t)){let n=new URL(t).pathname.slice(1),o={server:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:n||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},s=await new Ja.ConnectionPool(o).connect();s.on("error",c=>{}),this.mssqlPools.set(t,s)}return this.mssqlPools.get(t)}getPool(e){return this.getPgPool(e)}async closePgPool(e){let t=this.pgPools.get(e);t&&(await t.end(),this.pgPools.delete(e))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e))}async closePool(e){if(this.baseConfig?.dbType==="sqlite"&&e===this.baseConfig.url){this.closeSqliteDb();return}await this.closePgPool(e),await this.closeMysqlPool(e),await this.closeMssqlPool(e)}async closePoolByDatabase(e){if(this.baseConfig?.dbType==="sqlite"){this.closeSqliteDb();return}let t=this.buildConnectionString(e);await this.closePool(t)}async getMongoClient(){if(!this.mongoClient){if(!this.baseConfig)throw new Error("Base configuration not initialized");let e=new Qa(this.baseConfig.url);try{await e.connect(),this.mongoClient=e}catch(t){try{await e.close()}catch{}throw t}}return this.mongoClient}getMongoDbName(){if(!this.baseConfig)throw new Error("Base configuration not initialized");return new URL(this.baseConfig.url).pathname?.replace(/^\//,"")||"admin"}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType!=="redis")throw new Error("DATABASE_URL is not a redis:// connection");let t=e??this.getRedisDefaultDb(),r=this.redisClients.get(t);if(r)return r;let n=new URL(this.baseConfig.url),o={host:this.baseConfig.host,port:this.baseConfig.port,db:t,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};this.baseConfig.user&&(o.username=decodeURIComponent(this.baseConfig.user)),this.baseConfig.password&&(o.password=decodeURIComponent(this.baseConfig.password)),n.protocol==="rediss:"&&(o.tls={});let s=new Ga(o);try{if(await s.connect(),!this.redisClusterChecked){let c=await s.info("server");if(/^redis_mode:cluster\b/m.test(c))throw await s.quit().catch(()=>{}),new Error("Redis cluster mode is not supported. Use a single-node redis:// connection.");this.redisClusterChecked=!0}}catch(c){throw await s.quit().catch(()=>{}),c}return this.redisClients.set(t,s),s}getRedisDefaultDb(){if(!this.baseConfig)return 0;try{let t=new URL(this.baseConfig.url).pathname.replace(/^\//,"");if(!t)return 0;let r=Number.parseInt(t,10);return Number.isFinite(r)?r:0}catch{return 0}}async closeAll(){let e=Array.from(this.pgPools.entries()).map(async([o,s])=>{await s.end()}),t=Array.from(this.mysqlPools.entries()).map(async([o,s])=>{await s.end()}),r=Array.from(this.mssqlPools.entries()).map(async([o,s])=>{await s.close()});await Promise.all([...e,...t,...r]),this.pgPools.clear(),this.mysqlPools.clear(),this.mssqlPools.clear(),this.mongoClient&&(await this.mongoClient.close(),this.mongoClient=null),this.closeSqliteDb();let n=Array.from(this.redisClients.entries()).map(async([o,s])=>{await s.quit().catch(()=>{})});await Promise.all(n),this.redisClients.clear(),this.redisClusterChecked=!1}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys()),...Array.from(this.mssqlPools.keys())]}},ye=new $t,kr=a=>ye.getPgPool(a),qr=a=>ye.getMysqlPool(a),Ur=async a=>ye.getMssqlPool(a),Le=()=>ye.getDbType(),Fr=()=>ye.getSqliteDb(),Br=()=>ye.getMongoClient(),jr=()=>ye.getMongoDbName(),Hr=a=>ye.getMongoDb(a),Kr=a=>ye.getRedisClient(a),Vr=()=>ye.getRedisDefaultDb(),nt=a=>typeof a=="string"&&_t.isValid(a),at=a=>typeof a=="string"&&_t.isValid(a)?new _t(a):a});var z,H,B,G,Ot,Pt,ee,le,Ie,_e=E(()=>{"use strict";Me();z=a=>kr(a),H=a=>qr(a),B=a=>Ur(a),G=()=>Fr(),Ot=()=>Br(),Pt=()=>jr(),ee=a=>Hr(a),le=a=>Kr(a),Ie=()=>Vr()});function Se(){let a=process.env.DATABASE_URL;if(!a)return{host:"localhost",port:5432};try{let e=new URL(a),t=e.protocol.replace(":",""),r=t==="mongodb"||t==="mongodb+srv"?27017:t==="mssql"||t==="sqlserver"?1433:t==="mysql"||t==="mysql2"?3306:5432;return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||r}}catch{return{host:"localhost",port:5432}}}var Ve=E(()=>{"use strict"});function Wr(a){if(!a||a.length===0)return{};let e=[];for(let t of a){let r=t.columnName,n=eo(t.value),o=t.operator.toLowerCase();if(r)switch(o){case"=":e.push({[r]:n});break;case"!=":e.push({[r]:{$ne:n}});break;case">":e.push({[r]:{$gt:n}});break;case">=":e.push({[r]:{$gte:n}});break;case"<":e.push({[r]:{$lt:n}});break;case"<=":e.push({[r]:{$lte:n}});break;case"is":e.push({[r]:n});break;case"is not":e.push({[r]:{$ne:n}});break;case"like":e.push({[r]:{$regex:ot(String(n)),$options:""}});break;case"not like":e.push({[r]:{$not:{$regex:ot(String(n)),$options:""}}});break;case"ilike":e.push({[r]:{$regex:ot(String(n)),$options:"i"}});break;case"not ilike":e.push({[r]:{$not:{$regex:ot(String(n)),$options:"i"}}});break;default:e.push({[r]:n});break}}return e.length?{$and:e}:{}}function Lt(a,e){return a?Array.isArray(a)?a.length===0?{_id:1}:Object.fromEntries(a.map(t=>[t.columnName,t.direction==="desc"?-1:1])):typeof a=="string"&&a.length>0?{[a]:e==="desc"?-1:1}:{_id:1}:{_id:1}}function Mt(a){return Buffer.from(JSON.stringify({offset:a})).toString("base64url")}function zr(a){if(!a)return 0;try{let e=JSON.parse(Buffer.from(a,"base64url").toString("utf-8"));return typeof e.offset=="number"?e.offset:0}catch{return 0}}var ot,eo,Yr=E(()=>{"use strict";Me();ot=a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),eo=a=>{let e=a.trim();if(e==="null")return null;if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return!Number.isNaN(t)&&e!==""?t:nt(e)?at(e):e}});import{HTTPException as v}from"hono/http-exception";var It,xe,to,ro,Gr,We,no,Qr,ao,oo,so,ve,st,Jr=E(()=>{"use strict";De();_e();Me();Ve();Yr();It=a=>a instanceof Date?a.toISOString():typeof a=="bigint"?a.toString():a&&typeof a=="object"?"_bsontype"in a&&a._bsontype==="ObjectId"?a.toHexString():Array.isArray(a)?a.map(e=>It(e)):Object.fromEntries(Object.entries(a).map(([e,t])=>[e,It(t)])):a,xe=a=>It(a),to=a=>a instanceof Date?"date":a&&typeof a=="object"?Array.isArray(a)?"array":"_bsontype"in a?"text":"json":typeof a=="boolean"?"boolean":typeof a=="number"||typeof a=="bigint"?"number":"text",ro=a=>{switch(a){case"number":return"numeric";case"boolean":return"boolean";case"json":return"json";case"date":return"date";case"array":return"array";case"enum":return"enum";default:return"text"}},Gr=a=>typeof a=="string"&&nt(a),We=a=>at(a),no=a=>{if(!Number.isFinite(a))return"n/a";let e=["B","KB","MB","GB","TB"],t=a,r=0;for(;t>=1024&&r<e.length-1;)t/=1024,r++;return`${t.toFixed(1)} ${e[r]}`},Qr=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),ao=a=>{let e=a.trim();if(Qr.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},oo=a=>{if(a==null)return"null";if(a instanceof Date)return"date";if(typeof a=="boolean")return"bool";if(typeof a=="number")return Number.isInteger(a)?"int":"double";if(typeof a=="bigint")return"long";if(Array.isArray(a))return"array";if(typeof a=="object"){let e=a._bsontype;return e==="ObjectId"?"objectId":e==="Decimal128"?"decimal":e==="Binary"?"binData":e==="Timestamp"?"timestamp":e?e.toLowerCase():"object"}return"string"},so=(a,e)=>{if(a!=null&&a.trim()!=="")try{return JSON.parse(a)}catch{return a}switch(e){case"string":return"";case"int":case"long":case"double":case"decimal":return 0;case"bool":return!1;case"array":return[];case"object":return{};case"date":return new Date;default:return null}},ve=a=>{if(a._id&&typeof a._id=="string")return{...a,_id:We(a._id)};if(a._id&&typeof a._id=="object"){let e=a._id;if(Array.isArray(e.$in))return{...a,_id:{...e,$in:e.$in.map(t=>typeof t=="string"?We(t):t)}};if(Array.isArray(e.$nin))return{...a,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?We(t):t)}}}return a},st=class extends oe{runQuery(){throw new v(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new v(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(xe(t)))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"int":case"long":case"double":case"decimal":return"number";case"bool":return"boolean";case"date":return"date";case"array":return"array";case"object":return"json";default:return"text"}}mapFromUniversalType(e){switch(e){case"number":return"double";case"boolean":return"bool";case"date":return"date";case"array":return"array";case"json":return"object";default:return"string"}}wrapError(e){if(e instanceof v)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new v(503,{message:e.message})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:r,cursor:n,limit:o,direction:s="asc",sort:c,order:i,filters:l}=e,m=(await ee(r)).collection(t),p=Wr(l??[]),d=Lt(c??"",i),f=o&&o>0?o:50,b=zr(n),g=Number.isFinite(b)&&b>=0?b:0,h=s==="desc"?Math.max(g-f,0):g,[C,R]=await Promise.all([m.countDocuments(p),m.find(p).sort(d).skip(h).limit(f).toArray()]),N=R.map(S=>xe(S)),w=h+f,T=Math.max(h-f,0);return{data:N,meta:{limit:f,total:C,hasNextPage:w<C,hasPreviousPage:h>0,nextCursor:w<C?Mt(w):null,prevCursor:h>0?Mt(T):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let s=(await(await ee(t)).collection(e).find({}).limit(1e4).toArray()).map(i=>xe(i));return{cols:Array.from(new Set(s.flatMap(i=>Object.keys(i)))),rows:s}}catch(r){throw this.wrapError(r)}}async getDatabasesList(){try{let n=(await(await Ot()).db().admin().listDatabases()).databases??[];if(!n[0])throw new v(500,{message:"No databases returned from MongoDB"});return n.map(o=>({name:o.name,size:no(o.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:Pt()}}async getDatabaseConnectionInfo(){try{let t=(await Ot()).db().admin(),r=Se(),n={};try{n=await t.serverStatus()}catch{}return{host:r.host,port:r.port,user:"n/a",database:Pt(),version:n.version??"unknown",active_connections:n.connections?.current??0,max_connections:(n.connections?.current??0)+(n.connections?.available??0)}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=await ee(e),r=await t.listCollections().toArray(),n=[];for(let o of r){let s=await t.collection(o.name).estimatedDocumentCount();n.push({tableName:o.name,rowCount:s})}return n}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){try{let r=e?.tableName??"",n=await ee(t);if((await n.listCollections({name:r}).toArray()).length>0)throw new v(400,{message:`Collection "${r}" already exists`});let s=e?.fields??[];if(s.length===0){await n.createCollection(r);return}let c={},i=[];for(let l of s){let u=ao(l.columnType);if(!Qr.has(u))throw new v(400,{message:`Unsupported MongoDB BSON type "${l.columnType}" for field "${l.columnName}"`});l.isArray?c[l.columnName]={bsonType:"array",...u!=="array"?{items:{bsonType:u}}:{}}:c[l.columnName]={bsonType:u},l.isNullable||i.push(l.columnName)}await n.createCollection(r,{validator:{$jsonSchema:{bsonType:"object",required:i,properties:c,additionalProperties:!0}},validationAction:"error"})}catch(r){throw this.wrapError(r)}}async deleteTable({tableName:e,db:t}){try{let n=(await ee(t)).collection(e),o=await n.estimatedDocumentCount();return await n.drop(),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async getTableSchema({tableName:e,db:t}){try{let r=await ee(t);if((await r.listCollections({name:e}).toArray()).length===0)throw new v(404,{message:`Collection "${e}" does not exist`});let o=r.collection(e),s=await o.find({}).limit(200).toArray(),c=await o.estimatedDocumentCount(),i=new Map,l=new Map;for(let d of s)for(let[f,b]of Object.entries(d)){let g=oo(b);i.has(f)||(i.set(f,new Set),l.set(f,0)),i.get(f)?.add(g),l.set(f,(l.get(f)??0)+1)}let u={},m=[];for(let[d,f]of i.entries()){let b=l.get(d)??0,g=Array.from(f).filter(C=>C!=="null"),h=f.has("null")||b<s.length;b===s.length&&s.length>0&&!h&&m.push(d),u[d]=g.length===1?{bsonType:h?[g[0],"null"]:g[0]}:{bsonType:h?[...g,"null"]:g}}let p={collection:e,estimatedDocumentCount:c,sampledDocuments:s.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(p,null,2)}catch(r){throw this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let o=await(await ee(t)).collection(e).find({}).limit(200).toArray(),s=o.length,c=new Map,i=(l,u)=>{let m=to(u);if(!c.has(l))c.set(l,{types:new Set([m]),nullable:!1,presentCount:1});else{let p=c.get(l);p.types.add(m),p.presentCount+=1}};for(let l of o)for(let[u,m]of Object.entries(l)){if(m==null){if(!c.has(u))c.set(u,{types:new Set(["text"]),nullable:!0,presentCount:1});else{let p=c.get(u);p.nullable=!0,p.presentCount+=1}continue}i(u,m)}if(s>0)for(let l of c.values())l.presentCount<s&&(l.nullable=!0);return c.has("_id")||c.set("_id",{types:new Set(["text"]),nullable:!1,presentCount:s}),Array.from(c.entries()).map(([l,u])=>{let m=u.types.values().next().value??"text";return{columnName:l,dataType:m,dataTypeLabel:ro(m),isNullable:u.nullable,columnDefault:null,isPrimaryKey:l==="_id",isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}})}catch(r){throw this.wrapError(r)}}async addColumn(e){try{let{tableName:t,columnName:r,columnType:n,defaultValue:o,isNullable:s,db:c}=e,i=await ee(c),l=await i.listCollections({name:t}).toArray();if(l.length===0)throw new v(404,{message:`Collection "${t}" does not exist`});if(await i.collection(t).findOne({[r]:{$exists:!0}}))throw new v(409,{message:`Field "${r}" already exists in collection "${t}"`});let m=so(o,n);await i.collection(t).updateMany({},{$set:{[r]:m}});let d=l[0].options?.validator?.$jsonSchema??{},f={...d.properties??{},[r]:{bsonType:s?[n,"null"]:n}},b=[...d.required??[]];!s&&!b.includes(r)&&b.push(r),await i.command({collMod:t,validator:{$jsonSchema:{...d,bsonType:"object",properties:f,...b.length>0?{required:b}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{return{deletedCount:(await(await ee(r)).collection(e).updateMany({},{$unset:{[t]:""}})).modifiedCount}}catch(n){throw this.wrapError(n)}}async alterColumn(e){try{let{tableName:t,columnName:r,columnType:n,isNullable:o,db:s}=e,c=await ee(s),i=await c.listCollections({name:t}).toArray();if(i.length===0)throw new v(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new v(400,{message:'Cannot alter the "_id" field'});let u=i[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},p=[...u.required??[]];m[r]={bsonType:o?[n,"null"]:n};let d=p.indexOf(r);!o&&d===-1?p.push(r):o&&d!==-1&&p.splice(d,1),await c.command({collMod:t,validator:{$jsonSchema:{...u,bsonType:"object",properties:m,...p.length>0?{required:p}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async renameColumn(e){try{let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=await ee(o);if((await s.listCollections({name:t}).toArray()).length===0)throw new v(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new v(400,{message:'Cannot rename the "_id" field'});if(!await s.collection(t).findOne({[r]:{$exists:!0}}))throw new v(404,{message:`Field "${r}" does not exist in collection "${t}"`});if(await s.collection(t).findOne({[n]:{$exists:!0}}))throw new v(409,{message:`Field "${n}" already exists in collection "${t}"`});await s.collection(t).updateMany({[r]:{$exists:!0}},{$rename:{[r]:n}})}catch(t){throw this.wrapError(t)}}async addRecord({db:e,params:t}){try{let{tableName:r,data:n}=t,s=(await ee(e)).collection(r),c=xe(n);if((c._id===""||c._id===null)&&delete c._id,!(await s.insertOne(c)).insertedId)throw new v(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:n,primaryKey:o}=t,c=(await ee(e)).collection(r),i=0,l=o||"_id",u=new Map;for(let m of n){let p=m.rowData[l];if(p==null)throw new v(400,{message:`Primary key "${l}" not found in row data.`});u.has(p)||u.set(p,{}),u.get(p)[m.columnName]=m.value}for(let[m,p]of u.entries()){let d=l==="_id"&&Gr(m)?We(m):m,f=await c.updateOne({[l]:d},{$set:p});if(f.matchedCount===0)throw new v(404,{message:`Record with ${l} = ${String(m)} not found in "${r}"`});i+=f.modifiedCount}return{updatedCount:i}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:n}=e,s=(await ee(n)).collection(t),c=r[0]?.columnName??"_id",i=r.map(u=>c==="_id"&&Gr(u.value)?We(u.value):u.value);return{deletedCount:(await s.deleteMany({[c]:{$in:i}})).deletedCount??0}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:r,db:n}=e;if(!r||r.length===0)throw new v(400,{message:"At least one record is required"});let s=(await ee(n)).collection(t),c=r.map(l=>{let u=xe(l);return(u._id===""||u._id===null)&&delete u._id,u}),i=await s.insertMany(c,{ordered:!1});return{success:!0,message:`Successfully inserted ${i.insertedCount} record${i.insertedCount!==1?"s":""}`,successCount:i.insertedCount,failureCount:r.length-i.insertedCount}}catch(t){throw this.wrapError(t)}}async executeQuery({query:e,db:t}){try{if(!e?.trim())throw new v(400,{message:"Query is required"});let r;try{r=JSON.parse(e)}catch{throw new v(400,{message:"Mongo query must be valid JSON"})}if(!r.collection||!r.operation)throw new v(400,{message:"Mongo query must include collection and operation"});let o=(await ee(t)).collection(r.collection),s=performance.now(),c=[],i=0,l;switch(r.operation){case"find":{let d=ve(r.filter??{}),f=o.find(d,r.options??{});f.sort(r.sort??Lt("",void 0)),r.skip&&f.skip(r.skip),r.limit&&f.limit(r.limit),c=await f.toArray(),i=c.length;break}case"aggregate":{c=await o.aggregate(r.pipeline??[],r.options??{}).toArray(),i=c.length;break}case"insertOne":{let d=r.document;if(!d)throw new v(400,{message:"document is required"});i=(await o.insertOne(d)).insertedId?1:0,l="OK";break}case"insertMany":{let d=r.document;if(!Array.isArray(d))throw new v(400,{message:"document array is required"});i=(await o.insertMany(d)).insertedCount??0,l="OK";break}case"updateOne":{let d=ve(r.filter??{});if(!r.update)throw new v(400,{message:"update is required"});let f=await o.updateOne(d,r.update,r.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"updateMany":{let d=ve(r.filter??{});if(!r.update)throw new v(400,{message:"update is required"});let f=await o.updateMany(d,r.update,r.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"deleteOne":{let d=ve(r.filter??{});i=(await o.deleteOne(d,r.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let d=ve(r.filter??{});i=(await o.deleteMany(d,r.options??{})).deletedCount??0,l="OK";break}case"count":{let d=ve(r.filter??{});i=await o.countDocuments(d),c=[{count:i}],l="OK";break}default:throw new v(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-s,m=c.map(d=>xe(d));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:i,duration:u,message:l}}catch(r){throw this.wrapError(r)}}}});import{z as ke}from"zod";var D,Xr,ze,io,lo,ce,ue=E(()=>{"use strict";D=ke.object({db:ke.string("Database name is required")}),Xr=["pg","mysql","mssql","mongodb","sqlite"],ze=ke.enum(Xr,{message:"Invalid database type"}),io=D.extend({dbType:ze}),lo=ke.object({dbType:ze}),ce=ke.object({tableName:ke.string("Table name is required")})});import{z as ge}from"zod";var me,co,uo,Zr=E(()=>{"use strict";ue();me=ge.object({columnName:ge.string("Column name is required"),columnType:ge.string("Column type is required"),defaultValue:ge.string().optional(),isPrimaryKey:ge.boolean().default(!1),isNullable:ge.boolean().default(!1),isUnique:ge.boolean().default(!1),isIdentity:ge.boolean().default(!1),isArray:ge.boolean().default(!1)}),co=ce,uo=ge.object({db:D.shape.db,tableName:ce.shape.tableName,columnName:me.shape.columnName,columnType:me.shape.columnType,defaultValue:me.shape.defaultValue,isPrimaryKey:me.shape.isPrimaryKey,isNullable:me.shape.isNullable,isUnique:me.shape.isUnique,isIdentity:me.shape.isIdentity,isArray:me.shape.isArray})});import{z as Ye}from"zod";var xt,en=E(()=>{"use strict";xt=Ye.object({tableName:Ye.string("Table name is required"),data:Ye.record(Ye.string("Column name is required"),Ye.any())})});import{z as de}from"zod";var vt,te,mo,po,it=E(()=>{"use strict";ue();vt=D.extend({cascade:de.string().optional().transform(a=>a==="true")}),te=de.object({tableName:de.string("Table name is required"),columnName:de.string("Column name is required")}),mo=de.object({db:D.shape.db,tableName:te.shape.tableName,columnName:te.shape.columnName,cascade:de.boolean().optional()}),po=de.object({message:de.string("Message is required"),tableName:de.string("Table name is required"),columnName:de.string("Column name is required"),deletedCount:de.number("Deleted count is required").default(0)})});import{z as Ge}from"zod";var qe,fo,bo,tn=E(()=>{"use strict";ue();it();qe=Ge.object({columnType:Ge.string("Column type is required"),isNullable:Ge.boolean(),defaultValue:Ge.string().nullable().optional()}),fo=te,bo=Ge.object({db:D.shape.db,tableName:te.shape.tableName,columnName:te.shape.columnName,columnType:qe.shape.columnType,isNullable:qe.shape.isNullable,defaultValue:qe.shape.defaultValue})});var rn=E(()=>{"use strict"});import{z as Ue}from"zod";var kt,nn=E(()=>{"use strict";kt=Ue.object({tableName:Ue.string().min(1,"Table name is required"),records:Ue.array(Ue.record(Ue.string(),Ue.any())).min(1,"At least one record is required")})});import{z as pe}from"zod";var yo,qt,an=E(()=>{"use strict";ue();yo=pe.object({type:pe.string(),content:pe.string().optional()}).passthrough(),qt=pe.object({messages:pe.array(pe.object({id:pe.string(),role:pe.enum(["user","assistant","system","tool"]),parts:pe.array(yo)}).passthrough()),data:pe.object({conversationId:pe.string().optional(),db:D.shape.db})})});var on=E(()=>{"use strict"});import{z as ie}from"zod";var go,sn,U,ho,ln,To,Ut=E(()=>{"use strict";go=["text","boolean","number","enum","json","date","array"],sn=ie.enum(go),U={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},ho=["int","bigint","smallint","numeric","float","double","money","tinyint","mediumint","bit","boolean","text","varchar","char","tinytext","mediumtext","longtext","json","jsonb","xml","uuid","date","time","timestamp","timestamptz","interval","datetime","year","bytea","inet","cidr","macaddr","macaddr8","point","line","polygon","binary","varbinary","blob","tinyblob","mediumblob","longblob","array","enum","set"],ln=ie.enum(ho),To=ie.object({columnName:ie.string(),dataType:sn,dataTypeLabel:ln,isNullable:ie.boolean(),columnDefault:ie.string().nullable(),isPrimaryKey:ie.boolean(),isForeignKey:ie.boolean(),referencedTable:ie.string().nullable(),referencedColumn:ie.string().nullable(),enumValues:ie.array(ie.string()).nullable()})});function lt(a){let e=a?.toLowerCase().trim()||"";return e.includes("[]")||e==="date"||e==="time"||e==="time without time zone"||e.startsWith("time(")||e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")||e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?U.date:e==="integer"||e==="int"||e==="int4"||e==="bigint"||e==="int8"||e==="smallint"||e==="int2"||e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")||e==="real"||e==="float4"||e==="double precision"||e==="float8"||e==="float"||e==="serial"||e==="serial4"||e==="bigserial"||e==="serial8"||e==="money"?U.number:e==="boolean"||e==="bool"?U.boolean:e==="json"||e==="jsonb"?U.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?U.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")||e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"||e==="uuid"||e==="interval"||e.startsWith("interval")||e==="bytea"||e==="point"||e==="line"||e==="polygon"||e==="inet"||e==="cidr"||e==="macaddr"||e==="macaddr8"?U.text:U.text}function Ft(a){if(!a)return y.text;let e=a.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?y.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?y.bigint:e==="smallint"||e==="int2"?y.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?y.numeric:e==="real"||e==="float4"?y.float:e==="double precision"||e==="float8"||e==="float"?y.double:e==="money"?y.money:e==="boolean"||e==="bool"?y.boolean:e==="text"?y.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?y.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?y.char:e==="json"?y.json:e==="jsonb"?y.jsonb:e==="xml"?y.xml:e==="uuid"?y.uuid:e==="date"?y.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?y.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?y.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?y.timestamptz:e==="interval"||e.startsWith("interval")?y.interval:e==="bytea"?y.bytea:e==="inet"?y.inet:e==="cidr"?y.cidr:e==="macaddr"?y.macaddr:e==="macaddr8"?y.macaddr8:e==="point"?y.point:e==="line"?y.line:e==="polygon"?y.polygon:e.startsWith("array")||e.includes("[]")?y.text:e.startsWith("user-defined")||e==="enum"?y.enum:y.text}function ct(a,e){let t=a?.toLowerCase().trim()||"",r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?U.boolean:t==="tinyint"||t==="smallint"||t==="mediumint"||t==="int"||t==="integer"||t==="bigint"||t==="decimal"||t==="numeric"||t==="float"||t==="double"||t==="real"||t==="bit"?U.number:t==="boolean"||t==="bool"?U.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?U.date:t==="json"?U.json:t==="enum"||t==="set"?U.enum:U.text}function Bt(a,e){if(!a)return y.text;let t=a.toLowerCase().trim(),r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?y.boolean:t==="tinyint"?y.tinyint:t==="smallint"?y.smallint:t==="mediumint"?y.mediumint:t==="int"||t==="integer"?y.int:t==="bigint"?y.bigint:t==="decimal"||t==="numeric"?y.numeric:t==="float"||t==="real"?y.float:t==="double"?y.double:t==="bit"?y.bit:t==="boolean"||t==="bool"?y.boolean:t==="char"?y.char:t==="varchar"?y.varchar:t==="tinytext"?y.tinytext:t==="text"?y.text:t==="mediumtext"?y.mediumtext:t==="longtext"?y.longtext:t==="binary"?y.binary:t==="varbinary"?y.varbinary:t==="tinyblob"?y.tinyblob:t==="blob"?y.blob:t==="mediumblob"?y.mediumblob:t==="longblob"?y.longblob:t==="json"?y.json:t==="date"?y.date:t==="time"?y.time:t==="datetime"?y.datetime:t==="timestamp"?y.timestamp:t==="year"?y.year:t==="enum"?y.enum:t==="set"?y.set:y.text}function ut(a){let e=a?.toLowerCase().trim()||"";return e==="tinyint"||e==="smallint"||e==="int"||e==="bigint"||e==="decimal"||e==="numeric"||e==="float"||e==="real"||e==="money"||e==="smallmoney"?U.number:e==="bit"?U.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?U.date:e==="json"?U.json:U.text}function jt(a){if(!a)return y.text;let e=a.toLowerCase().trim();return e==="tinyint"?y.tinyint:e==="smallint"?y.smallint:e==="int"?y.int:e==="bigint"?y.bigint:e==="decimal"||e==="numeric"?y.numeric:e==="float"||e==="real"?y.float:e==="money"||e==="smallmoney"?y.money:e==="bit"?y.boolean:e==="char"?y.char:e==="varchar"?y.varchar:e==="text"?y.text:e==="nchar"?y.char:e==="nvarchar"?y.varchar:e==="ntext"?y.text:e==="binary"?y.binary:e==="varbinary"?y.varbinary:e==="image"?y.blob:e==="uniqueidentifier"?y.uuid:e==="date"?y.date:e==="time"?y.time:e==="datetime"||e==="datetime2"||e==="smalldatetime"?y.datetime:e==="datetimeoffset"?y.timestamptz:e==="json"?y.json:e==="xml"?y.xml:y.text}function mt(a){let e=a?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?U.boolean:e==="json"?U.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?U.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?U.number:U.text}function Ht(a){let e=a?.toLowerCase().trim()||"";return e==="integer"||e==="int"?y.int:e==="bigint"||e.startsWith("bigint(")?y.bigint:e==="smallint"||e.startsWith("smallint(")?y.smallint:e==="tinyint"||e.startsWith("tinyint(")?y.tinyint:e==="mediumint"||e.startsWith("mediumint(")?y.mediumint:e.includes("int")?y.int:e==="real"||e==="float"||e.startsWith("float(")?y.float:e==="double"||e==="double precision"||e.startsWith("double(")?y.double:e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?y.numeric:e==="boolean"||e==="bool"?y.boolean:e==="text"||e==="clob"?y.text:e==="varchar"||e.startsWith("varchar(")?y.varchar:e==="char"||e.startsWith("char(")?y.char:e==="json"?y.json:e==="date"?y.date:e==="time"?y.time:e==="datetime"?y.datetime:e==="timestamp"?y.timestamp:e==="blob"?y.blob:y.text}var y,cn=E(()=>{"use strict";Ut();y={int:"int",bigint:"bigint",smallint:"smallint",numeric:"numeric",float:"float",double:"double",money:"money",tinyint:"tinyint",mediumint:"mediumint",bit:"bit",boolean:"boolean",text:"text",varchar:"varchar",char:"char",tinytext:"tinytext",mediumtext:"mediumtext",longtext:"longtext",json:"json",jsonb:"jsonb",xml:"xml",uuid:"uuid",date:"date",time:"time",timestamp:"timestamp",timestamptz:"timestamptz",interval:"interval",datetime:"datetime",year:"year",bytea:"bytea",inet:"inet",cidr:"cidr",macaddr:"macaddr",macaddr8:"macaddr8",point:"point",line:"line",polygon:"polygon",binary:"binary",varbinary:"varbinary",blob:"blob",tinyblob:"tinyblob",mediumblob:"mediumblob",longblob:"longblob",array:"array",enum:"enum",set:"set"}});import{z as X}from"zod";var un,Kt,mn,dn,Vt,pn=E(()=>{"use strict";un=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],Kt=X.enum(un),mn=X.object({columnName:X.string("Column name is required"),columnType:X.string("Column type is required"),defaultValue:X.string().optional(),isPrimaryKey:X.boolean().default(!1),isNullable:X.boolean().default(!1),isUnique:X.boolean().default(!1),isIdentity:X.boolean().default(!1),isArray:X.boolean().default(!1)}),dn=X.object({columnName:X.string("Column name is required"),referencedTable:X.string("Referenced table is required"),referencedColumn:X.string("Referenced column is required"),onUpdate:Kt.default("NO ACTION"),onDelete:Kt.default("NO ACTION")}),Vt=X.object({tableName:X.string("Table name is required"),fields:X.array(mn).min(1,"At least one field is required"),foreignKeys:X.array(dn).optional()})});import{z as re}from"zod";var fn,Eo,Co,bn=E(()=>{"use strict";ue();fn=re.object({name:re.string("Name is required"),size:re.string("Size is required"),owner:re.string("Owner is required"),encoding:re.string("Encoding is required")}),Eo=re.object({databases:re.array(fn),dbType:ze}),Co=re.object({version:re.string("Version is required"),database:re.string("Database is required"),user:re.string("User is required"),host:re.string("Host is required").nullable(),port:re.number("Port is required").nullable(),active_connections:re.coerce.number("Active connections is required"),max_connections:re.coerce.number("Max connections is required")})});var yn=E(()=>{"use strict"});import{z as Fe}from"zod";var dt,gn=E(()=>{"use strict";dt=Fe.object({tableName:Fe.string("Table name is required"),primaryKeys:Fe.array(Fe.object({columnName:Fe.string("Column name is required"),value:Fe.any()})).min(1,"At least one primary key is required")})});import{z as wo}from"zod";var Wt,hn=E(()=>{"use strict";ue();Wt=D.extend({cascade:wo.string().optional().transform(a=>a==="true")})});import{z as Tn}from"zod";var zt,En=E(()=>{"use strict";zt=Tn.object({query:Tn.string("Query is required")})});import{z as Ro}from"zod";var Cn,Yt,wn=E(()=>{"use strict";ue();Cn=["csv","xlsx","json"],Yt=D.extend({format:Ro.enum(Cn,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});var Rn=E(()=>{"use strict"});import{z as Gt}from"zod";var pt,So,No,Sn=E(()=>{"use strict";ue();it();pt=Gt.object({newColumnName:Gt.string("New column name is required")}),So=te,No=Gt.object({db:D.shape.db,tableName:te.shape.tableName,columnName:te.shape.columnName,newColumnName:pt.shape.newColumnName})});import{z as F}from"zod";var Ao,Qe,Do,Nn,_o,Qt,An=E(()=>{"use strict";ue();Ao=F.object({columnName:F.string(),operator:F.string(),value:F.string()}),Qe=["asc","desc"],Do=F.object({columnName:F.string(),direction:F.enum(Qe)}),Nn=F.object({limit:F.number(),total:F.number(),hasNextPage:F.boolean(),hasPreviousPage:F.boolean(),nextCursor:F.string().nullable(),prevCursor:F.string().nullable()}),_o=F.object({data:F.array(F.record(F.string(),F.unknown())),meta:Nn}),Qt=F.object({db:D.shape.db,cursor:F.string().optional(),limit:F.string().optional().default("50").transform(Number),direction:F.enum(Qe).optional().default(Qe[0]),sort:F.string().optional().transform(a=>{if(!a)return"";try{let e=JSON.parse(a);return Array.isArray(e)?e:a}catch{return a}}),order:F.enum(Qe).optional(),filters:F.string().optional().transform(a=>{if(!a)return[];try{return JSON.parse(a)}catch{return[]}})})});import{z as ft}from"zod";var $o,Dn=E(()=>{"use strict";$o=ft.object({tableName:ft.string("Table name is required"),schemaName:ft.string().optional(),rowCount:ft.coerce.number("Row count is required")})});import{z as _n}from"zod";var Oo,$n=E(()=>{"use strict";Oo=_n.object({schema:_n.string()})});import{z as he}from"zod";var Jt,On=E(()=>{"use strict";Jt=he.object({tableName:he.string("Table name is required"),primaryKey:he.string("Primary key is required").default("id"),updates:he.array(he.object({rowData:he.record(he.string("Column name is required"),he.any()),columnName:he.string("Column name is required"),value:he.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var Pn={};fr(Pn,{DATABASE_TYPES:()=>Xr,DataTypes:()=>U,FOREIGN_KEY_ACTIONS:()=>un,FORMAT_TYPES:()=>Cn,StandardizedDataType:()=>y,addColumnParamSchema:()=>co,addColumnParamsSchema:()=>uo,addColumnSchema:()=>me,addRecordSchema:()=>xt,alterColumnParamSchema:()=>fo,alterColumnParamsSchema:()=>bo,alterColumnSchema:()=>qe,bulkInsertRecordsSchema:()=>kt,chatSchema:()=>qt,columnInfoSchema:()=>To,connectionInfoSchema:()=>Co,createTableSchema:()=>Vt,currentDatabaseSchema:()=>io,dataTypesSchema:()=>sn,databaseInfoSchema:()=>fn,databaseListSchema:()=>Eo,databaseSchema:()=>D,databaseTypeParamSchema:()=>lo,databaseTypeSchema:()=>ze,deleteColumnParamSchema:()=>te,deleteColumnParamsSchema:()=>mo,deleteColumnQuerySchema:()=>vt,deleteColumnSuccessResponseSchema:()=>po,deleteRecordSchema:()=>dt,deleteTableQuerySchema:()=>Wt,executeQuerySchema:()=>zt,exportTableSchema:()=>Yt,fieldDataSchema:()=>mn,filterSchema:()=>Ao,foreignKeyActionSchema:()=>Kt,foreignKeyDataSchema:()=>dn,mapMssqlToDataType:()=>ut,mapMysqlToDataType:()=>ct,mapPostgresToDataType:()=>lt,mapSqliteToDataType:()=>mt,renameColumnParamSchema:()=>So,renameColumnParamsSchema:()=>No,renameColumnSchema:()=>pt,sortDirections:()=>Qe,sortSchema:()=>Do,standardizeDataTypeLabel:()=>Ft,standardizeMssqlDataTypeLabel:()=>jt,standardizeMysqlDataTypeLabel:()=>Bt,standardizeSqliteDataTypeLabel:()=>Ht,standardizedDataTypeSchema:()=>ln,tableDataMetaSchema:()=>Nn,tableDataQuerySchema:()=>Qt,tableDataResultSchema:()=>_o,tableInfoSchema:()=>$o,tableNameSchema:()=>ce,tableSchemaResultSchema:()=>Oo,updateRecordsSchema:()=>Jt});var Te=E(()=>{"use strict";Zr();en();tn();rn();nn();an();on();cn();Ut();pn();ue();bn();yn();it();gn();hn();En();wn();Rn();Sn();An();Dn();$n();On()});function Xt(a,e=0){if(a.length===0)return{clause:"",values:[],nextIdx:e};let t=[],r=[],n=e;for(let o of a){let s=`[${o.columnName}]`;switch(o.operator){case"=":case"!=":case">":case">=":case"<":case"<=":t.push(`${s} ${o.operator} @p${n}`),r.push(o.value),n++;break;case"is":o.value.toLowerCase()==="null"?t.push(`${s} IS NULL`):(t.push(`${s} = @p${n}`),r.push(o.value),n++);break;case"is not":o.value.toLowerCase()==="null"?t.push(`${s} IS NOT NULL`):(t.push(`${s} != @p${n}`),r.push(o.value),n++);break;case"like":case"ilike":t.push(`${s} LIKE @p${n}`),r.push(o.value),n++;break;case"not like":case"not ilike":t.push(`${s} NOT LIKE @p${n}`),r.push(o.value),n++;break;default:break}}return t.length===0?{clause:"",values:[],nextIdx:e}:{clause:`WHERE ${t.join(" AND ")}`,values:r,nextIdx:n}}function Zt(a,e){return Array.isArray(a)?a.length===0?"":`ORDER BY ${a.map(t=>`[${t.columnName}] ${t.direction.toUpperCase()}`).join(", ")}`:a&&typeof a=="string"?`ORDER BY [${a}] ${e?.toUpperCase()||"ASC"}`:""}function er(a,e){if(e)return"NVARCHAR(MAX)";let t=a.toLowerCase().trim();return{serial:"INT IDENTITY(1,1)",serial4:"INT IDENTITY(1,1)",bigserial:"BIGINT IDENTITY(1,1)",serial8:"BIGINT IDENTITY(1,1)",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",tinyint:"TINYINT",numeric:"NUMERIC",decimal:"DECIMAL",real:"REAL",float4:"REAL",float:"FLOAT","double precision":"FLOAT",float8:"FLOAT",money:"MONEY",boolean:"BIT",bool:"BIT",text:"NVARCHAR(MAX)",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"UNIQUEIDENTIFIER",json:"NVARCHAR(MAX)",jsonb:"NVARCHAR(MAX)",xml:"XML",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME2","timestamp without time zone":"DATETIME2","timestamp with time zone":"DATETIMEOFFSET",timestamptz:"DATETIMEOFFSET",interval:"VARCHAR(255)",bytea:"VARBINARY(MAX)",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)"}[t]||a.toUpperCase()}function tr(a,e){let t=a.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("newid()")?e.toUpperCase().includes("UNIQUEIDENTIFIER")?"NEWID()":null:t.includes("getdate")||t.includes("current_timestamp")?"GETDATE()":a.trim():t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":a.trim()}function Ln(a,e={}){let t=er(a.columnType,a.isArray??!1),r=`[${a.columnName}] ${t}`;if(a.isIdentity&&!t.includes("IDENTITY")&&(r+=" IDENTITY(1,1)"),!a.isNullable&&!a.isPrimaryKey&&(r+=" NOT NULL"),a.defaultValue?.trim()&&!t.includes("IDENTITY")){let n=tr(a.defaultValue,t);n!==null&&(r+=` DEFAULT ${n}`)}return e.includeUnique&&a.isUnique&&!a.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&a.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var Mn=E(()=>{"use strict"});import{HTTPException as I}from"hono/http-exception";var Po,Lo,bt,In=E(()=>{"use strict";Te();De();_e();Ve();Mn();Po=547,Lo=3726,bt=class extends oe{async runQuery(e,t,r){let o=(await B(e)).request();return r.forEach((c,i)=>{o.input(`p${i}`,c)}),(await o.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return ut(e)}mapFromUniversalType(e){return{text:"NVARCHAR(MAX)",number:"INT",boolean:"BIT",json:"NVARCHAR(MAX)",date:"DATETIME2",array:"NVARCHAR(MAX)",enum:"NVARCHAR(255)"}[e]??"NVARCHAR(MAX)"}buildTableDataQuery(e){let{tableName:t,filters:r=[],sort:n=[],order:o="asc",limit:s=50,cursor:c}=e,{clause:i,values:l,nextIdx:u}=Xt(r,0),m=Zt(n,o)||"ORDER BY (SELECT NULL)",p=c?this.decodeOffsetCursor(c):0,d=`SELECT * FROM [${t}] ${i} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,f=[...l,p,s+1],b=`SELECT COUNT(*) as total FROM [${t}] ${i}`;return{sql:d,values:f,countSql:b,countValues:l}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){let{cursor:n,limit:o=50}=e,s=n?this.decodeOffsetCursor(n):0;return{nextCursor:r?this.makeCursor(s+o):null,prevCursor:s>0?this.makeCursor(Math.max(0,s-o)):null}}async getTableData(e){try{let{tableName:t,db:r,limit:n=50,sort:o=[],order:s="asc",cursor:c,filters:i=[]}=e,l=await B(r),u=c?this.decodeOffsetCursor(c):0,{clause:m,values:p,nextIdx:d}=Xt(i,0),f=Zt(o,s)||"ORDER BY (SELECT NULL)",b=l.request();p.forEach((T,S)=>{b.input(`p${S}`,T)});let g=await b.query(`SELECT COUNT(*) as total FROM [${t}] ${m}`),h=Number(g.recordset[0]?.total??0),C=l.request();p.forEach((T,S)=>{C.input(`p${S}`,T)}),C.input(`p${d}`,u),C.input(`p${d+1}`,n+1);let N=(await C.query(`SELECT * FROM [${t}] ${m} ${f} OFFSET @p${d} ROWS FETCH NEXT @p${d+1} ROWS ONLY`)).recordset,w=N.length>n;return w&&(N=N.slice(0,n)),{data:N,meta:{limit:n,total:h,hasNextPage:w,hasPreviousPage:u>0,nextCursor:w?this.makeCursor(u+n):null,prevCursor:u>0?this.makeCursor(Math.max(0,u-n)):null}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){let t=await(await B()).request().query(`
|
|
3
3
|
SELECT
|
|
4
4
|
d.name AS name,
|
|
5
5
|
CAST(ROUND(CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)), 2) AS VARCHAR(20)) + ' MB' AS size,
|
|
@@ -26,7 +26,7 @@ var Da=Object.defineProperty;var E=(a,e)=>()=>(a&&(e=a(a=0)),e);var pr=(a,e)=>{f
|
|
|
26
26
|
AND table_type = 'BASE TABLE'
|
|
27
27
|
AND table_schema = 'dbo'
|
|
28
28
|
ORDER BY table_name
|
|
29
|
-
`);return!r.recordset||r.recordset.length===0?[]:Promise.all(r.recordset.map(async n=>{let o=await t.request().query(`SELECT COUNT(*) as count FROM [${n.tableName}]`);return{tableName:n.tableName,rowCount:o.recordset[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:n,foreignKeys:o}=e,s=await B(t),c=n.map(m=>{let p=
|
|
29
|
+
`);return!r.recordset||r.recordset.length===0?[]:Promise.all(r.recordset.map(async n=>{let o=await t.request().query(`SELECT COUNT(*) as count FROM [${n.tableName}]`);return{tableName:n.tableName,rowCount:o.recordset[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:n,foreignKeys:o}=e,s=await B(t),c=n.map(m=>{let p=er(m.columnType,m.isArray??!1),d=`[${m.columnName}] ${p}`;if(!m.isNullable&&!m.isPrimaryKey&&(d+=" NOT NULL"),m.defaultValue&&!p.includes("IDENTITY")){let f=tr(m.defaultValue,p);f!==null&&(d+=` DEFAULT ${f}`)}return d}),i=[],l=n.filter(m=>m.isPrimaryKey);l.length>0&&i.push(`PRIMARY KEY (${l.map(m=>`[${m.columnName}]`).join(", ")})`);for(let m of n)m.isUnique&&!m.isPrimaryKey&&i.push(`UNIQUE ([${m.columnName}])`);let u=o?.map(m=>`CONSTRAINT [${`FK_${r}_${m.columnName}`}] FOREIGN KEY ([${m.columnName}]) REFERENCES [${m.referencedTable}] ([${m.referencedColumn}]) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await s.request().query(`CREATE TABLE [${r}] (
|
|
30
30
|
${[...c,...i,...u].join(`,
|
|
31
31
|
`)}
|
|
32
32
|
)`)}async deleteTable(e){let{tableName:t,db:r,cascade:n}=e,o=await B(r),s=await o.request().input("tableName",t).query(`
|
|
@@ -118,7 +118,7 @@ ${s.join(`,
|
|
|
118
118
|
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cc
|
|
119
119
|
ON chk.CONSTRAINT_NAME = cc.CONSTRAINT_NAME AND cc.TABLE_SCHEMA = 'dbo'
|
|
120
120
|
WHERE cc.TABLE_NAME = @tableName AND cc.TABLE_CATALOG = DB_NAME()
|
|
121
|
-
`),s=new Map;for(let c of o.recordset){let i=this.parseCheckConstraintValues(c.checkClause);i&&s.set(c.columnName,i)}return n.recordset.map(c=>{let i=s.get(c.columnName)??null;return{columnName:c.columnName,dataType:i?"enum":
|
|
121
|
+
`),s=new Map;for(let c of o.recordset){let i=this.parseCheckConstraintValues(c.checkClause);i&&s.set(c.columnName,i)}return n.recordset.map(c=>{let i=s.get(c.columnName)??null;return{columnName:c.columnName,dataType:i?"enum":ut(c.dataType),dataTypeLabel:i?"enum":jt(c.dataType),isNullable:!!c.isNullable,columnDefault:c.columnDefault??null,isPrimaryKey:!!c.isPrimaryKey,isForeignKey:!!c.isForeignKey,referencedTable:c.referencedTable??null,referencedColumn:c.referencedColumn??null,enumValues:i}})}async addColumn(e){let{tableName:t,columnName:r,columnType:n,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,db:u}=e,m=await B(u);await this.assertTableExists(m,t);let p=await m.request().input("tableName",t).input("columnName",r).query(`
|
|
122
122
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
123
123
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
124
124
|
`);if(Number(p.recordset[0]?.cnt??0)>0)throw new I(409,{message:`Column "${r}" already exists in table "${t}"`});let d=Ln({columnName:r,columnType:n,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l},{includePrimaryKey:!0,includeUnique:!0});await m.request().query(`ALTER TABLE [${t}] ADD ${d}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:n}=e,o=await B(n);return await this.assertTableExists(o,t),await this.assertColumnExists(o,t,r),{deletedCount:(await o.request().query(`ALTER TABLE [${t}] DROP COLUMN [${r}]`)).rowsAffected[0]??1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:n,isNullable:o,defaultValue:s,db:c}=e,i=await B(c);await this.assertTableExists(i,t),await this.assertColumnExists(i,t,r);let u=(await i.request().input("tableName",t).input("columnName",r).query(`
|
|
@@ -130,7 +130,7 @@ ${s.join(`,
|
|
|
130
130
|
`)).recordset[0]?.constraint_name;u&&await i.request().query(`ALTER TABLE [${t}] DROP CONSTRAINT [${u}]`);let m=o?"NULL":"NOT NULL";await i.request().query(`ALTER TABLE [${t}] ALTER COLUMN [${r}] ${n} ${m}`),s?.trim()&&await i.request().query(`ALTER TABLE [${t}] ADD DEFAULT ${s.trim()} FOR [${r}]`)}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=await B(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let c=await s.request().input("tableName",t).input("columnName",n).query(`
|
|
131
131
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
132
132
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
133
|
-
`);if(Number(c.recordset[0]?.cnt??0)>0)throw new I(409,{message:`Column "${n}" already exists in table "${t}"`});await s.request().query(`EXEC sp_rename '${t}.${r}', '${n}', 'COLUMN'`)}async addRecord({db:e,params:t}){let{tableName:r,data:n}=t,o=await B(e),s=await this.getBooleanColumnSet(r,e),c=await o.request().input("tableName",r).query("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(@tableName) AND is_identity = 1"),i=new Set(c.recordset.map(b=>b.name)),l=Object.keys(n).filter(b=>!i.has(b)),u=l.map(b=>{let g=n[b];return s.has(b)&&typeof g=="string"?g==="true"?1:0:g}),m=l.map(b=>`[${b}]`).join(", "),p=l.map((b,g)=>`@param${g}`).join(", "),d=o.request();l.forEach((b,g)=>{d.input(`param${g}`,u[g])});let f=await d.query(`INSERT INTO [${r}] (${m}) VALUES (${p})`);if(f.rowsAffected[0]===0)throw new I(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:f.rowsAffected[0]??0}}async updateRecords({params:e,db:t}){let{tableName:r,updates:n,primaryKey:o}=e,s=await B(t),c=await this.getBooleanColumnSet(r,t),i=new Map;for(let u of n){let m=u.rowData[o];if(m==null)throw new I(400,{message:`Primary key "${o}" not found in row data.`});i.has(m)||i.set(m,[]),i.get(m)?.push({columnName:u.columnName,value:u.value})}let l=s.transaction();await l.begin();try{let u=0;for(let[m,p]of i.entries()){let d=l.request(),f=p.map((g,h)=>`[${g.columnName}] = @value${h}`);p.forEach((g,h)=>{let C=g.value;C!==null&&typeof C=="object"&&(C=JSON.stringify(C)),c.has(g.columnName)&&typeof C=="string"&&(C=C==="true"?1:0),d.input(`value${h}`,C)}),d.input("pkValue",m);let b=await d.query(`UPDATE [${r}] SET ${f.join(", ")} WHERE [${o}] = @pkValue`);if(b.rowsAffected[0]===0)throw new I(404,{message:`Record with ${o} = ${m} not found in table "${r}"`});u+=b.rowsAffected[0]??0}return await l.commit(),{updatedCount:u}}catch(u){throw await l.rollback(),u instanceof I?u:new I(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=await B(r),o=t[0]?.columnName;if(!o)throw new I(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=n.transaction();await c.begin();try{let i=c.request();s.forEach((m,p)=>{i.input(`pk${p}`,m)});let l=s.map((m,p)=>`@pk${p}`).join(", "),u=await i.query(`DELETE FROM [${e}] WHERE [${o}] IN (${l})`);return await c.commit(),{deletedCount:u.rowsAffected[0]??0,fkViolation:!1,relatedRecords:[]}}catch(i){if(await c.rollback(),i.number===
|
|
133
|
+
`);if(Number(c.recordset[0]?.cnt??0)>0)throw new I(409,{message:`Column "${n}" already exists in table "${t}"`});await s.request().query(`EXEC sp_rename '${t}.${r}', '${n}', 'COLUMN'`)}async addRecord({db:e,params:t}){let{tableName:r,data:n}=t,o=await B(e),s=await this.getBooleanColumnSet(r,e),c=await o.request().input("tableName",r).query("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(@tableName) AND is_identity = 1"),i=new Set(c.recordset.map(b=>b.name)),l=Object.keys(n).filter(b=>!i.has(b)),u=l.map(b=>{let g=n[b];return s.has(b)&&typeof g=="string"?g==="true"?1:0:g}),m=l.map(b=>`[${b}]`).join(", "),p=l.map((b,g)=>`@param${g}`).join(", "),d=o.request();l.forEach((b,g)=>{d.input(`param${g}`,u[g])});let f=await d.query(`INSERT INTO [${r}] (${m}) VALUES (${p})`);if(f.rowsAffected[0]===0)throw new I(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:f.rowsAffected[0]??0}}async updateRecords({params:e,db:t}){let{tableName:r,updates:n,primaryKey:o}=e,s=await B(t),c=await this.getBooleanColumnSet(r,t),i=new Map;for(let u of n){let m=u.rowData[o];if(m==null)throw new I(400,{message:`Primary key "${o}" not found in row data.`});i.has(m)||i.set(m,[]),i.get(m)?.push({columnName:u.columnName,value:u.value})}let l=s.transaction();await l.begin();try{let u=0;for(let[m,p]of i.entries()){let d=l.request(),f=p.map((g,h)=>`[${g.columnName}] = @value${h}`);p.forEach((g,h)=>{let C=g.value;C!==null&&typeof C=="object"&&(C=JSON.stringify(C)),c.has(g.columnName)&&typeof C=="string"&&(C=C==="true"?1:0),d.input(`value${h}`,C)}),d.input("pkValue",m);let b=await d.query(`UPDATE [${r}] SET ${f.join(", ")} WHERE [${o}] = @pkValue`);if(b.rowsAffected[0]===0)throw new I(404,{message:`Record with ${o} = ${m} not found in table "${r}"`});u+=b.rowsAffected[0]??0}return await l.commit(),{updatedCount:u}}catch(u){throw await l.rollback(),u instanceof I?u:new I(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=await B(r),o=t[0]?.columnName;if(!o)throw new I(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=n.transaction();await c.begin();try{let i=c.request();s.forEach((m,p)=>{i.input(`pk${p}`,m)});let l=s.map((m,p)=>`@pk${p}`).join(", "),u=await i.query(`DELETE FROM [${e}] WHERE [${o}] IN (${l})`);return await c.commit(),{deletedCount:u.rowsAffected[0]??0,fkViolation:!1,relatedRecords:[]}}catch(i){if(await c.rollback(),i.number===Po)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw i instanceof I?i:new I(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=await B(r),o=t[0]?.columnName;if(!o)throw new I(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=n.transaction();await c.begin();try{let i=await this.getForeignKeyReferences(e,r),l=0,u=new Set,m=new Set,p=async(g,h,C,R)=>{let N=`${g}.${h}`;if(R.has(N))return;R.add(N);let w=await this.getForeignKeyReferences(g,r);for(let $ of w){let P=c.request();C.forEach((W,Z)=>{P.input(`val${Z}`,W)});let O=C.map((W,Z)=>`@val${Z}`).join(", "),k=(await P.query(`SELECT [${$.referencedColumn}] FROM [${g}] WHERE [${h}] IN (${O})`)).recordset.map(W=>W[$.referencedColumn]);k.length>0&&await p($.referencingTable,$.referencingColumn,k,R)}let T=c.request();C.forEach(($,P)=>{T.input(`delVal${P}`,$)});let S=C.map(($,P)=>`@delVal${P}`).join(", "),j=await T.query(`DELETE FROM [${g}] WHERE [${h}] IN (${S})`);l+=j.rowsAffected[0]??0,u.add(g)};for(let g of i)u.has(g.referencingTable)||await p(g.referencingTable,g.referencingColumn,s,m);let d=c.request();s.forEach((g,h)=>{d.input(`mainPk${h}`,g)});let f=s.map((g,h)=>`@mainPk${h}`).join(", "),b=await d.query(`DELETE FROM [${e}] WHERE [${o}] IN (${f})`);return await c.commit(),{deletedCount:(b.rowsAffected[0]??0)+l}}catch(i){throw await c.rollback(),i instanceof I?i:new I(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new I(400,{message:"At least one record is required"});let o=(await B(r)).transaction();try{let s=Object.keys(t[0]),c=s.map(l=>`[${l}]`).join(", "),i=await this.getBooleanColumnSet(e,r);await o.begin();for(let l=0;l<t.length;l++){let u=t[l],m=o.request(),p=s.map(f=>{let b=u[f];return i.has(f)&&typeof b=="string"?b==="true"?1:0:b}),d=s.map((f,b)=>`@p${l}_${b}`).join(", ");s.forEach((f,b)=>{m.input(`p${l}_${b}`,p[b])});try{await m.query(`INSERT INTO [${e}] (${c}) VALUES (${d})`)}catch(f){throw new I(500,{message:`Failed to insert record ${l+1}: ${f instanceof Error?f.message:String(f)}`})}}return await o.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(s){throw await o.rollback(),s instanceof I?s:new I(500,{message:`Failed to bulk insert records into "${e}"`})}}async executeQuery({query:e,db:t}){let r=await B(t);if(!e?.trim())throw new I(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.request().query(n),c=performance.now()-o;if(s.recordset){let i=s.recordset;return{columns:s.recordset.columns?Object.keys(s.recordset.columns):Object.keys(i[0]??{}),rows:i,rowCount:i.length,duration:c,message:i.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:s.rowsAffected[0]??0,duration:c,message:`OK \u2014 ${s.rowsAffected[0]??0} row(s) affected`}}async getForeignKeyReferences(e,t){return(await(await B(t)).request().input("tableName",e).query(`
|
|
134
134
|
SELECT
|
|
135
135
|
fk.name AS constraint_name,
|
|
136
136
|
OBJECT_NAME(fk.parent_object_id) AS referencing_table,
|
|
@@ -146,7 +146,7 @@ ${s.join(`,
|
|
|
146
146
|
`);if(Number(r.recordset[0]?.cnt??0)===0)throw new I(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let n=await e.request().input("tableName",t).input("columnName",r).query(`
|
|
147
147
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
148
148
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
149
|
-
`);if(Number(n.recordset[0]?.cnt??0)===0)throw new I(404,{message:`Column "${r}" does not exist in table "${t}"`})}parseCheckConstraintValues(e){let t=e.match(/'([^']+)'/g);return!t||t.length===0?null:t.map(r=>r.slice(1,-1))}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){let t=this.decodeCursor(e);return Number(t?.values._offset??0)}}});function
|
|
149
|
+
`);if(Number(n.recordset[0]?.cnt??0)===0)throw new I(404,{message:`Column "${r}" does not exist in table "${t}"`})}parseCheckConstraintValues(e){let t=e.match(/'([^']+)'/g);return!t||t.length===0?null:t.map(r=>r.slice(1,-1))}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){let t=this.decodeCursor(e);return Number(t?.values._offset??0)}}});function rr(a){if(a.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of a){let n=`\`${r.columnName}\``;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${n} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${n} IS NULL`):(e.push(`${n} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${n} IS NOT NULL`):(e.push(`${n} != ?`),t.push(r.value));break;case"like":case"ilike":e.push(`${n} LIKE ?`),t.push(r.value);break;case"not like":case"not ilike":e.push(`${n} NOT LIKE ?`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function nr(a,e){return Array.isArray(a)?a.length===0?"":`ORDER BY ${a.map(t=>`\`${t.columnName}\` ${t.direction.toUpperCase()}`).join(", ")}`:a&&typeof a=="string"?`ORDER BY \`${a}\` ${e?.toUpperCase()||"ASC"}`:""}function ar(a,e,t){let{values:r,sortColumns:n}=a;if(n.length===0)return{clause:"",values:[]};let i=t==="asc"===(e==="asc")?">":"<",l=n.map(p=>`\`${p}\``).join(", "),u=n.map(()=>"?").join(", "),m=n.map(p=>r[p]);return{clause:`(${l}) ${i} (${u})`,values:m}}function Mo(a,e){if(e)return"JSON";let t=a.toLowerCase().trim();return{serial:"INT AUTO_INCREMENT",serial4:"INT AUTO_INCREMENT",bigserial:"BIGINT AUTO_INCREMENT",serial8:"BIGINT AUTO_INCREMENT",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",numeric:"DECIMAL",decimal:"DECIMAL",real:"FLOAT",float4:"FLOAT",float:"FLOAT","double precision":"DOUBLE",float8:"DOUBLE",money:"DECIMAL(19, 4)",boolean:"TINYINT(1)",bool:"TINYINT(1)",text:"LONGTEXT",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"CHAR(36)",json:"JSON",jsonb:"JSON",xml:"LONGTEXT",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME","timestamp without time zone":"DATETIME","timestamp with time zone":"DATETIME",timestamptz:"DATETIME",interval:"VARCHAR(255)",bytea:"LONGBLOB",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)",point:"POINT",line:"LINESTRING",polygon:"POLYGON"}[t]||a.toUpperCase()}function Io(a,e){if(!a?.trim())return null;let t=a.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("uuid()")?!e.toUpperCase().includes("CHAR")&&!e.toUpperCase().includes("TEXT")?null:"(UUID())":t.includes("current_timestamp")||t.includes("now()")?"(CURRENT_TIMESTAMP)":t.includes("current_date")?"(CURRENT_DATE)":`(${a.trim()})`:t==="null"?"NULL":t==="true"?"1":t==="false"?"0":a.trim()}function yt(a,e={}){let t=Mo(a.columnType,a.isArray??!1),r=`\`${a.columnName}\` ${t}`;if(!a.isNullable&&!a.isPrimaryKey&&(r+=" NOT NULL"),a.defaultValue&&!t.includes("AUTO_INCREMENT")){let n=Io(a.defaultValue,t);n!==null&&(r+=` DEFAULT ${n}`)}return(a.isIdentity||e.preserveAutoIncrement)&&!t.includes("AUTO_INCREMENT")&&(r+=" AUTO_INCREMENT"),e.includeUnique&&a.isUnique&&!a.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&a.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var xn=E(()=>{"use strict"});import{HTTPException as L}from"hono/http-exception";var vn,xo,gt,kn=E(()=>{"use strict";Te();De();_e();Ve();xn();vn=1451,xo=1217,gt=class extends oe{async runQuery(e,t,r){let n=H(e),[o]=await n.execute(t,r);return o}quoteIdentifier(e){return`\`${e}\``}mapToUniversalType(e){return ct(e)}mapFromUniversalType(e){return{text:"LONGTEXT",number:"INT",boolean:"TINYINT(1)",json:"JSON",date:"DATETIME",array:"JSON",enum:"TEXT"}[e]??"LONGTEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:n=50,direction:o="asc",sort:s=[],order:c="asc",filters:i=[]}=e,l=[],u=c;Array.isArray(s)&&s.length>0?(l=s.map(w=>w.columnName),u=s[0].direction):typeof s=="string"&&s&&(l=[s]);let{clause:m,values:p}=rr(i),d="",f=[];if(r){let w=this.decodeCursor(r);if(w){let T=ar(w,o,u);d=T.clause,f=T.values}}let b="";m&&d?b=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?b=m:d&&(b=`WHERE ${d}`);let g=nr((Array.isArray(s),s),c),h=g;o==="desc"?g?h=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):l.length>0&&(h=`ORDER BY ${l.map(w=>`\`${w}\` ${u==="asc"?"DESC":"ASC"}`).join(", ")}`):!g&&l.length>0&&(h=`ORDER BY ${l.map(w=>`\`${w}\` ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM \`${t}\` ${b} ${h} LIMIT ${n+1}`,R=[...p,...f],N=`SELECT COUNT(*) as total FROM \`${t}\` ${m}`;return{sql:C,values:R,countSql:N,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:n="asc",sort:o=[],cursor:s}=e,c=[];Array.isArray(o)&&o.length>0?c=o.map(d=>d.columnName):typeof o=="string"&&o&&(c=[o]);let i=d=>this.encodeCursor({values:Object.fromEntries(c.map(f=>[f,d[f]])),sortColumns:c}),l=t[0],u=t[t.length-1],m=null,p=null;return n==="asc"?(r&&(m=i(u)),s&&(p=i(l))):(s&&(m=i(u)),r&&(p=i(l))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,db:r,limit:n=50,direction:o="asc",sort:s=[],order:c="asc",cursor:i,filters:l=[]}=e,u=H(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=c;Array.isArray(s)&&s.length>0?(p=s.map(k=>k.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=[...p,...m.filter(k=>!p.includes(k))],{clause:b,values:g}=rr(l),h="",C=[];if(i){let k=this.decodeCursor(i);if(k){let W=ar(k,o,d);h=W.clause,C=W.values}}let R="";b&&h?R=`WHERE ${b.replace(/^WHERE\s+/i,"")} AND ${h}`:b?R=b:h&&(R=`WHERE ${h}`);let N=nr((Array.isArray(s),s),c),w=N;o==="desc"?N?w=N.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):f.length>0&&(w=`ORDER BY ${f.map(k=>`\`${k}\` ${d==="asc"?"DESC":"ASC"}`).join(", ")}`):!N&&f.length>0&&(w=`ORDER BY ${f.map(k=>`\`${k}\` ${d.toUpperCase()}`).join(", ")}`);let[T]=await u.execute(`SELECT COUNT(*) as total FROM \`${t}\` ${b}`,g),S=Number(T[0]?.total??0),[j]=await u.execute(`SELECT * FROM \`${t}\` ${R} ${w} LIMIT ${Math.floor(n)+1}`,[...g,...C]),$=j,P=$.length>n;P&&($=$.slice(0,n)),o==="desc"&&($=$.reverse());let O=null,V=null;if($.length>0&&f.length>0){let k=$[0],W=$[$.length-1],Z=Y=>({values:Object.fromEntries(f.map(Q=>[Q,Y[Q]])),sortColumns:f});o==="asc"?(P&&(O=this.encodeCursor(Z(W))),i&&(V=this.encodeCursor(Z(k)))):(i&&(O=this.encodeCursor(Z(W))),P&&(V=this.encodeCursor(Z(k))))}return{data:$,meta:{limit:n,total:S,hasNextPage:o==="asc"?P:!!i,hasPreviousPage:o==="asc"?!!i:P,nextCursor:O,prevCursor:V}}}async getDatabasesList(){let e=H(),[t]=await e.execute(`
|
|
150
150
|
SELECT
|
|
151
151
|
s.SCHEMA_NAME AS name,
|
|
152
152
|
CONCAT(ROUND(COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024, 2), ' MB') AS size,
|
|
@@ -156,7 +156,7 @@ ${s.join(`,
|
|
|
156
156
|
LEFT JOIN information_schema.TABLES t ON t.TABLE_SCHEMA = s.SCHEMA_NAME
|
|
157
157
|
GROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME
|
|
158
158
|
ORDER BY s.SCHEMA_NAME
|
|
159
|
-
`);if(!t[0])throw new
|
|
159
|
+
`);if(!t[0])throw new L(500,{message:"No databases returned from server"});return t}async getCurrentDatabase(){let e=H(),[t]=await e.execute("SELECT DATABASE() AS db");if(!t[0])throw new L(500,{message:"No current database returned from server"});return t[0]}async getDatabaseConnectionInfo(){let e=H(),[t]=await e.execute(`
|
|
160
160
|
SELECT
|
|
161
161
|
VERSION() AS version,
|
|
162
162
|
DATABASE() AS database_name,
|
|
@@ -164,15 +164,15 @@ ${s.join(`,
|
|
|
164
164
|
@@hostname AS host,
|
|
165
165
|
@@port AS port,
|
|
166
166
|
@@max_connections AS max_connections
|
|
167
|
-
`),[r]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new
|
|
167
|
+
`),[r]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new L(500,{message:"No connection information returned from server"});let n=t[0],o=Se();return{host:String(n.host||o.host),port:Number(n.port||o.port),user:String(n.user),database:String(n.database_name??""),version:String(n.version),active_connections:Number(r[0]?.cnt??0),max_connections:Number(n.max_connections)}}async getTablesList(e){let t=H(e),[r]=await t.execute(`
|
|
168
168
|
SELECT table_name as tableName
|
|
169
169
|
FROM information_schema.tables
|
|
170
170
|
WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
|
|
171
171
|
ORDER BY table_name
|
|
172
|
-
`);return!r||r.length===0?[]:Promise.all(r.map(async n=>{let[o]=await t.execute(`SELECT COUNT(*) as count FROM \`${n.tableName}\``);return{tableName:n.tableName,rowCount:o[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:n,foreignKeys:o}=e,s=H(t),c=n.map(m=>
|
|
172
|
+
`);return!r||r.length===0?[]:Promise.all(r.map(async n=>{let[o]=await t.execute(`SELECT COUNT(*) as count FROM \`${n.tableName}\``);return{tableName:n.tableName,rowCount:o[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:n,foreignKeys:o}=e,s=H(t),c=n.map(m=>yt(m)),i=[],l=n.filter(m=>m.isPrimaryKey);l.length>0&&i.push(`PRIMARY KEY (${l.map(m=>`\`${m.columnName}\``).join(", ")})`);for(let m of n)m.isUnique&&!m.isPrimaryKey&&i.push(`UNIQUE KEY \`uq_${r}_${m.columnName}\` (\`${m.columnName}\`)`);let u=o?.map(m=>`CONSTRAINT \`${`fk_${r}_${m.columnName}_${m.referencedTable}_${m.referencedColumn}`}\` FOREIGN KEY (\`${m.columnName}\`) REFERENCES \`${m.referencedTable}\` (\`${m.referencedColumn}\`) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await s.execute(`CREATE TABLE \`${r}\` (
|
|
173
173
|
${[...c,...i,...u].join(`,
|
|
174
174
|
`)}
|
|
175
|
-
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:r,cascade:n}=e,o=H(r),[s]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(s[0]?.cnt??0)===0)throw new
|
|
175
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:r,cascade:n}=e,o=H(r),[s]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(s[0]?.cnt??0)===0)throw new L(404,{message:`Table "${t}" does not exist`});let c=await this.getTableRowCount(o,t);if(!n){let i=await this.getRelatedRecordsForTable(t,r);if(i.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:i}}try{if(n){let i=await o.getConnection();try{await i.execute("SET FOREIGN_KEY_CHECKS = 0"),await i.execute(`DROP TABLE \`${t}\``),await i.execute("SET FOREIGN_KEY_CHECKS = 1")}finally{i.release()}}else await o.execute(`DROP TABLE \`${t}\``);return{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(i){await o.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{});let l=i;if(l.errno===xo||l.errno===vn)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw i instanceof L?i:new L(500,{message:`Failed to delete table "${t}"`})}}async getTableSchema({tableName:e,db:t}){let r=H(t),[n]=await r.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[e]);if(Number(n[0]?.cnt??0)===0)throw new L(404,{message:`Table "${e}" does not exist`});let[o]=await r.execute(`SHOW CREATE TABLE \`${e}\``),s=o[0],c=s?.["Create Table"]??s?.create_table??"";if(!c)throw new L(500,{message:`Failed to retrieve schema for table "${e}"`});return c}async getTableColumns({tableName:e,db:t}){let r=H(t),[n]=await r.execute(`SELECT
|
|
176
176
|
c.COLUMN_NAME AS columnName,
|
|
177
177
|
c.DATA_TYPE AS dataType,
|
|
178
178
|
c.COLUMN_TYPE AS columnType,
|
|
@@ -190,7 +190,7 @@ ${s.join(`,
|
|
|
190
190
|
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
191
191
|
WHERE c.TABLE_SCHEMA = DATABASE()
|
|
192
192
|
AND c.TABLE_NAME = ?
|
|
193
|
-
ORDER BY c.ORDINAL_POSITION`,[e]);if(!n||n.length===0)throw new
|
|
193
|
+
ORDER BY c.ORDINAL_POSITION`,[e]);if(!n||n.length===0)throw new L(404,{message:`Table "${e}" does not exist`});return n.map(o=>{let s=o.dataType==="enum"||o.dataType==="set";return{columnName:o.columnName,dataType:ct(o.dataType,o.columnType),dataTypeLabel:Bt(o.dataType,o.columnType),isNullable:!!o.isNullable,columnDefault:o.columnDefault??null,isPrimaryKey:!!o.isPrimaryKey,isForeignKey:!!o.isForeignKey,referencedTable:o.referencedTable??null,referencedColumn:o.referencedColumn??null,enumValues:s?this.parseMysqlEnumValues(o.columnType):null}})}async addColumn(e){let{tableName:t,columnName:r,columnType:n,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,isArray:u,db:m}=e,p=H(m);await this.assertTableExists(p,t);let[d]=await p.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,r]);if(Number(d[0]?.cnt??0)>0)throw new L(409,{message:`Column "${r}" already exists in table "${t}"`});let f=yt({columnName:r,columnType:n,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,isArray:u},{includePrimaryKey:!0,includeUnique:!0});await p.execute(`ALTER TABLE \`${t}\` ADD COLUMN ${f}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:n}=e,o=H(n);await this.assertTableExists(o,t),await this.assertColumnExists(o,t,r);let[s]=await o.execute(`ALTER TABLE \`${t}\` DROP COLUMN \`${r}\``);return{deletedCount:s.affectedRows}}async alterColumn(e){let{tableName:t,columnName:r,columnType:n,isNullable:o,defaultValue:s,db:c}=e,i=H(c);await this.assertTableExists(i,t);let[l]=await i.execute("SELECT EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1",[t,r]),u=l[0];if(!u)throw new L(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=yt({columnName:r,columnType:n,defaultValue:s,isNullable:o},{preserveAutoIncrement:u.EXTRA?.toLowerCase().includes("auto_increment")});await i.execute(`ALTER TABLE \`${t}\` MODIFY COLUMN ${m}`)}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=H(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let[c]=await s.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,n]);if(Number(c[0]?.cnt??0)>0)throw new L(409,{message:`Column "${n}" already exists in table "${t}"`});await s.execute(`ALTER TABLE \`${t}\` RENAME COLUMN \`${r}\` TO \`${n}\``)}async addRecord({db:e,params:t}){let{tableName:r,data:n}=t,o=H(e),s=await this.getBooleanColumnSet(r,e),c=Object.keys(n),i=Object.values(n).map((u,m)=>s.has(c[m])&&typeof u=="string"?u==="true"?1:0:u),[l]=await o.execute(`INSERT INTO \`${r}\` (${c.map(u=>`\`${u}\``).join(", ")}) VALUES (${c.map(()=>"?").join(", ")})`,i);if(l.affectedRows===0)throw new L(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:l.affectedRows}}async updateRecords({params:e,db:t}){let{tableName:r,updates:n,primaryKey:o}=e,s=H(t),c=await this.getBooleanColumnSet(r,t),i=new Map;for(let u of n){let m=u.rowData[o];if(m==null)throw new L(400,{message:`Primary key "${o}" not found in row data.`});i.has(m)||i.set(m,[]),i.get(m)?.push({columnName:u.columnName,value:u.value})}let l=await s.getConnection();await l.beginTransaction();try{let u=0;for(let[m,p]of i.entries()){let d=p.map(g=>`\`${g.columnName}\` = ?`),f=p.map(g=>g.value!==null&&typeof g.value=="object"?JSON.stringify(g.value):c.has(g.columnName)&&typeof g.value=="string"?g.value==="true"?1:0:g.value);f.push(m);let[b]=await l.execute(`UPDATE \`${r}\` SET ${d.join(", ")} WHERE \`${o}\` = ?`,f);if(b.affectedRows===0)throw new L(404,{message:`Record with ${o} = ${m} not found in table "${r}"`});u+=b.affectedRows}return await l.commit(),{updatedCount:u}}catch(u){throw await l.rollback(),u instanceof L?u:new L(500,{message:`Failed to update records in "${r}"`})}finally{l.release()}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=H(r),o=t[0]?.columnName;if(!o)throw new L(400,{message:"Primary key column name is required"});let s=t.map(l=>l.value),c=s.map(()=>"?").join(", "),i=await n.getConnection();await i.beginTransaction();try{let[l]=await i.execute(`DELETE FROM \`${e}\` WHERE \`${o}\` IN (${c})`,s);return await i.commit(),{deletedCount:l.affectedRows,fkViolation:!1,relatedRecords:[]}}catch(l){if(await i.rollback(),l.errno===vn)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw l instanceof L?l:new L(500,{message:`Failed to delete records from "${e}"`})}finally{i.release()}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=H(r),o=t[0]?.columnName;if(!o)throw new L(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=await n.getConnection();await c.beginTransaction();try{await c.execute("SET FOREIGN_KEY_CHECKS = 0");let i=await this.getForeignKeyReferences(e,r),l=0,u=new Set,m=new Set,p=async(b,g,h,C)=>{let R=`${b}.${g}`;if(C.has(R))return;C.add(R);let N=await this.getForeignKeyReferences(b,r);for(let S of N){let j=h.map(()=>"?").join(", "),[$]=await c.execute(`SELECT \`${S.referencedColumn}\` FROM \`${b}\` WHERE \`${g}\` IN (${j})`,h),P=$.map(O=>O[S.referencedColumn]);P.length>0&&await p(S.referencingTable,S.referencingColumn,P,C)}let w=h.map(()=>"?").join(", "),[T]=await c.execute(`DELETE FROM \`${b}\` WHERE \`${g}\` IN (${w})`,h);l+=T.affectedRows,u.add(b)};for(let b of i)u.has(b.referencingTable)||await p(b.referencingTable,b.referencingColumn,s,m);let d=s.map(()=>"?").join(", "),[f]=await c.execute(`DELETE FROM \`${e}\` WHERE \`${o}\` IN (${d})`,s);return await c.execute("SET FOREIGN_KEY_CHECKS = 1"),await c.commit(),{deletedCount:f.affectedRows+l}}catch(i){throw await c.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{}),await c.rollback(),i instanceof L?i:new L(500,{message:`Failed to force delete records from "${e}"`})}finally{c.release()}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new L(400,{message:"At least one record is required"});let o=await H(r).getConnection();try{let s=Object.keys(t[0]),c=s.map(l=>`\`${l}\``).join(", "),i=await this.getBooleanColumnSet(e,r);await o.beginTransaction();for(let l=0;l<t.length;l++){let u=t[l],m=s.map(p=>{let d=u[p];return i.has(p)&&typeof d=="string"?d==="true"?1:0:d});try{await o.execute(`INSERT INTO \`${e}\` (${c}) VALUES (${s.map(()=>"?").join(", ")})`,m)}catch(p){throw new L(500,{message:`Failed to insert record ${l+1}: ${p instanceof Error?p.message:String(p)}`})}}return await o.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(s){throw await o.rollback(),s instanceof L?s:new L(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=H(t);if(!e?.trim())throw new L(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,""),o=performance.now(),[s,c]=await r.execute(n),i=performance.now()-o;if(Array.isArray(s)){let u=s;return{columns:c?c.map(p=>p.name):Object.keys(u[0]??{}),rows:u,rowCount:u.length,duration:i,message:u.length===0?"OK":void 0}}let l=s;return{columns:[],rows:[],rowCount:l.affectedRows,duration:i,message:`OK \u2014 ${l.affectedRows} row(s) affected`}}async getPrimaryKeyColumns(e,t){let[r]=await e.execute(`SELECT COLUMN_NAME as column_name
|
|
194
194
|
FROM information_schema.COLUMNS
|
|
195
195
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_KEY = 'PRI'
|
|
196
196
|
ORDER BY ORDINAL_POSITION`,[t]);return r.map(n=>n.column_name)}async getForeignKeyReferences(e,t){let r=H(t),[n]=await r.execute(`SELECT
|
|
@@ -206,7 +206,7 @@ ${s.join(`,
|
|
|
206
206
|
AND kcu.TABLE_NAME = tc.TABLE_NAME
|
|
207
207
|
WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
|
208
208
|
AND kcu.TABLE_SCHEMA = DATABASE()
|
|
209
|
-
AND kcu.REFERENCED_TABLE_NAME = ?`,[e]);return n.map(o=>({constraintName:o.constraint_name,referencingTable:o.referencing_table,referencingColumn:o.referencing_column,referencedTable:o.referenced_table,referencedColumn:o.referenced_column}))}async getRelatedRecordsForTable(e,t){let r=await this.getForeignKeyReferences(e,t);if(r.length===0)return[];let n=H(t),o=[];for(let s of r){let[c]=await n.execute(`SELECT * FROM \`${s.referencingTable}\` LIMIT 100`);c.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:c})}return o}async getRelatedRecords(e,t,r){let n=await this.getForeignKeyReferences(e,r);if(n.length===0)return[];let o=H(r),s=t.map(l=>l.value),c=[],i=new Map;for(let l of n){let u=`${l.referencingTable}.${l.referencingColumn}`;i.has(u)||i.set(u,[]),i.get(u)?.push(l)}for(let[,l]of i){let u=l[0];if(!u||!t.find(f=>f.columnName===u.referencedColumn))continue;let p=s.map(()=>"?").join(", "),[d]=await o.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${p}) LIMIT 100`,s);d.length>0&&c.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return c}async getTableRowCount(e,t){let[r]=await e.execute(`SELECT COUNT(*) as count FROM \`${t}\``);return Number(r[0]?.count??0)}async getBooleanColumnSet(e,t){let r=await this.getTableColumns({tableName:e,db:t});return new Set(r.filter(n=>n.dataTypeLabel==="boolean").map(n=>n.columnName))}async assertTableExists(e,t){let[r]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(r[0]?.cnt??0)===0)throw new
|
|
209
|
+
AND kcu.REFERENCED_TABLE_NAME = ?`,[e]);return n.map(o=>({constraintName:o.constraint_name,referencingTable:o.referencing_table,referencingColumn:o.referencing_column,referencedTable:o.referenced_table,referencedColumn:o.referenced_column}))}async getRelatedRecordsForTable(e,t){let r=await this.getForeignKeyReferences(e,t);if(r.length===0)return[];let n=H(t),o=[];for(let s of r){let[c]=await n.execute(`SELECT * FROM \`${s.referencingTable}\` LIMIT 100`);c.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:c})}return o}async getRelatedRecords(e,t,r){let n=await this.getForeignKeyReferences(e,r);if(n.length===0)return[];let o=H(r),s=t.map(l=>l.value),c=[],i=new Map;for(let l of n){let u=`${l.referencingTable}.${l.referencingColumn}`;i.has(u)||i.set(u,[]),i.get(u)?.push(l)}for(let[,l]of i){let u=l[0];if(!u||!t.find(f=>f.columnName===u.referencedColumn))continue;let p=s.map(()=>"?").join(", "),[d]=await o.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${p}) LIMIT 100`,s);d.length>0&&c.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return c}async getTableRowCount(e,t){let[r]=await e.execute(`SELECT COUNT(*) as count FROM \`${t}\``);return Number(r[0]?.count??0)}async getBooleanColumnSet(e,t){let r=await this.getTableColumns({tableName:e,db:t});return new Set(r.filter(n=>n.dataTypeLabel==="boolean").map(n=>n.columnName))}async assertTableExists(e,t){let[r]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(r[0]?.cnt??0)===0)throw new L(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let[n]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,r]);if(Number(n[0]?.cnt??0)===0)throw new L(404,{message:`Column "${r}" does not exist in table "${t}"`})}parseMysqlEnumValues(e){let t=e.match(/^(?:enum|set)\((.+)\)$/i);return t?.[1]?t[1].split(",").map(r=>r.trim().replace(/^'|'$/g,"")):null}}});function or(a){if(a.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of a){let n=t.length+1,o=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${o} ${r.operator} $${n}`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${o} IS NULL`):(e.push(`${o} = $${n}`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${o} IS NOT NULL`):(e.push(`${o} != $${n}`),t.push(r.value));break;case"like":e.push(`${o}::text LIKE $${n}`),t.push(r.value);break;case"not like":e.push(`${o}::text NOT LIKE $${n}`),t.push(r.value);break;case"ilike":e.push(`${o}::text ILIKE $${n}`),t.push(r.value);break;case"not ilike":e.push(`${o}::text NOT ILIKE $${n}`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function sr(a,e){return Array.isArray(a)?a.length===0?"":`ORDER BY ${a.map(r=>`"${r.columnName}" ${r.direction.toUpperCase()}`).join(", ")}`:a&&typeof a=="string"?`ORDER BY "${a}" ${e?.toUpperCase()||"ASC"}`:""}function ir(a,e,t,r){let{values:n,sortColumns:o}=a,s=[],c=[],u=t==="asc"===(e==="asc");if(o.length>0){let m=o.map(f=>`"${f}"`).join(", "),p=o.map((f,b)=>`$${r+b}`).join(", "),d=u?">":"<";s.push(`(${m}) ${d} (${p})`);for(let f of o)c.push(n[f])}return{clause:s.length>0?`(${s.join(" AND ")})`:"",values:c}}var qn=E(()=>{"use strict"});import{HTTPException as _}from"hono/http-exception";var ht,Un=E(()=>{"use strict";Te();De();_e();Ve();qn();ht=class extends oe{async runQuery(e,t,r){return(await z(e).query(t,r)).rows}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return lt(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"BOOLEAN",json:"JSONB",date:"TIMESTAMP WITH TIME ZONE",array:"TEXT[]",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:n=50,direction:o="asc",sort:s=[],order:c="asc",filters:i=[],db:l}=e,u=z(l),m=[],p=c;Array.isArray(s)&&s.length>0?(m=s.map(P=>P.columnName),p=s[0].direction):typeof s=="string"&&s&&(m=[s]);let d=m.length>0?[...m]:["ctid"],{clause:f,values:b}=or(i),g="",h=[];if(r){let P=this.decodeCursor(r);if(P){let O=ir(P,o,p,b.length+1);g=O.clause,h=O.values}}let C="";f&&g?C=`WHERE ${f.replace(/^WHERE\s+/i,"")} AND ${g}`:f?C=f:g&&(C=`WHERE ${g}`);let R=sr((Array.isArray(s),s),c),N=R;o==="desc"?R?N=R.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):N=`ORDER BY ${d.map(O=>`"${O}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!R&&d.length>0&&(N=`ORDER BY ${d.map(O=>`"${O}" ${p.toUpperCase()}`).join(", ")}`);let w=b.length+h.length+1,T=`SELECT * FROM "${t}" ${C} ${N} LIMIT $${w}`,S=[...b,...h,n+1],j=`SELECT COUNT(*) as total FROM "${t}" ${f}`;return{sql:T,values:S,countSql:j,countValues:b}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:n="asc",sort:o=[],cursor:s}=e,c=[];Array.isArray(o)&&o.length>0?c=o.map(d=>d.columnName):typeof o=="string"&&o&&(c=[o]),c.length===0&&(c=["ctid"]);let i=d=>{let f={values:Object.fromEntries(c.map(b=>[b,d[b]])),sortColumns:c};return this.encodeCursor(f)},l=t[0],u=t[t.length-1],m=null,p=null;return n==="asc"?(r&&(m=i(u)),s&&(p=i(l))):(s&&(m=i(u)),r&&(p=i(l))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,db:r,limit:n=50,direction:o="asc",sort:s=[],order:c="asc",cursor:i,filters:l=[]}=e,u=z(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=c;Array.isArray(s)&&s.length>0?(p=s.map(Y=>Y.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=[...p,...m.filter(Y=>!p.includes(Y))];f.length===0&&f.push("ctid");let{clause:b,values:g}=or(l),h="",C=[];if(i){let Y=this.decodeCursor(i);if(Y){let Q=ir(Y,o,d,g.length+1);h=Q.clause,C=Q.values}}let R="";b&&h?R=`WHERE ${b.replace(/^WHERE\s+/i,"")} AND ${h}`:b?R=b:h&&(R=`WHERE ${h}`);let N=sr((Array.isArray(s),s),c),w=N;o==="desc"?N?w=N.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):w=`ORDER BY ${f.map(Q=>`"${Q}" ${d==="asc"?"DESC":"ASC"}`).join(", ")}`:!N&&f.length>0&&(w=`ORDER BY ${f.map(Q=>`"${Q}" ${d.toUpperCase()}`).join(", ")}`);let T=await u.query(`SELECT COUNT(*) as total FROM "${t}" ${b}`,g),S=Number(T.rows[0].total),j=g.length+C.length+1,$=await u.query(`SELECT * FROM "${t}" ${R} ${w} LIMIT $${j}`,[...g,...C,n+1]),O=$.fields&&$.fields.length>0?$.rows.filter(Y=>Object.keys(Y).length>0):$.rows,V=O.length>n;V&&(O=O.slice(0,n)),o==="desc"&&(O=O.reverse());let k=Y=>({values:Object.fromEntries(f.map(Q=>[Q,Y[Q]])),sortColumns:f}),W=null,Z=null;if(O.length>0){let Y=O[0],Q=O[O.length-1];o==="asc"?(V&&(W=this.encodeCursor(k(Q))),i&&(Z=this.encodeCursor(k(Y)))):(i&&(W=this.encodeCursor(k(Q))),V&&(Z=this.encodeCursor(k(Y))))}return{data:O,meta:{limit:n,total:S,hasNextPage:o==="asc"?V:!!i,hasPreviousPage:o==="asc"?!!i:V,nextCursor:W,prevCursor:Z}}}async getDatabasesList(){let e=z(),{rows:t}=await e.query(`
|
|
210
210
|
SELECT
|
|
211
211
|
d.datname as name,
|
|
212
212
|
pg_size_pretty(pg_database_size(d.datname)) as size,
|
|
@@ -224,7 +224,7 @@ ${s.join(`,
|
|
|
224
224
|
inet_server_port() as port,
|
|
225
225
|
(SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,
|
|
226
226
|
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;
|
|
227
|
-
`);if(!t[0])throw new _(500,{message:"No connection information returned from database"});let{connectionInfoSchema:r}=await Promise.resolve().then(()=>(
|
|
227
|
+
`);if(!t[0])throw new _(500,{message:"No connection information returned from database"});let{connectionInfoSchema:r}=await Promise.resolve().then(()=>(Te(),Pn)),n=r.parse(t[0]),o=Se();return{host:n.host||o.host,port:n.port||o.port,user:n.user,database:n.database,version:n.version.toString(),active_connections:n.active_connections,max_connections:n.max_connections}}async getTablesList(e){let t=z(e),r=o=>o.replaceAll('"','""'),{rows:n}=await t.query(`
|
|
228
228
|
SELECT table_schema as "schemaName", table_name as "tableName"
|
|
229
229
|
FROM information_schema.tables
|
|
230
230
|
WHERE table_type = 'BASE TABLE'
|
|
@@ -264,7 +264,7 @@ ${s.join(`,
|
|
|
264
264
|
JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema
|
|
265
265
|
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = 'public' AND tc.table_name = $1
|
|
266
266
|
) fk ON c.column_name = fk.column_name
|
|
267
|
-
WHERE c.table_schema = 'public' AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e]);if(!n||n.length===0)throw new _(404,{message:`Table "${e}" does not exist`});return n.map(o=>{let s=null;return o.enumValues&&(Array.isArray(o.enumValues)?s=o.enumValues:typeof o.enumValues=="string"&&(s=o.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:o.columnName,dataType:
|
|
267
|
+
WHERE c.table_schema = 'public' AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e]);if(!n||n.length===0)throw new _(404,{message:`Table "${e}" does not exist`});return n.map(o=>{let s=null;return o.enumValues&&(Array.isArray(o.enumValues)?s=o.enumValues:typeof o.enumValues=="string"&&(s=o.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:o.columnName,dataType:lt(o.dataType),dataTypeLabel:Ft(o.dataType),isNullable:o.isNullable,columnDefault:o.columnDefault,isPrimaryKey:o.isPrimaryKey,isForeignKey:o.isForeignKey,referencedTable:o.referencedTable,referencedColumn:o.referencedColumn,enumValues:s}})}async addColumn(e){let{tableName:t,columnName:r,columnType:n,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,isArray:u,db:m}=e,p=z(m),{rows:d}=await p.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = 'public') as exists;",[t]);if(!d[0]?.exists)throw new _(404,{message:`Table "${t}" does not exist`});let{rows:f}=await p.query("SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = 'public') as exists;",[t,r]);if(f[0]?.exists)throw new _(409,{message:`Column "${r}" already exists in table "${t}"`});let b=`"${r}" ${n}`;u&&(b+="[]"),s&&(b+=" PRIMARY KEY"),i&&!s&&(b+=" UNIQUE"),c||(b+=" NOT NULL"),l&&(b+=" GENERATED ALWAYS AS IDENTITY"),o?.trim()&&!l&&(b+=` DEFAULT ${o.trim()}`),await p.query(`ALTER TABLE "${t}" ADD COLUMN ${b}`)}async deleteColumn(e){let{tableName:t,columnName:r,cascade:n,db:o}=e,s=z(o),{rows:c}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = 'public') as exists;",[t]);if(!c[0]?.exists)throw new _(404,{message:`Table "${t}" does not exist`});let{rows:i}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = 'public') as exists;",[t,r]);if(!i[0]?.exists)throw new _(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rowCount:l}=await s.query(`ALTER TABLE "${t}" DROP COLUMN "${r}" ${n?"CASCADE":"RESTRICT"}`);return{deletedCount:l??0}}async alterColumn(e){let{tableName:t,columnName:r,columnType:n,isNullable:o,defaultValue:s,db:c}=e,i=z(c),{rows:l}=await i.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = 'public') as exists;",[t]);if(!l[0]?.exists)throw new _(404,{message:`Table "${t}" does not exist`});let{rows:u}=await i.query("SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = 'public') as exists;",[t,r]);if(!u[0]?.exists)throw new _(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=await i.connect();try{await m.query("BEGIN"),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" TYPE ${n}`),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" ${o?"DROP":"SET"} NOT NULL`),s?.trim()?await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" SET DEFAULT ${s.trim()}`):await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" DROP DEFAULT`),await m.query("COMMIT")}catch(p){throw await m.query("ROLLBACK"),p}finally{m.release()}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=z(o),c="SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = 'public') as exists;",{rows:i}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = 'public') as exists;",[t]);if(!i[0]?.exists)throw new _(404,{message:`Table "${t}" does not exist`});let{rows:l}=await s.query(c,[t,r]);if(!l[0]?.exists)throw new _(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rows:u}=await s.query(c,[t,n]);if(u[0]?.exists)throw new _(409,{message:`Column "${n}" already exists in table "${t}"`});await s.query(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${n}"`)}async addRecord({db:e,params:t}){let{tableName:r,data:n}=t,o=z(e),s=Object.keys(n),c=Object.values(n),i=s.map((m,p)=>`$${p+1}`).join(", "),l=s.map(m=>`"${m}"`).join(", "),u=await o.query(`INSERT INTO "${r}" (${l}) VALUES (${i}) RETURNING *`,c);if(u.rowCount===0)throw new _(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:u.rowCount??0}}async updateRecords({params:e,db:t}){let{tableName:r,updates:n,primaryKey:o}=e,s=z(t),c=new Map;for(let i of n){let l=i.rowData[o];if(l==null)throw new _(400,{message:`Primary key "${o}" not found in row data.`});c.has(l)||c.set(l,[]),c.get(l)?.push({columnName:i.columnName,value:i.value})}await s.query("BEGIN");try{let i=0;for(let[l,u]of c.entries()){let m=u.map((f,b)=>`"${f.columnName}" = $${b+1}`),p=u.map(f=>f.value!==null&&typeof f.value=="object"?JSON.stringify(f.value):f.value);p.push(l);let d=await s.query(`UPDATE "${r}" SET ${m.join(", ")} WHERE "${o}" = $${p.length} RETURNING *`,p);if(d.rowCount===0)throw new _(404,{message:`Record with ${o} = ${l} not found in table "${r}"`});i+=d.rowCount??0}return await s.query("COMMIT"),{updatedCount:i}}catch(i){throw await s.query("ROLLBACK"),i instanceof _?i:new _(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=z(r),o=t[0]?.columnName;if(!o)throw new _(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=s.map((i,l)=>`$${l+1}`).join(", ");try{await n.query("BEGIN");let i=await n.query(`DELETE FROM "${e}" WHERE "${o}" IN (${c}) RETURNING *`,s);return await n.query("COMMIT"),{deletedCount:i.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(i){if(await n.query("ROLLBACK"),i.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(n,e,t,r)};throw i instanceof _?i:new _(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=z(r),o=t[0]?.columnName;if(!o)throw new _(400,{message:"Primary key column name is required"});let s=t.map(c=>c.value);await n.query("BEGIN");try{let c=await this.getFkConstraints(n,e),i=0,l=new Set,u=async(d,f,b)=>{let g=await this.getFkConstraints(n,d);for(let R of g){let N=b.map((S,j)=>`$${j+1}`).join(", "),{rows:w}=await n.query(`SELECT "${R.referencedColumn}" FROM "${d}" WHERE "${f}" IN (${N})`,b),T=w.map(S=>S[R.referencedColumn]);T.length>0&&await u(R.referencingTable,R.referencingColumn,T)}let h=b.map((R,N)=>`$${N+1}`).join(", "),C=await n.query(`DELETE FROM "${d}" WHERE "${f}" IN (${h})`,b);i+=C.rowCount??0,l.add(d)};for(let d of c)l.has(d.referencingTable)||await u(d.referencingTable,d.referencingColumn,s);let m=s.map((d,f)=>`$${f+1}`).join(", "),p=await n.query(`DELETE FROM "${e}" WHERE "${o}" IN (${m}) RETURNING *`,s);return await n.query("COMMIT"),{deletedCount:(p.rowCount??0)+i}}catch(c){throw await n.query("ROLLBACK"),c instanceof _?c:new _(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new _(400,{message:"At least one record is required"});let o=await z(r).connect();try{let s=Object.keys(t[0]),c=s.map(l=>`"${l}"`).join(", "),i=0;await o.query("BEGIN");for(let l of t){let u=s.map(p=>l[p]),m=s.map((p,d)=>`$${d+1}`).join(", ");try{await o.query(`INSERT INTO "${e}" (${c}) VALUES (${m}) RETURNING *`,u),i++}catch(p){throw new _(500,{message:`Failed: ${p instanceof Error?p.message:String(p)}`})}}return await o.query("COMMIT"),{success:!0,message:`Bulk insert completed: ${i} records inserted`,successCount:i,failureCount:0}}catch(s){throw await o.query("ROLLBACK"),s instanceof _?s:new _(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=z(t);if(!e?.trim())throw new _(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.query(n),c=performance.now()-o;return{columns:s.fields.map(i=>i.name),rows:s.rows,rowCount:s.rows.length,duration:c,message:s.rows.length===0?"OK":void 0}}async getPrimaryKeyColumns(e,t){return(await e.query(`SELECT a.attname as column_name
|
|
268
268
|
FROM pg_index i
|
|
269
269
|
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
270
270
|
WHERE i.indrelid = $1::regclass AND i.indisprimary
|
|
@@ -273,8 +273,8 @@ ${s.join(`,
|
|
|
273
273
|
FROM information_schema.table_constraints AS tc
|
|
274
274
|
JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
275
275
|
JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema
|
|
276
|
-
WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1`,[t]);return r.map(n=>({constraintName:n.constraint_name,referencingTable:n.referencing_table,referencingColumn:n.referencing_column,referencedTable:n.referenced_table,referencedColumn:n.referenced_column}))}async getFkReferencesForTable(e,t){return this.getFkConstraints(e,t)}async getRelatedRecordsForTable(e,t){let r=await this.getFkReferencesForTable(e,t);if(r.length===0)return[];let n=[];for(let o of r){let{rows:s}=await e.query(`SELECT * FROM "${o.referencingTable}" LIMIT 100`);s.length>0&&n.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return n}async getRelatedRecords(e,t,r,n){let o=await this.getFkConstraints(e,t);if(o.length===0)return[];let s=[],c=r.map(l=>l.value),i=new Map;for(let l of o){let u=`${l.referencingTable}.${l.referencingColumn}`,m=i.get(u)??[];m.push(l),i.set(u,m)}for(let[,l]of i){let u=l[0];if(!u||!r.find(f=>f.columnName===u.referencedColumn))continue;let p=c.map((f,b)=>`$${b+1}`).join(", "),{rows:d}=await e.query(`SELECT * FROM "${u.referencingTable}" WHERE "${u.referencingColumn}" IN (${p}) LIMIT 100`,c);d.length>0&&s.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return s}async getTableRowCount(e,t){let{rows:r}=await e.query(`SELECT COUNT(*) as count FROM "${t}"`);return Number.parseInt(r[0]?.count??"0",10)}}});function
|
|
277
|
-
`){t.length>0&&(e.push(t),t=""),r++;continue}t+=s,r++}if(n||o)throw new Error("Unterminated quoted string in command");return t.length>0&&e.push(t),e}function
|
|
276
|
+
WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1`,[t]);return r.map(n=>({constraintName:n.constraint_name,referencingTable:n.referencing_table,referencingColumn:n.referencing_column,referencedTable:n.referenced_table,referencedColumn:n.referenced_column}))}async getFkReferencesForTable(e,t){return this.getFkConstraints(e,t)}async getRelatedRecordsForTable(e,t){let r=await this.getFkReferencesForTable(e,t);if(r.length===0)return[];let n=[];for(let o of r){let{rows:s}=await e.query(`SELECT * FROM "${o.referencingTable}" LIMIT 100`);s.length>0&&n.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return n}async getRelatedRecords(e,t,r,n){let o=await this.getFkConstraints(e,t);if(o.length===0)return[];let s=[],c=r.map(l=>l.value),i=new Map;for(let l of o){let u=`${l.referencingTable}.${l.referencingColumn}`,m=i.get(u)??[];m.push(l),i.set(u,m)}for(let[,l]of i){let u=l[0];if(!u||!r.find(f=>f.columnName===u.referencedColumn))continue;let p=c.map((f,b)=>`$${b+1}`).join(", "),{rows:d}=await e.query(`SELECT * FROM "${u.referencingTable}" WHERE "${u.referencingColumn}" IN (${p}) LIMIT 100`,c);d.length>0&&s.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return s}async getTableRowCount(e,t){let{rows:r}=await e.query(`SELECT COUNT(*) as count FROM "${t}"`);return Number.parseInt(r[0]?.count??"0",10)}}});function Vn(a){let e=[],t="",r=0,n=!1,o=!1;for(;r<a.length;){let s=a[r];if(n){s==="'"?n=!1:t+=s,r++;continue}if(o){if(s==="\\"&&r+1<a.length){t+=a[r+1],r+=2;continue}s==='"'?o=!1:t+=s,r++;continue}if(s==="'"){n=!0,r++;continue}if(s==='"'){o=!0,r++;continue}if(s===" "||s===" "||s===`
|
|
277
|
+
`){t.length>0&&(e.push(t),t=""),r++;continue}t+=s,r++}if(n||o)throw new Error("Unterminated quoted string in command");return t.length>0&&e.push(t),e}function Wn(a,e){if(a.length===0)return Be(e);let t=a[0]?.toUpperCase()??"",r=a[1]?.toUpperCase();if((t==="ZRANGE"||t==="ZREVRANGE"||t==="ZRANGEBYSCORE")&&a.some(o=>o.toUpperCase()==="WITHSCORES"))return ko(e);if(r){let o=`${t} ${r}`,s=Hn[o];if(s)return s(e)}let n=Hn[t];return n?n(e):typeof e=="string"||typeof e=="number"||e===null?ne(e):vo(e)?Ee(e):Be(e)}var vo,Kn,Be,ne,Fn,Ee,Bn,ko,qo,jn,Hn,zn=E(()=>{"use strict";vo=a=>Array.isArray(a)&&a.every(e=>typeof e=="string"||e===null),Kn=a=>Array.isArray(a)&&a.length%2===0;Be=a=>({columns:["result"],rows:[{result:typeof a=="string"?a:JSON.stringify(a,null,2)}],rowCount:1}),ne=a=>a===null?{columns:["value"],rows:[{value:null}],rowCount:0}:{columns:["value"],rows:[{value:a}],rowCount:1},Fn=a=>({columns:["status"],rows:[{status:a}],rowCount:1}),Ee=a=>Array.isArray(a)?{columns:["#","value"],rows:a.map((e,t)=>({"#":t,value:e})),rowCount:a.length}:Be(a),Bn=a=>{if(!Kn(a))return Be(a);let e=[];for(let t=0;t<a.length;t+=2)e.push({field:a[t],value:a[t+1]});return{columns:["field","value"],rows:e,rowCount:e.length}},ko=a=>{if(!Kn(a))return Ee(a);let e=[];for(let t=0;t<a.length;t+=2)e.push({member:a[t],score:a[t+1]});return{columns:["member","score"],rows:e,rowCount:e.length}},qo=a=>{if(typeof a!="string")return Be(a);let e=[],t="";for(let r of a.split(/\r?\n/)){if(!r.trim())continue;if(r.startsWith("#")){t=r.replace(/^#\s*/,"").trim();continue}let n=r.indexOf(":");n<0||e.push({section:t,key:r.slice(0,n),value:r.slice(n+1)})}return{columns:["section","key","value"],rows:e,rowCount:e.length}},jn=a=>{if(!Array.isArray(a))return Be(a);let e=a.map(t=>{if(!Array.isArray(t)||t.length<2)return{id:null,fields:null};let[r,n]=t,o={};if(Array.isArray(n))for(let s=0;s<n.length;s+=2)o[String(n[s])]=n[s+1];return{id:r,fields:o}});return{columns:["id","fields"],rows:e,rowCount:e.length}},Hn={PING:Fn,GET:ne,SET:Fn,TYPE:ne,TTL:ne,EXISTS:ne,DBSIZE:ne,DEL:ne,INCR:ne,DECR:ne,STRLEN:ne,LLEN:ne,SCARD:ne,ZCARD:ne,HLEN:ne,HGET:ne,HMGET:Ee,MGET:Ee,KEYS:Ee,LRANGE:Ee,SMEMBERS:Ee,HGETALL:Bn,HKEYS:Ee,HVALS:Ee,"CONFIG GET":Bn,ZRANGE:Ee,INFO:qo,XRANGE:jn,XREVRANGE:jn}});import{HTTPException as A}from"hono/http-exception";function Gn(a){let e={};for(let t of a.split(/\r?\n/)){if(!t||t.startsWith("#"))continue;let r=t.indexOf(":");r<0||(e[t.slice(0,r)]=t.slice(r+1))}return e}function Go(a){let e=new Map;for(let t of a.split(/\r?\n/)){let r=t.match(/^db(\d+):keys=(\d+)/);r&&e.set(Number(r[1]),Number(r[2]))}return e}function Qn(a){let e=a.key;if(e==null||e==="")throw new A(400,{message:"Field 'key' is required"});return String(e)}function cr(a){let e=a.ttl;if(e==null||e==="")return null;let t=typeof e=="number"?e:Number.parseInt(String(e),10);return Number.isFinite(t)?t:null}function Et(a){return typeof a=="string"?a:a==null?"":typeof a=="object"?JSON.stringify(a):String(a)}function Jn(a,e){if(typeof a=="string"){try{let t=JSON.parse(a);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}throw new A(400,{message:`Value for ${e} must be a JSON object`})}if(a&&typeof a=="object"&&!Array.isArray(a))return a;throw new A(400,{message:`Value for ${e} must be a JSON object`})}function Xn(a,e){if(Array.isArray(a))return a;if(typeof a=="string")try{let t=JSON.parse(a);if(Array.isArray(t))return t}catch{}throw new A(400,{message:`Value for ${e} must be a JSON array`})}function Qo(a){let e;if(Array.isArray(a))e=a;else if(typeof a=="string")try{e=JSON.parse(a)}catch{throw new A(400,{message:"Value for zset must be an array of {member, score} entries"})}else throw new A(400,{message:"Value for zset must be an array of {member, score} entries"});let t=[];for(let r of e){if(!r||typeof r!="object")throw new A(400,{message:"Each zset entry must be an object with 'member' and 'score'"});let n=r;if(n.member===void 0||n.score===void 0)throw new A(400,{message:"Each zset entry must include 'member' and 'score'"});let o=typeof n.score=="number"?n.score:Number(n.score);if(!Number.isFinite(o))throw new A(400,{message:`Invalid score: ${String(n.score)}`});t.push({member:String(n.member),score:o})}return t}function Jo(a){if(!a)return[];let e=[];for(let t=0;t<a.length;t+=2){let r=Number(a[t+1]);e.push({member:a[t],score:Number.isFinite(r)?r:0})}return e}function Xo(a){if(!Array.isArray(a))return{length:0,firstId:null,lastId:null};let e={};for(let s=0;s<a.length;s+=2)e[String(a[s])]=a[s+1];let t=typeof e.length=="number"?e.length:Number.parseInt(String(e.length??"0"),10)||0,r=e["first-entry"],n=e["last-entry"],o=s=>Array.isArray(s)&&typeof s[0]=="string"?s[0]:null;return{length:t,firstId:o(r),lastId:o(n)}}var Je,lr,Tt,Uo,Fo,Bo,jo,Ho,Ko,Vo,Ne,fe,Wo,zo,Ce,je,He,Yn,Yo,Ct,Zn=E(()=>{"use strict";De();_e();zn();Je=["strings","hashes","lists","sets","zsets","streams"],lr={strings:"string",hashes:"hash",lists:"list",sets:"set",zsets:"zset",streams:"stream"},Tt="Schema is fixed for Redis tables; this operation is not supported",Uo="Sorting is not supported for Redis tables",Fo="Filtering is not supported for Redis tables",Bo="Backward pagination is not supported for Redis tables (SCAN is forward-only)",jo=10,Ho=3e4,Ko=1e4,Vo=a=>Je.includes(a),Ne=a=>{if(!Vo(a))throw new A(404,{message:`Table "${a}" does not exist in Redis. Valid tables: ${Je.join(", ")}`});return a},fe=a=>{if(a==="")return Ie();let e=Number.parseInt(a,10);if(!Number.isFinite(e)||e<0)throw new A(400,{message:`Invalid Redis database index: "${a}". Expected a non-negative integer.`});return e},Wo=a=>Buffer.from(JSON.stringify(a)).toString("base64url"),zo=a=>{try{return JSON.parse(Buffer.from(a,"base64url").toString("utf-8"))}catch{return null}},Ce=a=>({columnName:a.columnName,dataType:a.dataType,dataTypeLabel:a.dataTypeLabel??(a.dataType==="number"?"int":a.dataType==="json"?"json":a.dataType==="array"?"array":"text"),isNullable:a.isNullable??!1,columnDefault:a.columnDefault??null,isPrimaryKey:a.isPrimaryKey??!1,isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}),je=Ce({columnName:"key",dataType:"text",isPrimaryKey:!0}),He=Ce({columnName:"ttl",dataType:"number",isNullable:!0}),Yn={strings:[je,Ce({columnName:"value",dataType:"text",isNullable:!0}),He],hashes:[je,Ce({columnName:"value",dataType:"json"}),He],lists:[je,Ce({columnName:"value",dataType:"array"}),He],sets:[je,Ce({columnName:"value",dataType:"array"}),He],zsets:[je,Ce({columnName:"value",dataType:"json"}),He],streams:[je,Ce({columnName:"length",dataType:"number"}),Ce({columnName:"first-id",dataType:"text",isNullable:!0}),Ce({columnName:"last-id",dataType:"text",isNullable:!0}),He]},Yo={strings:`-- Redis string keys
|
|
278
278
|
-- Columns: key (text, PK), value (text), ttl (number, seconds; -1 = no TTL, -2 = missing)
|
|
279
279
|
-- Backed by: GET / SET / EXPIRE`,hashes:`-- Redis hash keys
|
|
280
280
|
-- Columns: key (text, PK), value (json: {field: value, ...}), ttl (number)
|
|
@@ -286,7 +286,7 @@ ${s.join(`,
|
|
|
286
286
|
-- Columns: key (text, PK), value (json: [{member, score}, ...]), ttl (number)
|
|
287
287
|
-- Backed by: ZRANGE WITHSCORES / ZADD / EXPIRE`,streams:`-- Redis stream keys
|
|
288
288
|
-- Columns: key (text, PK), length (number), first-id (text), last-id (text), ttl (number)
|
|
289
|
-
-- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},Et=class extends oe{countCache=new Map;runQuery(){throw new A(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new A(501,{message:"buildTableDataQuery is not supported for Redis"})}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"string":return"text";case"hash":return"json";case"list":case"set":return"array";case"zset":case"stream":return"json";case"integer":case"number":case"ttl":return"number";default:return"text"}}mapFromUniversalType(e){return"string"}async getDatabasesList(){try{let e=await le(Me()),t=await e.call("CONFIG","GET","databases"),r=16;if(Array.isArray(t)&&t.length>=2){let s=Number.parseInt(String(t[1]),10);Number.isFinite(s)&&s>0&&(r=s)}let n=await e.info("keyspace"),o=Yo(n);return Array.from({length:r},(s,c)=>({name:String(c),size:`${o.get(c)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(Me())}}async getDatabaseConnectionInfo(){try{let e=await le(Me()),[t,r]=await Promise.all([e.info("server"),e.info("clients")]),n=Yn(t),o=Yn(r),s=Number.parseInt(o.maxclients??"0",10);if(!Number.isFinite(s)||s===0){let i=await e.call("CONFIG","GET","maxclients");Array.isArray(i)&&i.length>=2&&(s=Number.parseInt(String(i[1]),10)||0)}let c=e.options;return{host:c.host??null,port:c.port??null,user:c.username||"default",database:String(c.db??Me()),version:n.redis_version??"unknown",active_connections:Number.parseInt(o.connected_clients??"0",10)||0,max_connections:s||0}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=fe(e),r=await this.getCachedCounts(t);return Ge.map(n=>({tableName:n,rowCount:r[n]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new A(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new A(400,{message:"Bulk deletion of Redis tables is not supported. Use FLUSHDB from the query runner to clear the entire logical database."})}async getTableSchema({tableName:e}){let t=Ne(e);return zo[t]}async getTableColumns({tableName:e}){let t=Ne(e);return zn[t]}async addColumn(e){throw new A(400,{message:ht})}async deleteColumn(e){throw new A(400,{message:ht})}async alterColumn(e){throw new A(400,{message:ht})}async renameColumn(e){throw new A(400,{message:ht})}async getTableData(e){try{let{tableName:t,db:r,cursor:n,limit:o=50,direction:s="asc",sort:c,filters:i}=e;if(s==="desc")throw new A(400,{message:Fo});if(c&&c.length>0)throw new A(400,{message:qo});if(i&&i.length>0)throw new A(400,{message:Uo});let l=Ne(t),u=ir[l],m=fe(r),p=await le(m),d="0";if(n){let S=Wo(n);if(!S||S.type!==l)throw new A(400,{message:"Invalid or mismatched cursor"});d=S.scanCursor}let f=[],b=0,g=!1;for(;f.length<o&&b<Bo;){let[S,j]=await p.scan(d,"MATCH","*","COUNT",Math.max(o*2,100),"TYPE",u);if(f.push(...j),d=S,b++,S==="0"){g=!0;break}}let h=f.slice(0,o),C=f.slice(o),R=await this.hydrateRows(p,l,h),N=await p.dbsize(),w=!g||C.length>0,T=w&&!g?Vo({scanCursor:d,type:l}):null;return{data:R,meta:{limit:o,total:N,hasNextPage:w,hasPreviousPage:!1,nextCursor:T,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,r){if(r.length===0)return[];let n=e.pipeline();for(let i of r)n.ttl(i);let o=await n.exec()??[],s=e.pipeline();for(let i of r)switch(t){case"strings":s.get(i);break;case"hashes":s.hgetall(i);break;case"lists":s.lrange(i,0,-1);break;case"sets":s.smembers(i);break;case"zsets":s.zrange(i,0,-1,"WITHSCORES");break;case"streams":s.xinfo("STREAM",i);break}let c=await s.exec()??[];return r.map((i,l)=>{let u=o[l]?.[1]??-2,m=c[l]?.[1];if(t==="streams"){let d=Jo(m);return this.normalizeRow({key:i,length:d.length,"first-id":d.firstId,"last-id":d.lastId,ttl:u})}let p;switch(t){case"strings":p=m??null;break;case"hashes":p=m;break;case"lists":case"sets":p=m;break;case"zsets":p=Qo(m);break}return this.normalizeRow({key:i,value:p,ttl:u})})}async getCachedCounts(e){let t=this.countCache.get(e);if(t&&Date.now()-t.timestamp<jo)return t.counts;let r=await le(e),n={},o=r.pipeline();for(let c of Ge)o.scan("0","MATCH","*","COUNT",Ho,"TYPE",ir[c]);let s=await o.exec()??[];return Ge.forEach((c,i)=>{let l=s[i]?.[1];n[c]=l?.[1]?.length??0}),this.countCache.set(e,{timestamp:Date.now(),counts:n}),n}async addRecord({db:e,params:t}){try{let{tableName:r,data:n}=t,o=Ne(r),s=Gn(n),c=lr(n),i=await le(fe(e));return await this.writeRecord(i,o,s,n.value,{mode:"create",ttl:c}),this.countCache.delete(fe(e)),{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:n,primaryKey:o}=t,s=Ne(r),c=o||"key",i=await le(fe(e)),l=new Map;for(let m of n){let p=m.rowData[c];if(p==null)throw new A(400,{message:`Primary key "${c}" not found in row data`});let d=String(p),f=l.get(d)??{...m.rowData};f[m.columnName]=m.value,l.set(d,f)}let u=0;for(let[m,p]of l.entries()){let d=p.value,f=lr(p);await this.writeRecord(i,s,m,d,{mode:"update",ttl:f}),u++}return{updatedCount:u}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:n}=e;Ne(t);let o=await le(fe(n)),s=r.map(i=>String(i.value));if(s.length===0)return{deletedCount:0,fkViolation:!1,relatedRecords:[]};let c=await o.del(...s);return this.countCache.delete(fe(n)),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:r,db:n}=e;if(!r||r.length===0)throw new A(400,{message:"At least one record is required"});let o=Ne(t),s=await le(fe(n)),c=[],i=0;for(let l=0;l<r.length;l++){let u=r[l];try{let m=Gn(u),p=lr(u);await this.writeRecord(s,o,m,u.value,{mode:"create",ttl:p}),i++}catch(m){c.push({recordIndex:l,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(fe(n)),{success:c.length===0,message:`Inserted ${i} of ${r.length} record${r.length===1?"":"s"}`,successCount:i,failureCount:c.length,...c.length>0?{errors:c}:{}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=Ne(e),n=fe(t),o=await le(n),s=ir[r],c=[],i="0";do{let[m,p]=await o.scan(i,"MATCH","*","COUNT",1e3,"TYPE",s);c.push(...p),i=m}while(i!=="0");if(c.length===0)throw new A(404,{message:`Table "${e}" has no data`});let l=await this.hydrateRows(o,r,c);return{cols:zn[r].map(m=>m.columnName),rows:l}}catch(r){throw this.wrapError(r)}}async writeRecord(e,t,r,n,o){if(t==="streams"&&o.mode==="update")throw new A(400,{message:"Streams are append-only; updating a stream record is not supported"});if(o.mode==="create")if(t==="strings"){if(await e.set(r,typeof n=="string"?n:JSON.stringify(n),"NX")===null)throw new A(409,{message:`Key "${r}" already exists`})}else{if(await e.exists(r))throw new A(409,{message:`Key "${r}" already exists`});await this.writeCollectionValue(e,t,r,n)}else if(t==="strings"){if(await e.set(r,typeof n=="string"?n:JSON.stringify(n),"XX")===null)throw new A(404,{message:`Key "${r}" does not exist`})}else{if(!await e.exists(r))throw new A(404,{message:`Key "${r}" does not exist`});await e.del(r),await this.writeCollectionValue(e,t,r,n)}o.ttl!==null&&o.ttl>0&&await e.expire(r,o.ttl)}async writeCollectionValue(e,t,r,n){switch(t){case"hashes":{let o=Qn(n,"hash"),s=[];for(let[c,i]of Object.entries(o))s.push(c,Tt(i));if(s.length===0)throw new A(400,{message:"Hash must have at least one field"});await e.hset(r,...s);return}case"lists":{let o=Jn(n,"list");if(o.length===0)throw new A(400,{message:"List must have at least one element"});await e.rpush(r,...o.map(Tt));return}case"sets":{let o=Jn(n,"set");if(o.length===0)throw new A(400,{message:"Set must have at least one member"});await e.sadd(r,...o.map(Tt));return}case"zsets":{let o=Go(n);if(o.length===0)throw new A(400,{message:"Sorted set must have at least one member"});let s=[];for(let c of o)s.push(c.score,c.member);await e.zadd(r,...s);return}case"streams":{let o=Qn(n,"stream"),s=[];for(let[c,i]of Object.entries(o))s.push(c,Tt(i));if(s.length===0)throw new A(400,{message:"Stream entry must have at least one field"});await e.xadd(r,"*",...s);return}}}async executeQuery({query:e,db:t}){let r=performance.now();try{if(!e?.trim())throw new A(400,{message:"Query is required"});let n;try{n=Kn(e.trim())}catch(u){throw new A(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(n.length===0)throw new A(400,{message:"Empty command"});let o=await le(fe(t)),[s,...c]=n,i;try{i=await o.call(s,...c)}catch(u){let m=u instanceof Error?u.message:String(u);return{columns:["error"],rows:[{error:m}],rowCount:0,duration:performance.now()-r,error:m}}return{...Vn(n,i),duration:performance.now()-r,message:typeof i=="string"?i:void 0}}catch(n){throw this.wrapError(n)}}}});function cr(a){if(!a.length)return{clause:"",values:[]};let e=[],t=[];for(let r of a){let n=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${n} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${n} IS NULL`):(e.push(`${n} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${n} IS NOT NULL`):(e.push(`${n} != ?`),t.push(r.value));break;case"like":e.push(`CAST(${n} AS TEXT) LIKE ?`),t.push(r.value);break;case"not like":e.push(`CAST(${n} AS TEXT) NOT LIKE ?`),t.push(r.value);break;case"ilike":e.push(`CAST(${n} AS TEXT) LIKE ? COLLATE NOCASE`),t.push(r.value);break;case"not ilike":e.push(`CAST(${n} AS TEXT) NOT LIKE ? COLLATE NOCASE`),t.push(r.value);break;default:break}}return e.length?{clause:`WHERE ${e.join(" AND ")}`,values:t}:{clause:"",values:[]}}function ur(a,e){return Array.isArray(a)?a.length?`ORDER BY ${a.map(t=>`"${t.columnName}" ${t.direction.toUpperCase()}`).join(", ")}`:"":a&&typeof a=="string"?`ORDER BY "${a}" ${e?.toUpperCase()||"ASC"}`:""}function mr(a,e,t){let{values:r,sortColumns:n}=a;if(!n.length)return{clause:"",values:[]};let i=t==="asc"===(e==="asc")?">":"<",l=n.map(p=>`"${p}"`).join(", "),u=n.map(()=>"?").join(", "),m=n.map(p=>r[p]);return{clause:`(${l}) ${i} (${u})`,values:m}}var Zn=E(()=>{"use strict"});import{statSync as Xo}from"fs";import{HTTPException as M}from"hono/http-exception";var Ct,ea=E(()=>{"use strict";he();De();_e();Zn();Ct=class extends oe{async runQuery(e,t,r){return G().prepare(t).all(...r)}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return ut(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"INTEGER",json:"TEXT",date:"TEXT",array:"TEXT",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:n=50,direction:o="asc",sort:s=[],order:c="asc",filters:i=[]}=e,l=[],u=c;Array.isArray(s)&&s.length>0?(l=s.map(w=>w.columnName),u=s[0].direction):typeof s=="string"&&s&&(l=[s]),l.length||(l=["rowid"]);let{clause:m,values:p}=cr(i),d="",f=[];if(r){let w=this.decodeCursor(r);if(w){let T=mr(w,o,u);d=T.clause,f=T.values}}let b="";m&&d?b=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?b=m:d&&(b=`WHERE ${d}`);let g=ur((Array.isArray(s),s),c),h=g;o==="desc"?g?h=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):h=`ORDER BY ${l.map(w=>`"${w}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(h=`ORDER BY ${l.map(w=>`"${w}" ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM "${t}" ${b} ${h} LIMIT ?`,R=[...p,...f,n+1],N=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:C,values:R,countSql:N,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(!t.length)return{nextCursor:null,prevCursor:null};let{direction:n="asc",sort:o=[],cursor:s}=e,c=[];Array.isArray(o)&&o.length>0?c=o.map(d=>d.columnName):typeof o=="string"&&o&&(c=[o]),c.length||(c=["rowid"]);let i=d=>{let f={values:Object.fromEntries(c.map(b=>[b,d[b]])),sortColumns:c};return this.encodeCursor(f)},l=t[0],u=t[t.length-1],m=null,p=null;return n==="asc"?(r&&(m=i(u)),s&&(p=i(l))):(s&&(m=i(u)),r&&(p=i(l))),{nextCursor:m,prevCursor:p}}async getTableData(e){try{let{tableName:t,db:r,limit:n=50,direction:o="asc",sort:s=[],order:c="asc",cursor:i,filters:l=[]}=e,u=G(),p=u.prepare(`PRAGMA table_info("${t}")`).all().filter(x=>x.pk>0).sort((x,ae)=>x.pk-ae.pk).map(x=>x.name),d=[],f=c;Array.isArray(s)&&s.length>0?(d=s.map(x=>x.columnName),f=s[0].direction):typeof s=="string"&&s&&(d=[s]);let b=[...d,...p.filter(x=>!d.includes(x))],g=b.length===0;g&&b.push("rowid");let{clause:h,values:C}=cr(l),R="",N=[];if(i){let x=this.decodeCursor(i);if(x){let ae=mr(x,o,f);R=ae.clause,N=ae.values}}let w="";h&&R?w=`WHERE ${h.replace(/^WHERE\s+/i,"")} AND ${R}`:h?w=h:R&&(w=`WHERE ${R}`);let T=ur((Array.isArray(s),s),c),S=p.filter(x=>!d.includes(x)),j=T;if(o==="desc")if(T){if(j=T.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),S.length){let x=f==="asc"?"DESC":"ASC";j+=`, ${S.map(ae=>`"${ae}" ${x}`).join(", ")}`}}else j=`ORDER BY ${b.map(x=>`"${x}" ${f==="asc"?"DESC":"ASC"}`).join(", ")}`;else T?S.length&&(j+=`, ${S.map(x=>`"${x}" ${f.toUpperCase()}`).join(", ")}`):j=`ORDER BY ${b.map(x=>`"${x}" ${f.toUpperCase()}`).join(", ")}`;let $=u.prepare(`SELECT COUNT(*) as total FROM "${t}" ${h}`).get(...C),L=Number($?.total??0),O=g?"*, rowid":"*",V=u.prepare(`SELECT ${O} FROM "${t}" ${w} ${j} LIMIT ?`).all(...C,...N,n+1),k=V.length>n,W=k?V.slice(0,n):V;o==="desc"&&(W=W.reverse());let Z=x=>({values:Object.fromEntries(b.map(ae=>[ae,x[ae]])),sortColumns:b}),Y=null,Q=null;if(W.length>0){let x=W[0],ae=W[W.length-1];o==="asc"?(k&&(Y=this.encodeCursor(Z(ae))),i&&(Q=this.encodeCursor(Z(x)))):(i&&(Y=this.encodeCursor(Z(ae))),k&&(Q=this.encodeCursor(Z(x))))}return{data:g?W.map(({rowid:x,...ae})=>ae):W,meta:{limit:n,total:L,hasNextPage:o==="asc"?k:!!i,hasPreviousPage:o==="asc"?!!i:k,nextCursor:Y,prevCursor:Q}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=G().prepare("PRAGMA database_list").all();if(!t.length)throw new M(500,{message:"No databases returned from SQLite"});return t.map(r=>({name:r.name,size:this.getFileSize(r.file),owner:"",encoding:"UTF-8"}))}catch(e){throw e instanceof M?e:this.wrapError(e)}}async getCurrentDatabase(){try{return{db:G().prepare("PRAGMA database_list").all().find(n=>n.name==="main")?.name??"main"}}catch(e){throw this.wrapError(e)}}async getDatabaseConnectionInfo(){try{return{host:null,port:null,user:"",database:"main",version:`SQLite ${G().prepare("SELECT sqlite_version() as version").get().version}`,active_connections:1,max_connections:1}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=G();return t.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all().map(n=>{let o=t.prepare(`SELECT COUNT(*) as count FROM "${n.name}"`).get();return{tableName:n.name,rowCount:o?.count??0}})}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:r,fields:n,foreignKeys:o}=e,s=G(),c=n.map(l=>{if(l.isPrimaryKey&&l.isIdentity)return`"${l.columnName}" INTEGER PRIMARY KEY AUTOINCREMENT`;let u=`"${l.columnName}" ${l.columnType}`;return l.isPrimaryKey&&(u+=" PRIMARY KEY"),l.isUnique&&!l.isPrimaryKey&&(u+=" UNIQUE"),!l.isNullable&&!l.isPrimaryKey&&(u+=" NOT NULL"),l.defaultValue?.trim()&&!l.isIdentity&&(u+=` DEFAULT ${l.defaultValue.trim()}`),u}),i=o?.map(l=>`FOREIGN KEY ("${l.columnName}") REFERENCES "${l.referencedTable}" ("${l.referencedColumn}") ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`)??[];s.prepare(`CREATE TABLE "${r}" (${[...c,...i].join(", ")})`).run()}async deleteTable(e){let{tableName:t,cascade:r}=e,n=G();if(!n.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});let c=n.prepare(`SELECT COUNT(*) as count FROM "${t}"`).get()?.count??0;if(!r&&this.getFkReferencesForTable(n,t).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:this.getRelatedRecordsForTable(n,t)};try{return n.prepare(`DROP TABLE "${t}"`).run(),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(i){if((i instanceof Error?i.message:String(i)).includes("FOREIGN KEY constraint"))return{deletedCount:0,fkViolation:!0,relatedRecords:this.getRelatedRecordsForTable(n,t)};throw i instanceof M?i:new M(500,{message:`Failed to delete table "${t}"`})}}async getTableSchema({tableName:e,db:t}){try{let n=G().prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name=?").get(e);if(!n)throw new M(404,{message:`Table "${e}" does not exist`});return n.sql}catch(r){throw r instanceof M?r:this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let r=G();if(!r.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(e))throw new M(404,{message:`Table "${e}" does not exist`});let o=r.prepare(`PRAGMA table_info("${e}")`).all(),s=r.prepare(`PRAGMA foreign_key_list("${e}")`).all(),c=new Map;for(let i of s)c.set(i.from,i);return o.map(i=>{let l=c.get(i.name),u=i.type.toLowerCase();return{columnName:i.name,dataType:ut(u),dataTypeLabel:jt(u),isNullable:i.notnull===0&&i.pk===0,columnDefault:i.dflt_value,isPrimaryKey:i.pk>0,isForeignKey:c.has(i.name),referencedTable:l?.table??null,referencedColumn:l?.to??null,enumValues:null}})}catch(r){throw r instanceof M?r:this.wrapError(r)}}async addColumn(e){let{tableName:t,columnName:r,columnType:n,defaultValue:o,isNullable:s,isUnique:c,db:i}=e,l=G();if(!l.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});if(l.prepare(`PRAGMA table_info("${t}")`).all().some(d=>d.name===r))throw new M(409,{message:`Column "${r}" already exists in table "${t}"`});let p=`"${r}" ${n}`;c&&(p+=" UNIQUE"),s||(p+=" NOT NULL"),o?.trim()&&(p+=` DEFAULT ${o.trim()}`);try{l.prepare(`ALTER TABLE "${t}" ADD COLUMN ${p}`).run()}catch(d){throw this.wrapError(d)}}async deleteColumn(e){let{tableName:t,columnName:r,db:n}=e,o=G();if(!o.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});if(!o.prepare(`PRAGMA table_info("${t}")`).all().some(i=>i.name===r))throw new M(404,{message:`Column "${r}" does not exist in table "${t}"`});try{o.prepare(`ALTER TABLE "${t}" DROP COLUMN "${r}"`).run()}catch(i){throw this.wrapError(i)}return{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:n,isNullable:o,defaultValue:s,db:c}=e,i=G();if(!i.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});let u=i.prepare(`PRAGMA table_info("${t}")`).all();if(!u.some(T=>T.name===r))throw new M(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=u.filter(T=>T.pk>0).sort((T,S)=>T.pk-S.pk),p=m.length>1,d=u.map(T=>{let S=T.name===r,j=S?n:T.type,$=S?o:T.notnull===0,L=S?s?.trim()||null:T.dflt_value,O=T.pk>0,V=`"${T.name}" ${j}`;return!p&&O&&(V+=" PRIMARY KEY"),!O&&!$&&(V+=" NOT NULL"),L&&(V+=` DEFAULT ${L}`),V});p&&d.push(`PRIMARY KEY (${m.map(T=>`"${T.name}"`).join(", ")})`);let f=i.prepare(`PRAGMA foreign_key_list("${t}")`).all(),b=new Map;for(let T of f){let S=b.get(T.id)??[];S.push(T),b.set(T.id,S)}let g=Array.from(b.values()).map(T=>{let S=T.map(V=>`"${V.from}"`).join(", "),j=T.map(V=>`"${V.to}"`).join(", "),{table:$,on_update:L,on_delete:O}=T[0];return`FOREIGN KEY (${S}) REFERENCES "${$}" (${j}) ON UPDATE ${L} ON DELETE ${O}`}),h=u.map(T=>`"${T.name}"`).join(", "),C=`${t}_alter_${Date.now()}`,R=i.prepare("SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL").all(t),N=i.prepare("SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?").all(t);i.pragma("foreign_keys = OFF");let w=i.transaction(()=>{i.prepare(`CREATE TABLE "${C}" (${[...d,...g].join(", ")})`).run(),i.prepare(`INSERT INTO "${C}" (${h}) SELECT ${h} FROM "${t}"`).run(),i.prepare(`DROP TABLE "${t}"`).run(),i.prepare(`ALTER TABLE "${C}" RENAME TO "${t}"`).run()});try{w();for(let{sql:T}of R)i.prepare(T).run();for(let{sql:T}of N)i.prepare(T).run()}catch(T){throw T instanceof M?T:this.wrapError(T)}finally{i.pragma("foreign_keys = ON")}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=G();if(!s.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});let i=s.prepare(`PRAGMA table_info("${t}")`).all();if(!i.some(l=>l.name===r))throw new M(404,{message:`Column "${r}" does not exist in table "${t}"`});if(i.some(l=>l.name===n))throw new M(409,{message:`Column "${n}" already exists in table "${t}"`});try{s.prepare(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${n}"`).run()}catch(l){throw this.wrapError(l)}}async addRecord({params:e}){let{tableName:t,data:r}=e,n=G(),o=Object.keys(r);if(!o.length)throw new M(400,{message:"No data provided for insert"});let s=Object.values(r).map(l=>l!==null&&typeof l=="object"?JSON.stringify(l):l),c=o.map(l=>`"${l}"`).join(", "),i=o.map(()=>"?").join(", ");try{let l=n.prepare(`INSERT INTO "${t}" (${c}) VALUES (${i})`).run(...s);if(l.changes===0)throw new M(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:l.changes}}catch(l){throw this.wrapError(l)}}async updateRecords({db:e,params:t}){let{tableName:r,updates:n,primaryKey:o}=t,s=G(),c=new Map;for(let l of n){let u=l.rowData[o];if(u==null)throw new M(400,{message:`Primary key "${o}" not found in row data.`});c.has(u)||c.set(u,[]),c.get(u)?.push({columnName:l.columnName,value:l.value})}let i=s.transaction(()=>{let l=0;for(let[u,m]of c.entries()){let p=m.map(b=>`"${b.columnName}" = ?`).join(", "),d=[...m.map(b=>b.value!==null&&typeof b.value=="object"?JSON.stringify(b.value):b.value),u],f=s.prepare(`UPDATE "${r}" SET ${p} WHERE "${o}" = ?`).run(...d);if(f.changes===0)throw new M(404,{message:`Record with ${o} = ${u} not found in table "${r}"`});l+=f.changes}return l});try{return{updatedCount:i()}}catch(l){throw l instanceof M?l:this.wrapError(l)}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=G(),o=t[0]?.columnName;if(!o)throw new M(400,{message:"Primary key column name is required"});let s=t.map(l=>l.value),c=s.map(()=>"?").join(", "),i=n.transaction(()=>n.prepare(`DELETE FROM "${e}" WHERE "${o}" IN (${c})`).run(...s).changes);try{return{deletedCount:i(),fkViolation:!1,relatedRecords:[]}}catch(l){if((l instanceof Error?l.message:String(l)).includes("FOREIGN KEY constraint failed"))return{deletedCount:0,fkViolation:!0,relatedRecords:this.getRelatedRecords(n,e,t)};throw this.wrapError(l)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=G(),o=t[0]?.columnName;if(!o)throw new M(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value);n.pragma("foreign_keys = OFF");let c=n.transaction(()=>{let i=this.getFkReferencesForTable(n,e),l=0;for(let p of i){let d=s.map(()=>"?").join(", "),f=n.prepare(`DELETE FROM "${p.referencingTable}" WHERE "${p.referencingColumn}" IN (${d})`).run(...s);l+=f.changes}let u=s.map(()=>"?").join(", ");return n.prepare(`DELETE FROM "${e}" WHERE "${o}" IN (${u})`).run(...s).changes+l});try{return{deletedCount:c()}}catch(i){throw i instanceof M?i:this.wrapError(i)}finally{n.pragma("foreign_keys = ON")}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t?.length)throw new M(400,{message:"At least one record is required"});let n=G(),o=Object.keys(t[0]),s=o.map(u=>`"${u}"`).join(", "),c=o.map(()=>"?").join(", "),i=n.prepare(`INSERT INTO "${e}" (${s}) VALUES (${c})`),l=n.transaction(u=>{let m=0;for(let p of u){let d=o.map(f=>{let b=p[f];return b!==null&&typeof b=="object"?JSON.stringify(b):b});i.run(...d),m++}return m});try{let u=l(t);return{success:!0,message:`Bulk insert completed: ${u} records inserted`,successCount:u,failureCount:0}}catch(u){throw u instanceof M?u:this.wrapError(u)}}async executeQuery({query:e,db:t}){let r=G();if(!e?.trim())throw new M(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,""),o=performance.now();try{let s=r.prepare(n);if(s.reader){let l=s.all(),u=performance.now()-o;return{columns:l.length>0?Object.keys(l[0]):[],rows:l,rowCount:l.length,duration:u,message:l.length===0?"OK":void 0}}let c=s.run(),i=performance.now()-o;return{columns:[],rows:[],rowCount:c.changes,duration:i,message:`OK (${c.changes} rows affected)`}}catch(s){throw this.wrapError(s)}}getFileSize(e){if(!e)return"in-memory";try{let r=Xo(e).size;return r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/(1024*1024)).toFixed(1)} MB`}catch{return"N/A"}}getFkReferencesForTable(e,t){let r=e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all(),n=[];for(let o of r){if(o.name===t)continue;let s=e.prepare(`PRAGMA foreign_key_list("${o.name}")`).all();for(let c of s)c.table===t&&n.push({constraintName:`fk_${o.name}_${c.from}_${t}_${c.to}`,referencingTable:o.name,referencingColumn:c.from,referencedTable:t,referencedColumn:c.to})}return n}getRelatedRecordsForTable(e,t){let r=this.getFkReferencesForTable(e,t);if(!r.length)return[];let n=[];for(let o of r){let s=e.prepare(`SELECT * FROM "${o.referencingTable}" LIMIT 100`).all();s.length>0&&n.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return n}getRelatedRecords(e,t,r){let n=this.getFkReferencesForTable(e,t);if(!n.length)return[];let o=[];for(let s of n){if(!r.find(m=>m.columnName===s.referencedColumn))continue;let i=r.map(m=>m.value),l=i.map(()=>"?").join(", "),u=e.prepare(`SELECT * FROM "${s.referencingTable}" WHERE "${s.referencingColumn}" IN (${l}) LIMIT 100`).all(...i);u.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:u})}return o}}});function ta(){se.register("pg",new gt),se.register("mysql",new yt),se.register("mssql",new ft),se.register("mongodb",new ot),se.register("sqlite",new Ct),se.register("redis",new Et)}var ra=E(()=>{"use strict";Re();Qr();Mn();vn();qn();Xn();ea()});import{HTTPException as Zo}from"hono/http-exception";import{DatabaseError as es}from"pg";import{ZodError as ts}from"zod";function na(a,e){if(a instanceof Zo)return e.json({error:a.message??"Internal server error"},a.status);if(a instanceof ts){let t=a.issues[0];return e.json({error:"Validation error",details:t.message},400)}if(a instanceof Error){let t=a;if(t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"||t.code==="ETIMEDOUT"||t.code==="ER_ACCESS_DENIED_ERROR"||t.code==="ER_BAD_HOST_ERROR"||t.code==="ECONNRESET"||t.errno===1045||t.errno===2003||t.errno===2002||a.message.includes("ECONNREFUSED")||a.message.includes("connection refused")||a.message.includes("timeout expired")||a.message.includes("Connection terminated")||a.message.includes("MongoNetworkError")||a.message.includes("MongoServerSelectionError")||a instanceof es&&a.code?.startsWith("08"))return e.json({error:"Database connection failed",details:a.message},503)}return e.json({error:a instanceof Error?a.message:"Internal server error"},500)}var aa=E(()=>{"use strict"});function sa(a){let e=a.dbType.toLowerCase(),t=a.dbType==="pg"?"PostgreSQL":a.dbType;return e.includes("mongo")?`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
|
|
289
|
+
-- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},Ct=class extends oe{countCache=new Map;runQuery(){throw new A(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new A(501,{message:"buildTableDataQuery is not supported for Redis"})}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"string":return"text";case"hash":return"json";case"list":case"set":return"array";case"zset":case"stream":return"json";case"integer":case"number":case"ttl":return"number";default:return"text"}}mapFromUniversalType(e){return"string"}async getDatabasesList(){try{let e=await le(Ie()),t=await e.call("CONFIG","GET","databases"),r=16;if(Array.isArray(t)&&t.length>=2){let s=Number.parseInt(String(t[1]),10);Number.isFinite(s)&&s>0&&(r=s)}let n=await e.info("keyspace"),o=Go(n);return Array.from({length:r},(s,c)=>({name:String(c),size:`${o.get(c)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(Ie())}}async getDatabaseConnectionInfo(){try{let e=await le(Ie()),[t,r]=await Promise.all([e.info("server"),e.info("clients")]),n=Gn(t),o=Gn(r),s=Number.parseInt(o.maxclients??"0",10);if(!Number.isFinite(s)||s===0){let i=await e.call("CONFIG","GET","maxclients");Array.isArray(i)&&i.length>=2&&(s=Number.parseInt(String(i[1]),10)||0)}let c=e.options;return{host:c.host??null,port:c.port??null,user:c.username||"default",database:String(c.db??Ie()),version:n.redis_version??"unknown",active_connections:Number.parseInt(o.connected_clients??"0",10)||0,max_connections:s||0}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=fe(e),r=await this.getCachedCounts(t);return Je.map(n=>({tableName:n,rowCount:r[n]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new A(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new A(400,{message:"Bulk deletion of Redis tables is not supported. Use FLUSHDB from the query runner to clear the entire logical database."})}async getTableSchema({tableName:e}){let t=Ne(e);return Yo[t]}async getTableColumns({tableName:e}){let t=Ne(e);return Yn[t]}async addColumn(e){throw new A(400,{message:Tt})}async deleteColumn(e){throw new A(400,{message:Tt})}async alterColumn(e){throw new A(400,{message:Tt})}async renameColumn(e){throw new A(400,{message:Tt})}async getTableData(e){try{let{tableName:t,db:r,cursor:n,limit:o=50,direction:s="asc",sort:c,filters:i}=e;if(s==="desc")throw new A(400,{message:Bo});if(c&&c.length>0)throw new A(400,{message:Uo});if(i&&i.length>0)throw new A(400,{message:Fo});let l=Ne(t),u=lr[l],m=fe(r),p=await le(m),d="0";if(n){let S=zo(n);if(!S||S.type!==l)throw new A(400,{message:"Invalid or mismatched cursor"});d=S.scanCursor}let f=[],b=0,g=!1;for(;f.length<o&&b<jo;){let[S,j]=await p.scan(d,"MATCH","*","COUNT",Math.max(o*2,100),"TYPE",u);if(f.push(...j),d=S,b++,S==="0"){g=!0;break}}let h=f.slice(0,o),C=f.slice(o),R=await this.hydrateRows(p,l,h),N=await p.dbsize(),w=!g||C.length>0,T=w&&!g?Wo({scanCursor:d,type:l}):null;return{data:R,meta:{limit:o,total:N,hasNextPage:w,hasPreviousPage:!1,nextCursor:T,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,r){if(r.length===0)return[];let n=e.pipeline();for(let i of r)n.ttl(i);let o=await n.exec()??[],s=e.pipeline();for(let i of r)switch(t){case"strings":s.get(i);break;case"hashes":s.hgetall(i);break;case"lists":s.lrange(i,0,-1);break;case"sets":s.smembers(i);break;case"zsets":s.zrange(i,0,-1,"WITHSCORES");break;case"streams":s.xinfo("STREAM",i);break}let c=await s.exec()??[];return r.map((i,l)=>{let u=o[l]?.[1]??-2,m=c[l]?.[1];if(t==="streams"){let d=Xo(m);return this.normalizeRow({key:i,length:d.length,"first-id":d.firstId,"last-id":d.lastId,ttl:u})}let p;switch(t){case"strings":p=m??null;break;case"hashes":p=m;break;case"lists":case"sets":p=m;break;case"zsets":p=Jo(m);break}return this.normalizeRow({key:i,value:p,ttl:u})})}async getCachedCounts(e){let t=this.countCache.get(e);if(t&&Date.now()-t.timestamp<Ho)return t.counts;let r=await le(e),n={},o=r.pipeline();for(let c of Je)o.scan("0","MATCH","*","COUNT",Ko,"TYPE",lr[c]);let s=await o.exec()??[];return Je.forEach((c,i)=>{let l=s[i]?.[1];n[c]=l?.[1]?.length??0}),this.countCache.set(e,{timestamp:Date.now(),counts:n}),n}async addRecord({db:e,params:t}){try{let{tableName:r,data:n}=t,o=Ne(r),s=Qn(n),c=cr(n),i=await le(fe(e));return await this.writeRecord(i,o,s,n.value,{mode:"create",ttl:c}),this.countCache.delete(fe(e)),{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:n,primaryKey:o}=t,s=Ne(r),c=o||"key",i=await le(fe(e)),l=new Map;for(let m of n){let p=m.rowData[c];if(p==null)throw new A(400,{message:`Primary key "${c}" not found in row data`});let d=String(p),f=l.get(d)??{...m.rowData};f[m.columnName]=m.value,l.set(d,f)}let u=0;for(let[m,p]of l.entries()){let d=p.value,f=cr(p);await this.writeRecord(i,s,m,d,{mode:"update",ttl:f}),u++}return{updatedCount:u}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:n}=e;Ne(t);let o=await le(fe(n)),s=r.map(i=>String(i.value));if(s.length===0)return{deletedCount:0,fkViolation:!1,relatedRecords:[]};let c=await o.del(...s);return this.countCache.delete(fe(n)),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:r,db:n}=e;if(!r||r.length===0)throw new A(400,{message:"At least one record is required"});let o=Ne(t),s=await le(fe(n)),c=[],i=0;for(let l=0;l<r.length;l++){let u=r[l];try{let m=Qn(u),p=cr(u);await this.writeRecord(s,o,m,u.value,{mode:"create",ttl:p}),i++}catch(m){c.push({recordIndex:l,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(fe(n)),{success:c.length===0,message:`Inserted ${i} of ${r.length} record${r.length===1?"":"s"}`,successCount:i,failureCount:c.length,...c.length>0?{errors:c}:{}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=Ne(e),n=fe(t),o=await le(n),s=lr[r],c=[],i="0";do{let[m,p]=await o.scan(i,"MATCH","*","COUNT",1e3,"TYPE",s);c.push(...p),i=m}while(i!=="0");if(c.length===0)throw new A(404,{message:`Table "${e}" has no data`});let l=await this.hydrateRows(o,r,c);return{cols:Yn[r].map(m=>m.columnName),rows:l}}catch(r){throw this.wrapError(r)}}async writeRecord(e,t,r,n,o){if(t==="streams"&&o.mode==="update")throw new A(400,{message:"Streams are append-only; updating a stream record is not supported"});if(o.mode==="create")if(t==="strings"){if(await e.set(r,typeof n=="string"?n:JSON.stringify(n),"NX")===null)throw new A(409,{message:`Key "${r}" already exists`})}else{if(await e.exists(r))throw new A(409,{message:`Key "${r}" already exists`});await this.writeCollectionValue(e,t,r,n)}else if(t==="strings"){if(await e.set(r,typeof n=="string"?n:JSON.stringify(n),"XX")===null)throw new A(404,{message:`Key "${r}" does not exist`})}else{if(!await e.exists(r))throw new A(404,{message:`Key "${r}" does not exist`});await e.del(r),await this.writeCollectionValue(e,t,r,n)}o.ttl!==null&&o.ttl>0&&await e.expire(r,o.ttl)}async writeCollectionValue(e,t,r,n){switch(t){case"hashes":{let o=Jn(n,"hash"),s=[];for(let[c,i]of Object.entries(o))s.push(c,Et(i));if(s.length===0)throw new A(400,{message:"Hash must have at least one field"});await e.hset(r,...s);return}case"lists":{let o=Xn(n,"list");if(o.length===0)throw new A(400,{message:"List must have at least one element"});await e.rpush(r,...o.map(Et));return}case"sets":{let o=Xn(n,"set");if(o.length===0)throw new A(400,{message:"Set must have at least one member"});await e.sadd(r,...o.map(Et));return}case"zsets":{let o=Qo(n);if(o.length===0)throw new A(400,{message:"Sorted set must have at least one member"});let s=[];for(let c of o)s.push(c.score,c.member);await e.zadd(r,...s);return}case"streams":{let o=Jn(n,"stream"),s=[];for(let[c,i]of Object.entries(o))s.push(c,Et(i));if(s.length===0)throw new A(400,{message:"Stream entry must have at least one field"});await e.xadd(r,"*",...s);return}}}async executeQuery({query:e,db:t}){let r=performance.now();try{if(!e?.trim())throw new A(400,{message:"Query is required"});let n;try{n=Vn(e.trim())}catch(u){throw new A(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(n.length===0)throw new A(400,{message:"Empty command"});let o=await le(fe(t)),[s,...c]=n,i;try{i=await o.call(s,...c)}catch(u){let m=u instanceof Error?u.message:String(u);return{columns:["error"],rows:[{error:m}],rowCount:0,duration:performance.now()-r,error:m}}return{...Wn(n,i),duration:performance.now()-r,message:typeof i=="string"?i:void 0}}catch(n){throw this.wrapError(n)}}}});function ur(a){if(!a.length)return{clause:"",values:[]};let e=[],t=[];for(let r of a){let n=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${n} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${n} IS NULL`):(e.push(`${n} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${n} IS NOT NULL`):(e.push(`${n} != ?`),t.push(r.value));break;case"like":e.push(`CAST(${n} AS TEXT) LIKE ?`),t.push(r.value);break;case"not like":e.push(`CAST(${n} AS TEXT) NOT LIKE ?`),t.push(r.value);break;case"ilike":e.push(`CAST(${n} AS TEXT) LIKE ? COLLATE NOCASE`),t.push(r.value);break;case"not ilike":e.push(`CAST(${n} AS TEXT) NOT LIKE ? COLLATE NOCASE`),t.push(r.value);break;default:break}}return e.length?{clause:`WHERE ${e.join(" AND ")}`,values:t}:{clause:"",values:[]}}function mr(a,e){return Array.isArray(a)?a.length?`ORDER BY ${a.map(t=>`"${t.columnName}" ${t.direction.toUpperCase()}`).join(", ")}`:"":a&&typeof a=="string"?`ORDER BY "${a}" ${e?.toUpperCase()||"ASC"}`:""}function dr(a,e,t){let{values:r,sortColumns:n}=a;if(!n.length)return{clause:"",values:[]};let i=t==="asc"===(e==="asc")?">":"<",l=n.map(p=>`"${p}"`).join(", "),u=n.map(()=>"?").join(", "),m=n.map(p=>r[p]);return{clause:`(${l}) ${i} (${u})`,values:m}}var ea=E(()=>{"use strict"});import{statSync as Zo}from"fs";import{HTTPException as M}from"hono/http-exception";var wt,ta=E(()=>{"use strict";Te();De();_e();ea();wt=class extends oe{async runQuery(e,t,r){return G().prepare(t).all(...r)}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return mt(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"INTEGER",json:"TEXT",date:"TEXT",array:"TEXT",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:n=50,direction:o="asc",sort:s=[],order:c="asc",filters:i=[]}=e,l=[],u=c;Array.isArray(s)&&s.length>0?(l=s.map(w=>w.columnName),u=s[0].direction):typeof s=="string"&&s&&(l=[s]),l.length||(l=["rowid"]);let{clause:m,values:p}=ur(i),d="",f=[];if(r){let w=this.decodeCursor(r);if(w){let T=dr(w,o,u);d=T.clause,f=T.values}}let b="";m&&d?b=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?b=m:d&&(b=`WHERE ${d}`);let g=mr((Array.isArray(s),s),c),h=g;o==="desc"?g?h=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):h=`ORDER BY ${l.map(w=>`"${w}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(h=`ORDER BY ${l.map(w=>`"${w}" ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM "${t}" ${b} ${h} LIMIT ?`,R=[...p,...f,n+1],N=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:C,values:R,countSql:N,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(!t.length)return{nextCursor:null,prevCursor:null};let{direction:n="asc",sort:o=[],cursor:s}=e,c=[];Array.isArray(o)&&o.length>0?c=o.map(d=>d.columnName):typeof o=="string"&&o&&(c=[o]),c.length||(c=["rowid"]);let i=d=>{let f={values:Object.fromEntries(c.map(b=>[b,d[b]])),sortColumns:c};return this.encodeCursor(f)},l=t[0],u=t[t.length-1],m=null,p=null;return n==="asc"?(r&&(m=i(u)),s&&(p=i(l))):(s&&(m=i(u)),r&&(p=i(l))),{nextCursor:m,prevCursor:p}}async getTableData(e){try{let{tableName:t,db:r,limit:n=50,direction:o="asc",sort:s=[],order:c="asc",cursor:i,filters:l=[]}=e,u=G(),p=u.prepare(`PRAGMA table_info("${t}")`).all().filter(x=>x.pk>0).sort((x,ae)=>x.pk-ae.pk).map(x=>x.name),d=[],f=c;Array.isArray(s)&&s.length>0?(d=s.map(x=>x.columnName),f=s[0].direction):typeof s=="string"&&s&&(d=[s]);let b=[...d,...p.filter(x=>!d.includes(x))],g=b.length===0;g&&b.push("rowid");let{clause:h,values:C}=ur(l),R="",N=[];if(i){let x=this.decodeCursor(i);if(x){let ae=dr(x,o,f);R=ae.clause,N=ae.values}}let w="";h&&R?w=`WHERE ${h.replace(/^WHERE\s+/i,"")} AND ${R}`:h?w=h:R&&(w=`WHERE ${R}`);let T=mr((Array.isArray(s),s),c),S=p.filter(x=>!d.includes(x)),j=T;if(o==="desc")if(T){if(j=T.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),S.length){let x=f==="asc"?"DESC":"ASC";j+=`, ${S.map(ae=>`"${ae}" ${x}`).join(", ")}`}}else j=`ORDER BY ${b.map(x=>`"${x}" ${f==="asc"?"DESC":"ASC"}`).join(", ")}`;else T?S.length&&(j+=`, ${S.map(x=>`"${x}" ${f.toUpperCase()}`).join(", ")}`):j=`ORDER BY ${b.map(x=>`"${x}" ${f.toUpperCase()}`).join(", ")}`;let $=u.prepare(`SELECT COUNT(*) as total FROM "${t}" ${h}`).get(...C),P=Number($?.total??0),O=g?"*, rowid":"*",V=u.prepare(`SELECT ${O} FROM "${t}" ${w} ${j} LIMIT ?`).all(...C,...N,n+1),k=V.length>n,W=k?V.slice(0,n):V;o==="desc"&&(W=W.reverse());let Z=x=>({values:Object.fromEntries(b.map(ae=>[ae,x[ae]])),sortColumns:b}),Y=null,Q=null;if(W.length>0){let x=W[0],ae=W[W.length-1];o==="asc"?(k&&(Y=this.encodeCursor(Z(ae))),i&&(Q=this.encodeCursor(Z(x)))):(i&&(Y=this.encodeCursor(Z(ae))),k&&(Q=this.encodeCursor(Z(x))))}return{data:g?W.map(({rowid:x,...ae})=>ae):W,meta:{limit:n,total:P,hasNextPage:o==="asc"?k:!!i,hasPreviousPage:o==="asc"?!!i:k,nextCursor:Y,prevCursor:Q}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=G().prepare("PRAGMA database_list").all();if(!t.length)throw new M(500,{message:"No databases returned from SQLite"});return t.map(r=>({name:r.name,size:this.getFileSize(r.file),owner:"",encoding:"UTF-8"}))}catch(e){throw e instanceof M?e:this.wrapError(e)}}async getCurrentDatabase(){try{return{db:G().prepare("PRAGMA database_list").all().find(n=>n.name==="main")?.name??"main"}}catch(e){throw this.wrapError(e)}}async getDatabaseConnectionInfo(){try{return{host:null,port:null,user:"",database:"main",version:`SQLite ${G().prepare("SELECT sqlite_version() as version").get().version}`,active_connections:1,max_connections:1}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=G();return t.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all().map(n=>{let o=t.prepare(`SELECT COUNT(*) as count FROM "${n.name}"`).get();return{tableName:n.name,rowCount:o?.count??0}})}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:r,fields:n,foreignKeys:o}=e,s=G(),c=n.map(l=>{if(l.isPrimaryKey&&l.isIdentity)return`"${l.columnName}" INTEGER PRIMARY KEY AUTOINCREMENT`;let u=`"${l.columnName}" ${l.columnType}`;return l.isPrimaryKey&&(u+=" PRIMARY KEY"),l.isUnique&&!l.isPrimaryKey&&(u+=" UNIQUE"),!l.isNullable&&!l.isPrimaryKey&&(u+=" NOT NULL"),l.defaultValue?.trim()&&!l.isIdentity&&(u+=` DEFAULT ${l.defaultValue.trim()}`),u}),i=o?.map(l=>`FOREIGN KEY ("${l.columnName}") REFERENCES "${l.referencedTable}" ("${l.referencedColumn}") ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`)??[];s.prepare(`CREATE TABLE "${r}" (${[...c,...i].join(", ")})`).run()}async deleteTable(e){let{tableName:t,cascade:r}=e,n=G();if(!n.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});let c=n.prepare(`SELECT COUNT(*) as count FROM "${t}"`).get()?.count??0;if(!r&&this.getFkReferencesForTable(n,t).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:this.getRelatedRecordsForTable(n,t)};try{return n.prepare(`DROP TABLE "${t}"`).run(),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(i){if((i instanceof Error?i.message:String(i)).includes("FOREIGN KEY constraint"))return{deletedCount:0,fkViolation:!0,relatedRecords:this.getRelatedRecordsForTable(n,t)};throw i instanceof M?i:new M(500,{message:`Failed to delete table "${t}"`})}}async getTableSchema({tableName:e,db:t}){try{let n=G().prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name=?").get(e);if(!n)throw new M(404,{message:`Table "${e}" does not exist`});return n.sql}catch(r){throw r instanceof M?r:this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let r=G();if(!r.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(e))throw new M(404,{message:`Table "${e}" does not exist`});let o=r.prepare(`PRAGMA table_info("${e}")`).all(),s=r.prepare(`PRAGMA foreign_key_list("${e}")`).all(),c=new Map;for(let i of s)c.set(i.from,i);return o.map(i=>{let l=c.get(i.name),u=i.type.toLowerCase();return{columnName:i.name,dataType:mt(u),dataTypeLabel:Ht(u),isNullable:i.notnull===0&&i.pk===0,columnDefault:i.dflt_value,isPrimaryKey:i.pk>0,isForeignKey:c.has(i.name),referencedTable:l?.table??null,referencedColumn:l?.to??null,enumValues:null}})}catch(r){throw r instanceof M?r:this.wrapError(r)}}async addColumn(e){let{tableName:t,columnName:r,columnType:n,defaultValue:o,isNullable:s,isUnique:c,db:i}=e,l=G();if(!l.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});if(l.prepare(`PRAGMA table_info("${t}")`).all().some(d=>d.name===r))throw new M(409,{message:`Column "${r}" already exists in table "${t}"`});let p=`"${r}" ${n}`;c&&(p+=" UNIQUE"),s||(p+=" NOT NULL"),o?.trim()&&(p+=` DEFAULT ${o.trim()}`);try{l.prepare(`ALTER TABLE "${t}" ADD COLUMN ${p}`).run()}catch(d){throw this.wrapError(d)}}async deleteColumn(e){let{tableName:t,columnName:r,db:n}=e,o=G();if(!o.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});if(!o.prepare(`PRAGMA table_info("${t}")`).all().some(i=>i.name===r))throw new M(404,{message:`Column "${r}" does not exist in table "${t}"`});try{o.prepare(`ALTER TABLE "${t}" DROP COLUMN "${r}"`).run()}catch(i){throw this.wrapError(i)}return{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:n,isNullable:o,defaultValue:s,db:c}=e,i=G();if(!i.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});let u=i.prepare(`PRAGMA table_info("${t}")`).all();if(!u.some(T=>T.name===r))throw new M(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=u.filter(T=>T.pk>0).sort((T,S)=>T.pk-S.pk),p=m.length>1,d=u.map(T=>{let S=T.name===r,j=S?n:T.type,$=S?o:T.notnull===0,P=S?s?.trim()||null:T.dflt_value,O=T.pk>0,V=`"${T.name}" ${j}`;return!p&&O&&(V+=" PRIMARY KEY"),!O&&!$&&(V+=" NOT NULL"),P&&(V+=` DEFAULT ${P}`),V});p&&d.push(`PRIMARY KEY (${m.map(T=>`"${T.name}"`).join(", ")})`);let f=i.prepare(`PRAGMA foreign_key_list("${t}")`).all(),b=new Map;for(let T of f){let S=b.get(T.id)??[];S.push(T),b.set(T.id,S)}let g=Array.from(b.values()).map(T=>{let S=T.map(V=>`"${V.from}"`).join(", "),j=T.map(V=>`"${V.to}"`).join(", "),{table:$,on_update:P,on_delete:O}=T[0];return`FOREIGN KEY (${S}) REFERENCES "${$}" (${j}) ON UPDATE ${P} ON DELETE ${O}`}),h=u.map(T=>`"${T.name}"`).join(", "),C=`${t}_alter_${Date.now()}`,R=i.prepare("SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL").all(t),N=i.prepare("SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?").all(t);i.pragma("foreign_keys = OFF");let w=i.transaction(()=>{i.prepare(`CREATE TABLE "${C}" (${[...d,...g].join(", ")})`).run(),i.prepare(`INSERT INTO "${C}" (${h}) SELECT ${h} FROM "${t}"`).run(),i.prepare(`DROP TABLE "${t}"`).run(),i.prepare(`ALTER TABLE "${C}" RENAME TO "${t}"`).run()});try{w();for(let{sql:T}of R)i.prepare(T).run();for(let{sql:T}of N)i.prepare(T).run()}catch(T){throw T instanceof M?T:this.wrapError(T)}finally{i.pragma("foreign_keys = ON")}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=G();if(!s.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new M(404,{message:`Table "${t}" does not exist`});let i=s.prepare(`PRAGMA table_info("${t}")`).all();if(!i.some(l=>l.name===r))throw new M(404,{message:`Column "${r}" does not exist in table "${t}"`});if(i.some(l=>l.name===n))throw new M(409,{message:`Column "${n}" already exists in table "${t}"`});try{s.prepare(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${n}"`).run()}catch(l){throw this.wrapError(l)}}async addRecord({params:e}){let{tableName:t,data:r}=e,n=G(),o=Object.keys(r);if(!o.length)throw new M(400,{message:"No data provided for insert"});let s=Object.values(r).map(l=>l!==null&&typeof l=="object"?JSON.stringify(l):l),c=o.map(l=>`"${l}"`).join(", "),i=o.map(()=>"?").join(", ");try{let l=n.prepare(`INSERT INTO "${t}" (${c}) VALUES (${i})`).run(...s);if(l.changes===0)throw new M(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:l.changes}}catch(l){throw this.wrapError(l)}}async updateRecords({db:e,params:t}){let{tableName:r,updates:n,primaryKey:o}=t,s=G(),c=new Map;for(let l of n){let u=l.rowData[o];if(u==null)throw new M(400,{message:`Primary key "${o}" not found in row data.`});c.has(u)||c.set(u,[]),c.get(u)?.push({columnName:l.columnName,value:l.value})}let i=s.transaction(()=>{let l=0;for(let[u,m]of c.entries()){let p=m.map(b=>`"${b.columnName}" = ?`).join(", "),d=[...m.map(b=>b.value!==null&&typeof b.value=="object"?JSON.stringify(b.value):b.value),u],f=s.prepare(`UPDATE "${r}" SET ${p} WHERE "${o}" = ?`).run(...d);if(f.changes===0)throw new M(404,{message:`Record with ${o} = ${u} not found in table "${r}"`});l+=f.changes}return l});try{return{updatedCount:i()}}catch(l){throw l instanceof M?l:this.wrapError(l)}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=G(),o=t[0]?.columnName;if(!o)throw new M(400,{message:"Primary key column name is required"});let s=t.map(l=>l.value),c=s.map(()=>"?").join(", "),i=n.transaction(()=>n.prepare(`DELETE FROM "${e}" WHERE "${o}" IN (${c})`).run(...s).changes);try{return{deletedCount:i(),fkViolation:!1,relatedRecords:[]}}catch(l){if((l instanceof Error?l.message:String(l)).includes("FOREIGN KEY constraint failed"))return{deletedCount:0,fkViolation:!0,relatedRecords:this.getRelatedRecords(n,e,t)};throw this.wrapError(l)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=G(),o=t[0]?.columnName;if(!o)throw new M(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value);n.pragma("foreign_keys = OFF");let c=n.transaction(()=>{let i=this.getFkReferencesForTable(n,e),l=0;for(let p of i){let d=s.map(()=>"?").join(", "),f=n.prepare(`DELETE FROM "${p.referencingTable}" WHERE "${p.referencingColumn}" IN (${d})`).run(...s);l+=f.changes}let u=s.map(()=>"?").join(", ");return n.prepare(`DELETE FROM "${e}" WHERE "${o}" IN (${u})`).run(...s).changes+l});try{return{deletedCount:c()}}catch(i){throw i instanceof M?i:this.wrapError(i)}finally{n.pragma("foreign_keys = ON")}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t?.length)throw new M(400,{message:"At least one record is required"});let n=G(),o=Object.keys(t[0]),s=o.map(u=>`"${u}"`).join(", "),c=o.map(()=>"?").join(", "),i=n.prepare(`INSERT INTO "${e}" (${s}) VALUES (${c})`),l=n.transaction(u=>{let m=0;for(let p of u){let d=o.map(f=>{let b=p[f];return b!==null&&typeof b=="object"?JSON.stringify(b):b});i.run(...d),m++}return m});try{let u=l(t);return{success:!0,message:`Bulk insert completed: ${u} records inserted`,successCount:u,failureCount:0}}catch(u){throw u instanceof M?u:this.wrapError(u)}}async executeQuery({query:e,db:t}){let r=G();if(!e?.trim())throw new M(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,""),o=performance.now();try{let s=r.prepare(n);if(s.reader){let l=s.all(),u=performance.now()-o;return{columns:l.length>0?Object.keys(l[0]):[],rows:l,rowCount:l.length,duration:u,message:l.length===0?"OK":void 0}}let c=s.run(),i=performance.now()-o;return{columns:[],rows:[],rowCount:c.changes,duration:i,message:`OK (${c.changes} rows affected)`}}catch(s){throw this.wrapError(s)}}getFileSize(e){if(!e)return"in-memory";try{let r=Zo(e).size;return r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/(1024*1024)).toFixed(1)} MB`}catch{return"N/A"}}getFkReferencesForTable(e,t){let r=e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all(),n=[];for(let o of r){if(o.name===t)continue;let s=e.prepare(`PRAGMA foreign_key_list("${o.name}")`).all();for(let c of s)c.table===t&&n.push({constraintName:`fk_${o.name}_${c.from}_${t}_${c.to}`,referencingTable:o.name,referencingColumn:c.from,referencedTable:t,referencedColumn:c.to})}return n}getRelatedRecordsForTable(e,t){let r=this.getFkReferencesForTable(e,t);if(!r.length)return[];let n=[];for(let o of r){let s=e.prepare(`SELECT * FROM "${o.referencingTable}" LIMIT 100`).all();s.length>0&&n.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return n}getRelatedRecords(e,t,r){let n=this.getFkReferencesForTable(e,t);if(!n.length)return[];let o=[];for(let s of n){if(!r.find(m=>m.columnName===s.referencedColumn))continue;let i=r.map(m=>m.value),l=i.map(()=>"?").join(", "),u=e.prepare(`SELECT * FROM "${s.referencingTable}" WHERE "${s.referencingColumn}" IN (${l}) LIMIT 100`).all(...i);u.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:u})}return o}}});function ra(){se.register("pg",new ht),se.register("mysql",new gt),se.register("mssql",new bt),se.register("mongodb",new st),se.register("sqlite",new wt),se.register("redis",new Ct)}var na=E(()=>{"use strict";Re();Jr();In();kn();Un();Zn();ta()});import{HTTPException as es}from"hono/http-exception";import{DatabaseError as ts}from"pg";import{ZodError as rs}from"zod";function aa(a,e){if(a instanceof es)return e.json({error:a.message??"Internal server error"},a.status);if(a instanceof rs){let t=a.issues[0];return e.json({error:"Validation error",details:t.message},400)}if(a instanceof Error){let t=a;if(t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"||t.code==="ETIMEDOUT"||t.code==="ER_ACCESS_DENIED_ERROR"||t.code==="ER_BAD_HOST_ERROR"||t.code==="ECONNRESET"||t.errno===1045||t.errno===2003||t.errno===2002||a.message.includes("ECONNREFUSED")||a.message.includes("connection refused")||a.message.includes("timeout expired")||a.message.includes("Connection terminated")||a.message.includes("MongoNetworkError")||a.message.includes("MongoServerSelectionError")||a instanceof ts&&a.code?.startsWith("08"))return e.json({error:"Database connection failed",details:a.message},503)}return e.json({error:a instanceof Error?a.message:"Internal server error"},500)}var oa=E(()=>{"use strict"});function ia(a){let e=a.dbType.toLowerCase(),t=a.dbType==="pg"?"PostgreSQL":a.dbType;return e.includes("mongo")?`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
|
|
290
290
|
|
|
291
291
|
**Your Role:**
|
|
292
292
|
1. Keep responses SHORT - 2-3 sentences maximum unless generating a query
|
|
@@ -300,7 +300,7 @@ ${s.join(`,
|
|
|
300
300
|
6. IMPORTANT: When the user asks about collections, fields, or any schema information, answer DIRECTLY from the "Database Context" above \u2014 do NOT generate a query to retrieve schema info you already have
|
|
301
301
|
|
|
302
302
|
**Database Context:**
|
|
303
|
-
${
|
|
303
|
+
${sa(a)}
|
|
304
304
|
|
|
305
305
|
**Guidelines:**
|
|
306
306
|
1. Always generate syntactically correct MongoDB queries
|
|
@@ -362,7 +362,7 @@ This will return the top 5 customers by revenue."`:`You are a database assistant
|
|
|
362
362
|
7. IMPORTANT: When the user asks about tables, columns, relationships, or any schema information, answer DIRECTLY from the "Database Context" above \u2014 do NOT generate a SQL query to retrieve schema info you already have
|
|
363
363
|
|
|
364
364
|
**Database Context:**
|
|
365
|
-
${
|
|
365
|
+
${sa(a)}
|
|
366
366
|
|
|
367
367
|
**Guidelines:**
|
|
368
368
|
1. Always generate syntactically correct SQL for the database type (${t})
|
|
@@ -400,7 +400,7 @@ LIMIT 5;
|
|
|
400
400
|
|
|
401
401
|
This will return the 5 customers with the highest total order value. You might also want to see:
|
|
402
402
|
- Revenue trends over time for these customers
|
|
403
|
-
- Their most frequently ordered products"`}function
|
|
403
|
+
- Their most frequently ordered products"`}function sa(a){let t=`Database Type: ${a.dbType==="pg"?"PostgreSQL":a.dbType}
|
|
404
404
|
|
|
405
405
|
`;t+=`**Tables and Columns:**
|
|
406
406
|
`;for(let r of a.tables){t+=`
|
|
@@ -414,5 +414,5 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
414
414
|
`)}if(a.relationships&&a.relationships.length>0){t+=`
|
|
415
415
|
**Relationships:**
|
|
416
416
|
`;for(let r of a.relationships)t+=` - ${r.fromTable}.${r.fromColumn} -> ${r.toTable}.${r.toColumn}
|
|
417
|
-
`}return t}var ia=E(()=>{"use strict"});function rs(a){let e={name:a.columnName,type:a.dataTypeLabel,nullable:a.isNullable};return a.isPrimaryKey&&(e.isPrimaryKey=!0),a.isForeignKey&&a.referencedTable&&a.referencedColumn&&(e.foreignKey=`${a.referencedTable}.${a.referencedColumn}`),a.enumValues&&a.enumValues.length>0&&(e.enumValues=a.enumValues,e.description=`Enum values: ${a.enumValues.join(", ")}`),e}function ns(a){let e=[];for(let t of a)for(let r of t.columns)if(r.foreignKey){let[n,o]=r.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:r.name,toTable:n,toColumn:o})}return e}function as(a){if(a==null)return"";if(a instanceof Date)return a.toISOString();if(typeof a=="bigint")return a.toString();if(typeof a=="object")try{return JSON.stringify(a)}catch{return String(a)}return String(a)}async function os(a,e,t){try{return(await a.getTableData({tableName:e,db:t,limit:3})).data.map(n=>Object.fromEntries(Object.entries(n).map(([o,s])=>[o,as(s)])))}catch{return[]}}async function ss(a,e={}){let t=Le(),{includeSampleData:r=!1,maxTables:n}=e,o=q(t);try{let s=await o.getTablesList(a),i=s.slice(0,n??s.length).map(m=>m.tableName).map(async m=>{let[p,d]=await Promise.all([o.getTableColumns({tableName:m,db:a}),r?os(o,m,a):Promise.resolve([])]),f={name:m,columns:p.map(rs)};return d.length>0&&(f.sampleData=d),f}),l=await Promise.all(i),u=ns(l);return{dbType:t,tables:l,relationships:u}}catch(s){throw new Error(`Failed to fetch database schema: ${s instanceof Error?s.message:"Unknown error"}`)}}async function la(a){return ss(a,{includeSampleData:!0,includeDescriptions:!0})}var ca=E(()=>{"use strict";Re();Pe()});import{zValidator as is}from"@hono/zod-validator";import{Hono as ls}from"hono";var ua,ma=E(()=>{"use strict";Ze();he();ia();ca();ua=new ls().basePath("/chat").get("/limit",async a=>{let e=await fetch(`${we.PROXY_URL}/chat/limit`,{headers:{"cf-connecting-ip":a.req.header("cf-connecting-ip")??"","x-real-ip":a.req.header("x-real-ip")??"","x-forwarded-for":a.req.header("x-forwarded-for")??"","x-api-key":a.req.header("x-api-key")??""}}),t=await e.json();return a.json(t,e.status)}).post("/",is("json",kt),async a=>{let{messages:e,data:t}=a.req.valid("json"),{db:r,conversationId:n}=t,o=await la(r),s=sa(o),c={messages:e,conversationId:n,systemPrompt:s},i=await fetch(`${we.PROXY_URL}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":a.req.header("cf-connecting-ip")??"","x-real-ip":a.req.header("x-real-ip")??"","x-forwarded-for":a.req.header("x-forwarded-for")??"","x-api-key":a.req.header("x-api-key")??""},body:JSON.stringify(c)});if(!i.ok){let m=await i.json();return a.json({error:m.error||"Proxy request failed"},i.status)}let{readable:l,writable:u}=new TransformStream;return i.body?.pipeTo(u),new Response(l,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})})});import{Hono as cs}from"hono";var da,pa=E(()=>{"use strict";Re();Pe();da=new cs().basePath("/databases").get("/",async a=>{let e=Le(),r=await q(e).getDatabasesList();return a.json({data:{databases:r,dbType:e}},200)}).get("/current",async a=>{let e=Le(),r=await q(e).getCurrentDatabase();return a.json({data:{db:r.db,dbType:e}},200)}).get("/connection",async a=>{let e=Le(),r=await q(e).getDatabaseConnectionInfo();return a.json({data:r},200)})});import{zValidator as fa}from"@hono/zod-validator";import{Hono as us}from"hono";var ba,ya=E(()=>{"use strict";he();Re();ba=new us().basePath("/query").post("/",fa("query",D),fa("json",Wt),async a=>{let{query:e}=a.req.valid("json"),{db:t}=a.req.valid("query"),r=a.get("dbType"),o=await q(r).executeQuery({query:e,db:t});return a.json({data:o},200)})});import{zValidator as Ce}from"@hono/zod-validator";import{Hono as ms}from"hono";var ga,ha=E(()=>{"use strict";he();Re();ga=new ms().basePath("/records").post("/",Ce("query",D),Ce("json",It),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,data:r}=a.req.valid("json"),n=a.get("dbType"),o=q(n),{insertedCount:s}=await o.addRecord({db:e,params:{tableName:t,data:r}});return a.json({data:`Record inserted into "${t}" with ${s} rows inserted`},200)}).patch("/",Ce("query",D),Ce("json",Qt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKey:r,updates:n}=a.req.valid("json"),o=a.get("dbType"),s=q(o),{updatedCount:c}=await s.updateRecords({params:{tableName:t,primaryKey:r,updates:n},db:e});return a.json({data:`Updated ${c} records in "${t}"`},200)}).delete("/",Ce("query",D),Ce("json",mt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:r}=a.req.valid("json"),n=a.get("dbType"),o=q(n),{deletedCount:s,fkViolation:c,relatedRecords:i}=await o.deleteRecords({tableName:t,primaryKeys:r,db:e});return c?a.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:i}},409):a.json({data:{deletedCount:s,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",Ce("query",D),Ce("json",mt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:r}=a.req.valid("json"),n=a.get("dbType"),s=await q(n).forceDeleteRecords({tableName:t,primaryKeys:r,db:e});return a.json({data:s},200)}).post("/bulk",Ce("query",D),Ce("json",vt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,records:r}=a.req.valid("json"),n=a.get("dbType"),s=await q(n).bulkInsertRecords({tableName:t,records:r,db:e});return a.json({data:s},200)})});import{utils as Qe,write as ds}from"xlsx";function Ta({cols:a,rows:e,format:t,tableName:r}){switch(t){case"json":{let n=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(n,"utf-8"))}case"csv":{let n=[a,...e?.map(c=>a?.map(i=>c[i]))??[]],o=Qe.aoa_to_sheet(n),s=Qe.sheet_to_csv(o);return new Uint8Array(Buffer.from(s,"utf-8"))}case"xlsx":{let n=[a,...e?.map(i=>a?.map(l=>i[l]))??[]],o=Qe.aoa_to_sheet(n),s=Qe.book_new();Qe.book_append_sheet(s,o,r.slice(0,31));let c=ds(s,{bookType:"xlsx",type:"buffer"});return new Uint8Array(c)}}}var Ea=E(()=>{"use strict"});import{zValidator as K}from"@hono/zod-validator";import{Hono as ps}from"hono";var Ca,wa=E(()=>{"use strict";he();Re();Ea();Ca=new ps().basePath("/tables").get("/",K("query",D),async a=>{let{db:e}=a.req.valid("query"),t=a.get("dbType"),n=await q(t).getTablesList(e);return a.json({data:n},200)}).post("/",K("query",D),K("json",Kt),async a=>{let{db:e}=a.req.valid("query"),t=a.req.valid("json"),r=a.get("dbType");return await q(r).createTable({tableData:t,db:e}),a.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",K("query",Vt),K("param",ce),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:r}=a.req.valid("param"),n=a.get("dbType"),s=await q(n).deleteTable({tableName:r,db:e,cascade:t});return a.json({data:s},200)}).delete("/:tableName/columns/:columnName",K("query",xt),K("param",te),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:r,columnName:n}=a.req.valid("param"),o=a.get("dbType"),s=q(o),{deletedCount:c}=await s.deleteColumn({tableName:r,columnName:n,cascade:t,db:e});return a.json({data:`Column "${n}" deleted successfully from table "${r}" with ${c} rows deleted`},200)}).post("/:tableName/columns",K("query",D),K("param",ce),K("json",me),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.req.valid("json"),n=a.get("dbType");return await q(n).addColumn({tableName:t,db:e,...r}),a.json({data:`Column "${r.columnName}" added successfully to table "${t}"`},200)}).patch("/:tableName/columns/:columnName/rename",K("query",D),K("param",te),K("json",dt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,columnName:r}=a.req.valid("param"),n=a.req.valid("json"),o=a.get("dbType");return await q(o).renameColumn({tableName:t,columnName:r,db:e,...n}),a.json({data:`Column "${r}" renamed to "${n.newColumnName}" in table "${t}"`},200)}).patch("/:tableName/columns/:columnName",K("query",D),K("param",te),K("json",ke),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,columnName:r}=a.req.valid("param"),n=a.req.valid("json"),o=a.get("dbType");return await q(o).alterColumn({tableName:t,columnName:r,db:e,...n}),a.json({data:`Column "${r}" updated successfully in table "${t}"`},200)}).get("/:tableName/columns",K("query",D),K("param",ce),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType"),o=await q(r).getTableColumns({tableName:t,db:e});return a.json({data:o},200)}).get("/:tableName/schema",K("query",D),K("param",ce),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType"),o=await q(r).getTableSchema({tableName:t,db:e});return a.json({data:{schema:o}},200)}).get("/:tableName/data",K("param",ce),K("query",Gt),async a=>{let{tableName:e}=a.req.valid("param"),{cursor:t,limit:r,direction:n,sort:o,order:s,filters:c,db:i}=a.req.valid("query"),l=a.get("dbType"),m=await q(l).getTableData({tableName:e,cursor:t,limit:r,direction:n,sort:o,order:s,filters:c,db:i});return a.json({data:m},200)}).get("/:tableName/export",K("param",ce),K("query",zt),async a=>{let{tableName:e}=a.req.valid("param"),{db:t,format:r}=a.req.valid("query"),n=a.get("dbType"),o=q(n),{cols:s,rows:c}=await o.exportTableData({tableName:e,db:t}),i=Ta({cols:s,rows:c,format:r,tableName:e}),l;switch(r){case"csv":l="text/csv";break;case"xlsx":l="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";break;case"json":l="application/json";break}return new Response(i,{headers:{"Content-Type":l??"","Content-Disposition":`attachment; filename="${e}_export.${r}"`}})})});var Na={};pr(Na,{createServer:()=>ws});import{existsSync as Ra}from"fs";import Ae from"path";import{fileURLToPath as fs}from"url";import{serveStatic as Je}from"@hono/node-server/serve-static";import{zValidator as bs}from"@hono/zod-validator";import{Hono as ys}from"hono";import{cors as gs}from"hono/cors";import{HTTPException as hs}from"hono/http-exception";import{logger as Ts}from"hono/logger";import{prettyJSON as Es}from"hono/pretty-json";import{z as Sa}from"zod";var Xe,Cs,ws,Aa=E(()=>{"use strict";Re();ra();aa();ma();pa();ya();ha();wa();Xe=()=>{if(process.env.NODE_ENV==="development")return Ae.resolve(process.cwd(),"../web/dist");let a=Ae.dirname(fs(import.meta.url)),e=Ae.resolve(a,"./web-dist"),t=Ae.resolve(process.cwd(),"../web/dist"),r=Ae.resolve(e,"index.html"),n=Ae.resolve(t,"index.html");return!Ra(r)&&Ra(n)?t:e},Cs=Sa.object({dbType:Sa.string().refine(a=>se.getSupportedTypes().includes(a),{message:`Invalid database type. Supported types: ${se.getSupportedTypes().join(", ")}`})}),ws=()=>{ta();let a=new ys({strict:!1}).use("/*",gs()).use(Es({space:2})).use(process.env.NODE_ENV==="development"?Ts():(e,t)=>t()).use("/favicon.ico",Je({path:Ae.resolve(Xe(),"favicon.ico")})).use("*",async(e,t)=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),await t()}).onError(na).route("/",da).route("/",ua).use("/assets/*",Je({root:Xe()})).use("/image.png",Je({root:Xe()})).use("/:dbType/*",bs("param",Cs,(e,t)=>{if(!e.success){let r=t.req.param("dbType");throw new hs(400,{message:`Invalid database type: "${r}". Supported types: ${se.getSupportedTypes().join(", ")}`})}}),async(e,t)=>{let{dbType:r}=e.req.valid("param");e.set("dbType",r),await t()}).route("/:dbType",Ca).route("/:dbType",ga).route("/:dbType",ba);return process.env.NODE_ENV!=="test"&&(a.use("/*",Je({root:Xe()})),a.get("/*",Je({path:Ae.resolve(Xe(),"index.html")}))),{app:a}}});Ze();import{intro as Rs,outro as Ss}from"@clack/prompts";import{serve as Ns}from"@hono/node-server";import dr from"picocolors";import{program as Rr}from"commander";var Sr=()=>(Rr.name("db-studio").option("-e, --env <path>","Path to custom .env file").option("-p, --port <port>","Port to run the server on").option("-d, --database-url <url>","Database URL to use").option("-n, --var-name <name>","Custom environment variable name (default: DATABASE_URL)").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv),Rr.opts());import{readFile as _a}from"fs/promises";import{resolve as $a}from"path";import{cancel as et,isCancel as Rt,note as Nr,select as Oa,spinner as La,text as Ar}from"@clack/prompts";import{parse as Pa}from"dotenv";import St from"picocolors";var Dr=async(a,e)=>{let t=e||"DATABASE_URL";if(a?.[t])return a[t];if(process.env[t])return process.env[t];let r=La();r.start("Looking for database connection..."),a?Nr(St.red(`${t} not found in .env or process.env`)):Nr(St.red(`No .env file found and ${t} not set in process.env`));let n=await Oa({message:`How do you want to provide ${t}?`,options:[{value:"manual",label:"Enter connection string manually"},{value:"other-env",label:"Use different .env file"},{value:"cancel",label:"Cancel / Exit"}],initialValue:"manual"});if((Rt(n)||n==="cancel")&&(et("No database connection provided. Exiting..."),process.exit(0)),n==="other-env"){r.start("Waiting for path...");let s=await Ar({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(i){if(!i?.trim())return"Path is required"}});Rt(s)&&(et("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let c=$a(s);try{let i=await _a(c,"utf-8"),l=Pa(i);if(l[t])return l[t];throw new Error(`${t} still missing in custom file`)}catch(i){let l=i;et(`Cannot read or parse file: ${St.dim(l.message)}`),process.exit(1)}}r.stop("Manual input...");let o=await Ar({message:`Paste your ${t}`,placeholder:"postgresql://user:password@localhost:5432/mydb or sqlite:///path/to/db.sqlite",validate(s){if(!s?.trim())return"Connection string is required!";if(!s.trim().startsWith("sqlite://"))try{new URL(s);return}catch{return"Must be a valid URL format"}}});return Rt(o)&&(et("Cancelled."),process.exit(0)),o.trim()};import{access as Ma,readFile as Ia}from"fs/promises";import{dirname as xa,resolve as Nt}from"path";import{parse as va}from"dotenv";var ka=async a=>{let e=Nt(a);for(;;){let t=Nt(e,".env");try{return await Ma(t),t}catch{}let r=xa(e);if(r===e)return null;e=r}},$e=async a=>{let e;if(a?e=Nt(a):e=await ka(process.cwd()),!e)return null;try{let t=await Ia(e,"utf-8");return va(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};wt();import{intro as qa,outro as Ua}from"@clack/prompts";import _r from"picocolors";var $r=()=>{qa(_r.inverse(" db-studio ")),Ua(_r.green(`For more information, visit: ${Cr.SITE_DOCS_LINK}`))};Ze();import{intro as Fa,note as Ba,outro as Or}from"@clack/prompts";import tt from"picocolors";var Lr=async(a,e,t)=>{Fa(tt.inverse(" db-studio "));let r=t||we.VAR_NAME,n=null;if(e)n=e;else{let o=a?await $e(a):await $e();o?.[r]?n=o[r]:process.env[r]&&(n=process.env[r]??null)}n?Or(tt.green(`\u2713 Database connection configured (using ${r})`)):(Ba(tt.red(`\u2717 ${r} not found`),"Status"),Or(tt.yellow("\u26A0 No database connection configured")))};import{intro as Ha,outro as Ka}from"@clack/prompts";import Mr from"picocolors";var Pr={name:"db-studio",type:"module",version:"1.9.4",description:"Modern database client for PostgreSQL with spreadsheet-like grid, AI-powered SQL assistance, ER diagrams, fast data browsing and editing. CLI tool, upcoming desktop & web versions.",keywords:["database client","database gui","database browser","sql client","sql editor","query tool","table editor","data editor","postgres","postgresql","postgresql client","postgresql gui","pgadmin alternative","mysql","mysql client","ai sql","er diagram","database management","database studio"],author:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",homepage:"https://dbstudio.sh",repository:{type:"git",url:"git+https://github.com/husamql3/db-studio.git"},bugs:{url:"https://github.com/husamql3/db-studio/issues"},license:"BSL-1.1",bin:{"db-studio":"./dist/index.js"},files:["dist"],scripts:{dev:"portless run","dev:app":"NODE_ENV=development tsx watch src/index.ts",build:"tsup --minify --sourcemap",prepack:"cd ../web && bun run build && cd ../server && bun run build",start:`sh -c 'APP_PORT=\${PORT:-3333}; portless proxy start >/dev/null && portless alias db-studio "$APP_PORT" --force >/dev/null && HOST=127.0.0.1 PORT="$APP_PORT" DB_STUDIO_SERVER_URL=https://db-studio.localhost node dist/index.js'`,format:"biome check --write --unsafe",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},portless:{name:"api.dbstudio",script:"dev:app"},dependencies:{"@clack/prompts":"^1.0.1","@hono/node-server":"^2.0.0","@hono/zod-validator":"^0.8.0","better-sqlite3":"^12.9.0",commander:"^15.0.0",dotenv:"^17.3.1",hono:"^4.10.4",ioredis:"^5.4.1",mongodb:"^7.1.1",mssql:"^12.2.0",mysql2:"^3.18.2",pg:"^8.13.1",picocolors:"^1.1.1",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@db-studio/shared":"workspace:*","@types/better-sqlite3":"^7.6.13","@types/mssql":"^12.3.0","@types/node":"^26.0.0","@types/pg":"^8.16.0","@vitest/coverage-v8":"^4.0.17",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^6.0.3",vitest:"^4.0.17"}};var Ir=()=>{Ha(Mr.inverse(" db-studio ")),Ka(Mr.green(`\u{1F680} db-studio v${Pr.version}`))};var As=async()=>{let{env:a,port:e,databaseUrl:t,varName:r,status:n,help:o,version:s}=Sr();o&&($r(),process.exit(0)),s&&(Ir(),process.exit(0)),n&&(await Lr(a,t,r),process.exit(0)),Rs(dr.inverse(" db-studio "));let c=Number.parseInt(e??process.env.PORT??String(we.PORT),10),i=process.env.HOST,l=r||we.VAR_NAME,u=a?await $e(a):await $e(),m=t||await Dr(u,l);process.env.DATABASE_URL=m;let{createServer:p}=await Promise.resolve().then(()=>(Aa(),Na)),{app:d}=p();Ns({fetch:d.fetch,hostname:i,port:c});let f=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${c}`;Ss(dr.green(`Server running at ${dr.cyan(f)}`))};As().catch(a=>{process.exit(1)});export{As as main};
|
|
417
|
+
`}return t}var la=E(()=>{"use strict"});function ns(a){let e={name:a.columnName,type:a.dataTypeLabel,nullable:a.isNullable};return a.isPrimaryKey&&(e.isPrimaryKey=!0),a.isForeignKey&&a.referencedTable&&a.referencedColumn&&(e.foreignKey=`${a.referencedTable}.${a.referencedColumn}`),a.enumValues&&a.enumValues.length>0&&(e.enumValues=a.enumValues,e.description=`Enum values: ${a.enumValues.join(", ")}`),e}function as(a){let e=[];for(let t of a)for(let r of t.columns)if(r.foreignKey){let[n,o]=r.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:r.name,toTable:n,toColumn:o})}return e}function os(a){if(a==null)return"";if(a instanceof Date)return a.toISOString();if(typeof a=="bigint")return a.toString();if(typeof a=="object")try{return JSON.stringify(a)}catch{return String(a)}return String(a)}async function ss(a,e,t){try{return(await a.getTableData({tableName:e,db:t,limit:3})).data.map(n=>Object.fromEntries(Object.entries(n).map(([o,s])=>[o,os(s)])))}catch{return[]}}async function is(a,e={}){let t=Le(),{includeSampleData:r=!1,maxTables:n}=e,o=q(t);try{let s=await o.getTablesList(a),i=s.slice(0,n??s.length).map(m=>m.tableName).map(async m=>{let[p,d]=await Promise.all([o.getTableColumns({tableName:m,db:a}),r?ss(o,m,a):Promise.resolve([])]),f={name:m,columns:p.map(ns)};return d.length>0&&(f.sampleData=d),f}),l=await Promise.all(i),u=as(l);return{dbType:t,tables:l,relationships:u}}catch(s){throw new Error(`Failed to fetch database schema: ${s instanceof Error?s.message:"Unknown error"}`)}}async function ca(a){return is(a,{includeSampleData:!0,includeDescriptions:!0})}var ua=E(()=>{"use strict";Re();Me()});import{zValidator as ls}from"@hono/zod-validator";import{Hono as cs}from"hono";var ma,da=E(()=>{"use strict";Ke();Te();la();ua();ma=new cs().basePath("/chat").get("/limit",async a=>{let e=await fetch(`${be.PROXY_URL}/chat/limit`,{headers:{"cf-connecting-ip":a.req.header("cf-connecting-ip")??"","x-real-ip":a.req.header("x-real-ip")??"","x-forwarded-for":a.req.header("x-forwarded-for")??"","x-api-key":a.req.header("x-api-key")??""}}),t=await e.json();return a.json(t,e.status)}).post("/",ls("json",qt),async a=>{let{messages:e,data:t}=a.req.valid("json"),{db:r,conversationId:n}=t,o=await ca(r),s=ia(o),c={messages:e,conversationId:n,systemPrompt:s},i=await fetch(`${be.PROXY_URL}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":a.req.header("cf-connecting-ip")??"","x-real-ip":a.req.header("x-real-ip")??"","x-forwarded-for":a.req.header("x-forwarded-for")??"","x-api-key":a.req.header("x-api-key")??""},body:JSON.stringify(c)});if(!i.ok){let m=await i.json();return a.json({error:m.error||"Proxy request failed"},i.status)}let{readable:l,writable:u}=new TransformStream;return i.body?.pipeTo(u),new Response(l,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})})});import{Hono as us}from"hono";var pa,fa=E(()=>{"use strict";Re();Me();pa=new us().basePath("/databases").get("/",async a=>{let e=Le(),r=await q(e).getDatabasesList();return a.json({data:{databases:r,dbType:e}},200)}).get("/current",async a=>{let e=Le(),r=await q(e).getCurrentDatabase();return a.json({data:{db:r.db,dbType:e}},200)}).get("/connection",async a=>{let e=Le(),r=await q(e).getDatabaseConnectionInfo();return a.json({data:r},200)})});import{zValidator as ba}from"@hono/zod-validator";import{Hono as ms}from"hono";var ya,ga=E(()=>{"use strict";Te();Re();ya=new ms().basePath("/query").post("/",ba("query",D),ba("json",zt),async a=>{let{query:e}=a.req.valid("json"),{db:t}=a.req.valid("query"),r=a.get("dbType"),o=await q(r).executeQuery({query:e,db:t});return a.json({data:o},200)})});import{zValidator as we}from"@hono/zod-validator";import{Hono as ds}from"hono";var ha,Ta=E(()=>{"use strict";Te();Re();ha=new ds().basePath("/records").post("/",we("query",D),we("json",xt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,data:r}=a.req.valid("json"),n=a.get("dbType"),o=q(n),{insertedCount:s}=await o.addRecord({db:e,params:{tableName:t,data:r}});return a.json({data:`Record inserted into "${t}" with ${s} rows inserted`},200)}).patch("/",we("query",D),we("json",Jt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKey:r,updates:n}=a.req.valid("json"),o=a.get("dbType"),s=q(o),{updatedCount:c}=await s.updateRecords({params:{tableName:t,primaryKey:r,updates:n},db:e});return a.json({data:`Updated ${c} records in "${t}"`},200)}).delete("/",we("query",D),we("json",dt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:r}=a.req.valid("json"),n=a.get("dbType"),o=q(n),{deletedCount:s,fkViolation:c,relatedRecords:i}=await o.deleteRecords({tableName:t,primaryKeys:r,db:e});return c?a.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:i}},409):a.json({data:{deletedCount:s,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",we("query",D),we("json",dt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:r}=a.req.valid("json"),n=a.get("dbType"),s=await q(n).forceDeleteRecords({tableName:t,primaryKeys:r,db:e});return a.json({data:s},200)}).post("/bulk",we("query",D),we("json",kt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,records:r}=a.req.valid("json"),n=a.get("dbType"),s=await q(n).bulkInsertRecords({tableName:t,records:r,db:e});return a.json({data:s},200)})});import{utils as Xe,write as ps}from"xlsx";function Ea({cols:a,rows:e,format:t,tableName:r}){switch(t){case"json":{let n=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(n,"utf-8"))}case"csv":{let n=[a,...e?.map(c=>a?.map(i=>c[i]))??[]],o=Xe.aoa_to_sheet(n),s=Xe.sheet_to_csv(o);return new Uint8Array(Buffer.from(s,"utf-8"))}case"xlsx":{let n=[a,...e?.map(i=>a?.map(l=>i[l]))??[]],o=Xe.aoa_to_sheet(n),s=Xe.book_new();Xe.book_append_sheet(s,o,r.slice(0,31));let c=ps(s,{bookType:"xlsx",type:"buffer"});return new Uint8Array(c)}}}var Ca=E(()=>{"use strict"});import{zValidator as K}from"@hono/zod-validator";import{Hono as fs}from"hono";var wa,Ra=E(()=>{"use strict";Te();Re();Ca();wa=new fs().basePath("/tables").get("/",K("query",D),async a=>{let{db:e}=a.req.valid("query"),t=a.get("dbType"),n=await q(t).getTablesList(e);return a.json({data:n},200)}).post("/",K("query",D),K("json",Vt),async a=>{let{db:e}=a.req.valid("query"),t=a.req.valid("json"),r=a.get("dbType");return await q(r).createTable({tableData:t,db:e}),a.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",K("query",Wt),K("param",ce),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:r}=a.req.valid("param"),n=a.get("dbType"),s=await q(n).deleteTable({tableName:r,db:e,cascade:t});return a.json({data:s},200)}).delete("/:tableName/columns/:columnName",K("query",vt),K("param",te),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:r,columnName:n}=a.req.valid("param"),o=a.get("dbType"),s=q(o),{deletedCount:c}=await s.deleteColumn({tableName:r,columnName:n,cascade:t,db:e});return a.json({data:`Column "${n}" deleted successfully from table "${r}" with ${c} rows deleted`},200)}).post("/:tableName/columns",K("query",D),K("param",ce),K("json",me),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.req.valid("json"),n=a.get("dbType");return await q(n).addColumn({tableName:t,db:e,...r}),a.json({data:`Column "${r.columnName}" added successfully to table "${t}"`},200)}).patch("/:tableName/columns/:columnName/rename",K("query",D),K("param",te),K("json",pt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,columnName:r}=a.req.valid("param"),n=a.req.valid("json"),o=a.get("dbType");return await q(o).renameColumn({tableName:t,columnName:r,db:e,...n}),a.json({data:`Column "${r}" renamed to "${n.newColumnName}" in table "${t}"`},200)}).patch("/:tableName/columns/:columnName",K("query",D),K("param",te),K("json",qe),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,columnName:r}=a.req.valid("param"),n=a.req.valid("json"),o=a.get("dbType");return await q(o).alterColumn({tableName:t,columnName:r,db:e,...n}),a.json({data:`Column "${r}" updated successfully in table "${t}"`},200)}).get("/:tableName/columns",K("query",D),K("param",ce),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType"),o=await q(r).getTableColumns({tableName:t,db:e});return a.json({data:o},200)}).get("/:tableName/schema",K("query",D),K("param",ce),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType"),o=await q(r).getTableSchema({tableName:t,db:e});return a.json({data:{schema:o}},200)}).get("/:tableName/data",K("param",ce),K("query",Qt),async a=>{let{tableName:e}=a.req.valid("param"),{cursor:t,limit:r,direction:n,sort:o,order:s,filters:c,db:i}=a.req.valid("query"),l=a.get("dbType"),m=await q(l).getTableData({tableName:e,cursor:t,limit:r,direction:n,sort:o,order:s,filters:c,db:i});return a.json({data:m},200)}).get("/:tableName/export",K("param",ce),K("query",Yt),async a=>{let{tableName:e}=a.req.valid("param"),{db:t,format:r}=a.req.valid("query"),n=a.get("dbType"),o=q(n),{cols:s,rows:c}=await o.exportTableData({tableName:e,db:t}),i=Ea({cols:s,rows:c,format:r,tableName:e}),l;switch(r){case"csv":l="text/csv";break;case"xlsx":l="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";break;case"json":l="application/json";break}return new Response(i,{headers:{"Content-Type":l??"","Content-Disposition":`attachment; filename="${e}_export.${r}"`}})})});var Aa={};fr(Aa,{createServer:()=>Rs});import{existsSync as Sa}from"fs";import Ae from"path";import{fileURLToPath as bs}from"url";import{serveStatic as Ze}from"@hono/node-server/serve-static";import{zValidator as ys}from"@hono/zod-validator";import{Hono as gs}from"hono";import{cors as hs}from"hono/cors";import{HTTPException as Ts}from"hono/http-exception";import{logger as Es}from"hono/logger";import{prettyJSON as Cs}from"hono/pretty-json";import{z as Na}from"zod";var $e,et,ws,Rs,Da=E(()=>{"use strict";Ke();Re();na();oa();da();fa();ga();Ta();Ra();({API_PREFIX:$e}=be),et=()=>{if(process.env.NODE_ENV==="development")return Ae.resolve(process.cwd(),"../web/dist");let a=Ae.dirname(bs(import.meta.url)),e=Ae.resolve(a,"./web-dist"),t=Ae.resolve(process.cwd(),"../web/dist"),r=Ae.resolve(e,"index.html"),n=Ae.resolve(t,"index.html");return!Sa(r)&&Sa(n)?t:e},ws=Na.object({dbType:Na.string().refine(a=>se.getSupportedTypes().includes(a),{message:`Invalid database type. Supported types: ${se.getSupportedTypes().join(", ")}`})}),Rs=()=>{ra();let a=new gs({strict:!1}).use("/*",hs()).use(Cs({space:2})).use(process.env.NODE_ENV==="development"?Es():(e,t)=>t()).use("/favicon.ico",Ze({path:Ae.resolve(et(),"favicon.ico")})).use("*",async(e,t)=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),await t()}).onError(aa).route($e,pa).route($e,ma).use("/assets/*",Ze({root:et()})).use("/image.png",Ze({root:et()})).use(`${$e}/:dbType/*`,ys("param",ws,(e,t)=>{if(!e.success){let r=t.req.param("dbType");throw new Ts(400,{message:`Invalid database type: "${r}". Supported types: ${se.getSupportedTypes().join(", ")}`})}}),async(e,t)=>{let{dbType:r}=e.req.valid("param");e.set("dbType",r),await t()}).route(`${$e}/:dbType`,wa).route(`${$e}/:dbType`,ha).route(`${$e}/:dbType`,ya);return process.env.NODE_ENV!=="test"&&(a.all(`${$e}/*`,e=>e.json({error:"Not found"},404)),a.use("/*",Ze({root:et()})),a.get("/*",Ze({path:Ae.resolve(et(),"index.html")}))),{app:a}}});Ke();import{intro as Ss,outro as Ns}from"@clack/prompts";import{serve as As}from"@hono/node-server";import pr from"picocolors";import{program as Sr}from"commander";var Nr=()=>(Sr.name("db-studio").option("-e, --env <path>","Path to custom .env file").option("-p, --port <port>","Port to run the server on").option("-d, --database-url <url>","Database URL to use").option("-n, --var-name <name>","Custom environment variable name (default: DATABASE_URL)").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv),Sr.opts());import{readFile as $a}from"fs/promises";import{resolve as Oa}from"path";import{cancel as tt,isCancel as St,note as Ar,select as Pa,spinner as La,text as Dr}from"@clack/prompts";import{parse as Ma}from"dotenv";import Nt from"picocolors";var _r=async(a,e)=>{let t=e||"DATABASE_URL";if(a?.[t])return a[t];if(process.env[t])return process.env[t];let r=La();r.start("Looking for database connection..."),a?Ar(Nt.red(`${t} not found in .env or process.env`)):Ar(Nt.red(`No .env file found and ${t} not set in process.env`));let n=await Pa({message:`How do you want to provide ${t}?`,options:[{value:"manual",label:"Enter connection string manually"},{value:"other-env",label:"Use different .env file"},{value:"cancel",label:"Cancel / Exit"}],initialValue:"manual"});if((St(n)||n==="cancel")&&(tt("No database connection provided. Exiting..."),process.exit(0)),n==="other-env"){r.start("Waiting for path...");let s=await Dr({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(i){if(!i?.trim())return"Path is required"}});St(s)&&(tt("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let c=Oa(s);try{let i=await $a(c,"utf-8"),l=Ma(i);if(l[t])return l[t];throw new Error(`${t} still missing in custom file`)}catch(i){let l=i;tt(`Cannot read or parse file: ${Nt.dim(l.message)}`),process.exit(1)}}r.stop("Manual input...");let o=await Dr({message:`Paste your ${t}`,placeholder:"postgresql://user:password@localhost:5432/mydb or sqlite:///path/to/db.sqlite",validate(s){if(!s?.trim())return"Connection string is required!";if(!s.trim().startsWith("sqlite://"))try{new URL(s);return}catch{return"Must be a valid URL format"}}});return St(o)&&(tt("Cancelled."),process.exit(0)),o.trim()};import{access as Ia,readFile as xa}from"fs/promises";import{dirname as va,resolve as At}from"path";import{parse as ka}from"dotenv";var qa=async a=>{let e=At(a);for(;;){let t=At(e,".env");try{return await Ia(t),t}catch{}let r=va(e);if(r===e)return null;e=r}},Oe=async a=>{let e;if(a?e=At(a):e=await qa(process.cwd()),!e)return null;try{let t=await xa(e,"utf-8");return ka(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};Rt();import{intro as Ua,outro as Fa}from"@clack/prompts";import $r from"picocolors";var Or=()=>{Ua($r.inverse(" db-studio ")),Fa($r.green(`For more information, visit: ${wr.SITE_DOCS_LINK}`))};Ke();import{intro as Ba,note as ja,outro as Pr}from"@clack/prompts";import rt from"picocolors";var Lr=async(a,e,t)=>{Ba(rt.inverse(" db-studio "));let r=t||be.VAR_NAME,n=null;if(e)n=e;else{let o=a?await Oe(a):await Oe();o?.[r]?n=o[r]:process.env[r]&&(n=process.env[r]??null)}n?Pr(rt.green(`\u2713 Database connection configured (using ${r})`)):(ja(rt.red(`\u2717 ${r} not found`),"Status"),Pr(rt.yellow("\u26A0 No database connection configured")))};import{intro as Ka,outro as Va}from"@clack/prompts";import Ir from"picocolors";var Mr={name:"db-studio",type:"module",version:"1.9.6",description:"Modern database client for PostgreSQL with spreadsheet-like grid, AI-powered SQL assistance, ER diagrams, fast data browsing and editing. CLI tool, upcoming desktop & web versions.",keywords:["database client","database gui","database browser","sql client","sql editor","query tool","table editor","data editor","postgres","postgresql","postgresql client","postgresql gui","pgadmin alternative","mysql","mysql client","ai sql","er diagram","database management","database studio"],author:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",homepage:"https://dbstudio.sh",repository:{type:"git",url:"git+https://github.com/husamql3/db-studio.git"},bugs:{url:"https://github.com/husamql3/db-studio/issues"},license:"BSL-1.1",bin:{"db-studio":"./dist/index.js"},files:["dist"],scripts:{dev:"portless run","dev:app":"NODE_ENV=development tsx watch src/index.ts",build:"tsup --minify --sourcemap",prepack:"cd ../web && bun run build && cd ../server && bun run build",start:`sh -c 'APP_PORT=\${PORT:-3333}; portless proxy start >/dev/null && portless alias db-studio "$APP_PORT" --force >/dev/null && HOST=127.0.0.1 PORT="$APP_PORT" DB_STUDIO_SERVER_URL=https://db-studio.localhost node dist/index.js'`,format:"biome check --write --unsafe",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},portless:{name:"api.dbstudio",script:"dev:app"},dependencies:{"@clack/prompts":"^1.0.1","@hono/node-server":"^2.0.0","@hono/zod-validator":"^0.8.0","better-sqlite3":"^12.9.0",commander:"^15.0.0",dotenv:"^17.3.1",hono:"^4.10.4",ioredis:"^5.4.1",mongodb:"^7.1.1",mssql:"^12.2.0",mysql2:"^3.18.2",pg:"^8.13.1",picocolors:"^1.1.1",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@db-studio/shared":"workspace:*","@types/better-sqlite3":"^7.6.13","@types/mssql":"^12.3.0","@types/node":"^26.0.0","@types/pg":"^8.16.0","@vitest/coverage-v8":"^4.0.17",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^6.0.3",vitest:"^4.0.17"}};var xr=()=>{Ka(Ir.inverse(" db-studio ")),Va(Ir.green(`\u{1F680} db-studio v${Mr.version}`))};var Ds=async()=>{let{env:a,port:e,databaseUrl:t,varName:r,status:n,help:o,version:s}=Nr();o&&(Or(),process.exit(0)),s&&(xr(),process.exit(0)),n&&(await Lr(a,t,r),process.exit(0)),Ss(pr.inverse(" db-studio "));let c=Number.parseInt(e??process.env.PORT??String(be.PORT),10),i=process.env.HOST,l=r||be.VAR_NAME,u=a?await Oe(a):await Oe(),m=t||await _r(u,l);process.env.DATABASE_URL=m;let{createServer:p}=await Promise.resolve().then(()=>(Da(),Aa)),{app:d}=p();As({fetch:d.fetch,hostname:i,port:c});let f=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${c}`;Ns(pr.green(`Server running at ${pr.cyan(f)}`))};Ds().catch(a=>{process.exit(1)});export{Ds as main};
|
|
418
418
|
//# sourceMappingURL=index.js.map
|