db-studio 1.13.0 → 1.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/index.js +105 -84
  2. package/dist/index.js.map +1 -1
  3. package/dist/web-dist/assets/{_pathlessLayout-zxU06-pr.js → _pathlessLayout-BYQmoqT2.js} +61 -61
  4. package/dist/web-dist/assets/_pathlessLayout-CdSIARYp.js +1 -0
  5. package/dist/web-dist/assets/_queryId-IoOxUaz6.js +1 -0
  6. package/dist/web-dist/assets/_table-BI9E6-Je.js +1 -0
  7. package/dist/web-dist/assets/_table-ClkqBjYZ.js +1 -0
  8. package/dist/web-dist/assets/badge-SEQODpjR.js +1 -0
  9. package/dist/web-dist/assets/browser-CHG4p052.js +1 -0
  10. package/dist/web-dist/assets/{bundle-mjs-uZfDJfiH.js → bundle-mjs-BZOM22--.js} +1 -1
  11. package/dist/web-dist/assets/code-editor-BIfiMFMb.js +9 -0
  12. package/dist/web-dist/assets/database.store-OsasuLJl.js +1 -0
  13. package/dist/web-dist/assets/{dist-BeZAMt_p.js → dist-D_0esNxp.js} +1 -1
  14. package/dist/web-dist/assets/{format-cell-value-wHw1lD8Z.js → format-cell-value-D41tFXxV.js} +1 -1
  15. package/dist/web-dist/assets/highlighted-body-OFNGDK62-DBl3trdK.js +1 -0
  16. package/dist/web-dist/assets/icons-rRDRsZcq.js +1 -0
  17. package/dist/web-dist/assets/index-Be5YdcX5.css +2 -0
  18. package/dist/web-dist/assets/index-CJ2YPwW4.js +36 -0
  19. package/dist/web-dist/assets/indexes-DMAVA8iJ.js +1 -0
  20. package/dist/web-dist/assets/logs-DCMuv22K.js +1 -0
  21. package/dist/web-dist/assets/mermaid-GHXKKRXX-DJ7TvQxw.js +1 -0
  22. package/dist/web-dist/assets/{middleware-CPy2Suyk.js → middleware-Y6OdmOWR.js} +1 -1
  23. package/dist/web-dist/assets/{monaco-editor-VzUhCCqE.js → monaco-editor-BO3WVEVM.js} +280 -280
  24. package/dist/web-dist/assets/monaco-editor-IL9D_L0g.css +1 -0
  25. package/dist/web-dist/assets/monitoring-BtlIcl3k.js +22 -0
  26. package/dist/web-dist/assets/overlay.store-DjYsesE7.js +11 -0
  27. package/dist/web-dist/assets/{queries.store-DFbzjjlv.js → queries.store-CxkLh1ra.js} +1 -1
  28. package/dist/web-dist/assets/query-runner-keHo7IiI.js +17 -0
  29. package/dist/web-dist/assets/radix-ui-C1Z_SoKk.js +51 -0
  30. package/dist/web-dist/assets/react-1gU4DcpZ.js +1 -0
  31. package/dist/web-dist/assets/{react-dom-t511kH7T.js → react-dom-DkH0eaTq.js} +1 -1
  32. package/dist/web-dist/assets/redis-value-BmLGJf9X.js +1 -0
  33. package/dist/web-dist/assets/{rolldown-runtime-Bc_uOZR3.js → rolldown-runtime-DY1mqKjv.js} +1 -1
  34. package/dist/web-dist/assets/runner-CvUPs6q4.js +1 -0
  35. package/dist/web-dist/assets/schema-9nf0q_01.js +57 -0
  36. package/dist/web-dist/assets/schema-C-10JjXl.js +1 -0
  37. package/dist/web-dist/assets/table-C75Kr4aI.js +1 -0
  38. package/dist/web-dist/assets/tanstack-C3XvOIUf.js +11 -0
  39. package/dist/web-dist/assets/visualizer-CiiH2acP.js +1 -0
  40. package/dist/web-dist/index.html +19 -19
  41. package/package.json +4 -4
  42. package/dist/web-dist/assets/_pathlessLayout-GynxlRL_.js +0 -1
  43. package/dist/web-dist/assets/_queryId-BRuHa3fh.js +0 -1
  44. package/dist/web-dist/assets/_table-8IAksPyY.js +0 -1
  45. package/dist/web-dist/assets/_table-CtfVc03T.js +0 -1
  46. package/dist/web-dist/assets/ai-assistant-CpA6z3NH.js +0 -1
  47. package/dist/web-dist/assets/browser-BGLz7ANr.js +0 -1
  48. package/dist/web-dist/assets/code-editor-CuKFGk5C.js +0 -9
  49. package/dist/web-dist/assets/database.store-B5cSp4MJ.js +0 -1
  50. package/dist/web-dist/assets/highlighted-body-OFNGDK62-BQA5yQZx.js +0 -1
  51. package/dist/web-dist/assets/icons-DMY0-Mbl.js +0 -1
  52. package/dist/web-dist/assets/index-BsliTpNZ.js +0 -35
  53. package/dist/web-dist/assets/index-Cyl_0l9I.css +0 -2
  54. package/dist/web-dist/assets/indexes-CNKwQMi3.js +0 -1
  55. package/dist/web-dist/assets/logs-BYKvN4gr.js +0 -1
  56. package/dist/web-dist/assets/mermaid-GHXKKRXX-BKNFWsy1.js +0 -1
  57. package/dist/web-dist/assets/monaco-editor-DcHpHuJd.css +0 -1
  58. package/dist/web-dist/assets/monitoring-B3eHd8rg.js +0 -22
  59. package/dist/web-dist/assets/popover-C6AOV9WB.js +0 -1
  60. package/dist/web-dist/assets/query-runner-RUXGiIf2.js +0 -17
  61. package/dist/web-dist/assets/radix-ui-CCBRgLy1.js +0 -51
  62. package/dist/web-dist/assets/react-frqLVtia.js +0 -1
  63. package/dist/web-dist/assets/redis-value-Lhzkhu4Q.js +0 -1
  64. package/dist/web-dist/assets/runner-lxnLCgPi.js +0 -1
  65. package/dist/web-dist/assets/schema-Bv15Fk7L.js +0 -1
  66. package/dist/web-dist/assets/schema-By474UiK.js +0 -64
  67. package/dist/web-dist/assets/table-B-C0yxvL.js +0 -1
  68. package/dist/web-dist/assets/tanstack-BfT_e-Qv.js +0 -10
  69. package/dist/web-dist/assets/tooltip-Dd1J4hNt.js +0 -9
  70. package/dist/web-dist/assets/visualizer-DOCDtIMq.js +0 -1
package/dist/index.js CHANGED
@@ -1,17 +1,30 @@
1
1
  #!/usr/bin/env node
2
- var Zo=Object.defineProperty;var N=(n,e)=>()=>(n&&(e=n(n=0)),e);var Nt=(n,e)=>{for(var t in e)Zo(n,t,{get:e[t],enumerable:!0})};var b=N(()=>{"use strict";(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};n.SENTRY_RELEASE={id:"db-studio@1.13.0"}}catch{}})()});var Cn=N(()=>{"use strict";b()});var Nn=N(()=>{"use strict";b()});var An=N(()=>{"use strict";b()});var _n,Dn,ke,vn=N(()=>{"use strict";b();_n=globalThis.process?.env,Dn=_n?.NODE_ENV,ke={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:Dn==="development",PROXY_URL:_n?.DB_STUDIO_PROXY_URL??(Dn==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var xn=N(()=>{"use strict";b()});var On,mr=N(()=>{"use strict";b();On={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:"db-studio",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 Pn=N(()=>{"use strict";b()});var ct=N(()=>{"use strict";b();Cn();Nn();An();vn();xn();mr();Pn()});var Be,br=N(()=>{Be={name:"db-studio",type:"module",version:"1.13.0",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} <husam@ql3.dev>",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:"Apache-2.0",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",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.db-studio",script:"dev:app"},dependencies:{"@clack/prompts":"^1.0.1","@hono/node-server":"^2.0.0","@hono/zod-validator":"^0.9.0","@sentry/node":"^10.73.0","better-sqlite3":"^13.0.3",commander:"^15.0.0",dotenv:"^17.3.1",hono:"^4.10.4",ioredis:"^6.0.0",mongodb:"^7.1.1",mssql:"^12.2.0",mysql2:"^3.18.2",open:"^11.0.0",pg:"^8.13.1",picocolors:"^1.1.1","posthog-node":"^5.20.0",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@db-studio/shared":"workspace:*","@sentry/esbuild-plugin":"^5.4.0","@types/better-sqlite3":"^9.6.0","@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:"^7.0.2",vitest:"^4.0.17"}}});var Yn={};Nt(Yn,{captureInstallationActive:()=>Er,captureServerError:()=>wr,captureServerEvent:()=>Ot,durationBucket:()=>hr,getTelemetryConfig:()=>vt,initServerObservability:()=>Wn,isTelemetryEnabled:()=>Je,operationForRequest:()=>ut,outcomeForStatus:()=>Tr,resetTelemetryId:()=>gr,setTelemetryEnabled:()=>xt,startServerSpan:()=>Sr,writeOperationalLog:()=>Rr});import{randomUUID as Vn}from"crypto";import{existsSync as hs,mkdirSync as Ts,readFileSync as Es,writeFileSync as ws}from"fs";import{homedir as Kn,platform as Ss}from"os";import Dt from"path";import*as be from"@sentry/node";import{HTTPException as Rs}from"hono/http-exception";import{PostHog as Cs}from"posthog-node";var Ns,zn,_t,As,Ds,Ie,Ge,_s,vs,Qe,Je,vt,xt,gr,hr,Tr,ut,Wn,Ot,Er,wr,Sr,Rr,mt=N(()=>{"use strict";b();br();Ns=()=>process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development",zn=()=>{let n=process.env.DB_STUDIO_DATA_DIR??process.env.XDG_STATE_HOME??(process.platform==="win32"?process.env.LOCALAPPDATA:Dt.join(Kn(),".local","state"));return Dt.join(n||Dt.join(Kn(),".db-studio"),"db-studio","telemetry.json")},_t=n=>{try{let e=zn();Ts(Dt.dirname(e),{recursive:!0}),ws(e,JSON.stringify(n),{encoding:"utf8",mode:384})}catch{}},As=()=>({installationId:Vn(),enabled:!0}),Ds=()=>{let n=zn();try{if(hs(n)){let t=JSON.parse(Es(n,"utf8"));if(typeof t.installationId=="string"&&typeof t.enabled=="boolean")return{installationId:t.installationId,enabled:t.enabled,lastActiveAt:typeof t.lastActiveAt=="string"?t.lastActiveAt:void 0}}}catch{}let e=As();return _t(e),e},_s="https://a1e890d1105f1f27fcb1dbead71c30dd@o4509725125181440.ingest.de.sentry.io/4512040493383760",vs="phc_nxaQk54MWAehmL72J4gjVbrQCpbSTedMyHn3PvFxAhkd",Qe=()=>Ie??=Ds(),Je=()=>!Ns()&&process.env.DB_STUDIO_TELEMETRY!=="0"&&Qe().enabled,vt=()=>({enabled:Je(),installationId:Qe().installationId,appVersion:Be.version}),xt=n=>{Ie={...Qe(),enabled:n},_t(Ie),n?(Ge?.enable(),Wn()):(Ge?.disable(),be.close(500))},gr=()=>(Ie={...Qe(),installationId:Vn(),lastActiveAt:void 0},_t(Ie),Ie.installationId),hr=n=>n<100?"under_100ms":n<1e3?"100ms_1s":n<5e3?"1s_5s":"over_5s",Tr=n=>n>=500?"server_error":n>=400?"client_error":"success",ut=(n,e)=>{let t=e.replace(/^\/api\/(?:pg|mysql|mssql|mongodb|sqlite|redis)(?=\/|$)/,"/api"),a=[[/^\/api\/databases(?:\/|$)/,"databases"],[/^\/api\/tables(?:\/|$)/,"tables"],[/^\/api\/records(?:\/|$)/,"records"],[/^\/api\/query(?:\/|$)/,"query"],[/^\/api\/keys(?:\/|$)/,"keys"],[/^\/api\/chat(?:\/|$)/,"chat"]].find(([o])=>o.test(t))?.[1]??"other";return`${n.toLowerCase()}_${a}`},Wn=()=>{if(!Je())return;let n=process.env.DB_STUDIO_SENTRY_DSN??_s;n&&(!be.isInitialized()||be.getClient()?.getOptions().enabled===!1)&&be.init({dsn:n,environment:process.env.NODE_ENV??"production",release:`db-studio@${Be.version}`,tracesSampleRate:.1,sendDefaultPii:!1,defaultIntegrations:!1,beforeSend(t){return delete t.request,delete t.user,delete t.breadcrumbs,t},beforeSendSpan(t){return{...t,data:Object.fromEntries(Object.entries(t.data??{}).filter(([r])=>r.startsWith("db_studio.")))}}});let e=process.env.DB_STUDIO_POSTHOG_KEY??vs;e&&!Ge&&(Ge=new Cs(e,{host:process.env.DB_STUDIO_POSTHOG_HOST??"https://eu.i.posthog.com",flushAt:20,flushInterval:1e4,requestTimeout:2e3}))},Ot=n=>{!Je()||!Ge||Ge.capture({distinctId:Qe().installationId,event:n.event,properties:{...n.properties,source:"server",app_version:Be.version,$geoip_disable:!1}})},Er=()=>{if(!Je())return;let n=Qe(),e=n.lastActiveAt?Date.parse(n.lastActiveAt):0;Date.now()-e<864e5||(Ie={...n,lastActiveAt:new Date().toISOString()},_t(Ie),Ot({event:"installation_active",properties:{runtime:`node-${process.versions.node.split(".")[0]}`,os:Ss()}}))},wr=(n,e)=>{if(!Je())return;let t=n instanceof Rs?"http":"runtime",r=new Error("Server operation failed");r.stack=void 0,be.captureException(r,{tags:{operation:e,source:"server",release:Be.version,error_kind:t},fingerprint:[e,t]})},Sr=(n,e,t)=>be.startSpan({name:n,op:"http.server",attributes:{"db_studio.operation":n,...e?{"db_studio.db_type":e}:{}}},t),Rr=(n,e,t)=>{let r=Object.fromEntries(Object.entries(t).filter(([,a])=>a!==void 0));process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:n,event:e,...r})}
3
- `)}});import xs from"better-sqlite3";import{Redis as Os}from"ioredis";import{MongoClient as Ps,ObjectId as Cr}from"mongodb";import ks from"mssql";import{createPool as $s}from"mysql2/promise";import{Pool as Gn}from"pg";var Nr,Te,Pt,kt,$t,Le,It,Lt,Mt,Qn,qt,Jn,Xn,Ut,Bt,Fe=N(()=>{"use strict";b();Nr=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)),console.error(`\u274C Database configuration error: ${this.initError.message}`)}}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";case"redis":case"rediss":return"redis";default:throw new Error(`Unsupported database type: ${t}. Supported types: PostgreSQL (postgres://), MySQL (mysql://), SQL Server (mssql://), MongoDB (mongodb://), SQLite (sqlite://), Redis/Valkey (redis:// or rediss://).`)}}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),a=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)||a,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 xs(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},a=new Gn(r);a.on("error",o=>{console.error(`Unexpected error on PostgreSQL pool for "${t}":`,o.message)}),this.pgPools.set(t,a)}return this.pgPools.get(t)??new Gn({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 a=new URL(t).pathname.slice(1),o=$s({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||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 a=new URL(t).pathname.slice(1),o={server:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},s=await new ks.ConnectionPool(o).connect();s.on("error",c=>{console.error(`Unexpected error on SQL Server pool for "${t}":`,c.message)}),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),console.log(`Closed PostgreSQL connection pool for: ${e}`))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e),console.log(`Closed MySQL connection pool for: ${e}`))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e),console.log(`Closed SQL Server connection pool for: ${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 Ps(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 a=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)),a.protocol==="rediss:"&&(o.tls={});let s=new Os(o);try{if(await s.connect(),!this.redisClusterChecked){let c=await s.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(c))throw await s.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let i=c.match(/^redis_version:([^\r\n]+)/m)?.[1],[l=0,u=0]=i?.split(".").map(Number)??[];if(l<6||l===6&&u<2)throw await s.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${i??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(c){throw await s.quit().catch(()=>{}),c}return this.redisClients.set(t,s),s}async getIsolatedRedisClient(e){let t=(await this.getRedisClient(e)).duplicate();return await t.connect(),t}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(),console.log(`Closed PostgreSQL pool for: ${o}`)}),t=Array.from(this.mysqlPools.entries()).map(async([o,s])=>{await s.end(),console.log(`Closed MySQL pool for: ${o}`)}),r=Array.from(this.mssqlPools.entries()).map(async([o,s])=>{await s.close(),console.log(`Closed SQL Server pool for: ${o}`)});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 a=Array.from(this.redisClients.entries()).map(async([o,s])=>{await s.quit().catch(()=>{}),console.log(`Closed Redis client for db=${o}`)});await Promise.all(a),this.redisClients.clear(),this.redisClusterChecked=!1}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys()),...Array.from(this.mssqlPools.keys())]}},Te=new Nr,Pt=n=>Te.getPgPool(n),kt=n=>Te.getMysqlPool(n),$t=async n=>Te.getMssqlPool(n),Le=()=>Te.getDbType(),It=()=>Te.getSqliteDb(),Lt=()=>Te.getMongoClient(),Mt=()=>Te.getMongoDbName(),Qn=n=>Te.getMongoDb(n),qt=n=>Te.getRedisClient(n),Jn=n=>Te.getIsolatedRedisClient(n),Xn=()=>Te.getRedisDefaultDb(),Ut=n=>typeof n=="string"&&Cr.isValid(n),Bt=n=>typeof n=="string"&&Cr.isValid(n)?new Cr(n):n});var ea={};Nt(ea,{checkDatabaseConnection:()=>Us,getDatabaseConnectionDetails:()=>qs});var Zn,Ls,Ms,qs,Us,ta=N(()=>{"use strict";b();Fe();Zn={pg:"PostgreSQL",mysql:"MySQL",mssql:"SQL Server",mongodb:"MongoDB",sqlite:"SQLite",redis:"Redis"},Ls=2e3,Ms=async n=>{let e;try{return await Promise.race([n,new Promise((t,r)=>{e=setTimeout(()=>r(new Error("Database startup check timed out")),Ls)})])}finally{e&&clearTimeout(e)}},qs=n=>{let e=Le();if(e==="sqlite")return{type:e,name:Zn[e],destination:"local file"};let t=new URL(n),r={pg:5432,mysql:3306,mssql:1433,mongodb:27017,redis:6379},a=Number.parseInt(t.port,10)||r[e];return{type:e,name:Zn[e],destination:`${t.hostname}:${a}`}},Us=async n=>{switch(n){case"pg":await Ms(Pt().query("SELECT 1"));return;case"mysql":await kt().query("SELECT 1");return;case"mssql":await(await $t()).request().query("SELECT 1");return;case"mongodb":{await(await Lt()).db(Mt()).command({ping:1});return}case"sqlite":It().prepare("SELECT 1").get();return;case"redis":await(await qt()).ping()}}});import{HTTPException as ra}from"hono/http-exception";function I(n){return fe.get(n)}function je(n,e){if(!Bs(n))throw new ra(400,{message:`Key browsing is not supported for database type: "${e}"`});return n}var Ar,fe,Bs,$e=N(()=>{"use strict";b();Ar=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new ra(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()]}},fe=new Ar;Bs=n=>"scanKeys"in n&&typeof n.scanKeys=="function"});import{HTTPException as Xe}from"hono/http-exception";import{DatabaseError as Fs}from"pg";function te(n){throw new Xe(501,{message:`${n} is not implemented for this database type`})}var me,He=N(()=>{"use strict";b();me=class{wrapError(e){if(e instanceof Xe)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 Fs&&e.code?.startsWith("08")?new Xe(503,{message:e.message}):new Xe(500,{message:e.message})}return new Xe(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,a]of Object.entries(e))t[r]=a;return t}async getTableData(e){try{let{db:t,limit:r=50,direction:a="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);a==="desc"&&(u=u.reverse());let{nextCursor:m,prevCursor:d}=this.buildCursors(e,u,l);return{data:u,meta:{limit:r,total:c,hasNextPage:a==="asc"?l:!!e.cursor,hasPreviousPage:a==="asc"?!!e.cursor:l,nextCursor:m,prevCursor:d}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=`SELECT * FROM ${this.quoteIdentifier(e)}`,a=await this.runQuery(t,r,[]);if(!a||a.length===0)throw new Xe(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(a[0]),rows:a}}catch(r){throw this.wrapError(r)}}getDatabasesList(){return te("getDatabasesList")}getCurrentDatabase(){return te("getCurrentDatabase")}getDatabaseConnectionInfo(){return te("getDatabaseConnectionInfo")}getTablesList(e){return te("getTablesList")}createTable(e){return te("createTable")}deleteTable(e){return te("deleteTable")}getTableSchema(e){return te("getTableSchema")}getTableColumns(e){return te("getTableColumns")}addColumn(e){return te("addColumn")}deleteColumn(e){return te("deleteColumn")}alterColumn(e){return te("alterColumn")}renameColumn(e){return te("renameColumn")}addRecord(e){return te("addRecord")}updateRecords(e){return te("updateRecords")}deleteRecords(e){return te("deleteRecords")}forceDeleteRecords(e){return te("forceDeleteRecords")}bulkInsertRecords(e){return te("bulkInsertRecords")}executeQuery(e){return te("executeQuery")}}});var J,W,z,Z,Dr,_r,oe,de,Ft,Ke,Ve=N(()=>{"use strict";b();Fe();J=n=>Pt(n),W=n=>kt(n),z=n=>$t(n),Z=()=>It(),Dr=()=>Lt(),_r=()=>Mt(),oe=n=>Qn(n),de=n=>qt(n),Ft=n=>Jn(n),Ke=()=>Xn()});function Me(){let n=process.env.DATABASE_URL;if(!n)return{host:"localhost",port:5432};try{let e=new URL(n),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(e){return console.error("Failed to parse DATABASE_URL:",e),{host:"localhost",port:5432}}}var dt=N(()=>{"use strict";b()});function na(n){if(!n||n.length===0)return{};let e=[];for(let t of n){let r=t.columnName,a=js(t.value),o=t.operator.toLowerCase();if(r)switch(o){case"=":e.push({[r]:a});break;case"!=":e.push({[r]:{$ne:a}});break;case">":e.push({[r]:{$gt:a}});break;case">=":e.push({[r]:{$gte:a}});break;case"<":e.push({[r]:{$lt:a}});break;case"<=":e.push({[r]:{$lte:a}});break;case"is":e.push({[r]:a});break;case"is not":e.push({[r]:{$ne:a}});break;case"like":e.push({[r]:{$regex:jt(String(a)),$options:""}});break;case"not like":e.push({[r]:{$not:{$regex:jt(String(a)),$options:""}}});break;case"ilike":e.push({[r]:{$regex:jt(String(a)),$options:"i"}});break;case"not ilike":e.push({[r]:{$not:{$regex:jt(String(a)),$options:"i"}}});break;default:e.push({[r]:a});break}}return e.length?{$and:e}:{}}function vr(n,e){return n?Array.isArray(n)?n.length===0?{_id:1}:Object.fromEntries(n.map(t=>[t.columnName,t.direction==="desc"?-1:1])):typeof n=="string"&&n.length>0?{[n]:e==="desc"?-1:1}:{_id:1}:{_id:1}}function xr(n){return Buffer.from(JSON.stringify({offset:n})).toString("base64url")}function aa(n){if(!n)return 0;try{let e=JSON.parse(Buffer.from(n,"base64url").toString("utf-8"));return typeof e.offset=="number"?e.offset:0}catch{return 0}}var jt,js,oa=N(()=>{"use strict";b();Fe();jt=n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),js=n=>{let e=n.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:Ut(e)?Bt(e):e}});import{HTTPException as j}from"hono/http-exception";var Or,Ze,Hs,Ks,sa,pt,Vs,ia,zs,Ws,Ys,et,Ht,la=N(()=>{"use strict";b();He();Ve();Fe();dt();oa();Or=n=>n instanceof Date?n.toISOString():typeof n=="bigint"?n.toString():n&&typeof n=="object"?"_bsontype"in n&&n._bsontype==="ObjectId"?n.toHexString():Array.isArray(n)?n.map(e=>Or(e)):Object.fromEntries(Object.entries(n).map(([e,t])=>[e,Or(t)])):n,Ze=n=>Or(n),Hs=n=>n instanceof Date?"date":n&&typeof n=="object"?Array.isArray(n)?"array":"_bsontype"in n?"text":"json":typeof n=="boolean"?"boolean":typeof n=="number"||typeof n=="bigint"?"number":"text",Ks=n=>{switch(n){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"}},sa=n=>typeof n=="string"&&Ut(n),pt=n=>Bt(n),Vs=n=>{if(!Number.isFinite(n))return"n/a";let e=["B","KB","MB","GB","TB"],t=n,r=0;for(;t>=1024&&r<e.length-1;)t/=1024,r++;return`${t.toFixed(1)} ${e[r]}`},ia=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),zs=n=>{let e=n.trim();if(ia.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},Ws=n=>{if(n==null)return"null";if(n instanceof Date)return"date";if(typeof n=="boolean")return"bool";if(typeof n=="number")return Number.isInteger(n)?"int":"double";if(typeof n=="bigint")return"long";if(Array.isArray(n))return"array";if(typeof n=="object"){let e=n._bsontype;return e==="ObjectId"?"objectId":e==="Decimal128"?"decimal":e==="Binary"?"binData":e==="Timestamp"?"timestamp":e?e.toLowerCase():"object"}return"string"},Ys=(n,e)=>{if(n!=null&&n.trim()!=="")try{return JSON.parse(n)}catch{return n}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}},et=n=>{if(n._id&&typeof n._id=="string")return{...n,_id:pt(n._id)};if(n._id&&typeof n._id=="object"){let e=n._id;if(Array.isArray(e.$in))return{...n,_id:{...e,$in:e.$in.map(t=>typeof t=="string"?pt(t):t)}};if(Array.isArray(e.$nin))return{...n,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?pt(t):t)}}}return n},Ht=class extends me{runQuery(){throw new j(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new j(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(Ze(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 j)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new j(503,{message:e.message})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:r,cursor:a,limit:o,direction:s="asc",sort:c,order:i,filters:l}=e,m=(await oe(r)).collection(t),d=na(l??[]),p=vr(c??"",i),f=o&&o>0?o:50,y=aa(a),h=Number.isFinite(y)&&y>=0?y:0,w=s==="desc"?Math.max(h-f,0):h,[E,A]=await Promise.all([m.countDocuments(d),m.find(d).sort(p).skip(w).limit(f).toArray()]),C=A.map(D=>Ze(D)),R=w+f,S=Math.max(w-f,0);return{data:C,meta:{limit:f,total:E,hasNextPage:R<E,hasPreviousPage:w>0,nextCursor:R<E?xr(R):null,prevCursor:w>0?xr(S):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let s=(await(await oe(t)).collection(e).find({}).limit(1e4).toArray()).map(i=>Ze(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 a=(await(await Dr()).db().admin().listDatabases()).databases??[];if(!a[0])throw new j(500,{message:"No databases returned from MongoDB"});return a.map(o=>({name:o.name,size:Vs(o.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:_r()}}async getDatabaseConnectionInfo(){try{let t=(await Dr()).db().admin(),r=Me(),a={};try{a=await t.serverStatus()}catch(o){console.warn("Failed to read MongoDB serverStatus:",o)}return{host:r.host,port:r.port,user:"n/a",database:_r(),version:a.version??"unknown",active_connections:a.connections?.current??0,max_connections:(a.connections?.current??0)+(a.connections?.available??0)}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=await oe(e),r=await t.listCollections().toArray(),a=[];for(let o of r){let s=await t.collection(o.name).estimatedDocumentCount();a.push({tableName:o.name,rowCount:s})}return a}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){try{let r=e?.tableName??"",a=await oe(t);if((await a.listCollections({name:r}).toArray()).length>0)throw new j(400,{message:`Collection "${r}" already exists`});let s=e?.fields??[];if(s.length===0){await a.createCollection(r);return}let c={},i=[];for(let l of s){let u=zs(l.columnType);if(!ia.has(u))throw new j(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 a.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 a=(await oe(t)).collection(e),o=await a.estimatedDocumentCount();return await a.drop(),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async getTableSchema({tableName:e,db:t}){try{let r=await oe(t);if((await r.listCollections({name:e}).toArray()).length===0)throw new j(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 p of s)for(let[f,y]of Object.entries(p)){let h=Ws(y);i.has(f)||(i.set(f,new Set),l.set(f,0)),i.get(f)?.add(h),l.set(f,(l.get(f)??0)+1)}let u={},m=[];for(let[p,f]of i.entries()){let y=l.get(p)??0,h=Array.from(f).filter(E=>E!=="null"),w=f.has("null")||y<s.length;y===s.length&&s.length>0&&!w&&m.push(p),u[p]=h.length===1?{bsonType:w?[h[0],"null"]:h[0]}:{bsonType:w?[...h,"null"]:h}}let d={collection:e,estimatedDocumentCount:c,sampledDocuments:s.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(d,null,2)}catch(r){throw this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let o=await(await oe(t)).collection(e).find({}).limit(200).toArray(),s=o.length,c=new Map,i=(l,u)=>{let m=Hs(u);if(!c.has(l))c.set(l,{types:new Set([m]),nullable:!1,presentCount:1});else{let d=c.get(l);d.types.add(m),d.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 d=c.get(u);d.nullable=!0,d.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:Ks(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:a,defaultValue:o,isNullable:s,db:c}=e,i=await oe(c),l=await i.listCollections({name:t}).toArray();if(l.length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(await i.collection(t).findOne({[r]:{$exists:!0}}))throw new j(409,{message:`Field "${r}" already exists in collection "${t}"`});let m=Ys(o,a);await i.collection(t).updateMany({},{$set:{[r]:m}});let p=l[0].options?.validator?.$jsonSchema??{},f={...p.properties??{},[r]:{bsonType:s?[a,"null"]:a}},y=[...p.required??[]];!s&&!y.includes(r)&&y.push(r),await i.command({collMod:t,validator:{$jsonSchema:{...p,bsonType:"object",properties:f,...y.length>0?{required:y}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{return{deletedCount:(await(await oe(r)).collection(e).updateMany({},{$unset:{[t]:""}})).modifiedCount}}catch(a){throw this.wrapError(a)}}async alterColumn(e){try{let{tableName:t,columnName:r,columnType:a,isNullable:o,db:s}=e,c=await oe(s),i=await c.listCollections({name:t}).toArray();if(i.length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new j(400,{message:'Cannot alter the "_id" field'});let u=i[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},d=[...u.required??[]];m[r]={bsonType:o?[a,"null"]:a};let p=d.indexOf(r);!o&&p===-1?d.push(r):o&&p!==-1&&d.splice(p,1),await c.command({collMod:t,validator:{$jsonSchema:{...u,bsonType:"object",properties:m,...d.length>0?{required:d}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async renameColumn(e){try{let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=await oe(o);if((await s.listCollections({name:t}).toArray()).length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new j(400,{message:'Cannot rename the "_id" field'});if(!await s.collection(t).findOne({[r]:{$exists:!0}}))throw new j(404,{message:`Field "${r}" does not exist in collection "${t}"`});if(await s.collection(t).findOne({[a]:{$exists:!0}}))throw new j(409,{message:`Field "${a}" already exists in collection "${t}"`});await s.collection(t).updateMany({[r]:{$exists:!0}},{$rename:{[r]:a}})}catch(t){throw this.wrapError(t)}}async addRecord({db:e,params:t}){try{let{tableName:r,data:a}=t,s=(await oe(e)).collection(r),c=Ze(a);if((c._id===""||c._id===null)&&delete c._id,!(await s.insertOne(c)).insertedId)throw new j(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:a,primaryKey:o}=t,c=(await oe(e)).collection(r),i=0,l=o||"_id",u=new Map;for(let m of a){let d=m.rowData[l];if(d==null)throw new j(400,{message:`Primary key "${l}" not found in row data.`});u.has(d)||u.set(d,{}),u.get(d)[m.columnName]=m.value}for(let[m,d]of u.entries()){let p=l==="_id"&&sa(m)?pt(m):m,f=await c.updateOne({[l]:p},{$set:d});if(f.matchedCount===0)throw new j(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:a}=e,s=(await oe(a)).collection(t),c=r[0]?.columnName??"_id",i=r.map(u=>c==="_id"&&sa(u.value)?pt(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:a}=e;if(!r||r.length===0)throw new j(400,{message:"At least one record is required"});let s=(await oe(a)).collection(t),c=r.map(l=>{let u=Ze(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 j(400,{message:"Query is required"});let r;try{r=JSON.parse(e)}catch{throw new j(400,{message:"Mongo query must be valid JSON"})}if(!r.collection||!r.operation)throw new j(400,{message:"Mongo query must include collection and operation"});let o=(await oe(t)).collection(r.collection),s=performance.now(),c=[],i=0,l;switch(r.operation){case"find":{let p=et(r.filter??{}),f=o.find(p,r.options??{});f.sort(r.sort??vr("",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 p=r.document;if(!p)throw new j(400,{message:"document is required"});i=(await o.insertOne(p)).insertedId?1:0,l="OK";break}case"insertMany":{let p=r.document;if(!Array.isArray(p))throw new j(400,{message:"document array is required"});i=(await o.insertMany(p)).insertedCount??0,l="OK";break}case"updateOne":{let p=et(r.filter??{});if(!r.update)throw new j(400,{message:"update is required"});let f=await o.updateOne(p,r.update,r.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"updateMany":{let p=et(r.filter??{});if(!r.update)throw new j(400,{message:"update is required"});let f=await o.updateMany(p,r.update,r.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"deleteOne":{let p=et(r.filter??{});i=(await o.deleteOne(p,r.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let p=et(r.filter??{});i=(await o.deleteMany(p,r.options??{})).deletedCount??0,l="OK";break}case"count":{let p=et(r.filter??{});i=await o.countDocuments(p),c=[{count:i}],l="OK";break}default:throw new j(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-s,m=c.map(p=>Ze(p));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 tt}from"zod";var P,ca,ft,Gs,Qs,Ee,we=N(()=>{"use strict";b();P=tt.object({db:tt.string("Database name is required")}),ca=["pg","mysql","mssql","mongodb","sqlite","redis"],ft=tt.enum(ca,{message:"Invalid database type"}),Gs=P.extend({dbType:ft}),Qs=tt.object({dbType:ft}),Ee=tt.object({tableName:tt.string("Table name is required")})});import{z as De}from"zod";var Se,Js,Xs,ua=N(()=>{"use strict";b();we();Se=De.object({columnName:De.string("Column name is required"),columnType:De.string("Column type is required"),defaultValue:De.string().optional(),isPrimaryKey:De.boolean().default(!1),isNullable:De.boolean().default(!1),isUnique:De.boolean().default(!1),isIdentity:De.boolean().default(!1),isArray:De.boolean().default(!1)}),Js=Ee,Xs=De.object({db:P.shape.db,tableName:Ee.shape.tableName,columnName:Se.shape.columnName,columnType:Se.shape.columnType,defaultValue:Se.shape.defaultValue,isPrimaryKey:Se.shape.isPrimaryKey,isNullable:Se.shape.isNullable,isUnique:Se.shape.isUnique,isIdentity:Se.shape.isIdentity,isArray:Se.shape.isArray})});import{z as yt}from"zod";var Pr,ma=N(()=>{"use strict";b();Pr=yt.object({tableName:yt.string("Table name is required"),data:yt.record(yt.string("Column name is required"),yt.any())})});import{z as Zs}from"zod";var da,kr,pa,$r,Ir=N(()=>{"use strict";b();da=["gemini","openai","anthropic","grok","openrouter"],kr=Zs.enum(da),pa=[{id:"gemini",label:"Google Gemini",models:[{id:"gemini-3-flash-preview",label:"Gemini 3 Flash"},{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro"}]},{id:"openai",label:"OpenAI",models:[{id:"gpt-5.2",label:"GPT-5.2"},{id:"gpt-5-mini",label:"GPT-5 mini"}]},{id:"anthropic",label:"Anthropic",models:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}]},{id:"grok",label:"xAI Grok",models:[{id:"grok-4.6",label:"Grok 4.6"},{id:"grok-4.5",label:"Grok 4.5"}]},{id:"openrouter",label:"OpenRouter",models:[{id:"openai/gpt-5.2",label:"GPT-5.2 via OpenRouter"},{id:"anthropic/claude-sonnet-4.6",label:"Claude Sonnet 4.6 via OpenRouter"}]}],$r=n=>pa.find(e=>e.id===n)?.models[0]?.id??"gemini-3-flash-preview"});import{z as Re}from"zod";var Lr,ie,ei,ti,Kt=N(()=>{"use strict";b();we();Lr=P.extend({cascade:Re.string().optional().transform(n=>n==="true")}),ie=Re.object({tableName:Re.string("Table name is required"),columnName:Re.string("Column name is required")}),ei=Re.object({db:P.shape.db,tableName:ie.shape.tableName,columnName:ie.shape.columnName,cascade:Re.boolean().optional()}),ti=Re.object({message:Re.string("Message is required"),tableName:Re.string("Table name is required"),columnName:Re.string("Column name is required"),deletedCount:Re.number("Deleted count is required").default(0)})});import{z as bt}from"zod";var rt,ri,ni,fa=N(()=>{"use strict";b();we();Kt();rt=bt.object({columnType:bt.string("Column type is required"),isNullable:bt.boolean(),defaultValue:bt.string().nullable().optional()}),ri=ie,ni=bt.object({db:P.shape.db,tableName:ie.shape.tableName,columnName:ie.shape.columnName,columnType:rt.shape.columnType,isNullable:rt.shape.isNullable,defaultValue:rt.shape.defaultValue})});var ya=N(()=>{"use strict";b()});import{z as nt}from"zod";var Mr,ba=N(()=>{"use strict";b();Mr=nt.object({tableName:nt.string().min(1,"Table name is required"),records:nt.array(nt.record(nt.string(),nt.any())).min(1,"At least one record is required")})});import{z as re}from"zod";var ai,oi,qr,ga=N(()=>{"use strict";b();Ir();we();ai=re.object({type:re.string(),content:re.string().optional()}).passthrough(),oi=re.object({provider:kr.optional().default("gemini"),model:re.string().min(1).optional(),messages:re.array(re.object({id:re.string(),role:re.enum(["user","assistant","system","tool","reasoning"]),content:re.union([re.string(),re.null(),re.array(re.unknown())]).optional(),parts:re.array(ai).optional()}).passthrough()),data:re.object({conversationId:re.string().optional(),db:P.shape.db,includeSchema:re.boolean().optional().default(!0)})}),qr=oi.transform(n=>({...n,model:n.model??$r(n.provider)}))});var ha=N(()=>{"use strict";b()});import{z as ge}from"zod";var si,Ta,K,ii,Ea,li,Ur=N(()=>{"use strict";b();si=["text","boolean","number","enum","json","date","array"],Ta=ge.enum(si),K={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},ii=["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"],Ea=ge.enum(ii),li=ge.object({columnName:ge.string(),dataType:Ta,dataTypeLabel:Ea,isNullable:ge.boolean(),columnDefault:ge.string().nullable(),isPrimaryKey:ge.boolean(),isForeignKey:ge.boolean(),referencedTable:ge.string().nullable(),referencedColumn:ge.string().nullable(),enumValues:ge.array(ge.string()).nullable()})});function Vt(n){let e=n?.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(")?K.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"?K.number:e==="boolean"||e==="bool"?K.boolean:e==="json"||e==="jsonb"?K.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?K.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"?K.text:K.text}function Br(n){if(!n)return T.text;let e=n.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?T.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?T.bigint:e==="smallint"||e==="int2"?T.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?T.numeric:e==="real"||e==="float4"?T.float:e==="double precision"||e==="float8"||e==="float"?T.double:e==="money"?T.money:e==="boolean"||e==="bool"?T.boolean:e==="text"?T.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?T.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?T.char:e==="json"?T.json:e==="jsonb"?T.jsonb:e==="xml"?T.xml:e==="uuid"?T.uuid:e==="date"?T.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?T.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?T.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?T.timestamptz:e==="interval"||e.startsWith("interval")?T.interval:e==="bytea"?T.bytea:e==="inet"?T.inet:e==="cidr"?T.cidr:e==="macaddr"?T.macaddr:e==="macaddr8"?T.macaddr8:e==="point"?T.point:e==="line"?T.line:e==="polygon"?T.polygon:e.startsWith("array")||e.includes("[]")?T.text:e.startsWith("user-defined")||e==="enum"?T.enum:T.text}function zt(n,e){let t=n?.toLowerCase().trim()||"",r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?K.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"?K.number:t==="boolean"||t==="bool"?K.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?K.date:t==="json"?K.json:t==="enum"||t==="set"?K.enum:K.text}function Fr(n,e){if(!n)return T.text;let t=n.toLowerCase().trim(),r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?T.boolean:t==="tinyint"?T.tinyint:t==="smallint"?T.smallint:t==="mediumint"?T.mediumint:t==="int"||t==="integer"?T.int:t==="bigint"?T.bigint:t==="decimal"||t==="numeric"?T.numeric:t==="float"||t==="real"?T.float:t==="double"?T.double:t==="bit"?T.bit:t==="boolean"||t==="bool"?T.boolean:t==="char"?T.char:t==="varchar"?T.varchar:t==="tinytext"?T.tinytext:t==="text"?T.text:t==="mediumtext"?T.mediumtext:t==="longtext"?T.longtext:t==="binary"?T.binary:t==="varbinary"?T.varbinary:t==="tinyblob"?T.tinyblob:t==="blob"?T.blob:t==="mediumblob"?T.mediumblob:t==="longblob"?T.longblob:t==="json"?T.json:t==="date"?T.date:t==="time"?T.time:t==="datetime"?T.datetime:t==="timestamp"?T.timestamp:t==="year"?T.year:t==="enum"?T.enum:t==="set"?T.set:T.text}function Wt(n){let e=n?.toLowerCase().trim()||"";return e==="tinyint"||e==="smallint"||e==="int"||e==="bigint"||e==="decimal"||e==="numeric"||e==="float"||e==="real"||e==="money"||e==="smallmoney"?K.number:e==="bit"?K.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?K.date:e==="json"?K.json:K.text}function jr(n){if(!n)return T.text;let e=n.toLowerCase().trim();return e==="tinyint"?T.tinyint:e==="smallint"?T.smallint:e==="int"?T.int:e==="bigint"?T.bigint:e==="decimal"||e==="numeric"?T.numeric:e==="float"||e==="real"?T.float:e==="money"||e==="smallmoney"?T.money:e==="bit"?T.boolean:e==="char"?T.char:e==="varchar"?T.varchar:e==="text"?T.text:e==="nchar"?T.char:e==="nvarchar"?T.varchar:e==="ntext"?T.text:e==="binary"?T.binary:e==="varbinary"?T.varbinary:e==="image"?T.blob:e==="uniqueidentifier"?T.uuid:e==="date"?T.date:e==="time"?T.time:e==="datetime"||e==="datetime2"||e==="smalldatetime"?T.datetime:e==="datetimeoffset"?T.timestamptz:e==="json"?T.json:e==="xml"?T.xml:T.text}function Yt(n){let e=n?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?K.boolean:e==="json"?K.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?K.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?K.number:K.text}function Hr(n){let e=n?.toLowerCase().trim()||"";return e==="integer"||e==="int"?T.int:e==="bigint"||e.startsWith("bigint(")?T.bigint:e==="smallint"||e.startsWith("smallint(")?T.smallint:e==="tinyint"||e.startsWith("tinyint(")?T.tinyint:e==="mediumint"||e.startsWith("mediumint(")?T.mediumint:e.includes("int")?T.int:e==="real"||e==="float"||e.startsWith("float(")?T.float:e==="double"||e==="double precision"||e.startsWith("double(")?T.double:e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?T.numeric:e==="boolean"||e==="bool"?T.boolean:e==="text"||e==="clob"?T.text:e==="varchar"||e.startsWith("varchar(")?T.varchar:e==="char"||e.startsWith("char(")?T.char:e==="json"?T.json:e==="date"?T.date:e==="time"?T.time:e==="datetime"?T.datetime:e==="timestamp"?T.timestamp:e==="blob"?T.blob:T.text}var T,wa=N(()=>{"use strict";b();Ur();T={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 ne}from"zod";var Sa,Kr,Ra,Ca,Vr,Na=N(()=>{"use strict";b();Sa=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],Kr=ne.enum(Sa),Ra=ne.object({columnName:ne.string("Column name is required"),columnType:ne.string("Column type is required"),defaultValue:ne.string().optional(),isPrimaryKey:ne.boolean().default(!1),isNullable:ne.boolean().default(!1),isUnique:ne.boolean().default(!1),isIdentity:ne.boolean().default(!1),isArray:ne.boolean().default(!1)}),Ca=ne.object({columnName:ne.string("Column name is required"),referencedTable:ne.string("Referenced table is required"),referencedColumn:ne.string("Referenced column is required"),onUpdate:Kr.default("NO ACTION"),onDelete:Kr.default("NO ACTION")}),Vr=ne.object({tableName:ne.string("Table name is required"),fields:ne.array(Ra).min(1,"At least one field is required"),foreignKeys:ne.array(Ca).optional()})});import{z as le}from"zod";var Aa,ci,ui,Da=N(()=>{"use strict";b();we();Aa=le.object({name:le.string("Name is required"),size:le.string("Size is required"),owner:le.string("Owner is required"),encoding:le.string("Encoding is required")}),ci=le.object({databases:le.array(Aa),dbType:ft}),ui=le.object({version:le.string("Version is required"),database:le.string("Database is required"),user:le.string("User is required"),host:le.string("Host is required").nullable(),port:le.number("Port is required").nullable(),active_connections:le.coerce.number("Active connections is required"),max_connections:le.coerce.number("Max connections is required")})});var _a=N(()=>{"use strict";b()});import{z as at}from"zod";var Gt,va=N(()=>{"use strict";b();Gt=at.object({tableName:at.string("Table name is required"),primaryKeys:at.array(at.object({columnName:at.string("Column name is required"),value:at.any()})).min(1,"At least one primary key is required")})});import{z as mi}from"zod";var zr,xa=N(()=>{"use strict";b();we();zr=P.extend({cascade:mi.string().optional().transform(n=>n==="true")})});import{z as Oa}from"zod";var Wr,Pa=N(()=>{"use strict";b();Wr=Oa.object({query:Oa.string("Query is required")})});import{z as di}from"zod";var ka,Yr,$a=N(()=>{"use strict";b();we();ka=["csv","xlsx","json"],Yr=P.extend({format:di.enum(ka,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as g}from"zod";var Qt,$,Gr,Qr,pi,Jr,ot,fi,yi,bi,gi,hi,Ti,Ei,Ia,wi,Xr,Si,Ri,Ci,Ni,Ai,Di,_i,Zr,vi,xi,Oi,Pi,ki,$i,Ii,Li,Mi,qi,Ui,Bi,Fi,ji,Hi,en,tn,Ki,La=N(()=>{"use strict";b();Qt=g.enum(["string","hash","list","set","zset","stream","unknown"]),$=g.object({base64:g.string().max(16*1024*1024).refine(n=>/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/.test(n),"Invalid unpadded base64url value"),utf8:g.string().optional()}),Gr=g.object({db:g.string(),cursor:g.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:g.coerce.number().int().min(1).max(200).default(50),search:g.string().max(512).optional(),exactPattern:g.stringbool().default(!1),type:Qt.exclude(["unknown"]).optional()}),Qr=g.object({key:$,type:Qt,ttlMs:g.number().int(),memoryBytes:g.number().int().nonnegative().nullable()}),pi=g.object({keys:g.array(Qr),nextCursor:g.string().nullable(),hasMore:g.boolean()}),Jr=g.object({db:g.string(),cursor:g.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:g.coerce.number().int().min(1).max(500).default(100),full:g.stringbool().default(!1),direction:g.enum(["forward","backward"]).default("forward")}),ot=g.object({key:g.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),fi=g.object({kind:g.literal("string"),value:$,truncated:g.boolean()}),yi=g.object({kind:g.literal("hash"),entries:g.array(g.object({field:$,value:$}))}),bi=g.object({kind:g.literal("list"),entries:g.array(g.object({index:g.number().int(),value:$}))}),gi=g.object({kind:g.literal("set"),members:g.array($)}),hi=g.object({kind:g.literal("zset"),entries:g.array(g.object({member:$,score:g.union([g.number(),g.literal("inf"),g.literal("-inf")])}))}),Ti=g.object({kind:g.literal("stream"),entries:g.array(g.object({id:g.string(),fields:g.array(g.object({field:$,value:$}))}))}),Ei=g.object({kind:g.literal("unknown")}),Ia=g.discriminatedUnion("kind",[fi,yi,bi,gi,hi,Ti,Ei]),wi=Qr.extend({length:g.number().int().nonnegative().nullable(),revision:g.string(),value:Ia,nextCursor:g.string().nullable(),hasMore:g.boolean()}),Xr=g.object({db:g.string(),offset:g.coerce.number().int().nonnegative().default(0),limit:g.coerce.number().int().min(1).max(1024*1024).default(1024*1024),expectedRevision:g.string().optional()}),Si=g.object({chunk:$,length:g.number().int().nonnegative(),nextOffset:g.number().int().nonnegative().nullable(),hasMore:g.boolean()}),Ri=g.object({kind:g.literal("string"),value:$}),Ci=g.object({kind:g.literal("hash"),entries:g.array(g.object({field:$,value:$})).min(1)}),Ni=g.object({kind:g.literal("list"),entries:g.array($).min(1)}),Ai=g.object({kind:g.literal("set"),members:g.array($).min(1)}),Di=g.object({kind:g.literal("zset"),entries:g.array(g.object({member:$,score:g.number()})).min(1)}),_i=g.object({kind:g.literal("stream"),id:g.string().default("*"),fields:g.array(g.object({field:$,value:$})).min(1)}),Zr=g.object({key:$,type:Qt.exclude(["unknown"]),value:g.discriminatedUnion("kind",[Ri,Ci,Ni,Ai,Di,_i]),ttlMs:g.number().int().positive().nullable().default(null)}),vi=g.object({key:$,revision:g.string().nullable(),deleted:g.boolean()}),xi=g.object({action:g.literal("rename"),newKey:$}),Oi=g.object({action:g.literal("setTtl"),ttlMs:g.number().int().positive().nullable()}),Pi=g.object({action:g.literal("setString"),value:$}),ki=g.object({action:g.literal("upsertHash"),field:$,value:$}),$i=g.object({action:g.literal("deleteHash"),field:$}),Ii=g.object({action:g.literal("pushList"),side:g.enum(["left","right"]),value:$}),Li=g.object({action:g.literal("setList"),index:g.number().int(),value:$}),Mi=g.object({action:g.literal("deleteList"),index:g.number().int()}),qi=g.object({action:g.literal("addSet"),member:$}),Ui=g.object({action:g.literal("removeSet"),member:$}),Bi=g.object({action:g.literal("upsertZset"),member:$,score:g.number()}),Fi=g.object({action:g.literal("removeZset"),member:$}),ji=g.object({action:g.literal("appendStream"),id:g.string().default("*"),fields:g.array(g.object({field:$,value:$})).min(1)}),Hi=g.object({action:g.literal("deleteStream"),id:g.string()}),en=g.object({expectedRevision:g.string(),force:g.boolean().default(!1),operation:g.discriminatedUnion("action",[xi,Oi,Pi,ki,$i,Ii,Li,Mi,qi,Ui,Bi,Fi,ji,Hi])}),tn=g.object({db:g.string(),expectedRevision:g.string(),force:g.stringbool().default(!1)}),Ki=g.object({deleted:g.boolean()})});var Ma=N(()=>{"use strict";b()});import{z as rn}from"zod";var Jt,Vi,zi,qa=N(()=>{"use strict";b();we();Kt();Jt=rn.object({newColumnName:rn.string("New column name is required")}),Vi=ie,zi=rn.object({db:P.shape.db,tableName:ie.shape.tableName,columnName:ie.shape.columnName,newColumnName:Jt.shape.newColumnName})});import{z as V}from"zod";var Wi,gt,Yi,Ua,Gi,nn,Ba=N(()=>{"use strict";b();we();Wi=V.object({columnName:V.string(),operator:V.string(),value:V.string()}),gt=["asc","desc"],Yi=V.object({columnName:V.string(),direction:V.enum(gt)}),Ua=V.object({limit:V.number(),total:V.number(),hasNextPage:V.boolean(),hasPreviousPage:V.boolean(),nextCursor:V.string().nullable(),prevCursor:V.string().nullable()}),Gi=V.object({data:V.array(V.record(V.string(),V.unknown())),meta:Ua}),nn=V.object({db:P.shape.db,cursor:V.string().optional(),limit:V.string().optional().default("50").transform(Number),direction:V.enum(gt).optional().default(gt[0]),sort:V.string().optional().transform(n=>{if(!n)return"";try{let e=JSON.parse(n);return Array.isArray(e)?e:n}catch{return n}}),order:V.enum(gt).optional(),filters:V.string().optional().transform(n=>{if(!n)return[];try{return JSON.parse(n)}catch{return[]}})})});import{z as Xt}from"zod";var Qi,Fa=N(()=>{"use strict";b();Qi=Xt.object({tableName:Xt.string("Table name is required"),schemaName:Xt.string().optional(),rowCount:Xt.coerce.number("Row count is required")})});import{z as ja}from"zod";var Ji,Ha=N(()=>{"use strict";b();Ji=ja.object({schema:ja.string()})});import{z as _e}from"zod";var an,Ka=N(()=>{"use strict";b();an=_e.object({tableName:_e.string("Table name is required"),primaryKey:_e.string("Primary key is required").default("id"),updates:_e.array(_e.object({rowData:_e.record(_e.string("Column name is required"),_e.any()),columnName:_e.string("Column name is required"),value:_e.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var Va={};Nt(Va,{AI_PROVIDERS:()=>da,AI_PROVIDER_OPTIONS:()=>pa,DATABASE_TYPES:()=>ca,DataTypes:()=>K,FOREIGN_KEY_ACTIONS:()=>Sa,FORMAT_TYPES:()=>ka,StandardizedDataType:()=>T,addColumnParamSchema:()=>Js,addColumnParamsSchema:()=>Xs,addColumnSchema:()=>Se,addRecordSchema:()=>Pr,aiProviderSchema:()=>kr,alterColumnParamSchema:()=>ri,alterColumnParamsSchema:()=>ni,alterColumnSchema:()=>rt,bulkInsertRecordsSchema:()=>Mr,chatSchema:()=>qr,columnInfoSchema:()=>li,connectionInfoSchema:()=>ui,createKeySchema:()=>Zr,createTableSchema:()=>Vr,currentDatabaseSchema:()=>Gs,dataTypesSchema:()=>Ta,databaseInfoSchema:()=>Aa,databaseListSchema:()=>ci,databaseSchema:()=>P,databaseTypeParamSchema:()=>Qs,databaseTypeSchema:()=>ft,deleteColumnParamSchema:()=>ie,deleteColumnParamsSchema:()=>ei,deleteColumnQuerySchema:()=>Lr,deleteColumnSuccessResponseSchema:()=>ti,deleteKeyQuerySchema:()=>tn,deleteKeyResultSchema:()=>Ki,deleteRecordSchema:()=>Gt,deleteTableQuerySchema:()=>zr,encodedRedisValueSchema:()=>$,executeQuerySchema:()=>Wr,exportTableSchema:()=>Yr,fieldDataSchema:()=>Ra,filterSchema:()=>Wi,foreignKeyActionSchema:()=>Kr,foreignKeyDataSchema:()=>Ca,getDefaultAiModel:()=>$r,keyActionSchema:()=>en,keyDetailsQuerySchema:()=>Jr,keyDetailsResultSchema:()=>wi,keyParamSchema:()=>ot,keyRawQuerySchema:()=>Xr,keyRawResultSchema:()=>Si,keyScanQuerySchema:()=>Gr,keyScanResultSchema:()=>pi,keyWriteResultSchema:()=>vi,mapMssqlToDataType:()=>Wt,mapMysqlToDataType:()=>zt,mapPostgresToDataType:()=>Vt,mapSqliteToDataType:()=>Yt,redisKeySummarySchema:()=>Qr,redisKeyTypeSchema:()=>Qt,redisKeyValueSchema:()=>Ia,renameColumnParamSchema:()=>Vi,renameColumnParamsSchema:()=>zi,renameColumnSchema:()=>Jt,sortDirections:()=>gt,sortSchema:()=>Yi,standardizeDataTypeLabel:()=>Br,standardizeMssqlDataTypeLabel:()=>jr,standardizeMysqlDataTypeLabel:()=>Fr,standardizeSqliteDataTypeLabel:()=>Hr,standardizedDataTypeSchema:()=>Ea,tableDataMetaSchema:()=>Ua,tableDataQuerySchema:()=>nn,tableDataResultSchema:()=>Gi,tableInfoSchema:()=>Qi,tableNameSchema:()=>Ee,tableSchemaResultSchema:()=>Ji,updateRecordsSchema:()=>an});var Ce=N(()=>{"use strict";b();ua();ma();Ir();fa();ya();ba();ga();ha();wa();Ur();Na();we();Da();_a();Kt();va();xa();Pa();$a();La();Ma();qa();Ba();Fa();Ha();Ka()});function on(n,e=0){if(n.length===0)return{clause:"",values:[],nextIdx:e};let t=[],r=[],a=e;for(let o of n){let s=`[${o.columnName}]`;switch(o.operator){case"=":case"!=":case">":case">=":case"<":case"<=":t.push(`${s} ${o.operator} @p${a}`),r.push(o.value),a++;break;case"is":o.value.toLowerCase()==="null"?t.push(`${s} IS NULL`):(t.push(`${s} = @p${a}`),r.push(o.value),a++);break;case"is not":o.value.toLowerCase()==="null"?t.push(`${s} IS NOT NULL`):(t.push(`${s} != @p${a}`),r.push(o.value),a++);break;case"like":case"ilike":t.push(`${s} LIKE @p${a}`),r.push(o.value),a++;break;case"not like":case"not ilike":t.push(`${s} NOT LIKE @p${a}`),r.push(o.value),a++;break;default:break}}return t.length===0?{clause:"",values:[],nextIdx:e}:{clause:`WHERE ${t.join(" AND ")}`,values:r,nextIdx:a}}function sn(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(t=>`[${t.columnName}] ${t.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY [${n}] ${e?.toUpperCase()||"ASC"}`:""}function ln(n,e){if(e)return"NVARCHAR(MAX)";let t=n.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]||n.toUpperCase()}function cn(n,e){let t=n.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("newid()")?e.toUpperCase().includes("UNIQUEIDENTIFIER")?"NEWID()":null:t.includes("getdate")||t.includes("current_timestamp")?"GETDATE()":n.trim():t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":n.trim()}function za(n,e={}){let t=ln(n.columnType,n.isArray??!1),r=`[${n.columnName}] ${t}`;if(n.isIdentity&&!t.includes("IDENTITY")&&(r+=" IDENTITY(1,1)"),!n.isNullable&&!n.isPrimaryKey&&(r+=" NOT NULL"),n.defaultValue?.trim()&&!t.includes("IDENTITY")){let a=cn(n.defaultValue,t);a!==null&&(r+=` DEFAULT ${a}`)}return e.includeUnique&&n.isUnique&&!n.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&n.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var Wa=N(()=>{"use strict";b()});import{HTTPException as U}from"hono/http-exception";var Xi,Zi,Zt,Ya=N(()=>{"use strict";b();Ce();He();Ve();dt();Wa();Xi=547,Zi=3726,Zt=class extends me{async runQuery(e,t,r){let o=(await z(e)).request();return r.forEach((c,i)=>{o.input(`p${i}`,c)}),(await o.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return Wt(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:a=[],order:o="asc",limit:s=50,cursor:c}=e,{clause:i,values:l,nextIdx:u}=on(r,0),m=sn(a,o)||"ORDER BY (SELECT NULL)",d=c?this.decodeOffsetCursor(c):0,p=`SELECT * FROM [${t}] ${i} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,f=[...l,d,s+1],y=`SELECT COUNT(*) as total FROM [${t}] ${i}`;return{sql:p,values:f,countSql:y,countValues:l}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){let{cursor:a,limit:o=50}=e,s=a?this.decodeOffsetCursor(a):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:a=50,sort:o=[],order:s="asc",cursor:c,filters:i=[]}=e,l=await z(r),u=c?this.decodeOffsetCursor(c):0,{clause:m,values:d,nextIdx:p}=on(i,0),f=sn(o,s)||"ORDER BY (SELECT NULL)",y=l.request();d.forEach((S,D)=>{y.input(`p${D}`,S)});let h=await y.query(`SELECT COUNT(*) as total FROM [${t}] ${m}`),w=Number(h.recordset[0]?.total??0),E=l.request();d.forEach((S,D)=>{E.input(`p${D}`,S)}),E.input(`p${p}`,u),E.input(`p${p+1}`,a+1);let C=(await E.query(`SELECT * FROM [${t}] ${m} ${f} OFFSET @p${p} ROWS FETCH NEXT @p${p+1} ROWS ONLY`)).recordset,R=C.length>a;return R&&(C=C.slice(0,a)),{data:C,meta:{limit:a,total:w,hasNextPage:R,hasPreviousPage:u>0,nextCursor:R?this.makeCursor(u+a):null,prevCursor:u>0?this.makeCursor(Math.max(0,u-a)):null}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){let t=await(await z()).request().query(`
4
- SELECT
5
- d.name AS name,
6
- CAST(ROUND(CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)), 2) AS VARCHAR(20)) + ' MB' AS size,
7
- SUSER_SNAME(d.owner_sid) AS owner,
8
- d.collation_name AS encoding
9
- FROM sys.databases d
10
- JOIN sys.master_files mf ON d.database_id = mf.database_id
11
- WHERE d.database_id > 4
12
- GROUP BY d.name, d.owner_sid, d.collation_name
13
- ORDER BY d.name
14
- `);if(!t.recordset[0])throw new U(500,{message:"No databases returned from server"});return t.recordset}async getCurrentDatabase(){let t=await(await z()).request().query("SELECT DB_NAME() AS db");if(!t.recordset[0])throw new U(500,{message:"No current database returned from server"});return t.recordset[0]}async getDatabaseConnectionInfo(){let t=await(await z()).request().query(`
2
+ var ps=Object.defineProperty;var C=(a,e)=>()=>(a&&(e=a(a=0)),e);var _t=(a,e)=>{for(var t in e)ps(a,t,{get:e[t],enumerable:!0})};var b=C(()=>{"use strict";(function(){try{var a=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};a.SENTRY_RELEASE={id:"db-studio@1.14.1"}}catch{}})()});var _a=C(()=>{"use strict";b()});var xa=C(()=>{"use strict";b()});var va=C(()=>{"use strict";b()});var $a,Oa,ke,Pa=C(()=>{"use strict";b();$a=globalThis.process?.env,Oa=$a?.NODE_ENV,ke={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:Oa==="development",PROXY_URL:$a?.DB_STUDIO_PROXY_URL??(Oa==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var ka=C(()=>{"use strict";b()});var La,yr=C(()=>{"use strict";b();La={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:"db-studio",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 Ia=C(()=>{"use strict";b()});var ut=C(()=>{"use strict";b();_a();xa();va();Pa();ka();yr();Ia()});var je,Er=C(()=>{je={name:"db-studio",type:"module",version:"1.14.1",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} <husam@ql3.dev>",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:"Apache-2.0",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",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.db-studio",script:"dev:app"},dependencies:{"@clack/prompts":"^1.0.1","@hono/node-server":"^2.0.0","@hono/zod-validator":"^0.9.0","@sentry/node":"^10.73.0","better-sqlite3":"^13.0.3",commander:"^15.0.0",dotenv:"^18.0.0",hono:"^4.10.4",ioredis:"^6.0.0",mongodb:"^7.1.1",mssql:"^12.2.0",mysql2:"^3.18.2",open:"^11.0.0",pg:"^8.13.1",picocolors:"^1.1.1","posthog-node":"^5.20.0",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@db-studio/shared":"workspace:*","@sentry/esbuild-plugin":"^5.4.0","@types/better-sqlite3":"^9.6.0","@types/mssql":"^12.3.0","@types/node":"^26.0.0","@types/pg":"^8.16.0","@vitest/coverage-v8":"^5.0.0",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^7.0.2",vitest:"^5.0.0"}}});var en={};_t(en,{captureInstallationActive:()=>Nr,captureServerError:()=>Ar,captureServerEvent:()=>kt,databaseTypeForRequest:()=>Cr,durationBucket:()=>Sr,getTelemetryConfig:()=>$t,initServerObservability:()=>Za,isTelemetryEnabled:()=>Ze,operationForRequest:()=>mt,outcomeForStatus:()=>Rr,resetTelemetryId:()=>wr,setTelemetryEnabled:()=>Pt,startServerSpan:()=>Dr,writeOperationalLog:()=>_r});import{randomUUID as Qa}from"crypto";import{existsSync as Ps,mkdirSync as ks,readFileSync as Ls,writeFileSync as Is}from"fs";import{homedir as Ga,platform as Ms}from"os";import vt from"path";import*as he from"@sentry/node";import{HTTPException as Ja}from"hono/http-exception";import{PostHog as qs}from"posthog-node";var Us,Xa,Ot,Bs,Fs,Ie,Je,js,Hs,Xe,Ze,$t,Pt,wr,Sr,Rr,mt,Cr,Za,kt,Nr,Ks,Vs,zs,Ar,Dr,_r,dt=C(()=>{"use strict";b();Er();Us=()=>process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development",Xa=()=>{let a=process.env.DB_STUDIO_DATA_DIR??process.env.XDG_STATE_HOME??(process.platform==="win32"?process.env.LOCALAPPDATA:vt.join(Ga(),".local","state"));return vt.join(a||vt.join(Ga(),".db-studio"),"db-studio","telemetry.json")},Ot=a=>{try{let e=Xa();ks(vt.dirname(e),{recursive:!0}),Is(e,JSON.stringify(a),{encoding:"utf8",mode:384})}catch{}},Bs=()=>({installationId:Qa(),enabled:!0}),Fs=()=>{let a=Xa();try{if(Ps(a)){let t=JSON.parse(Ls(a,"utf8"));if(typeof t.installationId=="string"&&typeof t.enabled=="boolean")return{installationId:t.installationId,enabled:t.enabled,lastActiveAt:typeof t.lastActiveAt=="string"?t.lastActiveAt:void 0}}}catch{}let e=Bs();return Ot(e),e},js="https://a1e890d1105f1f27fcb1dbead71c30dd@o4509725125181440.ingest.de.sentry.io/4512040493383760",Hs="phc_nxaQk54MWAehmL72J4gjVbrQCpbSTedMyHn3PvFxAhkd",Xe=()=>Ie??=Fs(),Ze=()=>!Us()&&process.env.DB_STUDIO_TELEMETRY!=="0"&&Xe().enabled,$t=()=>({enabled:Ze(),installationId:Xe().installationId,appVersion:je.version}),Pt=a=>{Ie={...Xe(),enabled:a},Ot(Ie),a?(Je?.enable(),Za()):(Je?.disable(),he.close(500))},wr=()=>(Ie={...Xe(),installationId:Qa(),lastActiveAt:void 0},Ot(Ie),Ie.installationId),Sr=a=>a<100?"under_100ms":a<1e3?"100ms_1s":a<5e3?"1s_5s":"over_5s",Rr=a=>a>=500?"server_error":a>=400?"client_error":"success",mt=(a,e)=>{let t=e.replace(/^\/api\/(?:pg|mysql|mssql|mongodb|sqlite|redis)(?=\/|$)/,"/api"),n=[[/^\/api\/databases(?:\/|$)/,"databases"],[/^\/api\/tables(?:\/|$)/,"tables"],[/^\/api\/records(?:\/|$)/,"records"],[/^\/api\/query(?:\/|$)/,"query"],[/^\/api\/keys(?:\/|$)/,"keys"],[/^\/api\/chat(?:\/|$)/,"chat"]].find(([o])=>o.test(t))?.[1]??"other";return`${a.toLowerCase()}_${n}`},Cr=a=>a.match(/^\/api\/(pg|mysql|mssql|mongodb|sqlite|redis)(?=\/|$)/)?.[1],Za=()=>{if(!Ze())return;let a=process.env.DB_STUDIO_SENTRY_DSN??js;a&&(!he.isInitialized()||he.getClient()?.getOptions().enabled===!1)&&he.init({dsn:a,environment:process.env.NODE_ENV??"production",release:`db-studio@${je.version}`,tracesSampleRate:.1,sendDefaultPii:!1,defaultIntegrations:!1,beforeSend(t){return delete t.request,delete t.user,delete t.breadcrumbs,t},beforeSendSpan(t){return{...t,data:Object.fromEntries(Object.entries(t.data??{}).filter(([r])=>r.startsWith("db_studio.")))}}});let e=process.env.DB_STUDIO_POSTHOG_KEY??Hs;e&&!Je&&(Je=new qs(e,{host:process.env.DB_STUDIO_POSTHOG_HOST??"https://eu.i.posthog.com",flushAt:20,flushInterval:1e4,requestTimeout:2e3}))},kt=a=>{!Ze()||!Je||Je.capture({distinctId:Xe().installationId,event:a.event,properties:{...a.properties,source:"server",app_version:je.version,$geoip_disable:!1}})},Nr=()=>{if(!Ze())return;let a=Xe(),e=a.lastActiveAt?Date.parse(a.lastActiveAt):0;Date.now()-e<864e5||(Ie={...a,lastActiveAt:new Date().toISOString()},Ot(Ie),kt({event:"installation_active",properties:{runtime:`node-${process.versions.node.split(".")[0]}`,os:Ms()}}))},Ks=a=>{let e=a instanceof Ja?"HTTPException":a instanceof Error?a.name:"Error";return/^[A-Za-z][A-Za-z0-9]{0,49}$/.test(e)?e:"Error"},Vs=a=>{if(!(a instanceof Error))return;let{code:e,errno:t}=a;if(typeof e=="string"&&/^[A-Z0-9_]{2,32}$/.test(e))return e;if(typeof t=="number"&&Number.isSafeInteger(t))return String(t)},zs=(a,e)=>{let t=new Error("Server operation failed");if(t.name=e,a instanceof Error&&a.stack){let r=a.stack.split(`
3
+ `).slice(1).filter(n=>/^\s*at\s/.test(n));t.stack=[`${e}: Server operation failed`,...r].join(`
4
+ `)}return t},Ar=(a,{operation:e,status:t,dbType:r})=>{if(!Ze()||t<500)return;let n=a instanceof Ja&&a.cause?a.cause:a,o=Ks(n),s=Vs(n);he.captureException(zs(n,o),{tags:{operation:e,source:"server",release:je.version,status:String(t),...r?{db_type:r}:{},error_type:o,...s?{error_code:s}:{}},fingerprint:[e,String(t),o,s??"unknown"]})},Dr=(a,e,t)=>he.startSpan({name:a,op:"http.server",attributes:{"db_studio.operation":a,...e?{"db_studio.db_type":e}:{}}},t),_r=(a,e,t)=>{let r=Object.fromEntries(Object.entries(t).filter(([,n])=>n!==void 0));process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:a,event:e,...r})}
5
+ `)}});import Ws from"better-sqlite3";import{Redis as Ys}from"ioredis";import{MongoClient as Gs,ObjectId as xr}from"mongodb";import Qs from"mssql";import{createPool as Js}from"mysql2/promise";import{Pool as tn}from"pg";var vr,Re,Lt,It,Mt,Me,qt,Ut,Bt,rn,Ft,an,nn,jt,Ht,He=C(()=>{"use strict";b();vr=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)),console.error(`\u274C Database configuration error: ${this.initError.message}`)}}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";case"redis":case"rediss":return"redis";default:throw new Error(`Unsupported database type: ${t}. Supported types: PostgreSQL (postgres://), MySQL (mysql://), SQL Server (mssql://), MongoDB (mongodb://), SQLite (sqlite://), Redis/Valkey (redis:// or rediss://).`)}}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 Ws(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 tn(r);n.on("connect",o=>{o.query(`DO $$
6
+ DECLARE extra text;
7
+ BEGIN
8
+ SELECT string_agg(quote_ident(nspname), ', ' ORDER BY nspname) INTO extra
9
+ FROM pg_namespace
10
+ WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'public')
11
+ AND nspname NOT LIKE 'pg_toast%'
12
+ AND nspname NOT LIKE 'pg_temp%';
13
+ IF extra IS NOT NULL THEN
14
+ EXECUTE 'SET search_path TO public, ' || extra;
15
+ END IF;
16
+ END $$;`).catch(s=>{console.error(`Failed to widen search_path for "${t}":`,s.message)})}),n.on("error",o=>{console.error(`Unexpected error on PostgreSQL pool for "${t}":`,o.message)}),this.pgPools.set(t,n)}return this.pgPools.get(t)??new tn({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=Js({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 Qs.ConnectionPool(o).connect();s.on("error",c=>{console.error(`Unexpected error on SQL Server pool for "${t}":`,c.message)}),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),console.log(`Closed PostgreSQL connection pool for: ${e}`))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e),console.log(`Closed MySQL connection pool for: ${e}`))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e),console.log(`Closed SQL Server connection pool for: ${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 Gs(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");let e=new URL(this.baseConfig.url).pathname.replace(/^\/+|\/+$/g,"");try{return decodeURIComponent(e)||"admin"}catch{return e||"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 Ys(o);try{if(await s.connect(),!this.redisClusterChecked){let c=await s.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(c))throw await s.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let i=c.match(/^redis_version:([^\r\n]+)/m)?.[1],[l=0,u=0]=i?.split(".").map(Number)??[];if(l<6||l===6&&u<2)throw await s.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${i??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(c){throw await s.quit().catch(()=>{}),c}return this.redisClients.set(t,s),s}async getIsolatedRedisClient(e){let t=(await this.getRedisClient(e)).duplicate();return await t.connect(),t}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(),console.log(`Closed PostgreSQL pool for: ${o}`)}),t=Array.from(this.mysqlPools.entries()).map(async([o,s])=>{await s.end(),console.log(`Closed MySQL pool for: ${o}`)}),r=Array.from(this.mssqlPools.entries()).map(async([o,s])=>{await s.close(),console.log(`Closed SQL Server pool for: ${o}`)});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(()=>{}),console.log(`Closed Redis client for db=${o}`)});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())]}},Re=new vr,Lt=a=>Re.getPgPool(a),It=a=>Re.getMysqlPool(a),Mt=async a=>Re.getMssqlPool(a),Me=()=>Re.getDbType(),qt=()=>Re.getSqliteDb(),Ut=()=>Re.getMongoClient(),Bt=()=>Re.getMongoDbName(),rn=a=>Re.getMongoDb(a),Ft=a=>Re.getRedisClient(a),an=a=>Re.getIsolatedRedisClient(a),nn=()=>Re.getRedisDefaultDb(),jt=a=>typeof a=="string"&&xr.isValid(a),Ht=a=>typeof a=="string"&&xr.isValid(a)?new xr(a):a});var sn={};_t(sn,{checkDatabaseConnection:()=>ri,getDatabaseConnectionDetails:()=>ti});var on,Zs,ei,ti,ri,ln=C(()=>{"use strict";b();He();on={pg:"PostgreSQL",mysql:"MySQL",mssql:"SQL Server",mongodb:"MongoDB",sqlite:"SQLite",redis:"Redis"},Zs=2e3,ei=async a=>{let e;try{return await Promise.race([a,new Promise((t,r)=>{e=setTimeout(()=>r(new Error("Database startup check timed out")),Zs)})])}finally{e&&clearTimeout(e)}},ti=a=>{let e=Me();if(e==="sqlite")return{type:e,name:on[e],destination:"local file"};let t=new URL(a),r={pg:5432,mysql:3306,mssql:1433,mongodb:27017,redis:6379},n=Number.parseInt(t.port,10)||r[e];return{type:e,name:on[e],destination:`${t.hostname}:${n}`}},ri=async a=>{switch(a){case"pg":await ei(Lt().query("SELECT 1"));return;case"mysql":await It().query("SELECT 1");return;case"mssql":await(await Mt()).request().query("SELECT 1");return;case"mongodb":{await(await Ut()).db(Bt()).command({ping:1});return}case"sqlite":qt().prepare("SELECT 1").get();return;case"redis":await(await Ft()).ping()}}});import{HTTPException as cn}from"hono/http-exception";function L(a){return ye.get(a)}function Ke(a,e){if(!ai(a))throw new cn(400,{message:`Key browsing is not supported for database type: "${e}"`});return a}var Or,ye,ai,Le=C(()=>{"use strict";b();Or=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new cn(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()]}},ye=new Or;ai=a=>"scanKeys"in a&&typeof a.scanKeys=="function"});import{HTTPException as qe}from"hono/http-exception";import{DatabaseError as ni}from"pg";function te(a){throw new qe(501,{message:`${a} is not implemented for this database type`})}var de,Ve=C(()=>{"use strict";b();de=class{wrapError(e){if(e instanceof qe)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 ni&&e.code?.startsWith("08")?new qe(503,{message:e.message,cause:e}):new qe(500,{message:e.message,cause:e})}return new qe(500,{message:"Internal server error",cause:e})}resolveKeyColumns(e){return e.primaryKeys?.length?e.primaryKeys:[e.primaryKey]}groupUpdatesByKey(e,t){let r=new Map;for(let n of e.updates){let o=t.map(i=>{let l=n.rowData[i];if(l==null)throw new qe(400,{message:`Primary key "${i}" not found in row data.`});return l}),s=JSON.stringify(o.map(i=>String(i))),c=r.get(s)??{keyValues:o,rowUpdates:[]};c.rowUpdates.push({columnName:n.columnName,value:n.value}),r.set(s,c)}return[...r.values()]}describeKey(e,t){return e.map((r,n)=>`${r} = ${t[n]}`).join(", ")}assertDifferentTableName(e,t){if(e===t)throw new qe(400,{message:`New table name must be different from "${e}"`})}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 qe(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 te("getDatabasesList")}getCurrentDatabase(){return te("getCurrentDatabase")}getDatabaseConnectionInfo(){return te("getDatabaseConnectionInfo")}getTablesList(e){return te("getTablesList")}createTable(e){return te("createTable")}deleteTable(e){return te("deleteTable")}renameTable(e){return te("renameTable")}getTableSchema(e){return te("getTableSchema")}getTableColumns(e){return te("getTableColumns")}addColumn(e){return te("addColumn")}deleteColumn(e){return te("deleteColumn")}alterColumn(e){return te("alterColumn")}renameColumn(e){return te("renameColumn")}addRecord(e){return te("addRecord")}updateRecords(e){return te("updateRecords")}deleteRecords(e){return te("deleteRecords")}forceDeleteRecords(e){return te("forceDeleteRecords")}bulkInsertRecords(e){return te("bulkInsertRecords")}executeQuery(e){return te("executeQuery")}}});var J,Y,V,X,$r,Kt,re,pe,Vt,ze,We=C(()=>{"use strict";b();He();J=a=>Lt(a),Y=a=>It(a),V=a=>Mt(a),X=()=>qt(),$r=()=>Ut(),Kt=()=>Bt(),re=a=>rn(a),pe=a=>Ft(a),Vt=a=>an(a),ze=()=>nn()});var oi,un,mn=C(()=>{"use strict";b();oi=new Set(["admin","config","local"]),un=(a,e)=>{let t=a.filter(r=>!oi.has(r.name)||r.name===e);return!e||t.some(r=>r.name===e)?t:[...t,{name:e,sizeOnDisk:0}]}});function Ue(){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(e){return console.error("Failed to parse DATABASE_URL:",e),{host:"localhost",port:5432}}}var pt=C(()=>{"use strict";b()});function dn(a){if(!a||a.length===0)return{};let e=[];for(let t of a){let r=t.columnName,n=si(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:zt(String(n)),$options:""}});break;case"not like":e.push({[r]:{$not:{$regex:zt(String(n)),$options:""}}});break;case"ilike":e.push({[r]:{$regex:zt(String(n)),$options:"i"}});break;case"not ilike":e.push({[r]:{$not:{$regex:zt(String(n)),$options:"i"}}});break;default:e.push({[r]:n});break}}return e.length?{$and:e}:{}}function Pr(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 kr(a){return Buffer.from(JSON.stringify({offset:a})).toString("base64url")}function pn(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 zt,si,fn=C(()=>{"use strict";b();He();zt=a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),si=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:jt(e)?Ht(e):e}});import{HTTPException as q}from"hono/http-exception";var Lr,et,ii,li,yn,ft,ci,bn,ui,mi,di,tt,Wt,hn=C(()=>{"use strict";b();Ve();We();He();mn();pt();fn();Lr=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=>Lr(e)):Object.fromEntries(Object.entries(a).map(([e,t])=>[e,Lr(t)])):a,et=a=>Lr(a),ii=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",li=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"}},yn=a=>typeof a=="string"&&jt(a),ft=a=>Ht(a),ci=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]}`},bn=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),ui=a=>{let e=a.trim();if(bn.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},mi=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"},di=(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}},tt=a=>{if(a._id&&typeof a._id=="string")return{...a,_id:ft(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"?ft(t):t)}};if(Array.isArray(e.$nin))return{...a,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?ft(t):t)}}}return a},Wt=class extends de{runQuery(){throw new q(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new q(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(et(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 q)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new q(503,{message:e.message,cause:e})}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 re(r)).collection(t),p=dn(l??[]),d=Pr(c??"",i),f=o&&o>0?o:50,y=pn(n),g=Number.isFinite(y)&&y>=0?y:0,E=s==="desc"?Math.max(g-f,0):g,[w,A]=await Promise.all([m.countDocuments(p),m.find(p).sort(d).skip(E).limit(f).toArray()]),N=A.map(D=>et(D)),R=E+f,S=Math.max(E-f,0);return{data:N,meta:{limit:f,total:w,hasNextPage:R<w,hasPreviousPage:E>0,nextCursor:R<w?kr(R):null,prevCursor:E>0?kr(S):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let s=(await(await re(t)).collection(e).find({}).limit(1e4).toArray()).map(i=>et(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 $r()).db().admin().listDatabases()).databases??[];if(!n[0])throw new q(500,{message:"No databases returned from MongoDB"});return un(n,Kt()).map(o=>({name:o.name,size:ci(o.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:Kt()}}async getDatabaseConnectionInfo(){try{let t=(await $r()).db().admin(),r=Ue(),n={};try{n=await t.serverStatus()}catch(o){console.warn("Failed to read MongoDB serverStatus:",o)}return{host:r.host,port:r.port,user:"n/a",database:Kt(),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 re(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 re(t);if((await n.listCollections({name:r}).toArray()).length>0)throw new q(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=ui(l.columnType);if(!bn.has(u))throw new q(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 re(t)).collection(e),o=await n.estimatedDocumentCount();return await n.drop(),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async renameTable(e){try{let{tableName:t,newTableName:r,db:n}=e;this.assertDifferentTableName(t,r);let o=await re(n);if((await o.listCollections({name:t}).toArray()).length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if((await o.listCollections({name:r}).toArray()).length>0)throw new q(409,{message:`Collection "${r}" already exists`});await o.collection(t).rename(r)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){try{let r=await re(t);if((await r.listCollections({name:e}).toArray()).length===0)throw new q(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,y]of Object.entries(d)){let g=mi(y);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 y=l.get(d)??0,g=Array.from(f).filter(w=>w!=="null"),E=f.has("null")||y<s.length;y===s.length&&s.length>0&&!E&&m.push(d),u[d]=g.length===1?{bsonType:E?[g[0],"null"]:g[0]}:{bsonType:E?[...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 re(t)).collection(e).find({}).limit(200).toArray(),s=o.length,c=new Map,i=(l,u)=>{let m=ii(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:li(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 re(c),l=await i.listCollections({name:t}).toArray();if(l.length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if(await i.collection(t).findOne({[r]:{$exists:!0}}))throw new q(409,{message:`Field "${r}" already exists in collection "${t}"`});let m=di(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}},y=[...d.required??[]];!s&&!y.includes(r)&&y.push(r),await i.command({collMod:t,validator:{$jsonSchema:{...d,bsonType:"object",properties:f,...y.length>0?{required:y}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{return{deletedCount:(await(await re(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 re(s),i=await c.listCollections({name:t}).toArray();if(i.length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new q(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 re(o);if((await s.listCollections({name:t}).toArray()).length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new q(400,{message:'Cannot rename the "_id" field'});if(!await s.collection(t).findOne({[r]:{$exists:!0}}))throw new q(404,{message:`Field "${r}" does not exist in collection "${t}"`});if(await s.collection(t).findOne({[n]:{$exists:!0}}))throw new q(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 re(e)).collection(r),c=et(n);if((c._id===""||c._id===null)&&delete c._id,!(await s.insertOne(c)).insertedId)throw new q(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}=t,o=(await re(e)).collection(r),s=0,c=this.resolveKeyColumns(t).map(l=>l||"_id"),i=this.groupUpdatesByKey({...t,primaryKeys:c},c);for(let{keyValues:l,rowUpdates:u}of i){if(u.some(f=>f.columnName==="_id"))throw new q(400,{message:'The "_id" field is immutable and cannot be updated.'});let m={};for(let f of u)m[f.columnName]=f.value;let p={};c.forEach((f,y)=>{let g=l[y];p[f]=f==="_id"&&yn(g)?ft(g):g});let d=await o.updateOne(p,{$set:m});if(d.matchedCount===0)throw new q(404,{message:`Record with ${this.describeKey(c,l)} not found in "${r}"`});s+=d.modifiedCount}return{updatedCount:s}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:n}=e,s=(await re(n)).collection(t),c=r[0]?.columnName??"_id",i=r.map(u=>c==="_id"&&yn(u.value)?ft(u.value):u.value);return{deletedCount:(await s.deleteMany({[c]:{$in:i}})).deletedCount??0,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 q(400,{message:"At least one record is required"});let s=(await re(n)).collection(t),c=r.map(l=>{let u=et(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 q(400,{message:"Query is required"});let r;try{r=JSON.parse(e)}catch{throw new q(400,{message:"Mongo query must be valid JSON"})}if(!r.collection||!r.operation)throw new q(400,{message:"Mongo query must include collection and operation"});let o=(await re(t)).collection(r.collection),s=performance.now(),c=[],i=0,l;switch(r.operation){case"find":{let d=tt(r.filter??{}),f=o.find(d,r.options??{});f.sort(r.sort??Pr("",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 q(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 q(400,{message:"document array is required"});i=(await o.insertMany(d)).insertedCount??0,l="OK";break}case"updateOne":{let d=tt(r.filter??{});if(!r.update)throw new q(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=tt(r.filter??{});if(!r.update)throw new q(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=tt(r.filter??{});i=(await o.deleteOne(d,r.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let d=tt(r.filter??{});i=(await o.deleteMany(d,r.options??{})).deletedCount??0,l="OK";break}case"count":{let d=tt(r.filter??{});i=await o.countDocuments(d),c=[{count:i}],l="OK";break}default:throw new q(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-s,m=c.map(d=>et(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 rt}from"zod";var O,gn,yt,pi,fi,ie,ge=C(()=>{"use strict";b();O=rt.object({db:rt.string("Database name is required")}),gn=["pg","mysql","mssql","mongodb","sqlite","redis"],yt=rt.enum(gn,{message:"Invalid database type"}),pi=O.extend({dbType:yt}),fi=rt.object({dbType:yt}),ie=rt.object({tableName:rt.string("Table name is required")})});import{z as xe}from"zod";var Ce,yi,bi,Tn=C(()=>{"use strict";b();ge();Ce=xe.object({columnName:xe.string("Column name is required"),columnType:xe.string("Column type is required"),defaultValue:xe.string().optional(),isPrimaryKey:xe.boolean().default(!1),isNullable:xe.boolean().default(!1),isUnique:xe.boolean().default(!1),isIdentity:xe.boolean().default(!1),isArray:xe.boolean().default(!1)}),yi=ie,bi=xe.object({db:O.shape.db,tableName:ie.shape.tableName,columnName:Ce.shape.columnName,columnType:Ce.shape.columnType,defaultValue:Ce.shape.defaultValue,isPrimaryKey:Ce.shape.isPrimaryKey,isNullable:Ce.shape.isNullable,isUnique:Ce.shape.isUnique,isIdentity:Ce.shape.isIdentity,isArray:Ce.shape.isArray})});import{z as bt}from"zod";var Ir,En=C(()=>{"use strict";b();Ir=bt.object({tableName:bt.string("Table name is required"),data:bt.record(bt.string("Column name is required"),bt.any())})});import{z as hi}from"zod";var wn,Mr,Sn,qr,Ur=C(()=>{"use strict";b();wn=["gemini","openai","anthropic","grok","openrouter"],Mr=hi.enum(wn),Sn=[{id:"gemini",label:"Google Gemini",models:[{id:"gemini-3-flash-preview",label:"Gemini 3 Flash"},{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro"}]},{id:"openai",label:"OpenAI",models:[{id:"gpt-5.2",label:"GPT-5.2"},{id:"gpt-5-mini",label:"GPT-5 mini"}]},{id:"anthropic",label:"Anthropic",models:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}]},{id:"grok",label:"xAI Grok",models:[{id:"grok-4.6",label:"Grok 4.6"},{id:"grok-4.5",label:"Grok 4.5"}]},{id:"openrouter",label:"OpenRouter",models:[{id:"openai/gpt-5.2",label:"GPT-5.2 via OpenRouter"},{id:"anthropic/claude-sonnet-4.6",label:"Claude Sonnet 4.6 via OpenRouter"}]}],qr=a=>Sn.find(e=>e.id===a)?.models[0]?.id??"gemini-3-flash-preview"});import{z as Ne}from"zod";var Br,le,gi,Ti,Yt=C(()=>{"use strict";b();ge();Br=O.extend({cascade:Ne.string().optional().transform(a=>a==="true")}),le=Ne.object({tableName:Ne.string("Table name is required"),columnName:Ne.string("Column name is required")}),gi=Ne.object({db:O.shape.db,tableName:le.shape.tableName,columnName:le.shape.columnName,cascade:Ne.boolean().optional()}),Ti=Ne.object({message:Ne.string("Message is required"),tableName:Ne.string("Table name is required"),columnName:Ne.string("Column name is required"),deletedCount:Ne.number("Deleted count is required").default(0)})});import{z as ht}from"zod";var at,Ei,wi,Rn=C(()=>{"use strict";b();ge();Yt();at=ht.object({columnType:ht.string("Column type is required"),isNullable:ht.boolean(),defaultValue:ht.string().nullable().optional()}),Ei=le,wi=ht.object({db:O.shape.db,tableName:le.shape.tableName,columnName:le.shape.columnName,columnType:at.shape.columnType,isNullable:at.shape.isNullable,defaultValue:at.shape.defaultValue})});var Cn=C(()=>{"use strict";b()});import{z as nt}from"zod";var Fr,Nn=C(()=>{"use strict";b();Fr=nt.object({tableName:nt.string().min(1,"Table name is required"),records:nt.array(nt.record(nt.string(),nt.any())).min(1,"At least one record is required")})});import{z as ae}from"zod";var Si,Ri,jr,An=C(()=>{"use strict";b();Ur();ge();Si=ae.object({type:ae.string(),content:ae.string().optional()}).passthrough(),Ri=ae.object({provider:Mr.optional().default("gemini"),model:ae.string().min(1).optional(),messages:ae.array(ae.object({id:ae.string(),role:ae.enum(["user","assistant","system","tool","reasoning"]),content:ae.union([ae.string(),ae.null(),ae.array(ae.unknown())]).optional(),parts:ae.array(Si).optional()}).passthrough()),data:ae.object({conversationId:ae.string().optional(),db:O.shape.db,includeSchema:ae.boolean().optional().default(!0)})}),jr=Ri.transform(a=>({...a,model:a.model??qr(a.provider)}))});var Dn=C(()=>{"use strict";b()});import{z as Te}from"zod";var Ci,_n,z,Ni,xn,Ai,Hr=C(()=>{"use strict";b();Ci=["text","boolean","number","enum","json","date","array"],_n=Te.enum(Ci),z={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},Ni=["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"],xn=Te.enum(Ni),Ai=Te.object({columnName:Te.string(),dataType:_n,dataTypeLabel:xn,isNullable:Te.boolean(),columnDefault:Te.string().nullable(),isPrimaryKey:Te.boolean(),isForeignKey:Te.boolean(),referencedTable:Te.string().nullable(),referencedColumn:Te.string().nullable(),enumValues:Te.array(Te.string()).nullable()})});function Gt(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(")?z.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"?z.number:e==="boolean"||e==="bool"?z.boolean:e==="json"||e==="jsonb"?z.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?z.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"?z.text:z.text}function Kr(a){if(!a)return T.text;let e=a.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?T.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?T.bigint:e==="smallint"||e==="int2"?T.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?T.numeric:e==="real"||e==="float4"?T.float:e==="double precision"||e==="float8"||e==="float"?T.double:e==="money"?T.money:e==="boolean"||e==="bool"?T.boolean:e==="text"?T.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?T.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?T.char:e==="json"?T.json:e==="jsonb"?T.jsonb:e==="xml"?T.xml:e==="uuid"?T.uuid:e==="date"?T.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?T.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?T.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?T.timestamptz:e==="interval"||e.startsWith("interval")?T.interval:e==="bytea"?T.bytea:e==="inet"?T.inet:e==="cidr"?T.cidr:e==="macaddr"?T.macaddr:e==="macaddr8"?T.macaddr8:e==="point"?T.point:e==="line"?T.line:e==="polygon"?T.polygon:e.startsWith("array")||e.includes("[]")?T.text:e.startsWith("user-defined")||e==="enum"?T.enum:T.text}function Qt(a,e){let t=a?.toLowerCase().trim()||"",r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?z.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"?z.number:t==="boolean"||t==="bool"?z.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?z.date:t==="json"?z.json:t==="enum"||t==="set"?z.enum:z.text}function Vr(a,e){if(!a)return T.text;let t=a.toLowerCase().trim(),r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="tinyint(1)"?T.boolean:t==="tinyint"?T.tinyint:t==="smallint"?T.smallint:t==="mediumint"?T.mediumint:t==="int"||t==="integer"?T.int:t==="bigint"?T.bigint:t==="decimal"||t==="numeric"?T.numeric:t==="float"||t==="real"?T.float:t==="double"?T.double:t==="bit"?T.bit:t==="boolean"||t==="bool"?T.boolean:t==="char"?T.char:t==="varchar"?T.varchar:t==="tinytext"?T.tinytext:t==="text"?T.text:t==="mediumtext"?T.mediumtext:t==="longtext"?T.longtext:t==="binary"?T.binary:t==="varbinary"?T.varbinary:t==="tinyblob"?T.tinyblob:t==="blob"?T.blob:t==="mediumblob"?T.mediumblob:t==="longblob"?T.longblob:t==="json"?T.json:t==="date"?T.date:t==="time"?T.time:t==="datetime"?T.datetime:t==="timestamp"?T.timestamp:t==="year"?T.year:t==="enum"?T.enum:t==="set"?T.set:T.text}function Jt(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"?z.number:e==="bit"?z.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?z.date:e==="json"?z.json:z.text}function zr(a){if(!a)return T.text;let e=a.toLowerCase().trim();return e==="tinyint"?T.tinyint:e==="smallint"?T.smallint:e==="int"?T.int:e==="bigint"?T.bigint:e==="decimal"||e==="numeric"?T.numeric:e==="float"||e==="real"?T.float:e==="money"||e==="smallmoney"?T.money:e==="bit"?T.boolean:e==="char"?T.char:e==="varchar"?T.varchar:e==="text"?T.text:e==="nchar"?T.char:e==="nvarchar"?T.varchar:e==="ntext"?T.text:e==="binary"?T.binary:e==="varbinary"?T.varbinary:e==="image"?T.blob:e==="uniqueidentifier"?T.uuid:e==="date"?T.date:e==="time"?T.time:e==="datetime"||e==="datetime2"||e==="smalldatetime"?T.datetime:e==="datetimeoffset"?T.timestamptz:e==="json"?T.json:e==="xml"?T.xml:T.text}function Xt(a){let e=a?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?z.boolean:e==="json"?z.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?z.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?z.number:z.text}function Wr(a){let e=a?.toLowerCase().trim()||"";return e==="integer"||e==="int"?T.int:e==="bigint"||e.startsWith("bigint(")?T.bigint:e==="smallint"||e.startsWith("smallint(")?T.smallint:e==="tinyint"||e.startsWith("tinyint(")?T.tinyint:e==="mediumint"||e.startsWith("mediumint(")?T.mediumint:e.includes("int")?T.int:e==="real"||e==="float"||e.startsWith("float(")?T.float:e==="double"||e==="double precision"||e.startsWith("double(")?T.double:e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?T.numeric:e==="boolean"||e==="bool"?T.boolean:e==="text"||e==="clob"?T.text:e==="varchar"||e.startsWith("varchar(")?T.varchar:e==="char"||e.startsWith("char(")?T.char:e==="json"?T.json:e==="date"?T.date:e==="time"?T.time:e==="datetime"?T.datetime:e==="timestamp"?T.timestamp:e==="blob"?T.blob:T.text}var T,vn=C(()=>{"use strict";b();Hr();T={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 ne}from"zod";var On,Yr,$n,Pn,Gr,kn=C(()=>{"use strict";b();On=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],Yr=ne.enum(On),$n=ne.object({columnName:ne.string("Column name is required"),columnType:ne.string("Column type is required"),defaultValue:ne.string().optional(),isPrimaryKey:ne.boolean().default(!1),isNullable:ne.boolean().default(!1),isUnique:ne.boolean().default(!1),isIdentity:ne.boolean().default(!1),isArray:ne.boolean().default(!1)}),Pn=ne.object({columnName:ne.string("Column name is required"),referencedTable:ne.string("Referenced table is required"),referencedColumn:ne.string("Referenced column is required"),onUpdate:Yr.default("NO ACTION"),onDelete:Yr.default("NO ACTION")}),Gr=ne.object({tableName:ne.string("Table name is required"),fields:ne.array($n).min(1,"At least one field is required"),foreignKeys:ne.array(Pn).optional()})});function Di(a,e){return a?Ln[a]?.[e]??!1:!1}var Ln,In=C(()=>{"use strict";b();Ln={pg:{liveMode:!0},mysql:{liveMode:!1},mssql:{liveMode:!1},sqlite:{liveMode:!1},mongodb:{liveMode:!1},redis:{liveMode:!1}}});import{z as ce}from"zod";var Mn,_i,xi,qn=C(()=>{"use strict";b();ge();Mn=ce.object({name:ce.string("Name is required"),size:ce.string("Size is required"),owner:ce.string("Owner is required"),encoding:ce.string("Encoding is required")}),_i=ce.object({databases:ce.array(Mn),dbType:yt}),xi=ce.object({version:ce.string("Version is required"),database:ce.string("Database is required"),user:ce.string("User is required"),host:ce.string("Host is required").nullable(),port:ce.number("Port is required").nullable(),active_connections:ce.coerce.number("Active connections is required"),max_connections:ce.coerce.number("Max connections is required")})});var Un=C(()=>{"use strict";b()});import{z as ot}from"zod";var Zt,Bn=C(()=>{"use strict";b();Zt=ot.object({tableName:ot.string("Table name is required"),primaryKeys:ot.array(ot.object({columnName:ot.string("Column name is required"),value:ot.any()})).min(1,"At least one primary key is required")})});import{z as vi}from"zod";var Qr,Fn=C(()=>{"use strict";b();ge();Qr=O.extend({cascade:vi.string().optional().transform(a=>a==="true")})});import{z as jn}from"zod";var Jr,Hn=C(()=>{"use strict";b();Jr=jn.object({query:jn.string("Query is required")})});import{z as Oi}from"zod";var Kn,Xr,Vn=C(()=>{"use strict";b();ge();Kn=["csv","xlsx","json"],Xr=O.extend({format:Oi.enum(Kn,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as h}from"zod";var er,I,Zr,ea,$i,ta,st,Pi,ki,Li,Ii,Mi,qi,Ui,zn,Bi,ra,Fi,ji,Hi,Ki,Vi,zi,Wi,aa,Yi,Gi,Qi,Ji,Xi,Zi,el,tl,rl,al,nl,ol,sl,il,ll,na,oa,cl,Wn=C(()=>{"use strict";b();er=h.enum(["string","hash","list","set","zset","stream","unknown"]),I=h.object({base64:h.string().max(16*1024*1024).refine(a=>/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/.test(a),"Invalid unpadded base64url value"),utf8:h.string().optional()}),Zr=h.object({db:h.string(),cursor:h.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:h.coerce.number().int().min(1).max(200).default(50),search:h.string().max(512).optional(),exactPattern:h.stringbool().default(!1),type:er.exclude(["unknown"]).optional()}),ea=h.object({key:I,type:er,ttlMs:h.number().int(),memoryBytes:h.number().int().nonnegative().nullable()}),$i=h.object({keys:h.array(ea),nextCursor:h.string().nullable(),hasMore:h.boolean()}),ta=h.object({db:h.string(),cursor:h.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:h.coerce.number().int().min(1).max(500).default(100),full:h.stringbool().default(!1),direction:h.enum(["forward","backward"]).default("forward")}),st=h.object({key:h.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),Pi=h.object({kind:h.literal("string"),value:I,truncated:h.boolean()}),ki=h.object({kind:h.literal("hash"),entries:h.array(h.object({field:I,value:I}))}),Li=h.object({kind:h.literal("list"),entries:h.array(h.object({index:h.number().int(),value:I}))}),Ii=h.object({kind:h.literal("set"),members:h.array(I)}),Mi=h.object({kind:h.literal("zset"),entries:h.array(h.object({member:I,score:h.union([h.number(),h.literal("inf"),h.literal("-inf")])}))}),qi=h.object({kind:h.literal("stream"),entries:h.array(h.object({id:h.string(),fields:h.array(h.object({field:I,value:I}))}))}),Ui=h.object({kind:h.literal("unknown")}),zn=h.discriminatedUnion("kind",[Pi,ki,Li,Ii,Mi,qi,Ui]),Bi=ea.extend({length:h.number().int().nonnegative().nullable(),revision:h.string(),value:zn,nextCursor:h.string().nullable(),hasMore:h.boolean()}),ra=h.object({db:h.string(),offset:h.coerce.number().int().nonnegative().default(0),limit:h.coerce.number().int().min(1).max(1024*1024).default(1024*1024),expectedRevision:h.string().optional()}),Fi=h.object({chunk:I,length:h.number().int().nonnegative(),nextOffset:h.number().int().nonnegative().nullable(),hasMore:h.boolean()}),ji=h.object({kind:h.literal("string"),value:I}),Hi=h.object({kind:h.literal("hash"),entries:h.array(h.object({field:I,value:I})).min(1)}),Ki=h.object({kind:h.literal("list"),entries:h.array(I).min(1)}),Vi=h.object({kind:h.literal("set"),members:h.array(I).min(1)}),zi=h.object({kind:h.literal("zset"),entries:h.array(h.object({member:I,score:h.number()})).min(1)}),Wi=h.object({kind:h.literal("stream"),id:h.string().default("*"),fields:h.array(h.object({field:I,value:I})).min(1)}),aa=h.object({key:I,type:er.exclude(["unknown"]),value:h.discriminatedUnion("kind",[ji,Hi,Ki,Vi,zi,Wi]),ttlMs:h.number().int().positive().nullable().default(null)}),Yi=h.object({key:I,revision:h.string().nullable(),deleted:h.boolean()}),Gi=h.object({action:h.literal("rename"),newKey:I}),Qi=h.object({action:h.literal("setTtl"),ttlMs:h.number().int().positive().nullable()}),Ji=h.object({action:h.literal("setString"),value:I}),Xi=h.object({action:h.literal("upsertHash"),field:I,value:I}),Zi=h.object({action:h.literal("deleteHash"),field:I}),el=h.object({action:h.literal("pushList"),side:h.enum(["left","right"]),value:I}),tl=h.object({action:h.literal("setList"),index:h.number().int(),value:I}),rl=h.object({action:h.literal("deleteList"),index:h.number().int()}),al=h.object({action:h.literal("addSet"),member:I}),nl=h.object({action:h.literal("removeSet"),member:I}),ol=h.object({action:h.literal("upsertZset"),member:I,score:h.number()}),sl=h.object({action:h.literal("removeZset"),member:I}),il=h.object({action:h.literal("appendStream"),id:h.string().default("*"),fields:h.array(h.object({field:I,value:I})).min(1)}),ll=h.object({action:h.literal("deleteStream"),id:h.string()}),na=h.object({expectedRevision:h.string(),force:h.boolean().default(!1),operation:h.discriminatedUnion("action",[Gi,Qi,Ji,Xi,Zi,el,tl,rl,al,nl,ol,sl,il,ll])}),oa=h.object({db:h.string(),expectedRevision:h.string(),force:h.stringbool().default(!1)}),cl=h.object({deleted:h.boolean()})});var Yn=C(()=>{"use strict";b()});import{z as sa}from"zod";var tr,ul,ml,Gn=C(()=>{"use strict";b();ge();Yt();tr=sa.object({newColumnName:sa.string("New column name is required")}),ul=le,ml=sa.object({db:O.shape.db,tableName:le.shape.tableName,columnName:le.shape.columnName,newColumnName:tr.shape.newColumnName})});import{z as rr}from"zod";var gt,dl,pl,Qn=C(()=>{"use strict";b();ge();gt=rr.object({newTableName:rr.string("New table name is required").trim().min(1,"New table name is required"),schemaName:rr.string().trim().min(1).optional()}),dl=ie,pl=rr.object({db:O.shape.db,tableName:ie.shape.tableName,newTableName:gt.shape.newTableName,schemaName:gt.shape.schemaName})});import{z as W}from"zod";var fl,Tt,yl,Jn,bl,ia,Xn=C(()=>{"use strict";b();ge();fl=W.object({columnName:W.string(),operator:W.string(),value:W.string()}),Tt=["asc","desc"],yl=W.object({columnName:W.string(),direction:W.enum(Tt)}),Jn=W.object({limit:W.number(),total:W.number(),hasNextPage:W.boolean(),hasPreviousPage:W.boolean(),nextCursor:W.string().nullable(),prevCursor:W.string().nullable()}),bl=W.object({data:W.array(W.record(W.string(),W.unknown())),meta:Jn}),ia=W.object({db:O.shape.db,cursor:W.string().optional(),limit:W.string().optional().default("50").transform(Number),direction:W.enum(Tt).optional().default(Tt[0]),sort:W.string().optional().transform(a=>{if(!a)return"";try{let e=JSON.parse(a);return Array.isArray(e)?e:a}catch{return a}}),order:W.enum(Tt).optional(),filters:W.string().optional().transform(a=>{if(!a)return[];try{return JSON.parse(a)}catch{return[]}})})});import{z as ar}from"zod";var hl,Zn=C(()=>{"use strict";b();hl=ar.object({tableName:ar.string("Table name is required"),schemaName:ar.string().optional(),rowCount:ar.coerce.number("Row count is required")})});import{z as eo}from"zod";var gl,to=C(()=>{"use strict";b();gl=eo.object({schema:eo.string()})});import{z as Ee}from"zod";var la,ro=C(()=>{"use strict";b();la=Ee.object({tableName:Ee.string("Table name is required"),primaryKey:Ee.string("Primary key is required").default("id"),primaryKeys:Ee.array(Ee.string().min(1)).min(1).optional(),updates:Ee.array(Ee.object({rowData:Ee.record(Ee.string("Column name is required"),Ee.any()),columnName:Ee.string("Column name is required"),value:Ee.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var ao={};_t(ao,{AI_PROVIDERS:()=>wn,AI_PROVIDER_OPTIONS:()=>Sn,DATABASE_CAPABILITIES:()=>Ln,DATABASE_TYPES:()=>gn,DataTypes:()=>z,FOREIGN_KEY_ACTIONS:()=>On,FORMAT_TYPES:()=>Kn,StandardizedDataType:()=>T,addColumnParamSchema:()=>yi,addColumnParamsSchema:()=>bi,addColumnSchema:()=>Ce,addRecordSchema:()=>Ir,aiProviderSchema:()=>Mr,alterColumnParamSchema:()=>Ei,alterColumnParamsSchema:()=>wi,alterColumnSchema:()=>at,bulkInsertRecordsSchema:()=>Fr,chatSchema:()=>jr,columnInfoSchema:()=>Ai,connectionInfoSchema:()=>xi,createKeySchema:()=>aa,createTableSchema:()=>Gr,currentDatabaseSchema:()=>pi,dataTypesSchema:()=>_n,databaseInfoSchema:()=>Mn,databaseListSchema:()=>_i,databaseSchema:()=>O,databaseTypeParamSchema:()=>fi,databaseTypeSchema:()=>yt,deleteColumnParamSchema:()=>le,deleteColumnParamsSchema:()=>gi,deleteColumnQuerySchema:()=>Br,deleteColumnSuccessResponseSchema:()=>Ti,deleteKeyQuerySchema:()=>oa,deleteKeyResultSchema:()=>cl,deleteRecordSchema:()=>Zt,deleteTableQuerySchema:()=>Qr,encodedRedisValueSchema:()=>I,executeQuerySchema:()=>Jr,exportTableSchema:()=>Xr,fieldDataSchema:()=>$n,filterSchema:()=>fl,foreignKeyActionSchema:()=>Yr,foreignKeyDataSchema:()=>Pn,getDefaultAiModel:()=>qr,hasDatabaseCapability:()=>Di,keyActionSchema:()=>na,keyDetailsQuerySchema:()=>ta,keyDetailsResultSchema:()=>Bi,keyParamSchema:()=>st,keyRawQuerySchema:()=>ra,keyRawResultSchema:()=>Fi,keyScanQuerySchema:()=>Zr,keyScanResultSchema:()=>$i,keyWriteResultSchema:()=>Yi,mapMssqlToDataType:()=>Jt,mapMysqlToDataType:()=>Qt,mapPostgresToDataType:()=>Gt,mapSqliteToDataType:()=>Xt,redisKeySummarySchema:()=>ea,redisKeyTypeSchema:()=>er,redisKeyValueSchema:()=>zn,renameColumnParamSchema:()=>ul,renameColumnParamsSchema:()=>ml,renameColumnSchema:()=>tr,renameTableParamSchema:()=>dl,renameTableParamsSchema:()=>pl,renameTableSchema:()=>gt,sortDirections:()=>Tt,sortSchema:()=>yl,standardizeDataTypeLabel:()=>Kr,standardizeMssqlDataTypeLabel:()=>zr,standardizeMysqlDataTypeLabel:()=>Vr,standardizeSqliteDataTypeLabel:()=>Wr,standardizedDataTypeSchema:()=>xn,tableDataMetaSchema:()=>Jn,tableDataQuerySchema:()=>ia,tableDataResultSchema:()=>bl,tableInfoSchema:()=>hl,tableNameSchema:()=>ie,tableSchemaResultSchema:()=>gl,updateRecordsSchema:()=>la});var Ae=C(()=>{"use strict";b();Tn();En();Ur();Rn();Cn();Nn();An();Dn();vn();Hr();kn();ge();In();qn();Un();Yt();Bn();Fn();Hn();Vn();Wn();Yn();Gn();Qn();Xn();Zn();to();ro()});function ca(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 ua(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 ma(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 da(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 no(a,e={}){let t=ma(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=da(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 oo=C(()=>{"use strict";b()});import{HTTPException as B}from"hono/http-exception";var Tl,El,nr,so=C(()=>{"use strict";b();Ae();Ve();We();pt();oo();Tl=547,El=3726,nr=class extends de{async runQuery(e,t,r){let o=(await V(e)).request();return r.forEach((c,i)=>{o.input(`p${i}`,c)}),(await o.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return Jt(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}=ca(r,0),m=ua(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],y=`SELECT COUNT(*) as total FROM [${t}] ${i}`;return{sql:d,values:f,countSql:y,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 V(r),u=c?this.decodeOffsetCursor(c):0,{clause:m,values:p,nextIdx:d}=ca(i,0),f=ua(o,s)||"ORDER BY (SELECT NULL)",y=l.request();p.forEach((S,D)=>{y.input(`p${D}`,S)});let g=await y.query(`SELECT COUNT(*) as total FROM [${t}] ${m}`),E=Number(g.recordset[0]?.total??0),w=l.request();p.forEach((S,D)=>{w.input(`p${D}`,S)}),w.input(`p${d}`,u),w.input(`p${d+1}`,n+1);let N=(await w.query(`SELECT * FROM [${t}] ${m} ${f} OFFSET @p${d} ROWS FETCH NEXT @p${d+1} ROWS ONLY`)).recordset,R=N.length>n;return R&&(N=N.slice(0,n)),{data:N,meta:{limit:n,total:E,hasNextPage:R,hasPreviousPage:u>0,nextCursor:R?this.makeCursor(u+n):null,prevCursor:u>0?this.makeCursor(Math.max(0,u-n)):null}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=await(await V()).request().query(`
17
+ SELECT
18
+ d.name AS name,
19
+ CAST(ROUND(CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)), 2) AS VARCHAR(20)) + ' MB' AS size,
20
+ SUSER_SNAME(d.owner_sid) AS owner,
21
+ d.collation_name AS encoding
22
+ FROM sys.databases d
23
+ JOIN sys.master_files mf ON d.database_id = mf.database_id
24
+ WHERE (d.database_id > 4 OR d.name = DB_NAME())
25
+ GROUP BY d.name, d.owner_sid, d.collation_name
26
+ ORDER BY d.name
27
+ `);if(!t.recordset[0])throw new B(500,{message:"No databases returned from server"});return t.recordset}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let t=await(await V()).request().query("SELECT DB_NAME() AS db");if(!t.recordset[0])throw new B(500,{message:"No current database returned from server"});return t.recordset[0]}async getDatabaseConnectionInfo(){let t=await(await V()).request().query(`
15
28
  SELECT
16
29
  @@VERSION AS version,
17
30
  DB_NAME() AS database_name,
@@ -20,23 +33,26 @@ var Zo=Object.defineProperty;var N=(n,e)=>()=>(n&&(e=n(n=0)),e);var Nt=(n,e)=>{f
20
33
  (SELECT local_tcp_port FROM sys.dm_exec_connections WHERE session_id = @@SPID) AS port,
21
34
  @@MAX_CONNECTIONS AS max_connections,
22
35
  (SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1) AS active_connections
23
- `);if(!t.recordset[0])throw new U(500,{message:"No connection information returned from server"});let r=t.recordset[0],a=Me();return{host:String(r.host||a.host),port:Number(r.port||a.port),user:String(r.user),database:String(r.database_name??""),version:String(r.version),active_connections:Number(r.active_connections??0),max_connections:Number(r.max_connections)}}async getTablesList(e){let t=await z(e),r=await t.request().query(`
36
+ `);if(!t.recordset[0])throw new B(500,{message:"No connection information returned from server"});let r=t.recordset[0],n=Ue();return{host:String(r.host||n.host),port:Number(r.port||n.port),user:String(r.user),database:String(r.database_name??""),version:String(r.version),active_connections:Number(r.active_connections??0),max_connections:Number(r.max_connections)}}async getTablesList(e){let t=await V(e),r=await t.request().query(`
24
37
  SELECT table_name AS tableName
25
38
  FROM information_schema.tables
26
39
  WHERE table_catalog = DB_NAME()
27
40
  AND table_type = 'BASE TABLE'
28
41
  AND table_schema = 'dbo'
29
42
  ORDER BY table_name
30
- `);return!r.recordset||r.recordset.length===0?[]:Promise.all(r.recordset.map(async a=>{let o=await t.request().query(`SELECT COUNT(*) as count FROM [${a.tableName}]`);return{tableName:a.tableName,rowCount:o.recordset[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=await z(t),c=a.map(m=>{let d=ln(m.columnType,m.isArray??!1),p=`[${m.columnName}] ${d}`;if(!m.isNullable&&!m.isPrimaryKey&&(p+=" NOT NULL"),m.defaultValue&&!d.includes("IDENTITY")){let f=cn(m.defaultValue,d);f!==null&&(p+=` DEFAULT ${f}`)}return p}),i=[],l=a.filter(m=>m.isPrimaryKey);l.length>0&&i.push(`PRIMARY KEY (${l.map(m=>`[${m.columnName}]`).join(", ")})`);for(let m of a)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}] (
43
+ `);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 V(t),c=n.map(m=>{let p=ma(m.columnType,m.isArray??!1),d=`[${m.columnName}] ${p}`;if(!m.isNullable&&!m.isPrimaryKey&&(d+=" NOT NULL"),m.defaultValue&&!p.includes("IDENTITY")){let f=da(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}] (
31
44
  ${[...c,...i,...u].join(`,
32
45
  `)}
33
- )`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=await z(r),s=await o.request().input("tableName",t).query(`
46
+ )`)}async deleteTable(e){let{tableName:t,db:r,cascade:n}=e,o=await V(r),s=await o.request().input("tableName",t).query(`
34
47
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
35
48
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
36
- `);if(Number(s.recordset[0]?.cnt??0)===0)throw new U(404,{message:`Table "${t}" does not exist`});let c=await this.getTableRowCount(t,r);if(!a){let i=await this.getRelatedRecordsForTable(t,r);if(i.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:i}}try{if(a){let i=await this.getForeignKeyReferences(t,r);for(let l of i)await o.request().query(`ALTER TABLE [${l.referencingTable}] DROP CONSTRAINT [${l.constraintName}]`)}return await o.request().query(`DROP TABLE [${t}]`),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(i){if(i.number===Zi)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw i instanceof U?i:new U(500,{message:`Failed to delete table "${t}"`})}}async getTableSchema({tableName:e,db:t}){let r=await z(t),a=await r.request().input("tableName",e).query(`
49
+ `);if(Number(s.recordset[0]?.cnt??0)===0)throw new B(404,{message:`Table "${t}" does not exist`});let c=await this.getTableRowCount(t,r);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 this.getForeignKeyReferences(t,r);for(let l of i)await o.request().query(`ALTER TABLE [${l.referencingTable}] DROP CONSTRAINT [${l.constraintName}]`)}return await o.request().query(`DROP TABLE [${t}]`),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(i){if(i.number===El)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw i instanceof B?i:new B(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,db:n}=e;this.assertDifferentTableName(t,r);let o=await V(n);await this.assertTableExists(o,t);let s=await o.request().input("tableName",r).query(`
50
+ SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
51
+ WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
52
+ `);if(Number(s.recordset[0]?.cnt??0)>0)throw new B(409,{message:`Table "${r}" already exists`});await o.request().input("oldName",t).input("newName",r).query("EXEC sp_rename @oldName, @newName")}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=await V(t),n=await r.request().input("tableName",e).query(`
37
53
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
38
54
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
39
- `);if(Number(a.recordset[0]?.cnt??0)===0)throw new U(404,{message:`Table "${e}" does not exist`});let o=await r.request().input("tableName",e).query(`
55
+ `);if(Number(n.recordset[0]?.cnt??0)===0)throw new B(404,{message:`Table "${e}" does not exist`});let o=await r.request().input("tableName",e).query(`
40
56
  SELECT
41
57
  c.COLUMN_NAME,
42
58
  c.DATA_TYPE,
@@ -72,10 +88,10 @@ var Zo=Object.defineProperty;var N=(n,e)=>()=>(n&&(e=n(n=0)),e);var Nt=(n,e)=>{f
72
88
  AND c.TABLE_NAME = @tableName
73
89
  AND c.TABLE_SCHEMA = 'dbo'
74
90
  ORDER BY c.ORDINAL_POSITION
75
- `);if(!o.recordset||o.recordset.length===0)throw new U(500,{message:`Failed to retrieve schema for table "${e}"`});let s=o.recordset.map(c=>{let i=` [${c.COLUMN_NAME}] ${c.DATA_TYPE}`;return c.CHARACTER_MAXIMUM_LENGTH?i+=c.CHARACTER_MAXIMUM_LENGTH===-1?"(MAX)":`(${c.CHARACTER_MAXIMUM_LENGTH})`:c.NUMERIC_PRECISION!==null&&c.NUMERIC_SCALE!==null?i+=`(${c.NUMERIC_PRECISION},${c.NUMERIC_SCALE})`:c.NUMERIC_PRECISION!==null&&(i+=`(${c.NUMERIC_PRECISION})`),i+=c.IS_NULLABLE==="YES"?" NULL":" NOT NULL",c.COLUMN_DEFAULT&&(i+=` DEFAULT ${c.COLUMN_DEFAULT}`),i});return`CREATE TABLE [${e}] (
91
+ `);if(!o.recordset||o.recordset.length===0)throw new B(500,{message:`Failed to retrieve schema for table "${e}"`});let s=o.recordset.map(c=>{let i=` [${c.COLUMN_NAME}] ${c.DATA_TYPE}`;return c.CHARACTER_MAXIMUM_LENGTH?i+=c.CHARACTER_MAXIMUM_LENGTH===-1?"(MAX)":`(${c.CHARACTER_MAXIMUM_LENGTH})`:c.NUMERIC_PRECISION!==null&&c.NUMERIC_SCALE!==null?i+=`(${c.NUMERIC_PRECISION},${c.NUMERIC_SCALE})`:c.NUMERIC_PRECISION!==null&&(i+=`(${c.NUMERIC_PRECISION})`),i+=c.IS_NULLABLE==="YES"?" NULL":" NOT NULL",c.COLUMN_DEFAULT&&(i+=` DEFAULT ${c.COLUMN_DEFAULT}`),i});return`CREATE TABLE [${e}] (
76
92
  ${s.join(`,
77
93
  `)}
78
- )`}async getTableColumns({tableName:e,db:t}){let r=await z(t),a=await r.request().input("tableName",e).query(`
94
+ )`}async getTableColumns({tableName:e,db:t}){let r=await V(t),n=await r.request().input("tableName",e).query(`
79
95
  SELECT
80
96
  c.COLUMN_NAME AS columnName,
81
97
  c.DATA_TYPE AS dataType,
@@ -113,25 +129,25 @@ ${s.join(`,
113
129
  AND c.TABLE_NAME = @tableName
114
130
  AND c.TABLE_SCHEMA = 'dbo'
115
131
  ORDER BY c.ORDINAL_POSITION
116
- `);if(!a.recordset||a.recordset.length===0)throw new U(404,{message:`Table "${e}" does not exist`});let o=await r.request().input("tableName",e).query(`
132
+ `);if(!n.recordset||n.recordset.length===0)throw new B(404,{message:`Table "${e}" does not exist`});let o=await r.request().input("tableName",e).query(`
117
133
  SELECT cc.COLUMN_NAME AS columnName, chk.CHECK_CLAUSE AS checkClause
118
134
  FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS chk
119
135
  JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cc
120
136
  ON chk.CONSTRAINT_NAME = cc.CONSTRAINT_NAME AND cc.TABLE_SCHEMA = 'dbo'
121
137
  WHERE cc.TABLE_NAME = @tableName AND cc.TABLE_CATALOG = DB_NAME()
122
- `),s=new Map;for(let c of o.recordset){let i=this.parseCheckConstraintValues(c.checkClause);i&&s.set(c.columnName,i)}return a.recordset.map(c=>{let i=s.get(c.columnName)??null;return{columnName:c.columnName,dataType:i?"enum":Wt(c.dataType),dataTypeLabel:i?"enum":jr(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:a,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,db:u}=e,m=await z(u);await this.assertTableExists(m,t);let d=await m.request().input("tableName",t).input("columnName",r).query(`
138
+ `),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":Jt(c.dataType),dataTypeLabel:i?"enum":zr(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 V(u);await this.assertTableExists(m,t);let p=await m.request().input("tableName",t).input("columnName",r).query(`
123
139
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
124
140
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
125
- `);if(Number(d.recordset[0]?.cnt??0)>0)throw new U(409,{message:`Column "${r}" already exists in table "${t}"`});let p=za({columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l},{includePrimaryKey:!0,includeUnique:!0});await m.request().query(`ALTER TABLE [${t}] ADD ${p}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:a}=e,o=await z(a);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:a,isNullable:o,defaultValue:s,db:c}=e,i=await z(c);await this.assertTableExists(i,t),await this.assertColumnExists(i,t,r);let u=(await i.request().input("tableName",t).input("columnName",r).query(`
141
+ `);if(Number(p.recordset[0]?.cnt??0)>0)throw new B(409,{message:`Column "${r}" already exists in table "${t}"`});let d=no({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 V(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 V(c);await this.assertTableExists(i,t),await this.assertColumnExists(i,t,r);let u=(await i.request().input("tableName",t).input("columnName",r).query(`
126
142
  SELECT dc.name AS constraint_name
127
143
  FROM sys.default_constraints dc
128
144
  JOIN sys.columns c
129
145
  ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
130
146
  WHERE OBJECT_NAME(dc.parent_object_id) = @tableName AND c.name = @columnName
131
- `)).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}] ${a} ${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:a,db:o}=e,s=await z(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let c=await s.request().input("tableName",t).input("columnName",a).query(`
147
+ `)).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 V(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let c=await s.request().input("tableName",t).input("columnName",n).query(`
132
148
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
133
149
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
134
- `);if(Number(c.recordset[0]?.cnt??0)>0)throw new U(409,{message:`Column "${a}" already exists in table "${t}"`});await s.request().query(`EXEC sp_rename '${t}.${r}', '${a}', 'COLUMN'`)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=await z(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(y=>y.name)),l=Object.keys(a).filter(y=>!i.has(y)),u=l.map(y=>{let h=a[y];return s.has(y)&&typeof h=="string"?h==="true"?1:0:h}),m=l.map(y=>`[${y}]`).join(", "),d=l.map((y,h)=>`@param${h}`).join(", "),p=o.request();l.forEach((y,h)=>{p.input(`param${h}`,u[h])});let f=await p.query(`INSERT INTO [${r}] (${m}) VALUES (${d})`);if(f.rowsAffected[0]===0)throw new U(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:f.rowsAffected[0]??0}}async updateRecords({params:e,db:t}){let{tableName:r,updates:a,primaryKey:o}=e,s=await z(t),c=await this.getBooleanColumnSet(r,t),i=new Map;for(let u of a){let m=u.rowData[o];if(m==null)throw new U(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,d]of i.entries()){let p=l.request(),f=d.map((h,w)=>`[${h.columnName}] = @value${w}`);d.forEach((h,w)=>{let E=h.value;E!==null&&typeof E=="object"&&(E=JSON.stringify(E)),c.has(h.columnName)&&typeof E=="string"&&(E=E==="true"?1:0),p.input(`value${w}`,E)}),p.input("pkValue",m);let y=await p.query(`UPDATE [${r}] SET ${f.join(", ")} WHERE [${o}] = @pkValue`);if(y.rowsAffected[0]===0)throw new U(404,{message:`Record with ${o} = ${m} not found in table "${r}"`});u+=y.rowsAffected[0]??0}return await l.commit(),{updatedCount:u}}catch(u){throw await l.rollback(),u instanceof U?u:new U(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=await z(r),o=t[0]?.columnName;if(!o)throw new U(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=a.transaction();await c.begin();try{let i=c.request();s.forEach((m,d)=>{i.input(`pk${d}`,m)});let l=s.map((m,d)=>`@pk${d}`).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===Xi)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw i instanceof U?i:new U(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=await z(r),o=t[0]?.columnName;if(!o)throw new U(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=a.transaction();await c.begin();try{let i=await this.getForeignKeyReferences(e,r),l=0,u=new Set,m=new Set,d=async(h,w,E,A)=>{let C=`${h}.${w}`;if(A.has(C))return;A.add(C);let R=await this.getForeignKeyReferences(h,r);for(let v of R){let O=c.request();E.forEach((Q,ae)=>{O.input(`val${ae}`,Q)});let k=E.map((Q,ae)=>`@val${ae}`).join(", "),H=(await O.query(`SELECT [${v.referencedColumn}] FROM [${h}] WHERE [${w}] IN (${k})`)).recordset.map(Q=>Q[v.referencedColumn]);H.length>0&&await d(v.referencingTable,v.referencingColumn,H,A)}let S=c.request();E.forEach((v,O)=>{S.input(`delVal${O}`,v)});let D=E.map((v,O)=>`@delVal${O}`).join(", "),x=await S.query(`DELETE FROM [${h}] WHERE [${w}] IN (${D})`);l+=x.rowsAffected[0]??0,u.add(h)};for(let h of i)u.has(h.referencingTable)||await d(h.referencingTable,h.referencingColumn,s,m);let p=c.request();s.forEach((h,w)=>{p.input(`mainPk${w}`,h)});let f=s.map((h,w)=>`@mainPk${w}`).join(", "),y=await p.query(`DELETE FROM [${e}] WHERE [${o}] IN (${f})`);return await c.commit(),{deletedCount:(y.rowsAffected[0]??0)+l}}catch(i){throw await c.rollback(),i instanceof U?i:new U(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new U(400,{message:"At least one record is required"});let o=(await z(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(),d=s.map(f=>{let y=u[f];return i.has(f)&&typeof y=="string"?y==="true"?1:0:y}),p=s.map((f,y)=>`@p${l}_${y}`).join(", ");s.forEach((f,y)=>{m.input(`p${l}_${y}`,d[y])});try{await m.query(`INSERT INTO [${e}] (${c}) VALUES (${p})`)}catch(f){throw new U(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 U?s:new U(500,{message:`Failed to bulk insert records into "${e}"`})}}async executeQuery({query:e,db:t}){let r=await z(t);if(!e?.trim())throw new U(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.request().query(a),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 z(t)).request().input("tableName",e).query(`
150
+ `);if(Number(c.recordset[0]?.cnt??0)>0)throw new B(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 V(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(y=>y.name)),l=Object.keys(n).filter(y=>!i.has(y)),u=l.map(y=>{let g=n[y];return s.has(y)&&typeof g=="string"?g==="true"?1:0:g}),m=l.map(y=>`[${y}]`).join(", "),p=l.map((y,g)=>`@param${g}`).join(", "),d=o.request();l.forEach((y,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 B(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:f.rowsAffected[0]??0}}async updateRecords({params:e,db:t}){let{tableName:r}=e,n=await V(t),o=await this.getBooleanColumnSet(r,t),s=this.resolveKeyColumns(e),c=this.groupUpdatesByKey(e,s),i=n.transaction();await i.begin();try{let l=0;for(let{keyValues:u,rowUpdates:m}of c){let p=i.request(),d=m.map((g,E)=>`[${g.columnName}] = @value${E}`);m.forEach((g,E)=>{let w=g.value;w!==null&&typeof w=="object"&&(w=JSON.stringify(w)),o.has(g.columnName)&&typeof w=="string"&&(w=w==="true"?1:0),p.input(`value${E}`,w)}),u.forEach((g,E)=>{p.input(`pkValue${E}`,g)});let f=s.map((g,E)=>`[${g}] = @pkValue${E}`),y=await p.query(`UPDATE [${r}] SET ${d.join(", ")} WHERE ${f.join(" AND ")}`);if(y.rowsAffected[0]===0)throw new B(404,{message:`Record with ${this.describeKey(s,u)} not found in table "${r}"`});l+=y.rowsAffected[0]??0}return await i.commit(),{updatedCount:l}}catch(l){throw await i.rollback(),l instanceof B?l:new B(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=await V(r),o=t[0]?.columnName;if(!o)throw new B(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===Tl)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw i instanceof B?i:new B(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=await V(r),o=t[0]?.columnName;if(!o)throw new B(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,E,w,A)=>{let N=`${g}.${E}`;if(A.has(N))return;A.add(N);let R=await this.getForeignKeyReferences(g,r);for(let x of R){let $=c.request();w.forEach((Q,oe)=>{$.input(`val${oe}`,Q)});let P=w.map((Q,oe)=>`@val${oe}`).join(", "),H=(await $.query(`SELECT [${x.referencedColumn}] FROM [${g}] WHERE [${E}] IN (${P})`)).recordset.map(Q=>Q[x.referencedColumn]);H.length>0&&await p(x.referencingTable,x.referencingColumn,H,A)}let S=c.request();w.forEach((x,$)=>{S.input(`delVal${$}`,x)});let D=w.map((x,$)=>`@delVal${$}`).join(", "),v=await S.query(`DELETE FROM [${g}] WHERE [${E}] IN (${D})`);l+=v.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,E)=>{d.input(`mainPk${E}`,g)});let f=s.map((g,E)=>`@mainPk${E}`).join(", "),y=await d.query(`DELETE FROM [${e}] WHERE [${o}] IN (${f})`);return await c.commit(),{deletedCount:(y.rowsAffected[0]??0)+l}}catch(i){throw await c.rollback(),i instanceof B?i:new B(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new B(400,{message:"At least one record is required"});let o=(await V(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 y=u[f];return i.has(f)&&typeof y=="string"?y==="true"?1:0:y}),d=s.map((f,y)=>`@p${l}_${y}`).join(", ");s.forEach((f,y)=>{m.input(`p${l}_${y}`,p[y])});try{await m.query(`INSERT INTO [${e}] (${c}) VALUES (${d})`)}catch(f){throw new B(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 B?s:new B(500,{message:`Failed to bulk insert records into "${e}"`})}}async executeQuery({query:e,db:t}){let r=await V(t);if(!e?.trim())throw new B(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 V(t)).request().input("tableName",e).query(`
135
151
  SELECT
136
152
  fk.name AS constraint_name,
137
153
  OBJECT_NAME(fk.parent_object_id) AS referencing_table,
@@ -141,23 +157,24 @@ ${s.join(`,
141
157
  FROM sys.foreign_keys fk
142
158
  INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
143
159
  WHERE OBJECT_NAME(fk.referenced_object_id) = @tableName
144
- `)).recordset.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 a=await z(t),o=[];for(let s of r){let c=await a.request().query(`SELECT TOP 100 * FROM [${s.referencingTable}]`);c.recordset.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:c.recordset})}return o}async getRelatedRecords(e,t,r){let a=await this.getForeignKeyReferences(e,r);if(a.length===0)return[];let o=await z(r),s=t.map(l=>l.value),c=[],i=new Map;for(let l of a){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(y=>y.columnName===u.referencedColumn))continue;let d=o.request();s.forEach((y,h)=>{d.input(`pk${h}`,y)});let p=s.map((y,h)=>`@pk${h}`).join(", "),f=await d.query(`SELECT TOP 100 * FROM [${u.referencingTable}] WHERE [${u.referencingColumn}] IN (${p})`);f.recordset.length>0&&c.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:f.recordset})}return c}async getTableRowCount(e,t){let a=await(await z(t)).request().query(`SELECT COUNT(*) as count FROM [${e}]`);return Number(a.recordset[0]?.count??0)}async getBooleanColumnSet(e,t){let r=await this.getTableColumns({tableName:e,db:t});return new Set(r.filter(a=>a.dataTypeLabel==="boolean").map(a=>a.columnName))}async assertTableExists(e,t){let r=await e.request().input("tableName",t).query(`
160
+ `)).recordset.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=await V(t),o=[];for(let s of r){let c=await n.request().query(`SELECT TOP 100 * FROM [${s.referencingTable}]`);c.recordset.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:c.recordset})}return o}async getRelatedRecords(e,t,r){let n=await this.getForeignKeyReferences(e,r);if(n.length===0)return[];let o=await V(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(y=>y.columnName===u.referencedColumn))continue;let p=o.request();s.forEach((y,g)=>{p.input(`pk${g}`,y)});let d=s.map((y,g)=>`@pk${g}`).join(", "),f=await p.query(`SELECT TOP 100 * FROM [${u.referencingTable}] WHERE [${u.referencingColumn}] IN (${d})`);f.recordset.length>0&&c.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:f.recordset})}return c}async getTableRowCount(e,t){let n=await(await V(t)).request().query(`SELECT COUNT(*) as count FROM [${e}]`);return Number(n.recordset[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.request().input("tableName",t).query(`
145
161
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
146
162
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
147
- `);if(Number(r.recordset[0]?.cnt??0)===0)throw new U(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let a=await e.request().input("tableName",t).input("columnName",r).query(`
163
+ `);if(Number(r.recordset[0]?.cnt??0)===0)throw new B(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let n=await e.request().input("tableName",t).input("columnName",r).query(`
148
164
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
149
165
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
150
- `);if(Number(a.recordset[0]?.cnt??0)===0)throw new U(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 un(n){if(n.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=`\`${r.columnName}\``;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":case"ilike":e.push(`${a} LIKE ?`),t.push(r.value);break;case"not like":case"not ilike":e.push(`${a} NOT LIKE ?`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function mn(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(t=>`\`${t.columnName}\` ${t.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY \`${n}\` ${e?.toUpperCase()||"ASC"}`:""}function dn(n,e,t){let{values:r,sortColumns:a}=n;if(a.length===0)return{clause:"",values:[]};let i=t==="asc"===(e==="asc")?">":"<",l=a.map(d=>`\`${d}\``).join(", "),u=a.map(()=>"?").join(", "),m=a.map(d=>r[d]);return{clause:`(${l}) ${i} (${u})`,values:m}}function el(n,e){if(e)return"JSON";let t=n.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]||n.toUpperCase()}function tl(n,e){if(!n?.trim())return null;let t=n.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)":`(${n.trim()})`:t==="null"?"NULL":t==="true"?"1":t==="false"?"0":n.trim()}function er(n,e={}){let t=el(n.columnType,n.isArray??!1),r=`\`${n.columnName}\` ${t}`;if(!n.isNullable&&!n.isPrimaryKey&&(r+=" NOT NULL"),n.defaultValue&&!t.includes("AUTO_INCREMENT")){let a=tl(n.defaultValue,t);a!==null&&(r+=` DEFAULT ${a}`)}return(n.isIdentity||e.preserveAutoIncrement)&&!t.includes("AUTO_INCREMENT")&&(r+=" AUTO_INCREMENT"),e.includeUnique&&n.isUnique&&!n.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&n.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var Ga=N(()=>{"use strict";b()});import{HTTPException as M}from"hono/http-exception";var Qa,rl,tr,Ja=N(()=>{"use strict";b();Ce();He();Ve();dt();Ga();Qa=1451,rl=1217,tr=class extends me{async runQuery(e,t,r){let a=W(e),[o]=await a.execute(t,r);return o}quoteIdentifier(e){return`\`${e}\``}mapToUniversalType(e){return zt(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:a=50,direction:o="asc",sort:s=[],order:c="asc",filters:i=[]}=e,l=[],u=c;Array.isArray(s)&&s.length>0?(l=s.map(R=>R.columnName),u=s[0].direction):typeof s=="string"&&s&&(l=[s]);let{clause:m,values:d}=un(i),p="",f=[];if(r){let R=this.decodeCursor(r);if(R){let S=dn(R,o,u);p=S.clause,f=S.values}}let y="";m&&p?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${p}`:m?y=m:p&&(y=`WHERE ${p}`);let h=mn((Array.isArray(s),s),c),w=h;o==="desc"?h?w=h.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):l.length>0&&(w=`ORDER BY ${l.map(R=>`\`${R}\` ${u==="asc"?"DESC":"ASC"}`).join(", ")}`):!h&&l.length>0&&(w=`ORDER BY ${l.map(R=>`\`${R}\` ${u.toUpperCase()}`).join(", ")}`);let E=`SELECT * FROM \`${t}\` ${y} ${w} LIMIT ${a+1}`,A=[...d,...f],C=`SELECT COUNT(*) as total FROM \`${t}\` ${m}`;return{sql:E,values:A,countSql:C,countValues:d}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,c=[];Array.isArray(o)&&o.length>0?c=o.map(p=>p.columnName):typeof o=="string"&&o&&(c=[o]);let i=p=>this.encodeCursor({values:Object.fromEntries(c.map(f=>[f,p[f]])),sortColumns:c}),l=t[0],u=t[t.length-1],m=null,d=null;return a==="asc"?(r&&(m=i(u)),s&&(d=i(l))):(s&&(m=i(u)),r&&(d=i(l))),{nextCursor:m,prevCursor:d}}async getTableData(e){let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:c="asc",cursor:i,filters:l=[]}=e,u=W(r),m=await this.getPrimaryKeyColumns(u,t),d=[],p=c;Array.isArray(s)&&s.length>0?(d=s.map(H=>H.columnName),p=s[0].direction):typeof s=="string"&&s&&(d=[s]);let f=[...d,...m.filter(H=>!d.includes(H))],{clause:y,values:h}=un(l),w="",E=[];if(i){let H=this.decodeCursor(i);if(H){let Q=dn(H,o,p);w=Q.clause,E=Q.values}}let A="";y&&w?A=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${w}`:y?A=y:w&&(A=`WHERE ${w}`);let C=mn((Array.isArray(s),s),c),R=C;o==="desc"?C?R=C.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):f.length>0&&(R=`ORDER BY ${f.map(H=>`\`${H}\` ${p==="asc"?"DESC":"ASC"}`).join(", ")}`):!C&&f.length>0&&(R=`ORDER BY ${f.map(H=>`\`${H}\` ${p.toUpperCase()}`).join(", ")}`);let[S]=await u.execute(`SELECT COUNT(*) as total FROM \`${t}\` ${y}`,h),D=Number(S[0]?.total??0),[x]=await u.execute(`SELECT * FROM \`${t}\` ${A} ${R} LIMIT ${Math.floor(a)+1}`,[...h,...E]),v=x,O=v.length>a;O&&(v=v.slice(0,a)),o==="desc"&&(v=v.reverse());let k=null,B=null;if(v.length>0&&f.length>0){let H=v[0],Q=v[v.length-1],ae=X=>({values:Object.fromEntries(f.map(ee=>[ee,X[ee]])),sortColumns:f});o==="asc"?(O&&(k=this.encodeCursor(ae(Q))),i&&(B=this.encodeCursor(ae(H)))):(i&&(k=this.encodeCursor(ae(Q))),O&&(B=this.encodeCursor(ae(H))))}return{data:v,meta:{limit:a,total:D,hasNextPage:o==="asc"?O:!!i,hasPreviousPage:o==="asc"?!!i:O,nextCursor:k,prevCursor:B}}}async getDatabasesList(){let e=W(),[t]=await e.execute(`
151
- SELECT
152
- s.SCHEMA_NAME AS name,
153
- CONCAT(ROUND(COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024, 2), ' MB') AS size,
154
- CURRENT_USER() AS owner,
155
- s.DEFAULT_CHARACTER_SET_NAME AS encoding
156
- FROM information_schema.SCHEMATA s
157
- LEFT JOIN information_schema.TABLES t ON t.TABLE_SCHEMA = s.SCHEMA_NAME
158
- GROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME
159
- ORDER BY s.SCHEMA_NAME
160
- `);if(!t[0])throw new M(500,{message:"No databases returned from server"});return t}async getCurrentDatabase(){let e=W(),[t]=await e.execute("SELECT DATABASE() AS db");if(!t[0])throw new M(500,{message:"No current database returned from server"});return t[0]}async getDatabaseConnectionInfo(){let e=W(),[t]=await e.execute(`
166
+ `);if(Number(n.recordset[0]?.cnt??0)===0)throw new B(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 pa(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 fa(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 ya(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 wl(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 Sl(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 or(a,e={}){let t=wl(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=Sl(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 io=C(()=>{"use strict";b()});import{HTTPException as U}from"hono/http-exception";var lo,Rl,sr,co=C(()=>{"use strict";b();Ae();Ve();We();pt();io();lo=1451,Rl=1217,sr=class extends de{async runQuery(e,t,r){let n=Y(e),[o]=await n.execute(t,r);return o}quoteIdentifier(e){return`\`${e}\``}mapToUniversalType(e){return Qt(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(R=>R.columnName),u=s[0].direction):typeof s=="string"&&s&&(l=[s]);let{clause:m,values:p}=pa(i),d="",f=[];if(r){let R=this.decodeCursor(r);if(R){let S=ya(R,o,u);d=S.clause,f=S.values}}let y="";m&&d?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?y=m:d&&(y=`WHERE ${d}`);let g=fa((Array.isArray(s),s),c),E=g;o==="desc"?g?E=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):l.length>0&&(E=`ORDER BY ${l.map(R=>`\`${R}\` ${u==="asc"?"DESC":"ASC"}`).join(", ")}`):!g&&l.length>0&&(E=`ORDER BY ${l.map(R=>`\`${R}\` ${u.toUpperCase()}`).join(", ")}`);let w=`SELECT * FROM \`${t}\` ${y} ${E} LIMIT ${n+1}`,A=[...p,...f],N=`SELECT COUNT(*) as total FROM \`${t}\` ${m}`;return{sql:w,values:A,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=Y(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=c;Array.isArray(s)&&s.length>0?(p=s.map(H=>H.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=[...p,...m.filter(H=>!p.includes(H))],{clause:y,values:g}=pa(l),E="",w=[];if(i){let H=this.decodeCursor(i);if(H){let Q=ya(H,o,d);E=Q.clause,w=Q.values}}let A="";y&&E?A=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${E}`:y?A=y:E&&(A=`WHERE ${E}`);let N=fa((Array.isArray(s),s),c),R=N;o==="desc"?N?R=N.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):f.length>0&&(R=`ORDER BY ${f.map(H=>`\`${H}\` ${d==="asc"?"DESC":"ASC"}`).join(", ")}`):!N&&f.length>0&&(R=`ORDER BY ${f.map(H=>`\`${H}\` ${d.toUpperCase()}`).join(", ")}`);let[S]=await u.execute(`SELECT COUNT(*) as total FROM \`${t}\` ${y}`,g),D=Number(S[0]?.total??0),[v]=await u.execute(`SELECT * FROM \`${t}\` ${A} ${R} LIMIT ${Math.floor(n)+1}`,[...g,...w]),x=v,$=x.length>n;$&&(x=x.slice(0,n)),o==="desc"&&(x=x.reverse());let P=null,F=null;if(x.length>0&&f.length>0){let H=x[0],Q=x[x.length-1],oe=Z=>({values:Object.fromEntries(f.map(ee=>[ee,Z[ee]])),sortColumns:f});o==="asc"?($&&(P=this.encodeCursor(oe(Q))),i&&(F=this.encodeCursor(oe(H)))):(i&&(P=this.encodeCursor(oe(Q))),$&&(F=this.encodeCursor(oe(H))))}return{data:x,meta:{limit:n,total:D,hasNextPage:o==="asc"?$:!!i,hasPreviousPage:o==="asc"?!!i:$,nextCursor:P,prevCursor:F}}}async getDatabasesList(){try{let e=Y(),[t]=await e.execute(`
167
+ SELECT
168
+ s.SCHEMA_NAME AS name,
169
+ CONCAT(ROUND(COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024, 2), ' MB') AS size,
170
+ CURRENT_USER() AS owner,
171
+ s.DEFAULT_CHARACTER_SET_NAME AS encoding
172
+ FROM information_schema.SCHEMATA s
173
+ LEFT JOIN information_schema.TABLES t ON t.TABLE_SCHEMA = s.SCHEMA_NAME
174
+ WHERE (s.SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') OR s.SCHEMA_NAME = DATABASE())
175
+ GROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME
176
+ ORDER BY s.SCHEMA_NAME
177
+ `);if(!t[0])throw new U(500,{message:"No databases returned from server"});return t}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=Y(),[t]=await e.execute("SELECT DATABASE() AS db");if(!t[0])throw new U(500,{message:"No current database returned from server"});return t[0]}async getDatabaseConnectionInfo(){let e=Y(),[t]=await e.execute(`
161
178
  SELECT
162
179
  VERSION() AS version,
163
180
  DATABASE() AS database_name,
@@ -165,15 +182,15 @@ ${s.join(`,
165
182
  @@hostname AS host,
166
183
  @@port AS port,
167
184
  @@max_connections AS max_connections
168
- `),[r]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new M(500,{message:"No connection information returned from server"});let a=t[0],o=Me();return{host:String(a.host||o.host),port:Number(a.port||o.port),user:String(a.user),database:String(a.database_name??""),version:String(a.version),active_connections:Number(r[0]?.cnt??0),max_connections:Number(a.max_connections)}}async getTablesList(e){let t=W(e),[r]=await t.execute(`
185
+ `),[r]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new U(500,{message:"No connection information returned from server"});let n=t[0],o=Ue();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=Y(e),[r]=await t.execute(`
169
186
  SELECT table_name as tableName
170
187
  FROM information_schema.tables
171
188
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
172
189
  ORDER BY table_name
173
- `);return!r||r.length===0?[]:Promise.all(r.map(async a=>{let[o]=await t.execute(`SELECT COUNT(*) as count FROM \`${a.tableName}\``);return{tableName:a.tableName,rowCount:o[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=W(t),c=a.map(m=>er(m)),i=[],l=a.filter(m=>m.isPrimaryKey);l.length>0&&i.push(`PRIMARY KEY (${l.map(m=>`\`${m.columnName}\``).join(", ")})`);for(let m of a)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}\` (
190
+ `);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=Y(t),c=n.map(m=>or(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}\` (
174
191
  ${[...c,...i,...u].join(`,
175
192
  `)}
176
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=W(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 M(404,{message:`Table "${t}" does not exist`});let c=await this.getTableRowCount(o,t);if(!a){let i=await this.getRelatedRecordsForTable(t,r);if(i.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:i}}try{if(a){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===rl||l.errno===Qa)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw i instanceof M?i:new M(500,{message:`Failed to delete table "${t}"`})}}async getTableSchema({tableName:e,db:t}){let r=W(t),[a]=await r.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[e]);if(Number(a[0]?.cnt??0)===0)throw new M(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 M(500,{message:`Failed to retrieve schema for table "${e}"`});return c}async getTableColumns({tableName:e,db:t}){let r=W(t),[a]=await r.execute(`SELECT
193
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:r,cascade:n}=e,o=Y(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 U(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===Rl||l.errno===lo)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw i instanceof U?i:new U(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,db:n}=e;this.assertDifferentTableName(t,r);let o=Y(n);await this.assertTableExists(o,t);let[s]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[r]);if(Number(s[0]?.cnt??0)>0)throw new U(409,{message:`Table "${r}" already exists`});await o.execute(`RENAME TABLE \`${t.replaceAll("`","``")}\` TO \`${r.replaceAll("`","``")}\``)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=Y(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 U(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 U(500,{message:`Failed to retrieve schema for table "${e}"`});return c}async getTableColumns({tableName:e,db:t}){let r=Y(t),[n]=await r.execute(`SELECT
177
194
  c.COLUMN_NAME AS columnName,
178
195
  c.DATA_TYPE AS dataType,
179
196
  c.COLUMN_TYPE AS columnType,
@@ -191,10 +208,10 @@ ${s.join(`,
191
208
  AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
192
209
  WHERE c.TABLE_SCHEMA = DATABASE()
193
210
  AND c.TABLE_NAME = ?
194
- ORDER BY c.ORDINAL_POSITION`,[e]);if(!a||a.length===0)throw new M(404,{message:`Table "${e}" does not exist`});return a.map(o=>{let s=o.dataType==="enum"||o.dataType==="set";return{columnName:o.columnName,dataType:zt(o.dataType,o.columnType),dataTypeLabel:Fr(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:a,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,isArray:u,db:m}=e,d=W(m);await this.assertTableExists(d,t);let[p]=await d.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,r]);if(Number(p[0]?.cnt??0)>0)throw new M(409,{message:`Column "${r}" already exists in table "${t}"`});let f=er({columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,isArray:u},{includePrimaryKey:!0,includeUnique:!0});await d.execute(`ALTER TABLE \`${t}\` ADD COLUMN ${f}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:a}=e,o=W(a);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:a,isNullable:o,defaultValue:s,db:c}=e,i=W(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 M(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=er({columnName:r,columnType:a,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:a,db:o}=e,s=W(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,a]);if(Number(c[0]?.cnt??0)>0)throw new M(409,{message:`Column "${a}" already exists in table "${t}"`});await s.execute(`ALTER TABLE \`${t}\` RENAME COLUMN \`${r}\` TO \`${a}\``)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=W(e),s=await this.getBooleanColumnSet(r,e),c=Object.keys(a),i=Object.values(a).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 M(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:l.affectedRows}}async updateRecords({params:e,db:t}){let{tableName:r,updates:a,primaryKey:o}=e,s=W(t),c=await this.getBooleanColumnSet(r,t),i=new Map;for(let u of a){let m=u.rowData[o];if(m==null)throw new M(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,d]of i.entries()){let p=d.map(h=>`\`${h.columnName}\` = ?`),f=d.map(h=>h.value!==null&&typeof h.value=="object"?JSON.stringify(h.value):c.has(h.columnName)&&typeof h.value=="string"?h.value==="true"?1:0:h.value);f.push(m);let[y]=await l.execute(`UPDATE \`${r}\` SET ${p.join(", ")} WHERE \`${o}\` = ?`,f);if(y.affectedRows===0)throw new M(404,{message:`Record with ${o} = ${m} not found in table "${r}"`});u+=y.affectedRows}return await l.commit(),{updatedCount:u}}catch(u){throw await l.rollback(),u instanceof M?u:new M(500,{message:`Failed to update records in "${r}"`})}finally{l.release()}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=W(r),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=await a.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===Qa)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw l instanceof M?l:new M(500,{message:`Failed to delete records from "${e}"`})}finally{i.release()}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=W(r),o=t[0]?.columnName;if(!o)throw new M(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),c=await a.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,d=async(y,h,w,E)=>{let A=`${y}.${h}`;if(E.has(A))return;E.add(A);let C=await this.getForeignKeyReferences(y,r);for(let D of C){let x=w.map(()=>"?").join(", "),[v]=await c.execute(`SELECT \`${D.referencedColumn}\` FROM \`${y}\` WHERE \`${h}\` IN (${x})`,w),O=v.map(k=>k[D.referencedColumn]);O.length>0&&await d(D.referencingTable,D.referencingColumn,O,E)}let R=w.map(()=>"?").join(", "),[S]=await c.execute(`DELETE FROM \`${y}\` WHERE \`${h}\` IN (${R})`,w);l+=S.affectedRows,u.add(y)};for(let y of i)u.has(y.referencingTable)||await d(y.referencingTable,y.referencingColumn,s,m);let p=s.map(()=>"?").join(", "),[f]=await c.execute(`DELETE FROM \`${e}\` WHERE \`${o}\` IN (${p})`,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 M?i:new M(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 M(400,{message:"At least one record is required"});let o=await W(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(d=>{let p=u[d];return i.has(d)&&typeof p=="string"?p==="true"?1:0:p});try{await o.execute(`INSERT INTO \`${e}\` (${c}) VALUES (${s.map(()=>"?").join(", ")})`,m)}catch(d){throw new M(500,{message:`Failed to insert record ${l+1}: ${d instanceof Error?d.message:String(d)}`})}}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 M?s:new M(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=W(t);if(!e?.trim())throw new M(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),[s,c]=await r.execute(a),i=performance.now()-o;if(Array.isArray(s)){let u=s;return{columns:c?c.map(d=>d.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
211
+ ORDER BY c.ORDINAL_POSITION`,[e]);if(!n||n.length===0)throw new U(404,{message:`Table "${e}" does not exist`});return n.map(o=>{let s=o.dataType==="enum"||o.dataType==="set";return{columnName:o.columnName,dataType:Qt(o.dataType,o.columnType),dataTypeLabel:Vr(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=Y(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 U(409,{message:`Column "${r}" already exists in table "${t}"`});let f=or({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=Y(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=Y(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 U(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=or({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=Y(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 U(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=Y(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 U(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:l.affectedRows}}async updateRecords({params:e,db:t}){let{tableName:r}=e,n=Y(t),o=await this.getBooleanColumnSet(r,t),s=this.resolveKeyColumns(e),c=this.groupUpdatesByKey(e,s),i=await n.getConnection();await i.beginTransaction();try{let l=0;for(let{keyValues:u,rowUpdates:m}of c){let p=m.map(g=>`\`${g.columnName}\` = ?`),d=m.map(g=>g.value!==null&&typeof g.value=="object"?JSON.stringify(g.value):o.has(g.columnName)&&typeof g.value=="string"?g.value==="true"?1:0:g.value);d.push(...u);let f=s.map(g=>`\`${g}\` = ?`),[y]=await i.execute(`UPDATE \`${r}\` SET ${p.join(", ")} WHERE ${f.join(" AND ")}`,d);if(y.affectedRows===0)throw new U(404,{message:`Record with ${this.describeKey(s,u)} not found in table "${r}"`});l+=y.affectedRows}return await i.commit(),{updatedCount:l}}catch(l){throw await i.rollback(),l instanceof U?l:new U(500,{message:`Failed to update records in "${r}"`})}finally{i.release()}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=Y(r),o=t[0]?.columnName;if(!o)throw new U(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===lo)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw l instanceof U?l:new U(500,{message:`Failed to delete records from "${e}"`})}finally{i.release()}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=Y(r),o=t[0]?.columnName;if(!o)throw new U(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(y,g,E,w)=>{let A=`${y}.${g}`;if(w.has(A))return;w.add(A);let N=await this.getForeignKeyReferences(y,r);for(let D of N){let v=E.map(()=>"?").join(", "),[x]=await c.execute(`SELECT \`${D.referencedColumn}\` FROM \`${y}\` WHERE \`${g}\` IN (${v})`,E),$=x.map(P=>P[D.referencedColumn]);$.length>0&&await p(D.referencingTable,D.referencingColumn,$,w)}let R=E.map(()=>"?").join(", "),[S]=await c.execute(`DELETE FROM \`${y}\` WHERE \`${g}\` IN (${R})`,E);l+=S.affectedRows,u.add(y)};for(let y of i)u.has(y.referencingTable)||await p(y.referencingTable,y.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 U?i:new U(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 U(400,{message:"At least one record is required"});let o=await Y(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 U(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 U?s:new U(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=Y(t);if(!e?.trim())throw new U(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
195
212
  FROM information_schema.COLUMNS
196
213
  WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_KEY = 'PRI'
197
- ORDER BY ORDINAL_POSITION`,[t]);return r.map(a=>a.column_name)}async getForeignKeyReferences(e,t){let r=W(t),[a]=await r.execute(`SELECT
214
+ ORDER BY ORDINAL_POSITION`,[t]);return r.map(n=>n.column_name)}async getForeignKeyReferences(e,t){let r=Y(t),[n]=await r.execute(`SELECT
198
215
  kcu.CONSTRAINT_NAME AS constraint_name,
199
216
  kcu.TABLE_NAME AS referencing_table,
200
217
  kcu.COLUMN_NAME AS referencing_column,
@@ -207,16 +224,20 @@ ${s.join(`,
207
224
  AND kcu.TABLE_NAME = tc.TABLE_NAME
208
225
  WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
209
226
  AND kcu.TABLE_SCHEMA = DATABASE()
210
- AND kcu.REFERENCED_TABLE_NAME = ?`,[e]);return a.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 a=W(t),o=[];for(let s of r){let[c]=await a.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 a=await this.getForeignKeyReferences(e,r);if(a.length===0)return[];let o=W(r),s=t.map(l=>l.value),c=[],i=new Map;for(let l of a){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 d=s.map(()=>"?").join(", "),[p]=await o.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${d}) LIMIT 100`,s);p.length>0&&c.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:p})}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(a=>a.dataTypeLabel==="boolean").map(a=>a.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 M(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let[a]=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(a[0]?.cnt??0)===0)throw new M(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 pn(n){if(n.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=t.length+1,o=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${o} ${r.operator} $${a}`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${o} IS NULL`):(e.push(`${o} = $${a}`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${o} IS NOT NULL`):(e.push(`${o} != $${a}`),t.push(r.value));break;case"like":e.push(`${o}::text LIKE $${a}`),t.push(r.value);break;case"not like":e.push(`${o}::text NOT LIKE $${a}`),t.push(r.value);break;case"ilike":e.push(`${o}::text ILIKE $${a}`),t.push(r.value);break;case"not ilike":e.push(`${o}::text NOT ILIKE $${a}`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function fn(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(r=>`"${r.columnName}" ${r.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY "${n}" ${e?.toUpperCase()||"ASC"}`:""}function yn(n,e,t,r){let{values:a,sortColumns:o}=n,s=[],c=[],u=t==="asc"===(e==="asc");if(o.length>0){let m=o.map(f=>`"${f}"`).join(", "),d=o.map((f,y)=>`$${r+y}`).join(", "),p=u?">":"<";s.push(`(${m}) ${p} (${d})`);for(let f of o)c.push(a[f])}return{clause:s.length>0?`(${s.join(" AND ")})`:"",values:c}}var Xa=N(()=>{"use strict";b()});import{HTTPException as L}from"hono/http-exception";var rr,Za=N(()=>{"use strict";b();Ce();He();Ve();dt();Xa();rr=class extends me{async runQuery(e,t,r){return(await J(e).query(t,r)).rows}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return Vt(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:a=50,direction:o="asc",sort:s=[],order:c="asc",filters:i=[],db:l}=e,u=J(l),m=[],d=c;Array.isArray(s)&&s.length>0?(m=s.map(O=>O.columnName),d=s[0].direction):typeof s=="string"&&s&&(m=[s]);let p=m.length>0?[...m]:["ctid"],{clause:f,values:y}=pn(i),h="",w=[];if(r){let O=this.decodeCursor(r);if(O){let k=yn(O,o,d,y.length+1);h=k.clause,w=k.values}}let E="";f&&h?E=`WHERE ${f.replace(/^WHERE\s+/i,"")} AND ${h}`:f?E=f:h&&(E=`WHERE ${h}`);let A=fn((Array.isArray(s),s),c),C=A;o==="desc"?A?C=A.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):C=`ORDER BY ${p.map(k=>`"${k}" ${d==="asc"?"DESC":"ASC"}`).join(", ")}`:!A&&p.length>0&&(C=`ORDER BY ${p.map(k=>`"${k}" ${d.toUpperCase()}`).join(", ")}`);let R=y.length+w.length+1,S=`SELECT * FROM "${t}" ${E} ${C} LIMIT $${R}`,D=[...y,...w,a+1],x=`SELECT COUNT(*) as total FROM "${t}" ${f}`;return{sql:S,values:D,countSql:x,countValues:y}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,c=[];Array.isArray(o)&&o.length>0?c=o.map(p=>p.columnName):typeof o=="string"&&o&&(c=[o]),c.length===0&&(c=["ctid"]);let i=p=>{let f={values:Object.fromEntries(c.map(y=>[y,p[y]])),sortColumns:c};return this.encodeCursor(f)},l=t[0],u=t[t.length-1],m=null,d=null;return a==="asc"?(r&&(m=i(u)),s&&(d=i(l))):(s&&(m=i(u)),r&&(d=i(l))),{nextCursor:m,prevCursor:d}}async getTableData(e){let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:c="asc",cursor:i,filters:l=[]}=e,u=J(r),m=await this.getPrimaryKeyColumns(u,t),d=[],p=c;Array.isArray(s)&&s.length>0?(d=s.map(X=>X.columnName),p=s[0].direction):typeof s=="string"&&s&&(d=[s]);let f=[...d,...m.filter(X=>!d.includes(X))];f.length===0&&f.push("ctid");let{clause:y,values:h}=pn(l),w="",E=[];if(i){let X=this.decodeCursor(i);if(X){let ee=yn(X,o,p,h.length+1);w=ee.clause,E=ee.values}}let A="";y&&w?A=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${w}`:y?A=y:w&&(A=`WHERE ${w}`);let C=fn((Array.isArray(s),s),c),R=C;o==="desc"?C?R=C.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):R=`ORDER BY ${f.map(ee=>`"${ee}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!C&&f.length>0&&(R=`ORDER BY ${f.map(ee=>`"${ee}" ${p.toUpperCase()}`).join(", ")}`);let S=await u.query(`SELECT COUNT(*) as total FROM "${t}" ${y}`,h),D=Number(S.rows[0].total),x=h.length+E.length+1,v=await u.query(`SELECT * FROM "${t}" ${A} ${R} LIMIT $${x}`,[...h,...E,a+1]),k=v.fields&&v.fields.length>0?v.rows.filter(X=>Object.keys(X).length>0):v.rows,B=k.length>a;B&&(k=k.slice(0,a)),o==="desc"&&(k=k.reverse());let H=X=>({values:Object.fromEntries(f.map(ee=>[ee,X[ee]])),sortColumns:f}),Q=null,ae=null;if(k.length>0){let X=k[0],ee=k[k.length-1];o==="asc"?(B&&(Q=this.encodeCursor(H(ee))),i&&(ae=this.encodeCursor(H(X)))):(i&&(Q=this.encodeCursor(H(ee))),B&&(ae=this.encodeCursor(H(X))))}return{data:k,meta:{limit:a,total:D,hasNextPage:o==="asc"?B:!!i,hasPreviousPage:o==="asc"?!!i:B,nextCursor:Q,prevCursor:ae}}}async getDatabasesList(){let e=J(),{rows:t}=await e.query(`
211
- SELECT
212
- d.datname as name,
213
- pg_size_pretty(pg_database_size(d.datname)) as size,
214
- pg_catalog.pg_get_userbyid(d.datdba) as owner,
215
- pg_encoding_to_char(d.encoding) as encoding
216
- FROM pg_catalog.pg_database d
217
- WHERE d.datistemplate = false
218
- ORDER BY d.datname;
219
- `);if(!t[0])throw new L(500,{message:"No databases returned from database"});return t}async getCurrentDatabase(){let e=J(),{rows:t}=await e.query("SELECT current_database() as database;");if(!t[0])throw new L(500,{message:"No current database returned from database"});return t[0]}async getDatabaseConnectionInfo(){let e=J(),{rows:t}=await e.query(`
227
+ 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=Y(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=Y(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 U(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 U(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 ba(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 ha(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 ga(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,y)=>`$${r+y}`).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 we,uo=C(()=>{"use strict";b();we=a=>`(SELECT sp.schema_name FROM unnest(current_schemas(false)) WITH ORDINALITY AS sp(schema_name, position)
228
+ JOIN information_schema.tables it
229
+ ON it.table_schema = sp.schema_name AND it.table_name = ${a}
230
+ ORDER BY sp.position LIMIT 1)`});import{HTTPException as k}from"hono/http-exception";var ir,mo=C(()=>{"use strict";b();Ae();Ve();We();pt();uo();ir=class extends de{async runQuery(e,t,r){return(await J(e).query(t,r)).rows}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return Gt(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=J(l),m=[],p=c;Array.isArray(s)&&s.length>0?(m=s.map($=>$.columnName),p=s[0].direction):typeof s=="string"&&s&&(m=[s]);let d=m.length>0?[...m]:["ctid"],{clause:f,values:y}=ba(i),g="",E=[];if(r){let $=this.decodeCursor(r);if($){let P=ga($,o,p,y.length+1);g=P.clause,E=P.values}}let w="";f&&g?w=`WHERE ${f.replace(/^WHERE\s+/i,"")} AND ${g}`:f?w=f:g&&(w=`WHERE ${g}`);let A=ha((Array.isArray(s),s),c),N=A;o==="desc"?A?N=A.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):N=`ORDER BY ${d.map(P=>`"${P}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!A&&d.length>0&&(N=`ORDER BY ${d.map(P=>`"${P}" ${p.toUpperCase()}`).join(", ")}`);let R=y.length+E.length+1,S=`SELECT * FROM "${t}" ${w} ${N} LIMIT $${R}`,D=[...y,...E,n+1],v=`SELECT COUNT(*) as total FROM "${t}" ${f}`;return{sql:S,values:D,countSql:v,countValues:y}}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(y=>[y,d[y]])),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=J(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=c;Array.isArray(s)&&s.length>0?(p=s.map(Z=>Z.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=[...p,...m.filter(Z=>!p.includes(Z))];f.length===0&&f.push("ctid");let{clause:y,values:g}=ba(l),E="",w=[];if(i){let Z=this.decodeCursor(i);if(Z){let ee=ga(Z,o,d,g.length+1);E=ee.clause,w=ee.values}}let A="";y&&E?A=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${E}`:y?A=y:E&&(A=`WHERE ${E}`);let N=ha((Array.isArray(s),s),c),R=N;o==="desc"?N?R=N.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):R=`ORDER BY ${f.map(ee=>`"${ee}" ${d==="asc"?"DESC":"ASC"}`).join(", ")}`:!N&&f.length>0&&(R=`ORDER BY ${f.map(ee=>`"${ee}" ${d.toUpperCase()}`).join(", ")}`);let S=await u.query(`SELECT COUNT(*) as total FROM "${t}" ${y}`,g),D=Number(S.rows[0].total),v=g.length+w.length+1,x=await u.query(`SELECT * FROM "${t}" ${A} ${R} LIMIT $${v}`,[...g,...w,n+1]),P=x.fields&&x.fields.length>0?x.rows.filter(Z=>Object.keys(Z).length>0):x.rows,F=P.length>n;F&&(P=P.slice(0,n)),o==="desc"&&(P=P.reverse());let H=Z=>({values:Object.fromEntries(f.map(ee=>[ee,Z[ee]])),sortColumns:f}),Q=null,oe=null;if(P.length>0){let Z=P[0],ee=P[P.length-1];o==="asc"?(F&&(Q=this.encodeCursor(H(ee))),i&&(oe=this.encodeCursor(H(Z)))):(i&&(Q=this.encodeCursor(H(ee))),F&&(oe=this.encodeCursor(H(Z))))}return{data:P,meta:{limit:n,total:D,hasNextPage:o==="asc"?F:!!i,hasPreviousPage:o==="asc"?!!i:F,nextCursor:Q,prevCursor:oe}}}async getDatabasesList(){try{let e=J(),{rows:t}=await e.query(`
231
+ SELECT
232
+ d.datname as name,
233
+ pg_size_pretty(pg_database_size(d.datname)) as size,
234
+ pg_catalog.pg_get_userbyid(d.datdba) as owner,
235
+ pg_encoding_to_char(d.encoding) as encoding
236
+ FROM pg_catalog.pg_database d
237
+ WHERE d.datistemplate = false
238
+ AND (d.datname NOT IN ('postgres', 'rdsadmin') OR d.datname = current_database())
239
+ ORDER BY d.datname;
240
+ `);if(!t[0])throw new k(500,{message:"No databases returned from database"});return t}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=J(),{rows:t}=await e.query("SELECT current_database() as database;");if(!t[0])throw new k(500,{message:"No current database returned from database"});return t[0]}async getDatabaseConnectionInfo(){let e=J(),{rows:t}=await e.query(`
220
241
  SELECT
221
242
  version() as version,
222
243
  current_database() as database,
@@ -225,25 +246,25 @@ ${s.join(`,
225
246
  inet_server_port() as port,
226
247
  (SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,
227
248
  (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;
228
- `);if(!t[0])throw new L(500,{message:"No connection information returned from database"});let{connectionInfoSchema:r}=await Promise.resolve().then(()=>(Ce(),Va)),a=r.parse(t[0]),o=Me();return{host:a.host||o.host,port:a.port||o.port,user:a.user,database:a.database,version:a.version.toString(),active_connections:a.active_connections,max_connections:a.max_connections}}async getTablesList(e){let t=J(e),r=o=>o.replaceAll('"','""'),{rows:a}=await t.query(`
249
+ `);if(!t[0])throw new k(500,{message:"No connection information returned from database"});let{connectionInfoSchema:r}=await Promise.resolve().then(()=>(Ae(),ao)),n=r.parse(t[0]),o=Ue();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=J(e),r=o=>o.replaceAll('"','""'),{rows:n}=await t.query(`
229
250
  SELECT table_schema as "schemaName", table_name as "tableName"
230
251
  FROM information_schema.tables
231
252
  WHERE table_type = 'BASE TABLE'
232
253
  AND table_schema NOT IN ('pg_catalog', 'information_schema')
233
254
  AND table_schema NOT LIKE 'pg_toast%'
234
255
  ORDER BY table_schema, table_name;
235
- `);return a[0]?Promise.all(a.map(async o=>{let{rows:s}=await t.query(`SELECT COUNT(*)::integer as count FROM "${r(o.schemaName)}"."${r(o.tableName)}"`);return{schemaName:o.schemaName,tableName:o.tableName,rowCount:s[0]?.count??0}})):[]}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=J(t),c=a.map(l=>{let u=`"${l.columnName}" ${l.columnType}`;return l.isArray&&(u+="[]"),l.isPrimaryKey&&(u+=" PRIMARY KEY"),l.isUnique&&!l.isPrimaryKey&&(u+=" UNIQUE"),l.isNullable||(u+=" NOT NULL"),l.isIdentity&&(u+=" GENERATED ALWAYS AS IDENTITY"),l.defaultValue&&!l.isIdentity&&(u+=` DEFAULT ${l.defaultValue}`),u}),i=o?.map(l=>`CONSTRAINT "${`fk_${r}_${l.columnName}_${l.referencedTable}_${l.referencedColumn}`}" FOREIGN KEY ("${l.columnName}") REFERENCES "${l.referencedTable}" ("${l.referencedColumn}") ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`)??[];await s.query(`CREATE TABLE "${r}" (
256
+ `);return n[0]?Promise.all(n.map(async o=>{let{rows:s}=await t.query(`SELECT COUNT(*)::integer as count FROM "${r(o.schemaName)}"."${r(o.tableName)}"`);return{schemaName:o.schemaName,tableName:o.tableName,rowCount:s[0]?.count??0}})):[]}async createTable({tableData:e,db:t}){let{tableName:r,fields:n,foreignKeys:o}=e,s=J(t),c=n.map(l=>{let u=`"${l.columnName}" ${l.columnType}`;return l.isArray&&(u+="[]"),l.isPrimaryKey&&(u+=" PRIMARY KEY"),l.isUnique&&!l.isPrimaryKey&&(u+=" UNIQUE"),l.isNullable||(u+=" NOT NULL"),l.isIdentity&&(u+=" GENERATED ALWAYS AS IDENTITY"),l.defaultValue&&!l.isIdentity&&(u+=` DEFAULT ${l.defaultValue}`),u}),i=o?.map(l=>`CONSTRAINT "${`fk_${r}_${l.columnName}_${l.referencedTable}_${l.referencedColumn}`}" FOREIGN KEY ("${l.columnName}") REFERENCES "${l.referencedTable}" ("${l.referencedColumn}") ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`)??[];await s.query(`CREATE TABLE "${r}" (
236
257
  ${[...c,...i].join(`,
237
258
  `)}
238
- );`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=J(r),{rows:s}=await o.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = 'public') as exists;",[t]);if(!s[0]?.exists)throw new L(404,{message:`Table "${t}" does not exist`});let c=await this.getTableRowCount(o,t);if(!a&&(await this.getFkReferencesForTable(o,t)).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};try{return await o.query(`DROP TABLE "${t}" ${a?"CASCADE":"RESTRICT"}`),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(i){if(i.code==="2BP01")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};throw i instanceof L?i:new L(500,{message:`Failed to delete table "${t}"`})}}async getTableSchema({tableName:e,db:t}){let r=J(t),{rows:a}=await r.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1) as exists",[e]);if(!a[0]?.exists)throw new L(404,{message:`Table "${e}" does not exist`});let{rows:o}=await r.query(`SELECT column_name, data_type, udt_name, is_nullable, column_default, character_maximum_length, numeric_precision, numeric_scale
239
- FROM information_schema.columns WHERE table_schema = 'public' AND table_name = $1 ORDER BY ordinal_position`,[e]),{rows:s}=await r.query(`SELECT tc.constraint_name, tc.constraint_type, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
259
+ );`)}async deleteTable(e){let{tableName:t,db:r,cascade:n}=e,o=J(r),{rows:s}=await o.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!s[0]?.exists)throw new k(404,{message:`Table "${t}" does not exist`});let c=await this.getTableRowCount(o,t);if(!n&&(await this.getFkReferencesForTable(o,t)).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};try{return await o.query(`DROP TABLE "${t}" ${n?"CASCADE":"RESTRICT"}`),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(i){if(i.code==="2BP01")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};throw i instanceof k?i:new k(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,schemaName:n,db:o}=e;this.assertDifferentTableName(t,r);let s=J(o),{rows:c}=await s.query(`SELECT table_schema as "schemaName" FROM information_schema.tables WHERE table_name = $1 AND table_schema NOT IN ('pg_catalog', 'information_schema') AND table_schema NOT LIKE 'pg_toast%';`,[t]),i=c.map(m=>m.schemaName);if(i.length===0)throw new k(404,{message:`Table "${t}" does not exist`});if(n&&!i.includes(n))throw new k(404,{message:`Table "${n}"."${t}" does not exist`});if(!n&&i.length>1)throw new k(400,{message:`Table "${t}" exists in multiple schemas (${i.join(", ")}); rename is ambiguous`});let l=n??i[0],{rows:u}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = $2) as exists;",[r,l]);if(u[0]?.exists)throw new k(409,{message:`Table "${r}" already exists`});await s.query(`ALTER TABLE "${l.replaceAll('"','""')}"."${t.replaceAll('"','""')}" RENAME TO "${r.replaceAll('"','""')}"`)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=J(t),{rows:n}=await r.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = ANY(current_schemas(false)) AND table_name = $1) as exists",[e]);if(!n[0]?.exists)throw new k(404,{message:`Table "${e}" does not exist`});let{rows:o}=await r.query(`SELECT column_name, data_type, udt_name, is_nullable, column_default, character_maximum_length, numeric_precision, numeric_scale
260
+ FROM information_schema.columns WHERE table_schema = ${we("$1")} AND table_name = $1 ORDER BY ordinal_position`,[e]),{rows:s}=await r.query(`SELECT tc.constraint_name, tc.constraint_type, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
240
261
  FROM information_schema.table_constraints tc
241
262
  JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
242
263
  LEFT JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema AND tc.constraint_type = 'FOREIGN KEY'
243
- WHERE tc.table_schema = 'public' AND tc.table_name = $1 ORDER BY tc.constraint_type, tc.constraint_name`,[e]),{rows:c}=await r.query(`SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = 'public' AND tablename = $1
244
- AND indexname NOT IN (SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = 'public' AND table_name = $1 AND constraint_type = 'PRIMARY KEY')`,[e]),i=p=>{let{data_type:f,udt_name:y,character_maximum_length:h,numeric_precision:w,numeric_scale:E}=p;return f==="USER-DEFINED"?y:f==="ARRAY"?`${y.replace(/^_/,"")}[]`:(f==="character varying"||f==="varchar")&&h?`varchar(${h})`:f==="character"&&h?`char(${h})`:f==="numeric"&&w!==null?E!==null&&E>0?`numeric(${w}, ${E})`:`numeric(${w})`:f==="timestamp with time zone"?"timestamp with time zone":f==="timestamp without time zone"?"timestamp":{"character varying":"varchar",character:"char","double precision":"float8",integer:"integer",bigint:"bigint",smallint:"smallint",boolean:"boolean",text:"text",uuid:"uuid",json:"json",jsonb:"jsonb",date:"date",time:"time",bytea:"bytea"}[f]||f},l=[`create table public.${e} (`],u=o.map(p=>{let f=` ${p.column_name} ${i(p)}`;return p.is_nullable==="NO"&&(f+=" not null"),p.column_default!==null&&(f+=` default ${p.column_default}`),f}),m=new Map;for(let p of s){let f=m.get(p.constraint_name)??[];f.push(p),m.set(p.constraint_name,f)}let d=[];for(let[p,f]of m){let y=f[0],h=f.map(w=>w.column_name).join(", ");y.constraint_type==="PRIMARY KEY"?d.push(` constraint ${p} primary key (${h})`):y.constraint_type==="FOREIGN KEY"?d.push(` constraint ${p} foreign key (${h}) references ${y.foreign_table_name} (${y.foreign_column_name})`):y.constraint_type==="UNIQUE"&&d.push(` constraint ${p} unique (${h})`)}l.push([...u,...d].join(`,
245
- `)),l.push(") tablespace pg_default;");for(let p of c)[...m.values()].some(y=>y[0].constraint_type==="UNIQUE"&&y[0].constraint_name===p.indexname)||(l.push(""),l.push(`${p.indexdef};`));return l.join(`
246
- `)}async getTableColumns({tableName:e,db:t}){let r=J(t),{rows:a}=await r.query(`SELECT
264
+ WHERE tc.table_schema = ${we("$1")} AND tc.table_name = $1 ORDER BY tc.constraint_type, tc.constraint_name`,[e]),{rows:c}=await r.query(`SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = ${we("$1")} AND tablename = $1
265
+ AND indexname NOT IN (SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = ${we("$1")} AND table_name = $1 AND constraint_type = 'PRIMARY KEY')`,[e]),i=d=>{let{data_type:f,udt_name:y,character_maximum_length:g,numeric_precision:E,numeric_scale:w}=d;return f==="USER-DEFINED"?y:f==="ARRAY"?`${y.replace(/^_/,"")}[]`:(f==="character varying"||f==="varchar")&&g?`varchar(${g})`:f==="character"&&g?`char(${g})`:f==="numeric"&&E!==null?w!==null&&w>0?`numeric(${E}, ${w})`:`numeric(${E})`:f==="timestamp with time zone"?"timestamp with time zone":f==="timestamp without time zone"?"timestamp":{"character varying":"varchar",character:"char","double precision":"float8",integer:"integer",bigint:"bigint",smallint:"smallint",boolean:"boolean",text:"text",uuid:"uuid",json:"json",jsonb:"jsonb",date:"date",time:"time",bytea:"bytea"}[f]||f},l=[`create table public.${e} (`],u=o.map(d=>{let f=` ${d.column_name} ${i(d)}`;return d.is_nullable==="NO"&&(f+=" not null"),d.column_default!==null&&(f+=` default ${d.column_default}`),f}),m=new Map;for(let d of s){let f=m.get(d.constraint_name)??[];f.push(d),m.set(d.constraint_name,f)}let p=[];for(let[d,f]of m){let y=f[0],g=f.map(E=>E.column_name).join(", ");y.constraint_type==="PRIMARY KEY"?p.push(` constraint ${d} primary key (${g})`):y.constraint_type==="FOREIGN KEY"?p.push(` constraint ${d} foreign key (${g}) references ${y.foreign_table_name} (${y.foreign_column_name})`):y.constraint_type==="UNIQUE"&&p.push(` constraint ${d} unique (${g})`)}l.push([...u,...p].join(`,
266
+ `)),l.push(") tablespace pg_default;");for(let d of c)[...m.values()].some(y=>y[0].constraint_type==="UNIQUE"&&y[0].constraint_name===d.indexname)||(l.push(""),l.push(`${d.indexdef};`));return l.join(`
267
+ `)}async getTableColumns({tableName:e,db:t}){let r=J(t),{rows:n}=await r.query(`SELECT
247
268
  c.column_name as "columnName", c.data_type as "dataType", c.udt_name as "udtName",
248
269
  c.is_nullable = 'YES' as "isNullable", c.column_default as "columnDefault",
249
270
  CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as "isPrimaryKey",
@@ -256,26 +277,26 @@ ${s.join(`,
256
277
  LEFT JOIN (
257
278
  SELECT ku.column_name FROM information_schema.table_constraints tc
258
279
  JOIN information_schema.key_column_usage ku ON tc.constraint_name = ku.constraint_name AND tc.table_schema = ku.table_schema
259
- WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = 'public' AND tc.table_name = $1
280
+ WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = ${we("$1")} AND tc.table_name = $1
260
281
  ) pk ON c.column_name = pk.column_name
261
282
  LEFT JOIN (
262
283
  SELECT kcu.column_name, ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
263
284
  FROM information_schema.table_constraints tc
264
285
  JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
265
286
  JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema
266
- WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = 'public' AND tc.table_name = $1
287
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = ${we("$1")} AND tc.table_name = $1
267
288
  ) fk ON c.column_name = fk.column_name
268
- WHERE c.table_schema = 'public' AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e]);if(!a||a.length===0)throw new L(404,{message:`Table "${e}" does not exist`});return a.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:Vt(o.dataType),dataTypeLabel:Br(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:a,defaultValue:o,isPrimaryKey:s,isNullable:c,isUnique:i,isIdentity:l,isArray:u,db:m}=e,d=J(m),{rows:p}=await d.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = 'public') as exists;",[t]);if(!p[0]?.exists)throw new L(404,{message:`Table "${t}" does not exist`});let{rows:f}=await d.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 L(409,{message:`Column "${r}" already exists in table "${t}"`});let y=`"${r}" ${a}`;u&&(y+="[]"),s&&(y+=" PRIMARY KEY"),i&&!s&&(y+=" UNIQUE"),c||(y+=" NOT NULL"),l&&(y+=" GENERATED ALWAYS AS IDENTITY"),o?.trim()&&!l&&(y+=` DEFAULT ${o.trim()}`),await d.query(`ALTER TABLE "${t}" ADD COLUMN ${y}`)}async deleteColumn(e){let{tableName:t,columnName:r,cascade:a,db:o}=e,s=J(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 L(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 L(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rowCount:l}=await s.query(`ALTER TABLE "${t}" DROP COLUMN "${r}" ${a?"CASCADE":"RESTRICT"}`);return{deletedCount:l??0}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:c}=e,i=J(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 L(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 L(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 ${a}`),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(d){throw await m.query("ROLLBACK"),d}finally{m.release()}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=J(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 L(404,{message:`Table "${t}" does not exist`});let{rows:l}=await s.query(c,[t,r]);if(!l[0]?.exists)throw new L(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rows:u}=await s.query(c,[t,a]);if(u[0]?.exists)throw new L(409,{message:`Column "${a}" already exists in table "${t}"`});await s.query(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${a}"`)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=J(e),s=Object.keys(a),c=Object.values(a),i=s.map((m,d)=>`$${d+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 L(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:u.rowCount??0}}async updateRecords({params:e,db:t}){let{tableName:r,updates:a,primaryKey:o}=e,s=J(t),c=new Map;for(let i of a){let l=i.rowData[o];if(l==null)throw new L(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,y)=>`"${f.columnName}" = $${y+1}`),d=u.map(f=>f.value!==null&&typeof f.value=="object"?JSON.stringify(f.value):f.value);d.push(l);let p=await s.query(`UPDATE "${r}" SET ${m.join(", ")} WHERE "${o}" = $${d.length} RETURNING *`,d);if(p.rowCount===0)throw new L(404,{message:`Record with ${o} = ${l} not found in table "${r}"`});i+=p.rowCount??0}return await s.query("COMMIT"),{updatedCount:i}}catch(i){throw await s.query("ROLLBACK"),i instanceof L?i:new L(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=J(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=s.map((i,l)=>`$${l+1}`).join(", ");try{await a.query("BEGIN");let i=await a.query(`DELETE FROM "${e}" WHERE "${o}" IN (${c}) RETURNING *`,s);return await a.query("COMMIT"),{deletedCount:i.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(i){if(await a.query("ROLLBACK"),i.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(a,e,t,r)};throw i instanceof L?i:new L(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=J(r),o=t[0]?.columnName;if(!o)throw new L(400,{message:"Primary key column name is required"});let s=t.map(c=>c.value);await a.query("BEGIN");try{let c=await this.getFkConstraints(a,e),i=0,l=new Set,u=async(p,f,y)=>{let h=await this.getFkConstraints(a,p);for(let A of h){let C=y.map((D,x)=>`$${x+1}`).join(", "),{rows:R}=await a.query(`SELECT "${A.referencedColumn}" FROM "${p}" WHERE "${f}" IN (${C})`,y),S=R.map(D=>D[A.referencedColumn]);S.length>0&&await u(A.referencingTable,A.referencingColumn,S)}let w=y.map((A,C)=>`$${C+1}`).join(", "),E=await a.query(`DELETE FROM "${p}" WHERE "${f}" IN (${w})`,y);i+=E.rowCount??0,l.add(p)};for(let p of c)l.has(p.referencingTable)||await u(p.referencingTable,p.referencingColumn,s);let m=s.map((p,f)=>`$${f+1}`).join(", "),d=await a.query(`DELETE FROM "${e}" WHERE "${o}" IN (${m}) RETURNING *`,s);return await a.query("COMMIT"),{deletedCount:(d.rowCount??0)+i}}catch(c){throw await a.query("ROLLBACK"),c instanceof L?c:new L(500,{message:`Failed to force delete records from "${e}"`})}}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 J(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(d=>l[d]),m=s.map((d,p)=>`$${p+1}`).join(", ");try{await o.query(`INSERT INTO "${e}" (${c}) VALUES (${m}) RETURNING *`,u),i++}catch(d){throw new L(500,{message:`Failed: ${d instanceof Error?d.message:String(d)}`})}}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 L?s:new L(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=J(t);if(!e?.trim())throw new L(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.query(a),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
289
+ WHERE c.table_schema = ${we("$1")} AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e]);if(!n||n.length===0)throw new k(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:Gt(o.dataType),dataTypeLabel:Kr(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=J(m),{rows:d}=await p.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!d[0]?.exists)throw new k(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 = ${we("$1")}) as exists;`,[t,r]);if(f[0]?.exists)throw new k(409,{message:`Column "${r}" already exists in table "${t}"`});let y=`"${r}" ${n}`;u&&(y+="[]"),s&&(y+=" PRIMARY KEY"),i&&!s&&(y+=" UNIQUE"),c||(y+=" NOT NULL"),l&&(y+=" GENERATED ALWAYS AS IDENTITY"),o?.trim()&&!l&&(y+=` DEFAULT ${o.trim()}`),await p.query(`ALTER TABLE "${t}" ADD COLUMN ${y}`)}async deleteColumn(e){let{tableName:t,columnName:r,cascade:n,db:o}=e,s=J(o),{rows:c}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!c[0]?.exists)throw new k(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 = ${we("$1")}) as exists;`,[t,r]);if(!i[0]?.exists)throw new k(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=J(c),{rows:l}=await i.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!l[0]?.exists)throw new k(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 = ${we("$1")}) as exists;`,[t,r]);if(!u[0]?.exists)throw new k(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=J(o),c=`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${we("$1")}) as exists;`,{rows:i}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!i[0]?.exists)throw new k(404,{message:`Table "${t}" does not exist`});let{rows:l}=await s.query(c,[t,r]);if(!l[0]?.exists)throw new k(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 k(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=J(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 k(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:u.rowCount??0}}async updateRecords({params:e,db:t}){let{tableName:r}=e,n=J(t),o=this.resolveKeyColumns(e),s=this.groupUpdatesByKey(e,o);await n.query("BEGIN");try{let c=0;for(let{keyValues:i,rowUpdates:l}of s){let u=l.map((f,y)=>`"${f.columnName}" = $${y+1}`),m=l.map(f=>f.value!==null&&typeof f.value=="object"?JSON.stringify(f.value):f.value),p=o.map((f,y)=>`"${f}" = $${m.length+y+1}`);m.push(...i);let d=await n.query(`UPDATE "${r}" SET ${u.join(", ")} WHERE ${p.join(" AND ")} RETURNING *`,m);if(d.rowCount===0)throw new k(404,{message:`Record with ${this.describeKey(o,i)} not found in table "${r}"`});c+=d.rowCount??0}return await n.query("COMMIT"),{updatedCount:c}}catch(c){throw await n.query("ROLLBACK"),c instanceof k?c:new k(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=J(r),o=t[0]?.columnName;if(!o)throw new k(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 k?i:new k(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let n=J(r),o=t[0]?.columnName;if(!o)throw new k(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,y)=>{let g=await this.getFkConstraints(n,d);for(let A of g){let N=y.map((D,v)=>`$${v+1}`).join(", "),{rows:R}=await n.query(`SELECT "${A.referencedColumn}" FROM "${d}" WHERE "${f}" IN (${N})`,y),S=R.map(D=>D[A.referencedColumn]);S.length>0&&await u(A.referencingTable,A.referencingColumn,S)}let E=y.map((A,N)=>`$${N+1}`).join(", "),w=await n.query(`DELETE FROM "${d}" WHERE "${f}" IN (${E})`,y);i+=w.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 k?c:new k(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new k(400,{message:"At least one record is required"});let o=await J(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 k(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 k?s:new k(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=J(t);if(!e?.trim())throw new k(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
269
290
  FROM pg_index i
270
291
  JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
271
292
  WHERE i.indrelid = $1::regclass AND i.indisprimary
272
- ORDER BY array_position(i.indkey, a.attnum)`,[`"${t}"`])).rows.map(a=>a.column_name)}async getFkConstraints(e,t){let{rows:r}=await e.query(`SELECT tc.constraint_name, tc.table_name as referencing_table, kcu.column_name as referencing_column,
293
+ ORDER BY array_position(i.indkey, a.attnum)`,[`"${t}"`])).rows.map(n=>n.column_name)}async getFkConstraints(e,t){let{rows:r}=await e.query(`SELECT tc.constraint_name, tc.table_name as referencing_table, kcu.column_name as referencing_column,
273
294
  ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
274
295
  FROM information_schema.table_constraints AS tc
275
296
  JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
276
297
  JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema
277
- WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1`,[t]);return r.map(a=>({constraintName:a.constraint_name,referencingTable:a.referencing_table,referencingColumn:a.referencing_column,referencedTable:a.referenced_table,referencedColumn:a.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 a=[];for(let o of r){let{rows:s}=await e.query(`SELECT * FROM "${o.referencingTable}" LIMIT 100`);s.length>0&&a.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return a}async getRelatedRecords(e,t,r,a){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 d=c.map((f,y)=>`$${y+1}`).join(", "),{rows:p}=await e.query(`SELECT * FROM "${u.referencingTable}" WHERE "${u.referencingColumn}" IN (${d}) LIMIT 100`,c);p.length>0&&s.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:p})}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 oo(n){let e=[],t="",r=0,a=!1,o=!1;for(;r<n.length;){let s=n[r];if(a){s==="'"?a=!1:t+=s,r++;continue}if(o){if(s==="\\"&&r+1<n.length){t+=n[r+1],r+=2;continue}s==='"'?o=!1:t+=s,r++;continue}if(s==="'"){a=!0,r++;continue}if(s==='"'){o=!0,r++;continue}if(s===" "||s===" "||s===`
278
- `){t.length>0&&(e.push(t),t=""),r++;continue}t+=s,r++}if(a||o)throw new Error("Unterminated quoted string in command");return t.length>0&&e.push(t),e}function so(n,e){if(n.length===0)return st(e);let t=n[0]?.toUpperCase()??"",r=n[1]?.toUpperCase();if((t==="ZRANGE"||t==="ZREVRANGE"||t==="ZRANGEBYSCORE")&&n.some(o=>o.toUpperCase()==="WITHSCORES"))return al(e);if(r){let o=`${t} ${r}`,s=no[o];if(s)return s(e)}let a=no[t];return a?a(e):typeof e=="string"||typeof e=="number"||e===null?ce(e):nl(e)?ve(e):st(e)}var nl,ao,st,ce,eo,ve,to,al,ol,ro,no,io=N(()=>{"use strict";b();nl=n=>Array.isArray(n)&&n.every(e=>typeof e=="string"||e===null),ao=n=>Array.isArray(n)&&n.length%2===0;st=n=>({columns:["result"],rows:[{result:typeof n=="string"?n:JSON.stringify(n,null,2)}],rowCount:1}),ce=n=>n===null?{columns:["value"],rows:[{value:null}],rowCount:0}:{columns:["value"],rows:[{value:n}],rowCount:1},eo=n=>({columns:["status"],rows:[{status:n}],rowCount:1}),ve=n=>Array.isArray(n)?{columns:["#","value"],rows:n.map((e,t)=>({"#":t,value:e})),rowCount:n.length}:st(n),to=n=>{if(!ao(n))return st(n);let e=[];for(let t=0;t<n.length;t+=2)e.push({field:n[t],value:n[t+1]});return{columns:["field","value"],rows:e,rowCount:e.length}},al=n=>{if(!ao(n))return ve(n);let e=[];for(let t=0;t<n.length;t+=2)e.push({member:n[t],score:n[t+1]});return{columns:["member","score"],rows:e,rowCount:e.length}},ol=n=>{if(typeof n!="string")return st(n);let e=[],t="";for(let r of n.split(/\r?\n/)){if(!r.trim())continue;if(r.startsWith("#")){t=r.replace(/^#\s*/,"").trim();continue}let a=r.indexOf(":");a<0||e.push({section:t,key:r.slice(0,a),value:r.slice(a+1)})}return{columns:["section","key","value"],rows:e,rowCount:e.length}},ro=n=>{if(!Array.isArray(n))return st(n);let e=n.map(t=>{if(!Array.isArray(t)||t.length<2)return{id:null,fields:null};let[r,a]=t,o={};if(Array.isArray(a))for(let s=0;s<a.length;s+=2)o[String(a[s])]=a[s+1];return{id:r,fields:o}});return{columns:["id","fields"],rows:e,rowCount:e.length}},no={PING:eo,GET:ce,SET:eo,TYPE:ce,TTL:ce,EXISTS:ce,DBSIZE:ce,DEL:ce,INCR:ce,DECR:ce,STRLEN:ce,LLEN:ce,SCARD:ce,ZCARD:ce,HLEN:ce,HGET:ce,HMGET:ve,MGET:ve,KEYS:ve,LRANGE:ve,SMEMBERS:ve,HGETALL:to,HKEYS:ve,HVALS:ve,"CONFIG GET":to,ZRANGE:ve,INFO:ol,XRANGE:ro,XREVRANGE:ro}});import{createHash as sl,randomBytes as il}from"crypto";import{HTTPException as _}from"hono/http-exception";import{z as Oe}from"zod";function co(n){let e={};for(let t of n.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 Cl(n){let e=new Map;for(let t of n.split(/\r?\n/)){let r=t.match(/^db(\d+):keys=(\d+)/);r&&e.set(Number(r[1]),Number(r[2]))}return e}function uo(n){let e=n.key;if(e==null||e==="")throw new _(400,{message:"Field 'key' is required"});return String(e)}function Tn(n){let e=n.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 sr(n){return typeof n=="string"?n:n==null?"":typeof n=="object"?JSON.stringify(n):String(n)}function mo(n,e){if(typeof n=="string"){try{let t=JSON.parse(n);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}throw new _(400,{message:`Value for ${e} must be a JSON object`})}if(n&&typeof n=="object"&&!Array.isArray(n))return n;throw new _(400,{message:`Value for ${e} must be a JSON object`})}function po(n,e){if(Array.isArray(n))return n;if(typeof n=="string")try{let t=JSON.parse(n);if(Array.isArray(t))return t}catch{}throw new _(400,{message:`Value for ${e} must be a JSON array`})}function Nl(n){let e;if(Array.isArray(n))e=n;else if(typeof n=="string")try{e=JSON.parse(n)}catch{throw new _(400,{message:"Value for zset must be an array of {member, score} entries"})}else throw new _(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 _(400,{message:"Each zset entry must be an object with 'member' and 'score'"});let a=r;if(a.member===void 0||a.score===void 0)throw new _(400,{message:"Each zset entry must include 'member' and 'score'"});let o=typeof a.score=="number"?a.score:Number(a.score);if(!Number.isFinite(o))throw new _(400,{message:`Invalid score: ${String(a.score)}`});t.push({member:String(a.member),score:o})}return t}function Al(n){if(!n)return[];let e=[];for(let t=0;t<n.length;t+=2){let r=Number(n[t+1]);e.push({member:n[t],score:Number.isFinite(r)?r:0})}return e}function Dl(n){if(!Array.isArray(n))return{length:0,firstId:null,lastId:null};let e={};for(let s=0;s<n.length;s+=2)e[String(n[s])]=n[s+1];let t=typeof e.length=="number"?e.length:Number.parseInt(String(e.length??"0"),10)||0,r=e["first-entry"],a=e["last-entry"],o=s=>Array.isArray(s)&&typeof s[0]=="string"?s[0]:null;return{length:t,firstId:o(r),lastId:o(a)}}var Et,bn,nr,ll,cl,ul,ml,dl,pl,fl,yl,bl,qe,se,gl,hl,ht,Tl,pe,El,ar,Y,or,ze,Tt,gn,ye,hn,wl,Sl,xe,it,lt,lo,Rl,ir,fo=N(()=>{"use strict";b();He();Ve();io();Et=["strings","hashes","lists","sets","zsets","streams"],bn={strings:"string",hashes:"hash",lists:"list",sets:"set",zsets:"zset",streams:"stream"},nr="Schema is fixed for Redis tables; this operation is not supported",ll="Sorting is not supported for Redis tables",cl="Filtering is not supported for Redis tables",ul="Backward pagination is not supported for Redis tables (SCAN is forward-only)",ml=10,dl=3e4,pl=1e4,fl=256*1024,yl=8*1024*1024,bl=n=>Et.includes(n),qe=n=>{if(!bl(n))throw new _(404,{message:`Table "${n}" does not exist in Redis. Valid tables: ${Et.join(", ")}`});return n},se=n=>{if(n==="")return Ke();let e=Number.parseInt(n,10);if(!Number.isFinite(e)||e<0)throw new _(400,{message:`Invalid Redis database index: "${n}". Expected a non-negative integer.`});return e},gl=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),hl=n=>{try{return Oe.object({scanCursor:Oe.string().regex(/^\d+$/),search:Oe.string().max(512).optional(),exactPattern:Oe.boolean(),type:Oe.enum(["string","hash","list","set","zset","stream"]).optional()}).parse(JSON.parse(Buffer.from(n,"base64url").toString("utf-8")))}catch{return null}},ht=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),Tl=n=>{try{return Oe.object({key:Oe.string().min(1).max(16*1024),type:Oe.enum(["string","hash","list","set","zset","stream","unknown"]),cursor:Oe.string().min(1).max(512),direction:Oe.enum(["forward","backward"])}).parse(JSON.parse(Buffer.from(n,"base64url").toString("utf8")))}catch{return null}},pe=n=>{let e=n.toString("utf8");return Buffer.from(e,"utf8").equals(n)?{base64:n.toString("base64url"),utf8:e}:{base64:n.toString("base64url")}},El=n=>n.replaceAll(/[\\*?[\]]/g,"\\$&"),ar=n=>{let e=Buffer.isBuffer(n)?n.toString("utf8"):String(n);return["string","hash","list","set","zset","stream"].includes(e)?e:"unknown"},Y=n=>Buffer.from(n,"base64url"),or=n=>n==="-"?Buffer.alloc(0):Y(n),ze=n=>sl("sha256").update(n).digest("base64url"),Tt=()=>new _(409,{message:"This key changed since it was loaded. Reload it or explicitly overwrite."}),gn=n=>{let e=n instanceof Error?n.message:String(n);return/(NOPERM|unknown command|not allowed|unsupported)/i.test(e)},ye=(n,e)=>{if(n!==e)throw new _(400,{message:`This operation requires a ${e} key, but the key is ${n}.`})},hn=n=>{if(n===null)throw Tt();if(!Array.isArray(n))return;let e=n.find(t=>Array.isArray(t)&&t[0]instanceof Error);if(e)throw new _(400,{message:e[0].message})},wl=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),Sl=n=>{try{return JSON.parse(Buffer.from(n,"base64url").toString("utf-8"))}catch{return null}},xe=n=>({columnName:n.columnName,dataType:n.dataType,dataTypeLabel:n.dataTypeLabel??(n.dataType==="number"?"int":n.dataType==="json"?"json":n.dataType==="array"?"array":"text"),isNullable:n.isNullable??!1,columnDefault:n.columnDefault??null,isPrimaryKey:n.isPrimaryKey??!1,isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}),it=xe({columnName:"key",dataType:"text",isPrimaryKey:!0}),lt=xe({columnName:"ttl",dataType:"number",isNullable:!0}),lo={strings:[it,xe({columnName:"value",dataType:"text",isNullable:!0}),lt],hashes:[it,xe({columnName:"value",dataType:"json"}),lt],lists:[it,xe({columnName:"value",dataType:"array"}),lt],sets:[it,xe({columnName:"value",dataType:"array"}),lt],zsets:[it,xe({columnName:"value",dataType:"json"}),lt],streams:[it,xe({columnName:"length",dataType:"number"}),xe({columnName:"first-id",dataType:"text",isNullable:!0}),xe({columnName:"last-id",dataType:"text",isNullable:!0}),lt]},Rl={strings:`-- Redis string keys
298
+ 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,y)=>`$${y+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 go(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===`
299
+ `){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 To(a,e){if(a.length===0)return it(e);let t=a[0]?.toUpperCase()??"",r=a[1]?.toUpperCase();if((t==="ZRANGE"||t==="ZREVRANGE"||t==="ZRANGEBYSCORE")&&a.some(o=>o.toUpperCase()==="WITHSCORES"))return Nl(e);if(r){let o=`${t} ${r}`,s=bo[o];if(s)return s(e)}let n=bo[t];return n?n(e):typeof e=="string"||typeof e=="number"||e===null?ue(e):Cl(e)?ve(e):it(e)}var Cl,ho,it,ue,po,ve,fo,Nl,Al,yo,bo,Eo=C(()=>{"use strict";b();Cl=a=>Array.isArray(a)&&a.every(e=>typeof e=="string"||e===null),ho=a=>Array.isArray(a)&&a.length%2===0;it=a=>({columns:["result"],rows:[{result:typeof a=="string"?a:JSON.stringify(a,null,2)}],rowCount:1}),ue=a=>a===null?{columns:["value"],rows:[{value:null}],rowCount:0}:{columns:["value"],rows:[{value:a}],rowCount:1},po=a=>({columns:["status"],rows:[{status:a}],rowCount:1}),ve=a=>Array.isArray(a)?{columns:["#","value"],rows:a.map((e,t)=>({"#":t,value:e})),rowCount:a.length}:it(a),fo=a=>{if(!ho(a))return it(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}},Nl=a=>{if(!ho(a))return ve(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}},Al=a=>{if(typeof a!="string")return it(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}},yo=a=>{if(!Array.isArray(a))return it(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}},bo={PING:po,GET:ue,SET:po,TYPE:ue,TTL:ue,EXISTS:ue,DBSIZE:ue,DEL:ue,INCR:ue,DECR:ue,STRLEN:ue,LLEN:ue,SCARD:ue,ZCARD:ue,HLEN:ue,HGET:ue,HMGET:ve,MGET:ve,KEYS:ve,LRANGE:ve,SMEMBERS:ve,HGETALL:fo,HKEYS:ve,HVALS:ve,"CONFIG GET":fo,ZRANGE:ve,INFO:Al,XRANGE:yo,XREVRANGE:yo}});import{createHash as Dl,randomBytes as _l}from"crypto";import{HTTPException as _}from"hono/http-exception";import{z as $e}from"zod";function So(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 Vl(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 Ro(a){let e=a.key;if(e==null||e==="")throw new _(400,{message:"Field 'key' is required"});return String(e)}function Sa(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 ur(a){return typeof a=="string"?a:a==null?"":typeof a=="object"?JSON.stringify(a):String(a)}function Co(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 _(400,{message:`Value for ${e} must be a JSON object`})}if(a&&typeof a=="object"&&!Array.isArray(a))return a;throw new _(400,{message:`Value for ${e} must be a JSON object`})}function No(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 _(400,{message:`Value for ${e} must be a JSON array`})}function zl(a){let e;if(Array.isArray(a))e=a;else if(typeof a=="string")try{e=JSON.parse(a)}catch{throw new _(400,{message:"Value for zset must be an array of {member, score} entries"})}else throw new _(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 _(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 _(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 _(400,{message:`Invalid score: ${String(n.score)}`});t.push({member:String(n.member),score:o})}return t}function Wl(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 Yl(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 Rt,Ta,Et,xl,vl,Ol,$l,Pl,kl,Ll,Il,Ml,Be,se,ql,Ul,wt,Bl,fe,Fl,lr,G,cr,Ye,St,Ea,be,wa,jl,Hl,Oe,lt,ct,wo,Kl,mr,Ao=C(()=>{"use strict";b();Ve();We();Eo();Rt=["strings","hashes","lists","sets","zsets","streams"],Ta={strings:"string",hashes:"hash",lists:"list",sets:"set",zsets:"zset",streams:"stream"},Et="Schema is fixed for Redis tables; this operation is not supported",xl="Sorting is not supported for Redis tables",vl="Filtering is not supported for Redis tables",Ol="Backward pagination is not supported for Redis tables (SCAN is forward-only)",$l=10,Pl=3e4,kl=1e4,Ll=256*1024,Il=8*1024*1024,Ml=a=>Rt.includes(a),Be=a=>{if(!Ml(a))throw new _(404,{message:`Table "${a}" does not exist in Redis. Valid tables: ${Rt.join(", ")}`});return a},se=a=>{if(a==="")return ze();let e=Number.parseInt(a,10);if(!Number.isFinite(e)||e<0)throw new _(400,{message:`Invalid Redis database index: "${a}". Expected a non-negative integer.`});return e},ql=a=>Buffer.from(JSON.stringify(a)).toString("base64url"),Ul=a=>{try{return $e.object({scanCursor:$e.string().regex(/^\d+$/),search:$e.string().max(512).optional(),exactPattern:$e.boolean(),type:$e.enum(["string","hash","list","set","zset","stream"]).optional()}).parse(JSON.parse(Buffer.from(a,"base64url").toString("utf-8")))}catch{return null}},wt=a=>Buffer.from(JSON.stringify(a)).toString("base64url"),Bl=a=>{try{return $e.object({key:$e.string().min(1).max(16*1024),type:$e.enum(["string","hash","list","set","zset","stream","unknown"]),cursor:$e.string().min(1).max(512),direction:$e.enum(["forward","backward"])}).parse(JSON.parse(Buffer.from(a,"base64url").toString("utf8")))}catch{return null}},fe=a=>{let e=a.toString("utf8");return Buffer.from(e,"utf8").equals(a)?{base64:a.toString("base64url"),utf8:e}:{base64:a.toString("base64url")}},Fl=a=>a.replaceAll(/[\\*?[\]]/g,"\\$&"),lr=a=>{let e=Buffer.isBuffer(a)?a.toString("utf8"):String(a);return["string","hash","list","set","zset","stream"].includes(e)?e:"unknown"},G=a=>Buffer.from(a,"base64url"),cr=a=>a==="-"?Buffer.alloc(0):G(a),Ye=a=>Dl("sha256").update(a).digest("base64url"),St=()=>new _(409,{message:"This key changed since it was loaded. Reload it or explicitly overwrite."}),Ea=a=>{let e=a instanceof Error?a.message:String(a);return/(NOPERM|unknown command|not allowed|unsupported)/i.test(e)},be=(a,e)=>{if(a!==e)throw new _(400,{message:`This operation requires a ${e} key, but the key is ${a}.`})},wa=a=>{if(a===null)throw St();if(!Array.isArray(a))return;let e=a.find(t=>Array.isArray(t)&&t[0]instanceof Error);if(e)throw new _(400,{message:e[0].message})},jl=a=>Buffer.from(JSON.stringify(a)).toString("base64url"),Hl=a=>{try{return JSON.parse(Buffer.from(a,"base64url").toString("utf-8"))}catch{return null}},Oe=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}),lt=Oe({columnName:"key",dataType:"text",isPrimaryKey:!0}),ct=Oe({columnName:"ttl",dataType:"number",isNullable:!0}),wo={strings:[lt,Oe({columnName:"value",dataType:"text",isNullable:!0}),ct],hashes:[lt,Oe({columnName:"value",dataType:"json"}),ct],lists:[lt,Oe({columnName:"value",dataType:"array"}),ct],sets:[lt,Oe({columnName:"value",dataType:"array"}),ct],zsets:[lt,Oe({columnName:"value",dataType:"json"}),ct],streams:[lt,Oe({columnName:"length",dataType:"number"}),Oe({columnName:"first-id",dataType:"text",isNullable:!0}),Oe({columnName:"last-id",dataType:"text",isNullable:!0}),ct]},Kl={strings:`-- Redis string keys
279
300
  -- Columns: key (text, PK), value (text), ttl (number, seconds; -1 = no TTL, -2 = missing)
280
301
  -- Backed by: GET / SET / EXPIRE`,hashes:`-- Redis hash keys
281
302
  -- Columns: key (text, PK), value (json: {field: value, ...}), ttl (number)
@@ -287,9 +308,9 @@ ${s.join(`,
287
308
  -- Columns: key (text, PK), value (json: [{member, score}, ...]), ttl (number)
288
309
  -- Backed by: ZRANGE WITHSCORES / ZADD / EXPIRE`,streams:`-- Redis stream keys
289
310
  -- Columns: key (text, PK), length (number), first-id (text), last-id (text), ttl (number)
290
- -- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},ir=class extends me{countCache=new Map;runQuery(){throw new _(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new _(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 scanKeys(e){try{let{db:t,limit:r,search:a,exactPattern:o,type:s,cursor:c}=e,i=se(t),l=await de(i),u="0";if(c){let E=hl(c);if(!E||E.search!==a||E.exactPattern!==o||E.type!==s)throw new _(400,{message:"Invalid or stale key scan cursor"});u=E.scanCursor}let m=a?o?a:`*${El(a)}*`:"*",d=[u,"MATCH",m,"COUNT",r];s&&d.push("TYPE",s);let[p,f]=await l.scanBuffer(...d),y=Buffer.isBuffer(p)?p.toString("utf8"):p,h=l.pipeline();for(let E of f)h.call("TYPE",E),h.pttl(E),h.call("MEMORY","USAGE",E);let w=await h.exec()??[];return{keys:f.map((E,A)=>{let C=A*3,R=w[C+2]?.[1];return{key:pe(E),type:ar(w[C]?.[1]),ttlMs:Number(w[C+1]?.[1]??-2),memoryBytes:R==null?null:Number(R)}}),nextCursor:y==="0"?null:gl({scanCursor:y,search:a,exactPattern:o,type:s}),hasMore:y!=="0"}}catch(t){throw this.wrapError(t)}}async getKeyDetails(e){try{let{db:t,key:r,cursor:a,limit:o,full:s,direction:c}=e,i=or(r),l=await de(se(t)),[u,m,d,p]=await Promise.all([l.callBuffer("TYPE",i),l.pttl(i),l.call("MEMORY","USAGE",i).catch(()=>null),l.callBuffer("DUMP",i)]),f=p;if(!f)throw new _(404,{message:"Redis key no longer exists"});let y=ar(u),h={key:pe(i),type:y,ttlMs:Number(m),memoryBytes:d===null?null:Number(d),revision:ze(f)},w=a?Tl(a):null;if(a&&(!w||w.key!==r||w.type!==y||w.direction!==c))throw new _(400,{message:"Invalid or stale key details cursor"});if(y==="string"){let E=await l.strlen(i),A=s?yl:fl,C=await l.getrangeBuffer(i,0,A-1);return{...h,length:E,value:{kind:"string",value:pe(C),truncated:E>A},nextCursor:null,hasMore:!1}}if(y==="hash"){let[E,A]=await Promise.all([l.hlen(i),l.hscanBuffer(i,w?.cursor??"0","COUNT",String(o))]),[C,R]=A,S=Buffer.isBuffer(C)?C.toString("utf8"):C,D=[];for(let x=0;x<R.length;x+=2)D.push({field:pe(R[x]),value:pe(R[x+1])});return{...h,length:E,value:{kind:"hash",entries:D},nextCursor:S==="0"?null:ht({key:r,type:y,cursor:S,direction:c}),hasMore:S!=="0"}}if(y==="list"){let E=Number.parseInt(w?.cursor??"0",10),A=await l.llen(i),C=await l.lrangeBuffer(i,E,E+o-1),R=E+C.length,S=R<A;return{...h,length:A,value:{kind:"list",entries:C.map((D,x)=>({index:E+x,value:pe(D)}))},nextCursor:S?ht({key:r,type:y,cursor:String(R),direction:c}):null,hasMore:S}}if(y==="set"){let[E,A]=await Promise.all([l.scard(i),l.sscanBuffer(i,w?.cursor??"0","COUNT",String(o))]),[C,R]=A,S=Buffer.isBuffer(C)?C.toString("utf8"):C;return{...h,length:E,value:{kind:"set",members:R.map(pe)},nextCursor:S==="0"?null:ht({key:r,type:y,cursor:S,direction:c}),hasMore:S!=="0"}}if(y==="zset"){let[E,A]=await Promise.all([l.zcard(i),l.zscanBuffer(i,w?.cursor??"0","COUNT",String(o))]),[C,R]=A,S=Buffer.isBuffer(C)?C.toString("utf8"):C,D=[];for(let x=0;x<R.length;x+=2)D.push({member:pe(R[x]),score:(()=>{let v=R[x+1].toString("utf8");return v==="inf"?"inf":v==="-inf"?"-inf":Number(v)})()});return{...h,length:E,value:{kind:"zset",entries:D},nextCursor:S==="0"?null:ht({key:r,type:y,cursor:S,direction:c}),hasMore:S!=="0"}}if(y==="stream"){let E=w?.cursor??(c==="forward"?"-":"+"),[A,C]=await Promise.all([l.xlen(i),c==="forward"?l.xrangeBuffer(i,E,"+","COUNT",o+1):l.xrevrangeBuffer(i,E,"-","COUNT",o+1)]),R=C.length>o,D=C.slice(0,o).map(([v,O])=>{let k=[];for(let B=0;B<O.length;B+=2)k.push({field:pe(O[B]),value:pe(O[B+1])});return{id:v.toString("utf8"),fields:k}}),x=D.at(-1)?.id;return{...h,length:A,value:{kind:"stream",entries:D},nextCursor:R&&x?ht({key:r,type:y,cursor:`(${x}`,direction:c}):null,hasMore:R}}return{...h,length:null,value:{kind:"unknown"},nextCursor:null,hasMore:!1}}catch(t){throw this.wrapError(t)}}async getStringChunk(e){try{let t=await de(se(e.db)),r=or(e.key),a=ar(await t.callBuffer("TYPE",r));if(a==="unknown")throw new _(404,{message:"Redis key no longer exists"});if(ye(a,"string"),e.expectedRevision){let i=await t.callBuffer("DUMP",r);if(!i||ze(i)!==e.expectedRevision)throw Tt()}let o=await t.strlen(r),s=await t.getrangeBuffer(r,e.offset,e.offset+e.limit-1),c=e.offset+s.length;return{chunk:pe(s),length:o,nextOffset:c<o?c:null,hasMore:c<o}}catch(t){throw this.wrapError(t)}}async createKey(e){let t=null;try{t=await Ft(se(e.db));let r=Y(e.key.base64);if(await t.watch(r),await t.exists(r)!==0)throw new _(409,{message:"A Redis key with this name already exists."});if(e.type!==e.value.kind)throw new _(400,{message:"The initial value does not match the selected Redis key type."});let a=t.multi();switch(e.value.kind){case"string":a.set(r,Y(e.value.value.base64));break;case"hash":a.hset(r,...e.value.entries.flatMap(({field:s,value:c})=>[Y(s.base64),Y(c.base64)]));break;case"list":a.rpush(r,...e.value.entries.map(s=>Y(s.base64)));break;case"set":a.sadd(r,...e.value.members.map(s=>Y(s.base64)));break;case"zset":a.zadd(r,...e.value.entries.flatMap(({member:s,score:c})=>[c,Y(s.base64)]));break;case"stream":a.xadd(r,e.value.id,...e.value.fields.flatMap(({field:s,value:c})=>[Y(s.base64),Y(c.base64)]));break}e.ttlMs!==null&&a.pexpire(r,e.ttlMs),hn(await a.exec());let o=await t.callBuffer("DUMP",r);if(!o)throw Tt();return{key:pe(r),revision:ze(o),deleted:!1}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async applyKeyAction(e){let t=null;try{t=await Ft(se(e.db));let r=or(e.key),a=e.operation.action==="rename"?Y(e.operation.newKey.base64):null;a&&!a.equals(r)?await t.watch(r,a):await t.watch(r);let[o,s,c]=await Promise.all([t.callBuffer("DUMP",r),t.callBuffer("TYPE",r),t.pttl(r)]),i=o;if(!i)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&ze(i)!==e.expectedRevision)throw Tt();let l=ar(s);if(a&&!a.equals(r)&&await t.exists(a)!==0)throw new _(409,{message:"A Redis key with the new name already exists."});let u=t.multi();switch(e.operation.action){case"rename":if(!a||a.equals(r))return{key:pe(r),revision:ze(i),deleted:!1};u.rename(r,a);break;case"setTtl":e.operation.ttlMs===null?u.persist(r):u.pexpire(r,e.operation.ttlMs);break;case"setString":ye(l,"string"),u.set(r,Y(e.operation.value.base64)),c>0&&u.pexpire(r,c);break;case"upsertHash":ye(l,"hash"),u.hset(r,Y(e.operation.field.base64),Y(e.operation.value.base64));break;case"deleteHash":ye(l,"hash"),u.hdel(r,Y(e.operation.field.base64));break;case"pushList":ye(l,"list"),e.operation.side==="left"?u.lpush(r,Y(e.operation.value.base64)):u.rpush(r,Y(e.operation.value.base64));break;case"setList":ye(l,"list"),u.lset(r,e.operation.index,Y(e.operation.value.base64));break;case"deleteList":{ye(l,"list");let p=Buffer.concat([Buffer.from("db-studio:list-delete:"),il(32)]);u.lset(r,e.operation.index,p),u.lrem(r,1,p);break}case"addSet":ye(l,"set"),u.sadd(r,Y(e.operation.member.base64));break;case"removeSet":ye(l,"set"),u.srem(r,Y(e.operation.member.base64));break;case"upsertZset":ye(l,"zset"),u.zadd(r,e.operation.score,Y(e.operation.member.base64));break;case"removeZset":ye(l,"zset"),u.zrem(r,Y(e.operation.member.base64));break;case"appendStream":ye(l,"stream"),u.xadd(r,e.operation.id,...e.operation.fields.flatMap(({field:p,value:f})=>[Y(p.base64),Y(f.base64)]));break;case"deleteStream":ye(l,"stream"),u.xdel(r,e.operation.id);break}hn(await u.exec());let m=a&&!a.equals(r)?a:r,d=await t.callBuffer("DUMP",m);return{key:pe(m),revision:d?ze(d):null,deleted:d===null}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async deleteKey(e){let t=null;try{t=await Ft(se(e.db));let r=or(e.key);await t.watch(r);let a=await t.callBuffer("DUMP",r);if(!a)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&ze(a)!==e.expectedRevision)throw Tt();let o=t.multi().del(r);return hn(await o.exec()),{deleted:!0}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async getDatabasesList(){try{let e=await de(Ke()),t=1,r=!1,a=null;try{a=await e.call("CONFIG","GET","databases")}catch(i){if(!gn(i))throw i}if(Array.isArray(a)&&a.length>=2){let i=Number.parseInt(String(a[1]),10);Number.isFinite(i)&&i>0&&(t=i,r=!0)}let o="";try{o=await e.info("keyspace")}catch(i){if(!gn(i))throw i}let s=Cl(o);return(r?Array.from({length:t},(i,l)=>l):[Ke()]).map(i=>({name:String(i),size:`${s.get(i)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(Ke())}}async getDatabaseConnectionInfo(){try{let e=await de(Ke()),[t,r]=await Promise.all([e.info("server"),e.info("clients")]),a=co(t),o=co(r),s=Number.parseInt(o.maxclients??"0",10);if(!Number.isFinite(s)||s===0){let i=await e.call("CONFIG","GET","maxclients").catch(l=>{if(!gn(l))throw l;return null});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??Ke()),version:a.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=se(e),r=await this.getCachedCounts(t);return Et.map(a=>({tableName:a,rowCount:r[a]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new _(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new _(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=qe(e);return Rl[t]}async getTableColumns({tableName:e}){let t=qe(e);return lo[t]}async addColumn(e){throw new _(400,{message:nr})}async deleteColumn(e){throw new _(400,{message:nr})}async alterColumn(e){throw new _(400,{message:nr})}async renameColumn(e){throw new _(400,{message:nr})}async getTableData(e){try{let{tableName:t,db:r,cursor:a,limit:o=50,direction:s="asc",sort:c,filters:i}=e;if(s==="desc")throw new _(400,{message:ul});if(c&&c.length>0)throw new _(400,{message:ll});if(i&&i.length>0)throw new _(400,{message:cl});let l=qe(t),u=bn[l],m=se(r),d=await de(m),p="0";if(a){let D=Sl(a);if(!D||D.type!==l)throw new _(400,{message:"Invalid or mismatched cursor"});p=D.scanCursor}let f=[],y=0,h=!1;for(;f.length<o&&y<ml;){let[D,x]=await d.scan(p,"MATCH","*","COUNT",Math.max(o*2,100),"TYPE",u);if(f.push(...x),p=D,y++,D==="0"){h=!0;break}}let w=f.slice(0,o),E=f.slice(o),A=await this.hydrateRows(d,l,w),C=await d.dbsize(),R=!h||E.length>0,S=R&&!h?wl({scanCursor:p,type:l}):null;return{data:A,meta:{limit:o,total:C,hasNextPage:R,hasPreviousPage:!1,nextCursor:S,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,r){if(r.length===0)return[];let a=e.pipeline();for(let i of r)a.ttl(i);let o=await a.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 p=Dl(m);return this.normalizeRow({key:i,length:p.length,"first-id":p.firstId,"last-id":p.lastId,ttl:u})}let d;switch(t){case"strings":d=m??null;break;case"hashes":d=m;break;case"lists":case"sets":d=m;break;case"zsets":d=Al(m);break}return this.normalizeRow({key:i,value:d,ttl:u})})}async getCachedCounts(e){let t=this.countCache.get(e);if(t&&Date.now()-t.timestamp<dl)return t.counts;let r=await de(e),a={},o=r.pipeline();for(let c of Et)o.scan("0","MATCH","*","COUNT",pl,"TYPE",bn[c]);let s=await o.exec()??[];return Et.forEach((c,i)=>{let l=s[i]?.[1];a[c]=l?.[1]?.length??0}),this.countCache.set(e,{timestamp:Date.now(),counts:a}),a}async addRecord({db:e,params:t}){try{let{tableName:r,data:a}=t,o=qe(r),s=uo(a),c=Tn(a),i=await de(se(e));return await this.writeRecord(i,o,s,a.value,{mode:"create",ttl:c}),this.countCache.delete(se(e)),{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:a,primaryKey:o}=t,s=qe(r),c=o||"key",i=await de(se(e)),l=new Map;for(let m of a){let d=m.rowData[c];if(d==null)throw new _(400,{message:`Primary key "${c}" not found in row data`});let p=String(d),f=l.get(p)??{...m.rowData};f[m.columnName]=m.value,l.set(p,f)}let u=0;for(let[m,d]of l.entries()){let p=d.value,f=Tn(d);await this.writeRecord(i,s,m,p,{mode:"update",ttl:f}),u++}return{updatedCount:u}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:a}=e;qe(t);let o=await de(se(a)),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(se(a)),{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:a}=e;if(!r||r.length===0)throw new _(400,{message:"At least one record is required"});let o=qe(t),s=await de(se(a)),c=[],i=0;for(let l=0;l<r.length;l++){let u=r[l];try{let m=uo(u),d=Tn(u);await this.writeRecord(s,o,m,u.value,{mode:"create",ttl:d}),i++}catch(m){c.push({recordIndex:l,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(se(a)),{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=qe(e),a=se(t),o=await de(a),s=bn[r],c=[],i="0";do{let[m,d]=await o.scan(i,"MATCH","*","COUNT",1e3,"TYPE",s);c.push(...d),i=m}while(i!=="0");if(c.length===0)throw new _(404,{message:`Table "${e}" has no data`});let l=await this.hydrateRows(o,r,c);return{cols:lo[r].map(m=>m.columnName),rows:l}}catch(r){throw this.wrapError(r)}}async writeRecord(e,t,r,a,o){if(t==="streams"&&o.mode==="update")throw new _(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 a=="string"?a:JSON.stringify(a),"NX")===null)throw new _(409,{message:`Key "${r}" already exists`})}else{if(await e.exists(r))throw new _(409,{message:`Key "${r}" already exists`});await this.writeCollectionValue(e,t,r,a)}else if(t==="strings"){if(await e.set(r,typeof a=="string"?a:JSON.stringify(a),"XX")===null)throw new _(404,{message:`Key "${r}" does not exist`})}else{if(!await e.exists(r))throw new _(404,{message:`Key "${r}" does not exist`});await e.del(r),await this.writeCollectionValue(e,t,r,a)}o.ttl!==null&&o.ttl>0&&await e.expire(r,o.ttl)}async writeCollectionValue(e,t,r,a){switch(t){case"hashes":{let o=mo(a,"hash"),s=[];for(let[c,i]of Object.entries(o))s.push(c,sr(i));if(s.length===0)throw new _(400,{message:"Hash must have at least one field"});await e.hset(r,...s);return}case"lists":{let o=po(a,"list");if(o.length===0)throw new _(400,{message:"List must have at least one element"});await e.rpush(r,...o.map(sr));return}case"sets":{let o=po(a,"set");if(o.length===0)throw new _(400,{message:"Set must have at least one member"});await e.sadd(r,...o.map(sr));return}case"zsets":{let o=Nl(a);if(o.length===0)throw new _(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=mo(a,"stream"),s=[];for(let[c,i]of Object.entries(o))s.push(c,sr(i));if(s.length===0)throw new _(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 _(400,{message:"Query is required"});let a;try{a=oo(e.trim())}catch(u){throw new _(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(a.length===0)throw new _(400,{message:"Empty command"});let o=await de(se(t)),[s,...c]=a,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{...so(a,i),duration:performance.now()-r,message:typeof i=="string"?i:void 0}}catch(a){throw this.wrapError(a)}}}});function En(n){if(!n.length)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":e.push(`CAST(${a} AS TEXT) LIKE ?`),t.push(r.value);break;case"not like":e.push(`CAST(${a} AS TEXT) NOT LIKE ?`),t.push(r.value);break;case"ilike":e.push(`CAST(${a} AS TEXT) LIKE ? COLLATE NOCASE`),t.push(r.value);break;case"not ilike":e.push(`CAST(${a} 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 wn(n,e){return Array.isArray(n)?n.length?`ORDER BY ${n.map(t=>`"${t.columnName}" ${t.direction.toUpperCase()}`).join(", ")}`:"":n&&typeof n=="string"?`ORDER BY "${n}" ${e?.toUpperCase()||"ASC"}`:""}function Sn(n,e,t){let{values:r,sortColumns:a}=n;if(!a.length)return{clause:"",values:[]};let i=t==="asc"===(e==="asc")?">":"<",l=a.map(d=>`"${d}"`).join(", "),u=a.map(()=>"?").join(", "),m=a.map(d=>r[d]);return{clause:`(${l}) ${i} (${u})`,values:m}}var yo=N(()=>{"use strict";b()});import{statSync as _l}from"fs";import{HTTPException as q}from"hono/http-exception";var lr,bo=N(()=>{"use strict";b();Ce();He();Ve();yo();lr=class extends me{async runQuery(e,t,r){return Z().prepare(t).all(...r)}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return Yt(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:a=50,direction:o="asc",sort:s=[],order:c="asc",filters:i=[]}=e,l=[],u=c;Array.isArray(s)&&s.length>0?(l=s.map(R=>R.columnName),u=s[0].direction):typeof s=="string"&&s&&(l=[s]),l.length||(l=["rowid"]);let{clause:m,values:d}=En(i),p="",f=[];if(r){let R=this.decodeCursor(r);if(R){let S=Sn(R,o,u);p=S.clause,f=S.values}}let y="";m&&p?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${p}`:m?y=m:p&&(y=`WHERE ${p}`);let h=wn((Array.isArray(s),s),c),w=h;o==="desc"?h?w=h.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):w=`ORDER BY ${l.map(R=>`"${R}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:h||(w=`ORDER BY ${l.map(R=>`"${R}" ${u.toUpperCase()}`).join(", ")}`);let E=`SELECT * FROM "${t}" ${y} ${w} LIMIT ?`,A=[...d,...f,a+1],C=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:E,values:A,countSql:C,countValues:d}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(!t.length)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,c=[];Array.isArray(o)&&o.length>0?c=o.map(p=>p.columnName):typeof o=="string"&&o&&(c=[o]),c.length||(c=["rowid"]);let i=p=>{let f={values:Object.fromEntries(c.map(y=>[y,p[y]])),sortColumns:c};return this.encodeCursor(f)},l=t[0],u=t[t.length-1],m=null,d=null;return a==="asc"?(r&&(m=i(u)),s&&(d=i(l))):(s&&(m=i(u)),r&&(d=i(l))),{nextCursor:m,prevCursor:d}}async getTableData(e){try{let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:c="asc",cursor:i,filters:l=[]}=e,u=Z(),d=u.prepare(`PRAGMA table_info("${t}")`).all().filter(F=>F.pk>0).sort((F,ue)=>F.pk-ue.pk).map(F=>F.name),p=[],f=c;Array.isArray(s)&&s.length>0?(p=s.map(F=>F.columnName),f=s[0].direction):typeof s=="string"&&s&&(p=[s]);let y=[...p,...d.filter(F=>!p.includes(F))],h=y.length===0;h&&y.push("rowid");let{clause:w,values:E}=En(l),A="",C=[];if(i){let F=this.decodeCursor(i);if(F){let ue=Sn(F,o,f);A=ue.clause,C=ue.values}}let R="";w&&A?R=`WHERE ${w.replace(/^WHERE\s+/i,"")} AND ${A}`:w?R=w:A&&(R=`WHERE ${A}`);let S=wn((Array.isArray(s),s),c),D=d.filter(F=>!p.includes(F)),x=S;if(o==="desc")if(S){if(x=S.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),D.length){let F=f==="asc"?"DESC":"ASC";x+=`, ${D.map(ue=>`"${ue}" ${F}`).join(", ")}`}}else x=`ORDER BY ${y.map(F=>`"${F}" ${f==="asc"?"DESC":"ASC"}`).join(", ")}`;else S?D.length&&(x+=`, ${D.map(F=>`"${F}" ${f.toUpperCase()}`).join(", ")}`):x=`ORDER BY ${y.map(F=>`"${F}" ${f.toUpperCase()}`).join(", ")}`;let v=u.prepare(`SELECT COUNT(*) as total FROM "${t}" ${w}`).get(...E),O=Number(v?.total??0),k=h?"*, rowid":"*",B=u.prepare(`SELECT ${k} FROM "${t}" ${R} ${x} LIMIT ?`).all(...E,...C,a+1),H=B.length>a,Q=H?B.slice(0,a):B;o==="desc"&&(Q=Q.reverse());let ae=F=>({values:Object.fromEntries(y.map(ue=>[ue,F[ue]])),sortColumns:y}),X=null,ee=null;if(Q.length>0){let F=Q[0],ue=Q[Q.length-1];o==="asc"?(H&&(X=this.encodeCursor(ae(ue))),i&&(ee=this.encodeCursor(ae(F)))):(i&&(X=this.encodeCursor(ae(ue))),H&&(ee=this.encodeCursor(ae(F))))}return{data:h?Q.map(({rowid:F,...ue})=>ue):Q,meta:{limit:a,total:O,hasNextPage:o==="asc"?H:!!i,hasPreviousPage:o==="asc"?!!i:H,nextCursor:X,prevCursor:ee}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=Z().prepare("PRAGMA database_list").all();if(!t.length)throw new q(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 q?e:this.wrapError(e)}}async getCurrentDatabase(){try{return{db:Z().prepare("PRAGMA database_list").all().find(a=>a.name==="main")?.name??"main"}}catch(e){throw this.wrapError(e)}}async getDatabaseConnectionInfo(){try{return{host:null,port:null,user:"",database:"main",version:`SQLite ${Z().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=Z();return t.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all().map(a=>{let o=t.prepare(`SELECT COUNT(*) as count FROM "${a.name}"`).get();return{tableName:a.name,rowCount:o?.count??0}})}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=Z(),c=a.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,a=Z();if(!a.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new q(404,{message:`Table "${t}" does not exist`});let c=a.prepare(`SELECT COUNT(*) as count FROM "${t}"`).get()?.count??0;if(!r&&this.getFkReferencesForTable(a,t).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:this.getRelatedRecordsForTable(a,t)};try{return a.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(a,t)};throw i instanceof q?i:new q(500,{message:`Failed to delete table "${t}"`})}}async getTableSchema({tableName:e,db:t}){try{let a=Z().prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name=?").get(e);if(!a)throw new q(404,{message:`Table "${e}" does not exist`});return a.sql}catch(r){throw r instanceof q?r:this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let r=Z();if(!r.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(e))throw new q(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:Yt(u),dataTypeLabel:Hr(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 q?r:this.wrapError(r)}}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isNullable:s,isUnique:c,db:i}=e,l=Z();if(!l.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new q(404,{message:`Table "${t}" does not exist`});if(l.prepare(`PRAGMA table_info("${t}")`).all().some(p=>p.name===r))throw new q(409,{message:`Column "${r}" already exists in table "${t}"`});let d=`"${r}" ${a}`;c&&(d+=" UNIQUE"),s||(d+=" NOT NULL"),o?.trim()&&(d+=` DEFAULT ${o.trim()}`);try{l.prepare(`ALTER TABLE "${t}" ADD COLUMN ${d}`).run()}catch(p){throw this.wrapError(p)}}async deleteColumn(e){let{tableName:t,columnName:r,db:a}=e,o=Z();if(!o.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new q(404,{message:`Table "${t}" does not exist`});if(!o.prepare(`PRAGMA table_info("${t}")`).all().some(i=>i.name===r))throw new q(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:a,isNullable:o,defaultValue:s,db:c}=e,i=Z();if(!i.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new q(404,{message:`Table "${t}" does not exist`});let u=i.prepare(`PRAGMA table_info("${t}")`).all();if(!u.some(S=>S.name===r))throw new q(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=u.filter(S=>S.pk>0).sort((S,D)=>S.pk-D.pk),d=m.length>1,p=u.map(S=>{let D=S.name===r,x=D?a:S.type,v=D?o:S.notnull===0,O=D?s?.trim()||null:S.dflt_value,k=S.pk>0,B=`"${S.name}" ${x}`;return!d&&k&&(B+=" PRIMARY KEY"),!k&&!v&&(B+=" NOT NULL"),O&&(B+=` DEFAULT ${O}`),B});d&&p.push(`PRIMARY KEY (${m.map(S=>`"${S.name}"`).join(", ")})`);let f=i.prepare(`PRAGMA foreign_key_list("${t}")`).all(),y=new Map;for(let S of f){let D=y.get(S.id)??[];D.push(S),y.set(S.id,D)}let h=Array.from(y.values()).map(S=>{let D=S.map(B=>`"${B.from}"`).join(", "),x=S.map(B=>`"${B.to}"`).join(", "),{table:v,on_update:O,on_delete:k}=S[0];return`FOREIGN KEY (${D}) REFERENCES "${v}" (${x}) ON UPDATE ${O} ON DELETE ${k}`}),w=u.map(S=>`"${S.name}"`).join(", "),E=`${t}_alter_${Date.now()}`,A=i.prepare("SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL").all(t),C=i.prepare("SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?").all(t);i.pragma("foreign_keys = OFF");let R=i.transaction(()=>{i.prepare(`CREATE TABLE "${E}" (${[...p,...h].join(", ")})`).run(),i.prepare(`INSERT INTO "${E}" (${w}) SELECT ${w} FROM "${t}"`).run(),i.prepare(`DROP TABLE "${t}"`).run(),i.prepare(`ALTER TABLE "${E}" RENAME TO "${t}"`).run()});try{R();for(let{sql:S}of A)i.prepare(S).run();for(let{sql:S}of C)i.prepare(S).run()}catch(S){throw S instanceof q?S:this.wrapError(S)}finally{i.pragma("foreign_keys = ON")}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=Z();if(!s.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(t))throw new q(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 q(404,{message:`Column "${r}" does not exist in table "${t}"`});if(i.some(l=>l.name===a))throw new q(409,{message:`Column "${a}" already exists in table "${t}"`});try{s.prepare(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${a}"`).run()}catch(l){throw this.wrapError(l)}}async addRecord({params:e}){let{tableName:t,data:r}=e,a=Z(),o=Object.keys(r);if(!o.length)throw new q(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=a.prepare(`INSERT INTO "${t}" (${c}) VALUES (${i})`).run(...s);if(l.changes===0)throw new q(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:a,primaryKey:o}=t,s=Z(),c=new Map;for(let l of a){let u=l.rowData[o];if(u==null)throw new q(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 d=m.map(y=>`"${y.columnName}" = ?`).join(", "),p=[...m.map(y=>y.value!==null&&typeof y.value=="object"?JSON.stringify(y.value):y.value),u],f=s.prepare(`UPDATE "${r}" SET ${d} WHERE "${o}" = ?`).run(...p);if(f.changes===0)throw new q(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 q?l:this.wrapError(l)}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=Z(),o=t[0]?.columnName;if(!o)throw new q(400,{message:"Primary key column name is required"});let s=t.map(l=>l.value),c=s.map(()=>"?").join(", "),i=a.transaction(()=>a.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(a,e,t)};throw this.wrapError(l)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=Z(),o=t[0]?.columnName;if(!o)throw new q(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value);a.pragma("foreign_keys = OFF");let c=a.transaction(()=>{let i=this.getFkReferencesForTable(a,e),l=0;for(let d of i){let p=s.map(()=>"?").join(", "),f=a.prepare(`DELETE FROM "${d.referencingTable}" WHERE "${d.referencingColumn}" IN (${p})`).run(...s);l+=f.changes}let u=s.map(()=>"?").join(", ");return a.prepare(`DELETE FROM "${e}" WHERE "${o}" IN (${u})`).run(...s).changes+l});try{return{deletedCount:c()}}catch(i){throw i instanceof q?i:this.wrapError(i)}finally{a.pragma("foreign_keys = ON")}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t?.length)throw new q(400,{message:"At least one record is required"});let a=Z(),o=Object.keys(t[0]),s=o.map(u=>`"${u}"`).join(", "),c=o.map(()=>"?").join(", "),i=a.prepare(`INSERT INTO "${e}" (${s}) VALUES (${c})`),l=a.transaction(u=>{let m=0;for(let d of u){let p=o.map(f=>{let y=d[f];return y!==null&&typeof y=="object"?JSON.stringify(y):y});i.run(...p),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 q?u:this.wrapError(u)}}async executeQuery({query:e,db:t}){let r=Z();if(!e?.trim())throw new q(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now();try{let s=r.prepare(a);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=_l(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(),a=[];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&&a.push({constraintName:`fk_${o.name}_${c.from}_${t}_${c.to}`,referencingTable:o.name,referencingColumn:c.from,referencedTable:t,referencedColumn:c.to})}return a}getRelatedRecordsForTable(e,t){let r=this.getFkReferencesForTable(e,t);if(!r.length)return[];let a=[];for(let o of r){let s=e.prepare(`SELECT * FROM "${o.referencingTable}" LIMIT 100`).all();s.length>0&&a.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return a}getRelatedRecords(e,t,r){let a=this.getFkReferencesForTable(e,t);if(!a.length)return[];let o=[];for(let s of a){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 go(){fe.register("pg",new rr),fe.register("mysql",new tr),fe.register("mssql",new Zt),fe.register("mongodb",new Ht),fe.register("sqlite",new lr),fe.register("redis",new ir)}var ho=N(()=>{"use strict";b();$e();la();Ya();Ja();Za();fo();bo()});import{HTTPException as To}from"hono/http-exception";import{DatabaseError as vl}from"pg";import{ZodError as xl}from"zod";function Eo(n,e){let t=ut(e.req.method,e.req.path),r=Ol(n);if(Rr("error","request_failed",{operation:t,error_type:r}),wr(n,t),n instanceof To)return e.json({error:n.message??"Internal server error"},n.status);if(n instanceof xl){let a=n.issues[0];return e.json({error:"Validation error",details:a.message},400)}if(n instanceof Error){let a=n;if(a.code==="ECONNREFUSED"||a.code==="ENOTFOUND"||a.code==="ETIMEDOUT"||a.code==="ER_ACCESS_DENIED_ERROR"||a.code==="ER_BAD_HOST_ERROR"||a.code==="ECONNRESET"||a.errno===1045||a.errno===2003||a.errno===2002||n.message.includes("ECONNREFUSED")||n.message.includes("connection refused")||n.message.includes("timeout expired")||n.message.includes("Connection terminated")||n.message.includes("MongoNetworkError")||n.message.includes("MongoServerSelectionError")||n instanceof vl&&n.code?.startsWith("08"))return e.json({error:"Database connection failed",details:n.message},503)}return e.json({error:n instanceof Error?n.message:"Internal server error"},500)}var Ol,wo=N(()=>{"use strict";b();mt();Ol=n=>n instanceof To?"HTTPException":n instanceof Error?n.name:"UnknownError"});function Ro(n){if(!n)return`You are a database assistant for db-studio. Keep answers concise and focused.
311
+ -- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},mr=class extends de{countCache=new Map;runQuery(){throw new _(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new _(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 scanKeys(e){try{let{db:t,limit:r,search:n,exactPattern:o,type:s,cursor:c}=e,i=se(t),l=await pe(i),u="0";if(c){let w=Ul(c);if(!w||w.search!==n||w.exactPattern!==o||w.type!==s)throw new _(400,{message:"Invalid or stale key scan cursor"});u=w.scanCursor}let m=n?o?n:`*${Fl(n)}*`:"*",p=[u,"MATCH",m,"COUNT",r];s&&p.push("TYPE",s);let[d,f]=await l.scanBuffer(...p),y=Buffer.isBuffer(d)?d.toString("utf8"):d,g=l.pipeline();for(let w of f)g.call("TYPE",w),g.pttl(w),g.call("MEMORY","USAGE",w);let E=await g.exec()??[];return{keys:f.map((w,A)=>{let N=A*3,R=E[N+2]?.[1];return{key:fe(w),type:lr(E[N]?.[1]),ttlMs:Number(E[N+1]?.[1]??-2),memoryBytes:R==null?null:Number(R)}}),nextCursor:y==="0"?null:ql({scanCursor:y,search:n,exactPattern:o,type:s}),hasMore:y!=="0"}}catch(t){throw this.wrapError(t)}}async getKeyDetails(e){try{let{db:t,key:r,cursor:n,limit:o,full:s,direction:c}=e,i=cr(r),l=await pe(se(t)),[u,m,p,d]=await Promise.all([l.callBuffer("TYPE",i),l.pttl(i),l.call("MEMORY","USAGE",i).catch(()=>null),l.callBuffer("DUMP",i)]),f=d;if(!f)throw new _(404,{message:"Redis key no longer exists"});let y=lr(u),g={key:fe(i),type:y,ttlMs:Number(m),memoryBytes:p===null?null:Number(p),revision:Ye(f)},E=n?Bl(n):null;if(n&&(!E||E.key!==r||E.type!==y||E.direction!==c))throw new _(400,{message:"Invalid or stale key details cursor"});if(y==="string"){let w=await l.strlen(i),A=s?Il:Ll,N=await l.getrangeBuffer(i,0,A-1);return{...g,length:w,value:{kind:"string",value:fe(N),truncated:w>A},nextCursor:null,hasMore:!1}}if(y==="hash"){let[w,A]=await Promise.all([l.hlen(i),l.hscanBuffer(i,E?.cursor??"0","COUNT",String(o))]),[N,R]=A,S=Buffer.isBuffer(N)?N.toString("utf8"):N,D=[];for(let v=0;v<R.length;v+=2)D.push({field:fe(R[v]),value:fe(R[v+1])});return{...g,length:w,value:{kind:"hash",entries:D},nextCursor:S==="0"?null:wt({key:r,type:y,cursor:S,direction:c}),hasMore:S!=="0"}}if(y==="list"){let w=Number.parseInt(E?.cursor??"0",10),A=await l.llen(i),N=await l.lrangeBuffer(i,w,w+o-1),R=w+N.length,S=R<A;return{...g,length:A,value:{kind:"list",entries:N.map((D,v)=>({index:w+v,value:fe(D)}))},nextCursor:S?wt({key:r,type:y,cursor:String(R),direction:c}):null,hasMore:S}}if(y==="set"){let[w,A]=await Promise.all([l.scard(i),l.sscanBuffer(i,E?.cursor??"0","COUNT",String(o))]),[N,R]=A,S=Buffer.isBuffer(N)?N.toString("utf8"):N;return{...g,length:w,value:{kind:"set",members:R.map(fe)},nextCursor:S==="0"?null:wt({key:r,type:y,cursor:S,direction:c}),hasMore:S!=="0"}}if(y==="zset"){let[w,A]=await Promise.all([l.zcard(i),l.zscanBuffer(i,E?.cursor??"0","COUNT",String(o))]),[N,R]=A,S=Buffer.isBuffer(N)?N.toString("utf8"):N,D=[];for(let v=0;v<R.length;v+=2)D.push({member:fe(R[v]),score:(()=>{let x=R[v+1].toString("utf8");return x==="inf"?"inf":x==="-inf"?"-inf":Number(x)})()});return{...g,length:w,value:{kind:"zset",entries:D},nextCursor:S==="0"?null:wt({key:r,type:y,cursor:S,direction:c}),hasMore:S!=="0"}}if(y==="stream"){let w=E?.cursor??(c==="forward"?"-":"+"),[A,N]=await Promise.all([l.xlen(i),c==="forward"?l.xrangeBuffer(i,w,"+","COUNT",o+1):l.xrevrangeBuffer(i,w,"-","COUNT",o+1)]),R=N.length>o,D=N.slice(0,o).map(([x,$])=>{let P=[];for(let F=0;F<$.length;F+=2)P.push({field:fe($[F]),value:fe($[F+1])});return{id:x.toString("utf8"),fields:P}}),v=D.at(-1)?.id;return{...g,length:A,value:{kind:"stream",entries:D},nextCursor:R&&v?wt({key:r,type:y,cursor:`(${v}`,direction:c}):null,hasMore:R}}return{...g,length:null,value:{kind:"unknown"},nextCursor:null,hasMore:!1}}catch(t){throw this.wrapError(t)}}async getStringChunk(e){try{let t=await pe(se(e.db)),r=cr(e.key),n=lr(await t.callBuffer("TYPE",r));if(n==="unknown")throw new _(404,{message:"Redis key no longer exists"});if(be(n,"string"),e.expectedRevision){let i=await t.callBuffer("DUMP",r);if(!i||Ye(i)!==e.expectedRevision)throw St()}let o=await t.strlen(r),s=await t.getrangeBuffer(r,e.offset,e.offset+e.limit-1),c=e.offset+s.length;return{chunk:fe(s),length:o,nextOffset:c<o?c:null,hasMore:c<o}}catch(t){throw this.wrapError(t)}}async createKey(e){let t=null;try{t=await Vt(se(e.db));let r=G(e.key.base64);if(await t.watch(r),await t.exists(r)!==0)throw new _(409,{message:"A Redis key with this name already exists."});if(e.type!==e.value.kind)throw new _(400,{message:"The initial value does not match the selected Redis key type."});let n=t.multi();switch(e.value.kind){case"string":n.set(r,G(e.value.value.base64));break;case"hash":n.hset(r,...e.value.entries.flatMap(({field:s,value:c})=>[G(s.base64),G(c.base64)]));break;case"list":n.rpush(r,...e.value.entries.map(s=>G(s.base64)));break;case"set":n.sadd(r,...e.value.members.map(s=>G(s.base64)));break;case"zset":n.zadd(r,...e.value.entries.flatMap(({member:s,score:c})=>[c,G(s.base64)]));break;case"stream":n.xadd(r,e.value.id,...e.value.fields.flatMap(({field:s,value:c})=>[G(s.base64),G(c.base64)]));break}e.ttlMs!==null&&n.pexpire(r,e.ttlMs),wa(await n.exec());let o=await t.callBuffer("DUMP",r);if(!o)throw St();return{key:fe(r),revision:Ye(o),deleted:!1}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async applyKeyAction(e){let t=null;try{t=await Vt(se(e.db));let r=cr(e.key),n=e.operation.action==="rename"?G(e.operation.newKey.base64):null;n&&!n.equals(r)?await t.watch(r,n):await t.watch(r);let[o,s,c]=await Promise.all([t.callBuffer("DUMP",r),t.callBuffer("TYPE",r),t.pttl(r)]),i=o;if(!i)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&Ye(i)!==e.expectedRevision)throw St();let l=lr(s);if(n&&!n.equals(r)&&await t.exists(n)!==0)throw new _(409,{message:"A Redis key with the new name already exists."});let u=t.multi();switch(e.operation.action){case"rename":if(!n||n.equals(r))return{key:fe(r),revision:Ye(i),deleted:!1};u.rename(r,n);break;case"setTtl":e.operation.ttlMs===null?u.persist(r):u.pexpire(r,e.operation.ttlMs);break;case"setString":be(l,"string"),u.set(r,G(e.operation.value.base64)),c>0&&u.pexpire(r,c);break;case"upsertHash":be(l,"hash"),u.hset(r,G(e.operation.field.base64),G(e.operation.value.base64));break;case"deleteHash":be(l,"hash"),u.hdel(r,G(e.operation.field.base64));break;case"pushList":be(l,"list"),e.operation.side==="left"?u.lpush(r,G(e.operation.value.base64)):u.rpush(r,G(e.operation.value.base64));break;case"setList":be(l,"list"),u.lset(r,e.operation.index,G(e.operation.value.base64));break;case"deleteList":{be(l,"list");let d=Buffer.concat([Buffer.from("db-studio:list-delete:"),_l(32)]);u.lset(r,e.operation.index,d),u.lrem(r,1,d);break}case"addSet":be(l,"set"),u.sadd(r,G(e.operation.member.base64));break;case"removeSet":be(l,"set"),u.srem(r,G(e.operation.member.base64));break;case"upsertZset":be(l,"zset"),u.zadd(r,e.operation.score,G(e.operation.member.base64));break;case"removeZset":be(l,"zset"),u.zrem(r,G(e.operation.member.base64));break;case"appendStream":be(l,"stream"),u.xadd(r,e.operation.id,...e.operation.fields.flatMap(({field:d,value:f})=>[G(d.base64),G(f.base64)]));break;case"deleteStream":be(l,"stream"),u.xdel(r,e.operation.id);break}wa(await u.exec());let m=n&&!n.equals(r)?n:r,p=await t.callBuffer("DUMP",m);return{key:fe(m),revision:p?Ye(p):null,deleted:p===null}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async deleteKey(e){let t=null;try{t=await Vt(se(e.db));let r=cr(e.key);await t.watch(r);let n=await t.callBuffer("DUMP",r);if(!n)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&Ye(n)!==e.expectedRevision)throw St();let o=t.multi().del(r);return wa(await o.exec()),{deleted:!0}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async getDatabasesList(){try{let e=await pe(ze()),t=1,r=!1,n=null;try{n=await e.call("CONFIG","GET","databases")}catch(i){if(!Ea(i))throw i}if(Array.isArray(n)&&n.length>=2){let i=Number.parseInt(String(n[1]),10);Number.isFinite(i)&&i>0&&(t=i,r=!0)}let o="";try{o=await e.info("keyspace")}catch(i){if(!Ea(i))throw i}let s=Vl(o);return(r?Array.from({length:t},(i,l)=>l):[ze()]).map(i=>({name:String(i),size:`${s.get(i)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(ze())}}async getDatabaseConnectionInfo(){try{let e=await pe(ze()),[t,r]=await Promise.all([e.info("server"),e.info("clients")]),n=So(t),o=So(r),s=Number.parseInt(o.maxclients??"0",10);if(!Number.isFinite(s)||s===0){let i=await e.call("CONFIG","GET","maxclients").catch(l=>{if(!Ea(l))throw l;return null});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??ze()),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=se(e),r=await this.getCachedCounts(t);return Rt.map(n=>({tableName:n,rowCount:r[n]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new _(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new _(400,{message:"Bulk deletion of Redis tables is not supported. Use FLUSHDB from the query runner to clear the entire logical database."})}async renameTable(e){throw new _(400,{message:Et})}async getTableSchema({tableName:e}){let t=Be(e);return Kl[t]}async getTableColumns({tableName:e}){let t=Be(e);return wo[t]}async addColumn(e){throw new _(400,{message:Et})}async deleteColumn(e){throw new _(400,{message:Et})}async alterColumn(e){throw new _(400,{message:Et})}async renameColumn(e){throw new _(400,{message:Et})}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 _(400,{message:Ol});if(c&&c.length>0)throw new _(400,{message:xl});if(i&&i.length>0)throw new _(400,{message:vl});let l=Be(t),u=Ta[l],m=se(r),p=await pe(m),d="0";if(n){let D=Hl(n);if(!D||D.type!==l)throw new _(400,{message:"Invalid or mismatched cursor"});d=D.scanCursor}let f=[],y=0,g=!1;for(;f.length<o&&y<$l;){let[D,v]=await p.scan(d,"MATCH","*","COUNT",Math.max(o*2,100),"TYPE",u);if(f.push(...v),d=D,y++,D==="0"){g=!0;break}}let E=f.slice(0,o),w=f.slice(o),A=await this.hydrateRows(p,l,E),N=await p.dbsize(),R=!g||w.length>0,S=R&&!g?jl({scanCursor:d,type:l}):null;return{data:A,meta:{limit:o,total:N,hasNextPage:R,hasPreviousPage:!1,nextCursor:S,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=Yl(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=Wl(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<Pl)return t.counts;let r=await pe(e),n={},o=r.pipeline();for(let c of Rt)o.scan("0","MATCH","*","COUNT",kl,"TYPE",Ta[c]);let s=await o.exec()??[];return Rt.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=Be(r),s=Ro(n),c=Sa(n),i=await pe(se(e));return await this.writeRecord(i,o,s,n.value,{mode:"create",ttl:c}),this.countCache.delete(se(e)),{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:n,primaryKey:o,primaryKeys:s}=t,c=Be(r),i=s?.[0]||o||"key",l=await pe(se(e)),u=new Map;for(let p of n){let d=p.rowData[i];if(d==null)throw new _(400,{message:`Primary key "${i}" not found in row data`});let f=String(d),y=u.get(f)??{...p.rowData};y[p.columnName]=p.value,u.set(f,y)}let m=0;for(let[p,d]of u.entries()){let f=d.value,y=Sa(d);await this.writeRecord(l,c,p,f,{mode:"update",ttl:y});let g=d[i],E=g==null?p:String(g);if(E!==p&&await l.renamenx(p,E)===0)throw new _(409,{message:`Key "${E}" already exists`});m++}return{updatedCount:m}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:n}=e;Be(t);let o=await pe(se(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(se(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 _(400,{message:"At least one record is required"});let o=Be(t),s=await pe(se(n)),c=[],i=0;for(let l=0;l<r.length;l++){let u=r[l];try{let m=Ro(u),p=Sa(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(se(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=Be(e),n=se(t),o=await pe(n),s=Ta[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 _(404,{message:`Table "${e}" has no data`});let l=await this.hydrateRows(o,r,c);return{cols:wo[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 _(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 _(409,{message:`Key "${r}" already exists`})}else{if(await e.exists(r))throw new _(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 _(404,{message:`Key "${r}" does not exist`})}else{if(!await e.exists(r))throw new _(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=Co(n,"hash"),s=[];for(let[c,i]of Object.entries(o))s.push(c,ur(i));if(s.length===0)throw new _(400,{message:"Hash must have at least one field"});await e.hset(r,...s);return}case"lists":{let o=No(n,"list");if(o.length===0)throw new _(400,{message:"List must have at least one element"});await e.rpush(r,...o.map(ur));return}case"sets":{let o=No(n,"set");if(o.length===0)throw new _(400,{message:"Set must have at least one member"});await e.sadd(r,...o.map(ur));return}case"zsets":{let o=zl(n);if(o.length===0)throw new _(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=Co(n,"stream"),s=[];for(let[c,i]of Object.entries(o))s.push(c,ur(i));if(s.length===0)throw new _(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 _(400,{message:"Query is required"});let n;try{n=go(e.trim())}catch(u){throw new _(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(n.length===0)throw new _(400,{message:"Empty command"});let o=await pe(se(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{...To(n,i),duration:performance.now()-r,message:typeof i=="string"?i:void 0}}catch(n){throw this.wrapError(n)}}}});function Ra(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 Ca(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 Na(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 Do=C(()=>{"use strict";b()});import{statSync as Gl}from"fs";import{HTTPException as M}from"hono/http-exception";var dr,_o=C(()=>{"use strict";b();Ae();Ve();We();Do();dr=class extends de{async runQuery(e,t,r){return X().prepare(t).all(...r)}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return Xt(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(R=>R.columnName),u=s[0].direction):typeof s=="string"&&s&&(l=[s]),l.length||(l=["rowid"]);let{clause:m,values:p}=Ra(i),d="",f=[];if(r){let R=this.decodeCursor(r);if(R){let S=Na(R,o,u);d=S.clause,f=S.values}}let y="";m&&d?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?y=m:d&&(y=`WHERE ${d}`);let g=Ca((Array.isArray(s),s),c),E=g;o==="desc"?g?E=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):E=`ORDER BY ${l.map(R=>`"${R}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(E=`ORDER BY ${l.map(R=>`"${R}" ${u.toUpperCase()}`).join(", ")}`);let w=`SELECT * FROM "${t}" ${y} ${E} LIMIT ?`,A=[...p,...f,n+1],N=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:w,values:A,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(y=>[y,d[y]])),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=X(),p=u.prepare(`PRAGMA table_info("${t}")`).all().filter(j=>j.pk>0).sort((j,me)=>j.pk-me.pk).map(j=>j.name),d=[],f=c;Array.isArray(s)&&s.length>0?(d=s.map(j=>j.columnName),f=s[0].direction):typeof s=="string"&&s&&(d=[s]);let y=[...d,...p.filter(j=>!d.includes(j))],g=y.length===0;g&&y.push("rowid");let{clause:E,values:w}=Ra(l),A="",N=[];if(i){let j=this.decodeCursor(i);if(j){let me=Na(j,o,f);A=me.clause,N=me.values}}let R="";E&&A?R=`WHERE ${E.replace(/^WHERE\s+/i,"")} AND ${A}`:E?R=E:A&&(R=`WHERE ${A}`);let S=Ca((Array.isArray(s),s),c),D=p.filter(j=>!d.includes(j)),v=S;if(o==="desc")if(S){if(v=S.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),D.length){let j=f==="asc"?"DESC":"ASC";v+=`, ${D.map(me=>`"${me}" ${j}`).join(", ")}`}}else v=`ORDER BY ${y.map(j=>`"${j}" ${f==="asc"?"DESC":"ASC"}`).join(", ")}`;else S?D.length&&(v+=`, ${D.map(j=>`"${j}" ${f.toUpperCase()}`).join(", ")}`):v=`ORDER BY ${y.map(j=>`"${j}" ${f.toUpperCase()}`).join(", ")}`;let x=u.prepare(`SELECT COUNT(*) as total FROM "${t}" ${E}`).get(...w),$=Number(x?.total??0),P=g?"*, rowid":"*",F=u.prepare(`SELECT ${P} FROM "${t}" ${R} ${v} LIMIT ?`).all(...w,...N,n+1),H=F.length>n,Q=H?F.slice(0,n):F;o==="desc"&&(Q=Q.reverse());let oe=j=>({values:Object.fromEntries(y.map(me=>[me,j[me]])),sortColumns:y}),Z=null,ee=null;if(Q.length>0){let j=Q[0],me=Q[Q.length-1];o==="asc"?(H&&(Z=this.encodeCursor(oe(me))),i&&(ee=this.encodeCursor(oe(j)))):(i&&(Z=this.encodeCursor(oe(me))),H&&(ee=this.encodeCursor(oe(j))))}return{data:g?Q.map(({rowid:j,...me})=>me):Q,meta:{limit:n,total:$,hasNextPage:o==="asc"?H:!!i,hasPreviousPage:o==="asc"?!!i:H,nextCursor:Z,prevCursor:ee}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=X().prepare("PRAGMA database_list").all();if(!t.length)throw new M(500,{message:"No databases returned from SQLite"});return t.filter(r=>r.name!=="temp").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:X().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 ${X().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=X();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=X(),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=X();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 renameTable(e){let{tableName:t,newTableName:r,db:n}=e;this.assertDifferentTableName(t,r);let o=X();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("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(r))throw new M(409,{message:`Table "${r}" already exists`});try{let i=l=>l.replaceAll('"','""');o.prepare(`ALTER TABLE "${i(t)}" RENAME TO "${i(r)}"`).run()}catch(i){throw this.wrapError(i)}}async getTableSchema({tableName:e,db:t}){try{let n=X().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=X();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:Xt(u),dataTypeLabel:Wr(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=X();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=X();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=X();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(S=>S.name===r))throw new M(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=u.filter(S=>S.pk>0).sort((S,D)=>S.pk-D.pk),p=m.length>1,d=u.map(S=>{let D=S.name===r,v=D?n:S.type,x=D?o:S.notnull===0,$=D?s?.trim()||null:S.dflt_value,P=S.pk>0,F=`"${S.name}" ${v}`;return!p&&P&&(F+=" PRIMARY KEY"),!P&&!x&&(F+=" NOT NULL"),$&&(F+=` DEFAULT ${$}`),F});p&&d.push(`PRIMARY KEY (${m.map(S=>`"${S.name}"`).join(", ")})`);let f=i.prepare(`PRAGMA foreign_key_list("${t}")`).all(),y=new Map;for(let S of f){let D=y.get(S.id)??[];D.push(S),y.set(S.id,D)}let g=Array.from(y.values()).map(S=>{let D=S.map(F=>`"${F.from}"`).join(", "),v=S.map(F=>`"${F.to}"`).join(", "),{table:x,on_update:$,on_delete:P}=S[0];return`FOREIGN KEY (${D}) REFERENCES "${x}" (${v}) ON UPDATE ${$} ON DELETE ${P}`}),E=u.map(S=>`"${S.name}"`).join(", "),w=`${t}_alter_${Date.now()}`,A=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 R=i.transaction(()=>{i.prepare(`CREATE TABLE "${w}" (${[...d,...g].join(", ")})`).run(),i.prepare(`INSERT INTO "${w}" (${E}) SELECT ${E} FROM "${t}"`).run(),i.prepare(`DROP TABLE "${t}"`).run(),i.prepare(`ALTER TABLE "${w}" RENAME TO "${t}"`).run()});try{R();for(let{sql:S}of A)i.prepare(S).run();for(let{sql:S}of N)i.prepare(S).run()}catch(S){throw S instanceof M?S:this.wrapError(S)}finally{i.pragma("foreign_keys = ON")}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:n,db:o}=e,s=X();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=X(),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}=t,n=X(),o=this.resolveKeyColumns(t),s=this.groupUpdatesByKey(t,o),c=n.transaction(()=>{let i=0;for(let{keyValues:l,rowUpdates:u}of s){let m=u.map(y=>`"${y.columnName}" = ?`).join(", "),p=[...u.map(y=>y.value!==null&&typeof y.value=="object"?JSON.stringify(y.value):y.value),...l],d=o.map(y=>`"${y}" = ?`).join(" AND "),f=n.prepare(`UPDATE "${r}" SET ${m} WHERE ${d}`).run(...p);if(f.changes===0)throw new M(404,{message:`Record with ${this.describeKey(o,l)} not found in table "${r}"`});i+=f.changes}return i});try{return{updatedCount:c()}}catch(i){throw i instanceof M?i:this.wrapError(i)}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let n=X(),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=X(),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=X(),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 y=p[f];return y!==null&&typeof y=="object"?JSON.stringify(y):y});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=X();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=Gl(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 xo(){ye.register("pg",new ir),ye.register("mysql",new sr),ye.register("mssql",new nr),ye.register("mongodb",new Wt),ye.register("sqlite",new dr),ye.register("redis",new mr)}var vo=C(()=>{"use strict";b();Le();hn();so();co();mo();Ao();_o()});import{HTTPException as Aa}from"hono/http-exception";import{DatabaseError as Ql}from"pg";import{ZodError as Oo}from"zod";function Po(a,e){let t=mt(e.req.method,e.req.path),r=Jl(a),n=Xl(a);if(_r("error","request_failed",{operation:t,error_type:r}),Ar(a,{operation:t,status:n,dbType:Cr(e.req.path)}),a instanceof Aa)return e.json({error:a.message??"Internal server error"},a.status);if(a instanceof Oo){let o=a.issues[0];return e.json({error:"Validation error",details:o.message},400)}return a instanceof Error&&$o(a)?e.json({error:"Database connection failed",details:a.message},503):e.json({error:a instanceof Error?a.message:"Internal server error"},500)}var Jl,$o,Xl,ko=C(()=>{"use strict";b();dt();Jl=a=>a instanceof Aa?"HTTPException":a instanceof Error?a.name:"UnknownError",$o=a=>{let e=a;return e.code==="ECONNREFUSED"||e.code==="ENOTFOUND"||e.code==="ETIMEDOUT"||e.code==="ER_ACCESS_DENIED_ERROR"||e.code==="ER_BAD_HOST_ERROR"||e.code==="ECONNRESET"||e.errno===1045||e.errno===2003||e.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 Ql&&a.code?.startsWith("08")===!0},Xl=a=>a instanceof Aa?a.status:a instanceof Oo?400:a instanceof Error&&$o(a)?503:500});function Io(a){if(!a)return`You are a database assistant for db-studio. Keep answers concise and focused.
291
312
 
292
- The user chose not to share their database schema. Do not claim to know their table or column names. Ask for the minimum missing details needed to answer accurately, generate queries in fenced code blocks, and warn before potentially destructive or expensive operations.`;let e=n.dbType.toLowerCase(),t=n.dbType==="pg"?"PostgreSQL":n.dbType;return e.includes("mongo")?`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
313
+ The user chose not to share their database schema. Do not claim to know their table or column names. Ask for the minimum missing details needed to answer accurately, generate queries in fenced code blocks, and warn before potentially destructive or expensive operations.`;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.
293
314
 
294
315
  **Your Role:**
295
316
  1. Keep responses SHORT - 2-3 sentences maximum unless generating a query
@@ -303,7 +324,7 @@ The user chose not to share their database schema. Do not claim to know their ta
303
324
  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
304
325
 
305
326
  **Database Context:**
306
- ${So(n)}
327
+ ${Lo(a)}
307
328
 
308
329
  **Guidelines:**
309
330
  1. Always generate syntactically correct MongoDB queries
@@ -365,7 +386,7 @@ This will return the top 5 customers by revenue."`:`You are a database assistant
365
386
  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
366
387
 
367
388
  **Database Context:**
368
- ${So(n)}
389
+ ${Lo(a)}
369
390
 
370
391
  **Guidelines:**
371
392
  1. Always generate syntactically correct SQL for the database type (${t})
@@ -403,26 +424,26 @@ LIMIT 5;
403
424
 
404
425
  This will return the 5 customers with the highest total order value. You might also want to see:
405
426
  - Revenue trends over time for these customers
406
- - Their most frequently ordered products"`}function So(n){let t=`Database Type: ${n.dbType==="pg"?"PostgreSQL":n.dbType}
427
+ - Their most frequently ordered products"`}function Lo(a){let t=`Database Type: ${a.dbType==="pg"?"PostgreSQL":a.dbType}
407
428
 
408
429
  `;t+=`**Tables and Columns:**
409
- `;for(let r of n.tables){t+=`
430
+ `;for(let r of a.tables){t+=`
410
431
  ### ${r.name}
411
432
  `,r.description&&(t+=`Description: ${r.description}
412
433
  `),t+=`Columns:
413
- `;for(let a of r.columns){let o=a.isPrimaryKey?" [PRIMARY KEY]":"",s=a.foreignKey?` [FK -> ${a.foreignKey}]`:"",c=a.nullable?"NULL":"NOT NULL";t+=` - ${a.name}: ${a.type} ${c}${o}${s}
414
- `,a.description&&(t+=` ${a.description}
434
+ `;for(let n of r.columns){let o=n.isPrimaryKey?" [PRIMARY KEY]":"",s=n.foreignKey?` [FK -> ${n.foreignKey}]`:"",c=n.nullable?"NULL":"NOT NULL";t+=` - ${n.name}: ${n.type} ${c}${o}${s}
435
+ `,n.description&&(t+=` ${n.description}
415
436
  `)}r.sampleData&&r.sampleData.length>0&&(t+=`Sample data (${r.sampleData.length} rows):
416
437
  `,t+=`${JSON.stringify(r.sampleData.slice(0,3),null,2)}
417
- `)}if(n.relationships&&n.relationships.length>0){t+=`
438
+ `)}if(a.relationships&&a.relationships.length>0){t+=`
418
439
  **Relationships:**
419
- `;for(let r of n.relationships)t+=` - ${r.fromTable}.${r.fromColumn} -> ${r.toTable}.${r.toColumn}
420
- `}return t}var Co=N(()=>{"use strict";b()});function Pl(n){let e={name:n.columnName,type:n.dataTypeLabel,nullable:n.isNullable};return n.isPrimaryKey&&(e.isPrimaryKey=!0),n.isForeignKey&&n.referencedTable&&n.referencedColumn&&(e.foreignKey=`${n.referencedTable}.${n.referencedColumn}`),n.enumValues&&n.enumValues.length>0&&(e.enumValues=n.enumValues,e.description=`Enum values: ${n.enumValues.join(", ")}`),e}function kl(n){let e=[];for(let t of n)for(let r of t.columns)if(r.foreignKey){let[a,o]=r.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:r.name,toTable:a,toColumn:o})}return e}function $l(n){if(n==null)return"";if(n instanceof Date)return n.toISOString();if(typeof n=="bigint")return n.toString();if(typeof n=="object")try{return JSON.stringify(n)}catch{return String(n)}return String(n)}async function Il(n,e,t){try{return(await n.getTableData({tableName:e,db:t,limit:3})).data.map(a=>Object.fromEntries(Object.entries(a).map(([o,s])=>[o,$l(s)])))}catch(r){return console.warn(`Could not fetch sample data for table ${e}:`,r),[]}}async function Ll(n,e,t){try{return await n.getTableColumns({tableName:e,db:t})}catch(r){return console.warn(`Could not fetch columns for table ${e}:`,r),[]}}async function Ml(n,e={}){let t=Le(),{includeSampleData:r=!1,maxTables:a}=e,o=I(t);try{let s=await o.getTablesList(n),i=s.slice(0,a??s.length).map(async({schemaName:m,tableName:d})=>{let[p,f]=await Promise.all([Ll(o,d,n),r?Il(o,d,n):Promise.resolve([])]),y={name:m?`${m}.${d}`:d,columns:p.map(Pl)};return f.length>0&&(y.sampleData=f),y}),l=await Promise.all(i),u=kl(l);return{dbType:t,tables:l,relationships:u}}catch(s){throw console.error("Error fetching database schema:",s),new Error(`Failed to fetch database schema: ${s instanceof Error?s.message:"Unknown error"}`)}}async function No(n){return Ml(n,{includeSampleData:!0,includeDescriptions:!0})}var Ao=N(()=>{"use strict";b();$e();Fe()});import{zValidator as ql}from"@hono/zod-validator";import{Hono as Ul}from"hono";import{HTTPException as Do}from"hono/http-exception";var Bl,_o,vo,xo=N(()=>{"use strict";b();ct();Ce();Co();Ao();Bl=new Set(["localhost","127.0.0.1","::1","[::1]"]),_o=()=>{let n;try{n=new URL(ke.PROXY_URL)}catch{throw new Do(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=Bl.has(n.hostname)||n.hostname.endsWith(".localhost");if(n.protocol!=="https:"&&!(n.protocol==="http:"&&e))throw new Do(500,{message:"DB_STUDIO_PROXY_URL must use HTTPS unless it points at loopback"});return n.origin},vo=new Ul().basePath("/chat").get("/limit",async n=>{let e=_o();try{let t=await fetch(`${e}/chat/limit`,{headers:{"cf-connecting-ip":n.req.header("cf-connecting-ip")??"","x-real-ip":n.req.header("x-real-ip")??"","x-forwarded-for":n.req.header("x-forwarded-for")??"","x-api-key":n.req.header("x-api-key")??""}});return t.ok?n.json(await t.json(),200):n.json({limit:3,used:3,remaining:0},200)}catch{return n.json({limit:3,used:3,remaining:0},200)}}).post("/",ql("json",qr),async n=>{let{messages:e,data:t,provider:r,model:a}=n.req.valid("json"),{db:o,conversationId:s,includeSchema:c}=t,i=c?await No(o):null,l=Ro(i),u={messages:e,conversationId:s,systemPrompt:l,provider:r,model:a},m=await fetch(`${_o()}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":n.req.header("cf-connecting-ip")??"","x-real-ip":n.req.header("x-real-ip")??"","x-forwarded-for":n.req.header("x-forwarded-for")??"","x-api-key":n.req.header("x-api-key")??"","x-byok-gemini":n.req.header("x-byok-gemini")??"","x-byok-openai":n.req.header("x-byok-openai")??"","x-byok-anthropic":n.req.header("x-byok-anthropic")??"","x-byok-grok":n.req.header("x-byok-grok")??"","x-byok-openrouter":n.req.header("x-byok-openrouter")??""},body:JSON.stringify(u)});if(!m.ok){let d=await m.json();return n.json({error:d.error||"Proxy request failed"},m.status)}return new Response(m.body,{status:m.status,headers:m.headers})})});import{Hono as Fl}from"hono";var Oo,Po=N(()=>{"use strict";b();$e();Fe();Oo=new Fl().basePath("/databases").get("/",async n=>{let e=Le(),r=await I(e).getDatabasesList();return n.json({data:{databases:r,dbType:e}},200)}).get("/current",async n=>{let e=Le(),r=await I(e).getCurrentDatabase();return n.json({data:{db:r.db,dbType:e}},200)}).get("/connection",async n=>{let e=Le(),r=await I(e).getDatabaseConnectionInfo();return n.json({data:r},200)})});import{zValidator as he}from"@hono/zod-validator";import{Hono as jl}from"hono";var ko,$o=N(()=>{"use strict";b();Ce();$e();ko=new jl().basePath("/keys").get("/",he("query",Gr),async n=>{let e=n.req.valid("query"),t=n.get("dbType"),r=je(I(t),t);return n.json({data:await r.scanKeys(e)},200)}).post("/",he("query",P),he("json",Zr),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType"),a=je(I(r),r);return n.json({data:await a.createKey({db:e,...t})},200)}).get("/:key/raw",he("param",ot),he("query",Xr),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=je(I(r),r);return n.json({data:await a.getStringChunk({...t,key:e})},200)}).get("/:key",he("param",ot),he("query",Jr),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=je(I(r),r);return n.json({data:await a.getKeyDetails({...t,key:e})},200)}).post("/:key/actions",he("param",ot),he("query",P),he("json",en),async n=>{let{key:e}=n.req.valid("param"),{db:t}=n.req.valid("query"),r=n.req.valid("json"),a=n.get("dbType"),o=je(I(a),a);return n.json({data:await o.applyKeyAction({db:t,key:e,...r})},200)}).delete("/:key",he("param",ot),he("query",tn),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=je(I(r),r);return n.json({data:await a.deleteKey({...t,key:e})},200)})});import{zValidator as Io}from"@hono/zod-validator";import{Hono as Hl}from"hono";var Lo,Mo=N(()=>{"use strict";b();Ce();$e();Lo=new Hl().basePath("/query").post("/",Io("query",P),Io("json",Wr),async n=>{let{query:e}=n.req.valid("json"),{db:t}=n.req.valid("query"),r=n.get("dbType"),o=await I(r).executeQuery({query:e,db:t});return n.json({data:o},200)})});import{zValidator as Pe}from"@hono/zod-validator";import{Hono as Kl}from"hono";var qo,Uo=N(()=>{"use strict";b();Ce();$e();qo=new Kl().basePath("/records").post("/",Pe("query",P),Pe("json",Pr),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,data:r}=n.req.valid("json"),a=n.get("dbType"),o=I(a),{insertedCount:s}=await o.addRecord({db:e,params:{tableName:t,data:r}});return n.json({data:`Record inserted into "${t}" with ${s} rows inserted`},200)}).patch("/",Pe("query",P),Pe("json",an),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,primaryKey:r,updates:a}=n.req.valid("json"),o=n.get("dbType"),s=I(o),{updatedCount:c}=await s.updateRecords({params:{tableName:t,primaryKey:r,updates:a},db:e});return n.json({data:`Updated ${c} records in "${t}"`},200)}).delete("/",Pe("query",P),Pe("json",Gt),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,primaryKeys:r}=n.req.valid("json"),a=n.get("dbType"),o=I(a),{deletedCount:s,fkViolation:c,relatedRecords:i}=await o.deleteRecords({tableName:t,primaryKeys:r,db:e});return c?n.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:i}},409):n.json({data:{deletedCount:s,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",Pe("query",P),Pe("json",Gt),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,primaryKeys:r}=n.req.valid("json"),a=n.get("dbType"),s=await I(a).forceDeleteRecords({tableName:t,primaryKeys:r,db:e});return n.json({data:s},200)}).post("/bulk",Pe("query",P),Pe("json",Mr),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,records:r}=n.req.valid("json"),a=n.get("dbType"),s=await I(a).bulkInsertRecords({tableName:t,records:r,db:e});return console.log("result",s),n.json({data:s},200)})});import{utils as wt,write as Vl}from"xlsx";function Bo({cols:n,rows:e,format:t,tableName:r}){switch(t){case"json":{let a=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(a,"utf-8"))}case"csv":{let a=[n,...e?.map(c=>n?.map(i=>c[i]))??[]],o=wt.aoa_to_sheet(a),s=wt.sheet_to_csv(o);return new Uint8Array(Buffer.from(s,"utf-8"))}case"xlsx":{let a=[n,...e?.map(i=>n?.map(l=>i[l]))??[]],o=wt.aoa_to_sheet(a),s=wt.book_new();wt.book_append_sheet(s,o,r.slice(0,31));let c=Vl(s,{bookType:"xlsx",type:"buffer"});return new Uint8Array(c)}}}var Fo=N(()=>{"use strict";b()});import{zValidator as G}from"@hono/zod-validator";import{Hono as zl}from"hono";var jo,Ho=N(()=>{"use strict";b();Ce();$e();Fo();jo=new zl().basePath("/tables").get("/",G("query",P),async n=>{let{db:e}=n.req.valid("query"),t=n.get("dbType"),a=await I(t).getTablesList(e);return n.json({data:a},200)}).post("/",G("query",P),G("json",Vr),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType");return await I(r).createTable({tableData:t,db:e}),n.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",G("query",zr),G("param",Ee),async n=>{let{db:e,cascade:t}=n.req.valid("query"),{tableName:r}=n.req.valid("param"),a=n.get("dbType"),s=await I(a).deleteTable({tableName:r,db:e,cascade:t});return n.json({data:s},200)}).delete("/:tableName/columns/:columnName",G("query",Lr),G("param",ie),async n=>{let{db:e,cascade:t}=n.req.valid("query"),{tableName:r,columnName:a}=n.req.valid("param"),o=n.get("dbType"),s=I(o),{deletedCount:c}=await s.deleteColumn({tableName:r,columnName:a,cascade:t,db:e});return n.json({data:`Column "${a}" deleted successfully from table "${r}" with ${c} rows deleted`},200)}).post("/:tableName/columns",G("query",P),G("param",Ee),G("json",Se),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.req.valid("json"),a=n.get("dbType");return await I(a).addColumn({tableName:t,db:e,...r}),n.json({data:`Column "${r.columnName}" added successfully to table "${t}"`},200)}).patch("/:tableName/columns/:columnName/rename",G("query",P),G("param",ie),G("json",Jt),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,columnName:r}=n.req.valid("param"),a=n.req.valid("json"),o=n.get("dbType");return await I(o).renameColumn({tableName:t,columnName:r,db:e,...a}),n.json({data:`Column "${r}" renamed to "${a.newColumnName}" in table "${t}"`},200)}).patch("/:tableName/columns/:columnName",G("query",P),G("param",ie),G("json",rt),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,columnName:r}=n.req.valid("param"),a=n.req.valid("json"),o=n.get("dbType");return await I(o).alterColumn({tableName:t,columnName:r,db:e,...a}),n.json({data:`Column "${r}" updated successfully in table "${t}"`},200)}).get("/:tableName/columns",G("query",P),G("param",Ee),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.get("dbType"),o=await I(r).getTableColumns({tableName:t,db:e});return n.json({data:o},200)}).get("/:tableName/schema",G("query",P),G("param",Ee),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.get("dbType"),o=await I(r).getTableSchema({tableName:t,db:e});return n.json({data:{schema:o}},200)}).get("/:tableName/data",G("param",Ee),G("query",nn),async n=>{let{tableName:e}=n.req.valid("param"),{cursor:t,limit:r,direction:a,sort:o,order:s,filters:c,db:i}=n.req.valid("query"),l=n.get("dbType"),m=await I(l).getTableData({tableName:e,cursor:t,limit:r,direction:a,sort:o,order:s,filters:c,db:i});return n.json({data:m},200)}).get("/:tableName/export",G("param",Ee),G("query",Yr),async n=>{let{tableName:e}=n.req.valid("param"),{db:t,format:r}=n.req.valid("query"),a=n.get("dbType"),o=I(a),{cols:s,rows:c}=await o.exportTableData({tableName:e,db:t}),i=Bo({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}"`}})})});import{Hono as Wl}from"hono";import{z as Ko}from"zod";var Yl,Vo,zo=N(()=>{"use strict";b();mt();Yl=Ko.object({enabled:Ko.boolean()}).strict(),Vo=new Wl().basePath("/telemetry").get("/config",async n=>((n.req.header("x-db-studio-gpc")==="1"||n.req.header("sec-gpc")==="1")&&xt(!1),Er(),n.json({data:vt()},200))).put("/preference",async n=>{let e=Yl.safeParse(await n.req.json().catch(()=>{}));return e.success?(xt(e.data.enabled),n.json({data:vt()},200)):n.json({error:"Invalid telemetry preference"},400)}).post("/reset",async n=>n.json({data:{installationId:gr()}},200))});var Qo={};Nt(Qo,{createServer:()=>rc});import{existsSync as Wo}from"fs";import Ue from"path";import{fileURLToPath as Gl}from"url";import{serveStatic as St}from"@hono/node-server/serve-static";import{zValidator as Ql}from"@hono/zod-validator";import{Hono as Jl}from"hono";import{cors as Xl}from"hono/cors";import{HTTPException as Zl}from"hono/http-exception";import{logger as ec}from"hono/logger";import{prettyJSON as tc}from"hono/pretty-json";import{z as Yo}from"zod";var Ne,Rt,Go,rc,Jo=N(()=>{"use strict";b();ct();$e();ho();wo();mt();xo();Po();$o();Mo();Uo();Ho();zo();({API_PREFIX:Ne}=ke),Rt=()=>{if(process.env.NODE_ENV==="development")return Ue.resolve(process.cwd(),"../web/dist");let n=Ue.dirname(Gl(import.meta.url)),e=Ue.resolve(n,"./web-dist"),t=Ue.resolve(process.cwd(),"../web/dist"),r=Ue.resolve(e,"index.html"),a=Ue.resolve(t,"index.html");return!Wo(r)&&Wo(a)?t:e},Go=Yo.object({dbType:Yo.string().refine(n=>fe.getSupportedTypes().includes(n),{message:`Invalid database type. Supported types: ${fe.getSupportedTypes().join(", ")}`})}),rc=()=>{go();let n=new Jl({strict:!1}).use("/*",Xl({origin:e=>{if(!e)return;if((process.env.ALLOWED_ORIGINS?.split(",").map(r=>r.trim()).filter(Boolean)??[]).includes(e))return e;if(process.env.NODE_ENV==="development")try{let r=new URL(e);if(r.hostname==="localhost"||r.hostname.endsWith(".localhost")||r.hostname==="127.0.0.1")return e}catch{}},allowMethods:["GET","POST","PUT","DELETE","OPTIONS"],allowHeaders:["Content-Type","X-Run-Id","X-DB-Studio-GPC","x-byok-gemini","x-byok-openai","x-byok-anthropic","x-byok-grok","x-byok-openrouter"]})).use(tc({space:2})).use(process.env.NODE_ENV==="development"?ec():(e,t)=>t()).use(`${Ne}/*`,async(e,t)=>{if(e.req.path.startsWith(`${Ne}/telemetry`))return t();let r=performance.now(),a=ut(e.req.method,e.req.path),o=e.req.path.split("/")[2],s=fe.getSupportedTypes().find(c=>c===o);await Sr(a,s,t),Ot({event:"server_operation",properties:{operation:a,method:e.req.method,outcome:Tr(e.res.status),duration_bucket:hr(performance.now()-r),db_type:s}})}).use("/favicon.ico",St({path:Ue.resolve(Rt(),"favicon.ico")})).onError(Eo).route(Ne,Oo).route(Ne,vo).route(Ne,Vo).use("/assets/*",St({root:Rt()})).use("/image.png",St({root:Rt()})).use(`${Ne}/:dbType/*`,Ql("param",Go,(e,t)=>{if(!e.success){let r=t.req.param("dbType");throw new Zl(400,{message:`Invalid database type: "${r}". Supported types: ${fe.getSupportedTypes().join(", ")}`})}}),async(e,t)=>{let{dbType:r}=Go.parse({dbType:e.req.param("dbType")});e.set("dbType",r),await t()}).route(`${Ne}/:dbType`,jo).route(`${Ne}/:dbType`,qo).route(`${Ne}/:dbType`,Lo).route(`${Ne}/:dbType`,ko);return process.env.NODE_ENV!=="test"&&(n.all(`${Ne}/*`,e=>e.json({error:"Not found"},404)),n.use("/*",St({root:Rt()})),n.get("/*",St({path:Ue.resolve(Rt(),"index.html")}))),{app:n}}});b();b();(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new n.Error().stack;e&&(n._sentryDebugIds=n._sentryDebugIds||{},n._sentryDebugIds[e]="c1988efd-aa19-4d5d-8a8e-6c8c3acb61d4",n._sentryDebugIdIdentifier="sentry-dbid-c1988efd-aa19-4d5d-8a8e-6c8c3acb61d4")}catch{}})();b();ct();import{intro as nc,log as ur,outro as Xo,spinner as ac}from"@clack/prompts";import{serve as oc}from"@hono/node-server";import Ct from"picocolors";b();import{program as dr}from"commander";var kn=()=>{dr.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("--open","Open db-studio in the default browser").option("--no-open","Do not open db-studio in the default browser").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv);let n=dr.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&dr.error("Do not combine --open and --no-open"),{...n,open:e?!0:t?!1:void 0}};b();import{readFile as es}from"fs/promises";import{resolve as ts}from"path";import{cancel as At,isCancel as pr,note as $n,select as rs,spinner as ns,text as In}from"@clack/prompts";import{parse as as}from"dotenv";import fr from"picocolors";var Ln=async(n,e)=>{let t=e||"DATABASE_URL";if(n?.[t])return n[t];if(process.env[t])return process.env[t];let r=ns();r.start("Looking for database connection..."),n?$n(fr.red(`${t} not found in .env or process.env`)):$n(fr.red(`No .env file found and ${t} not set in process.env`));let a=await rs({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((pr(a)||a==="cancel")&&(At("No database connection provided. Exiting..."),process.exit(0)),a==="other-env"){r.start("Waiting for path...");let s=await In({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(i){if(!i?.trim())return"Path is required"}});pr(s)&&(At("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let c=ts(s);try{let i=await es(c,"utf-8"),l=as(i);if(l[t])return l[t];throw new Error(`${t} still missing in custom file`)}catch(i){let l=i;At(`Cannot read or parse file: ${fr.dim(l.message)}`),process.exit(1)}}r.stop("Manual input...");let o=await In({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 pr(o)&&(At("Cancelled."),process.exit(0)),o.trim()};b();import{access as os,readFile as ss}from"fs/promises";import{dirname as is,resolve as yr}from"path";import{parse as ls}from"dotenv";var cs=async n=>{let e=yr(n);for(;;){let t=yr(e,".env");try{return await os(t),t}catch{}let r=is(e);if(r===e)return null;e=r}},We=async n=>{let e;if(n?e=yr(n):e=await cs(process.cwd()),!e)return null;try{let t=await ss(e,"utf-8");return ls(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};b();import us from"open";var Mn=n=>n===!0,qn=async n=>{await us(n)};b();mr();import{intro as ms,outro as ds}from"@clack/prompts";import Ye from"picocolors";var Un=()=>{ms(Ye.inverse(" db-studio ")),console.log(Ye.bold(`
440
+ `;for(let r of a.relationships)t+=` - ${r.fromTable}.${r.fromColumn} -> ${r.toTable}.${r.toColumn}
441
+ `}return t}var Mo=C(()=>{"use strict";b()});function Zl(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 ec(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 tc(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 rc(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,tc(s)])))}catch(r){return console.warn(`Could not fetch sample data for table ${e}:`,r),[]}}async function ac(a,e,t){try{return await a.getTableColumns({tableName:e,db:t})}catch(r){return console.warn(`Could not fetch columns for table ${e}:`,r),[]}}async function nc(a,e={}){let t=Me(),{includeSampleData:r=!1,maxTables:n}=e,o=L(t);try{let s=await o.getTablesList(a),i=s.slice(0,n??s.length).map(async({schemaName:m,tableName:p})=>{let[d,f]=await Promise.all([ac(o,p,a),r?rc(o,p,a):Promise.resolve([])]),y={name:m?`${m}.${p}`:p,columns:d.map(Zl)};return f.length>0&&(y.sampleData=f),y}),l=await Promise.all(i),u=ec(l);return{dbType:t,tables:l,relationships:u}}catch(s){throw console.error("Error fetching database schema:",s),new Error(`Failed to fetch database schema: ${s instanceof Error?s.message:"Unknown error"}`)}}async function qo(a){return nc(a,{includeSampleData:!0,includeDescriptions:!0})}var Uo=C(()=>{"use strict";b();Le();He()});import{zValidator as oc}from"@hono/zod-validator";import{Hono as sc}from"hono";import{HTTPException as Bo}from"hono/http-exception";var ic,Fo,jo,Ho=C(()=>{"use strict";b();ut();Ae();Mo();Uo();ic=new Set(["localhost","127.0.0.1","::1","[::1]"]),Fo=()=>{let a;try{a=new URL(ke.PROXY_URL)}catch{throw new Bo(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=ic.has(a.hostname)||a.hostname.endsWith(".localhost");if(a.protocol!=="https:"&&!(a.protocol==="http:"&&e))throw new Bo(500,{message:"DB_STUDIO_PROXY_URL must use HTTPS unless it points at loopback"});return a.origin},jo=new sc().basePath("/chat").get("/limit",async a=>{let e=Fo();try{let t=await fetch(`${e}/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")??""}});return t.ok?a.json(await t.json(),200):a.json({limit:3,used:3,remaining:0},200)}catch{return a.json({limit:3,used:3,remaining:0},200)}}).post("/",oc("json",jr),async a=>{let{messages:e,data:t,provider:r,model:n}=a.req.valid("json"),{db:o,conversationId:s,includeSchema:c}=t,i=c?await qo(o):null,l=Io(i),u={messages:e,conversationId:s,systemPrompt:l,provider:r,model:n},m=await fetch(`${Fo()}/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")??"","x-byok-gemini":a.req.header("x-byok-gemini")??"","x-byok-openai":a.req.header("x-byok-openai")??"","x-byok-anthropic":a.req.header("x-byok-anthropic")??"","x-byok-grok":a.req.header("x-byok-grok")??"","x-byok-openrouter":a.req.header("x-byok-openrouter")??""},body:JSON.stringify(u)});if(!m.ok){let p=await m.json();return a.json({error:p.error||"Proxy request failed"},m.status)}return new Response(m.body,{status:m.status,headers:m.headers})})});import{Hono as lc}from"hono";var Ko,Vo=C(()=>{"use strict";b();Le();He();Ko=new lc().basePath("/databases").get("/",async a=>{let e=Me(),r=await L(e).getDatabasesList();return a.json({data:{databases:r,dbType:e}},200)}).get("/current",async a=>{let e=Me(),r=await L(e).getCurrentDatabase();return a.json({data:{db:r.db,dbType:e}},200)}).get("/connection",async a=>{let e=Me(),r=await L(e).getDatabaseConnectionInfo();return a.json({data:r},200)})});import{zValidator as Se}from"@hono/zod-validator";import{Hono as cc}from"hono";var zo,Wo=C(()=>{"use strict";b();Ae();Le();zo=new cc().basePath("/keys").get("/",Se("query",Zr),async a=>{let e=a.req.valid("query"),t=a.get("dbType"),r=Ke(L(t),t);return a.json({data:await r.scanKeys(e)},200)}).post("/",Se("query",O),Se("json",aa),async a=>{let{db:e}=a.req.valid("query"),t=a.req.valid("json"),r=a.get("dbType"),n=Ke(L(r),r);return a.json({data:await n.createKey({db:e,...t})},200)}).get("/:key/raw",Se("param",st),Se("query",ra),async a=>{let{key:e}=a.req.valid("param"),t=a.req.valid("query"),r=a.get("dbType"),n=Ke(L(r),r);return a.json({data:await n.getStringChunk({...t,key:e})},200)}).get("/:key",Se("param",st),Se("query",ta),async a=>{let{key:e}=a.req.valid("param"),t=a.req.valid("query"),r=a.get("dbType"),n=Ke(L(r),r);return a.json({data:await n.getKeyDetails({...t,key:e})},200)}).post("/:key/actions",Se("param",st),Se("query",O),Se("json",na),async a=>{let{key:e}=a.req.valid("param"),{db:t}=a.req.valid("query"),r=a.req.valid("json"),n=a.get("dbType"),o=Ke(L(n),n);return a.json({data:await o.applyKeyAction({db:t,key:e,...r})},200)}).delete("/:key",Se("param",st),Se("query",oa),async a=>{let{key:e}=a.req.valid("param"),t=a.req.valid("query"),r=a.get("dbType"),n=Ke(L(r),r);return a.json({data:await n.deleteKey({...t,key:e})},200)})});import{zValidator as Yo}from"@hono/zod-validator";import{Hono as uc}from"hono";var Go,Qo=C(()=>{"use strict";b();Ae();Le();Go=new uc().basePath("/query").post("/",Yo("query",O),Yo("json",Jr),async a=>{let{query:e}=a.req.valid("json"),{db:t}=a.req.valid("query"),r=a.get("dbType"),o=await L(r).executeQuery({query:e,db:t});return a.json({data:o},200)})});import{zValidator as Pe}from"@hono/zod-validator";import{Hono as mc}from"hono";var Jo,Xo=C(()=>{"use strict";b();Ae();Le();Jo=new mc().basePath("/records").post("/",Pe("query",O),Pe("json",Ir),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,data:r}=a.req.valid("json"),n=a.get("dbType"),o=L(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("/",Pe("query",O),Pe("json",la),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKey:r,updates:n}=a.req.valid("json"),o=a.get("dbType"),s=L(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("/",Pe("query",O),Pe("json",Zt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:r}=a.req.valid("json"),n=a.get("dbType"),o=L(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",Pe("query",O),Pe("json",Zt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:r}=a.req.valid("json"),n=a.get("dbType"),s=await L(n).forceDeleteRecords({tableName:t,primaryKeys:r,db:e});return a.json({data:s},200)}).post("/bulk",Pe("query",O),Pe("json",Fr),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,records:r}=a.req.valid("json"),n=a.get("dbType"),s=await L(n).bulkInsertRecords({tableName:t,records:r,db:e});return console.log("result",s),a.json({data:s},200)})});import{utils as Ct,write as dc}from"xlsx";function es({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=Ct.aoa_to_sheet(Zo(a,e)),o=Ct.sheet_to_csv(n);return new Uint8Array(Buffer.from(o,"utf-8"))}case"xlsx":{let n=Ct.aoa_to_sheet(Zo(a,e)),o=Ct.book_new();Ct.book_append_sheet(o,n,r.slice(0,31));let s=dc(o,{bookType:"xlsx",type:"buffer"});return new Uint8Array(s)}}}var pc,Zo,ts=C(()=>{"use strict";b();pc=a=>a==null||a instanceof Date?a:Buffer.isBuffer(a)?`0x${a.toString("hex")}`:typeof a=="object"?JSON.stringify(a):typeof a=="bigint"?a.toString():a,Zo=(a,e)=>[a,...e?.map(t=>a?.map(r=>pc(t[r])))??[]]});import{zValidator as K}from"@hono/zod-validator";import{Hono as fc}from"hono";var rs,as=C(()=>{"use strict";b();Ae();Le();ts();rs=new fc().basePath("/tables").get("/",K("query",O),async a=>{let{db:e}=a.req.valid("query"),t=a.get("dbType"),n=await L(t).getTablesList(e);return a.json({data:n},200)}).post("/",K("query",O),K("json",Gr),async a=>{let{db:e}=a.req.valid("query"),t=a.req.valid("json"),r=a.get("dbType");return await L(r).createTable({tableData:t,db:e}),a.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",K("query",Qr),K("param",ie),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:r}=a.req.valid("param"),n=a.get("dbType"),s=await L(n).deleteTable({tableName:r,db:e,cascade:t});return a.json({data:s},200)}).patch("/:tableName/rename",K("query",O),K("param",ie),K("json",gt),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 L(n).renameTable({tableName:t,db:e,...r}),a.json({data:`Table "${t}" renamed to "${r.newTableName}"`},200)}).delete("/:tableName/columns/:columnName",K("query",Br),K("param",le),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:r,columnName:n}=a.req.valid("param"),o=a.get("dbType"),s=L(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",O),K("param",ie),K("json",Ce),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 L(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",O),K("param",le),K("json",tr),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 L(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",O),K("param",le),K("json",at),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 L(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",O),K("param",ie),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType"),o=await L(r).getTableColumns({tableName:t,db:e});return a.json({data:o},200)}).get("/:tableName/schema",K("query",O),K("param",ie),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType"),o=await L(r).getTableSchema({tableName:t,db:e});return a.json({data:{schema:o}},200)}).get("/:tableName/data",K("param",ie),K("query",ia),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 L(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",ie),K("query",Xr),async a=>{let{tableName:e}=a.req.valid("param"),{db:t,format:r}=a.req.valid("query"),n=a.get("dbType"),o=L(n),{cols:s,rows:c}=await o.exportTableData({tableName:e,db:t}),i=es({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}"`}})})});import{Hono as yc}from"hono";import{z as ns}from"zod";var bc,os,ss=C(()=>{"use strict";b();dt();bc=ns.object({enabled:ns.boolean()}).strict(),os=new yc().basePath("/telemetry").get("/config",async a=>((a.req.header("x-db-studio-gpc")==="1"||a.req.header("sec-gpc")==="1")&&Pt(!1),Nr(),a.json({data:$t()},200))).put("/preference",async a=>{let e=bc.safeParse(await a.req.json().catch(()=>{}));return e.success?(Pt(e.data.enabled),a.json({data:$t()},200)):a.json({error:"Invalid telemetry preference"},400)}).post("/reset",async a=>a.json({data:{installationId:wr()}},200))});var us={};_t(us,{createServer:()=>Cc});import{existsSync as is}from"fs";import Fe from"path";import{fileURLToPath as hc}from"url";import{serveStatic as Nt}from"@hono/node-server/serve-static";import{zValidator as gc}from"@hono/zod-validator";import{Hono as Tc}from"hono";import{cors as Ec}from"hono/cors";import{HTTPException as wc}from"hono/http-exception";import{logger as Sc}from"hono/logger";import{prettyJSON as Rc}from"hono/pretty-json";import{z as ls}from"zod";var De,At,cs,Cc,ms=C(()=>{"use strict";b();ut();Le();vo();ko();dt();Ho();Vo();Wo();Qo();Xo();as();ss();({API_PREFIX:De}=ke),At=()=>{if(process.env.NODE_ENV==="development")return Fe.resolve(process.cwd(),"../web/dist");let a=Fe.dirname(hc(import.meta.url)),e=Fe.resolve(a,"./web-dist"),t=Fe.resolve(process.cwd(),"../web/dist"),r=Fe.resolve(e,"index.html"),n=Fe.resolve(t,"index.html");return!is(r)&&is(n)?t:e},cs=ls.object({dbType:ls.string().refine(a=>ye.getSupportedTypes().includes(a),{message:`Invalid database type. Supported types: ${ye.getSupportedTypes().join(", ")}`})}),Cc=()=>{xo();let a=new Tc({strict:!1}).use("/*",Ec({origin:e=>{if(!e)return;if((process.env.ALLOWED_ORIGINS?.split(",").map(r=>r.trim()).filter(Boolean)??[]).includes(e))return e;if(process.env.NODE_ENV==="development")try{let r=new URL(e);if(r.hostname==="localhost"||r.hostname.endsWith(".localhost")||r.hostname==="127.0.0.1")return e}catch{}},allowMethods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowHeaders:["Content-Type","X-Run-Id","X-DB-Studio-GPC","x-byok-gemini","x-byok-openai","x-byok-anthropic","x-byok-grok","x-byok-openrouter"],maxAge:600})).use(Rc({space:2})).use(process.env.NODE_ENV==="development"?Sc():(e,t)=>t()).use(`${De}/*`,async(e,t)=>{if(e.req.path.startsWith(`${De}/telemetry`))return t();let r=performance.now(),n=mt(e.req.method,e.req.path),o=e.req.path.split("/")[2],s=ye.getSupportedTypes().find(c=>c===o);await Dr(n,s,t),kt({event:"server_operation",properties:{operation:n,method:e.req.method,outcome:Rr(e.res.status),duration_bucket:Sr(performance.now()-r),db_type:s}})}).use("/favicon.ico",Nt({path:Fe.resolve(At(),"favicon.ico")})).onError(Po).route(De,Ko).route(De,jo).route(De,os).use("/assets/*",Nt({root:At()})).use("/image.png",Nt({root:At()})).use(`${De}/:dbType/*`,gc("param",cs,(e,t)=>{if(!e.success){let r=t.req.param("dbType");throw new wc(400,{message:`Invalid database type: "${r}". Supported types: ${ye.getSupportedTypes().join(", ")}`})}}),async(e,t)=>{let{dbType:r}=cs.parse({dbType:e.req.param("dbType")});e.set("dbType",r),await t()}).route(`${De}/:dbType`,rs).route(`${De}/:dbType`,Jo).route(`${De}/:dbType`,Go).route(`${De}/:dbType`,zo);return process.env.NODE_ENV!=="test"&&(a.all(`${De}/*`,e=>e.json({error:"Not found"},404)),a.use("/*",Nt({root:At()})),a.get("/*",Nt({path:Fe.resolve(At(),"index.html")}))),{app:a}}});b();b();(function(){try{var a=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new a.Error().stack;e&&(a._sentryDebugIds=a._sentryDebugIds||{},a._sentryDebugIds[e]="78850f5e-49f2-47b3-b50b-976e47d75b0e",a._sentryDebugIdIdentifier="sentry-dbid-78850f5e-49f2-47b3-b50b-976e47d75b0e")}catch{}})();b();ut();import{intro as Nc,log as fr,outro as ds,spinner as Ac}from"@clack/prompts";import{serve as Dc}from"@hono/node-server";import Dt from"picocolors";b();import{program as br}from"commander";var Ma=()=>{br.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("--open","Open db-studio in the default browser").option("--no-open","Do not open db-studio in the default browser").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv);let a=br.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&br.error("Do not combine --open and --no-open"),{...a,open:e?!0:t?!1:void 0}};b();import{readFile as fs}from"fs/promises";import{resolve as ys}from"path";import{cancel as xt,isCancel as hr,note as qa,select as bs,spinner as hs,text as Ua}from"@clack/prompts";import{parse as gs}from"dotenv";import gr from"picocolors";var Ba=async(a,e)=>{let t=e||"DATABASE_URL";if(a?.[t])return a[t];if(process.env[t])return process.env[t];let r=hs();r.start("Looking for database connection..."),a?qa(gr.red(`${t} not found in .env or process.env`)):qa(gr.red(`No .env file found and ${t} not set in process.env`));let n=await bs({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((hr(n)||n==="cancel")&&(xt("No database connection provided. Exiting..."),process.exit(0)),n==="other-env"){r.start("Waiting for path...");let s=await Ua({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(i){if(!i?.trim())return"Path is required"}});hr(s)&&(xt("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let c=ys(s);try{let i=await fs(c,"utf-8"),l=gs(i);if(l[t])return l[t];throw new Error(`${t} still missing in custom file`)}catch(i){let l=i;xt(`Cannot read or parse file: ${gr.dim(l.message)}`),process.exit(1)}}r.stop("Manual input...");let o=await Ua({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 hr(o)&&(xt("Cancelled."),process.exit(0)),o.trim()};b();import{access as Ts,readFile as Es}from"fs/promises";import{dirname as ws,resolve as Tr}from"path";import{parse as Ss}from"dotenv";var Rs=async a=>{let e=Tr(a);for(;;){let t=Tr(e,".env");try{return await Ts(t),t}catch{}let r=ws(e);if(r===e)return null;e=r}},Ge=async a=>{let e;if(a?e=Tr(a):e=await Rs(process.cwd()),!e)return null;try{let t=await Es(e,"utf-8");return Ss(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};b();import Cs from"open";var Fa=a=>a===!0,ja=async a=>{await Cs(a)};b();var Ns=/\b(?:postgres(?:ql)?|mysql2?|mssql|sqlserver|mongodb(?:\+srv)?|sqlite|rediss?):\/\/\S+/gi,Ha=a=>a.replace(Ns,e=>`the configured database${e.match(/[),.]+$/)?.[0]??""}`);b();yr();import{intro as As,outro as Ds}from"@clack/prompts";import Qe from"picocolors";var Ka=()=>{As(Qe.inverse(" db-studio ")),console.log(Qe.bold(`
421
442
  Usage:`)),console.log(` db-studio [options]
422
- `),console.log(Ye.bold("Supported Databases:")),console.log(` MySQL, PostgreSQL
423
- `),console.log(Ye.bold("Options:")),console.log(" -e, --env <path> Path to custom .env file"),console.log(" -p, --port <port> Port to run the server on (default: 3333)"),console.log(" -d, --database-url <url> Database URL to use"),console.log(" --open Open db-studio in the default browser (off by default)"),console.log(" --no-open Do not open db-studio in the default browser"),console.log(" -n, --var-name <name> Custom environment variable name (default: DATABASE_URL)"),console.log(" -s, --status Show status of the database connection"),console.log(" -h, --help Show this help message"),console.log(` -v, --version Show version number
424
- `),console.log(Ye.bold("Examples:")),console.log(" db-studio"),console.log(" db-studio -e .env.local"),console.log(" db-studio -p 4000"),console.log(" db-studio -d postgresql://user:pass@localhost:5432/mydb"),console.log(" db-studio -n MY_DATABASE_URL"),console.log(" db-studio -e .env.production -n PROD_DB_URL"),console.log(` db-studio --status
425
- `),ds(Ye.green(`For more information, visit: ${On.SITE_DOCS_LINK}`))};b();ct();import{intro as ps,note as fs,outro as Bn}from"@clack/prompts";import Ae from"picocolors";var Fn=async(n,e,t)=>{ps(Ae.inverse(" db-studio "));let r=t||ke.VAR_NAME,a=null;if(e)a=e;else{let o=n?await We(n):await We();o?.[r]?a=o[r]:process.env[r]&&(a=process.env[r]??null)}a?Bn(Ae.green(`\u2713 Database connection configured (using ${r})`)):(fs(Ae.red(`\u2717 ${r} not found`),"Status"),console.log(Ae.yellow(`
426
- To configure database connection:`)),console.log(Ae.dim(" \u2022 Supported databases: MySQL, PostgreSQL")),console.log(Ae.dim(` \u2022 Add ${r} to your .env file or set it in process.env`)),console.log(Ae.dim(" \u2022 Use -d flag: db-studio -d <url>")),console.log(Ae.dim(" \u2022 Use -e flag: db-studio -e <path-to-env>")),console.log(Ae.dim(` \u2022 Use -n flag: db-studio -n <var-name>
427
- `)),Bn(Ae.yellow("\u26A0 No database connection configured")))};b();br();import{intro as bs,outro as gs}from"@clack/prompts";import jn from"picocolors";var Hn=()=>{bs(jn.inverse(" db-studio ")),gs(jn.green(`\u{1F680} db-studio v${Be.version}`))};var sc=async()=>{let{env:n,port:e,databaseUrl:t,varName:r,open:a,status:o,help:s,version:c}=kn();s&&(Un(),process.exit(0)),c&&(Hn(),process.exit(0)),o&&(await Fn(n,t,r),process.exit(0)),nc(Ct.inverse(" db-studio "));let i=n?await We(n):await We();if(i)for(let[O,k]of Object.entries(i))process.env[O]===void 0&&(process.env[O]=k);let l=Number.parseInt(e??process.env.PORT??String(ke.PORT),10),u=process.env.HOST,m=r||ke.VAR_NAME,d=!!i?.[m],p=!!process.env[m],f=t||await Ln(i,m),y=t?"Using database URL from --database-url":d?`Found ${m} in ${n??".env"}`:p?`Found ${m} in environment`:"Using database URL provided interactively";ur.success(y),process.env.DATABASE_URL=f;let{initServerObservability:h}=await Promise.resolve().then(()=>(mt(),Yn));h();let{checkDatabaseConnection:w,getDatabaseConnectionDetails:E}=await Promise.resolve().then(()=>(ta(),ea)),{type:A,name:C,destination:R}=E(f),S=ac();S.start(`Connecting to ${C}...`);try{await w(A),S.stop(`Connected to ${C} at ${R}`)}catch(O){throw S.stop(`Could not connect to ${C} at ${R}`),O}let{createServer:D}=await Promise.resolve().then(()=>(Jo(),Qo)),{app:x}=D();oc({fetch:x.fetch,hostname:u,port:l});let v=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${l}`;if(ur.success(`Server listening at ${Ct.cyan(v)}`),Mn(a))try{await qn(v),ur.success("Opened db-studio in your browser")}catch{ur.warn(`Could not open your browser. Visit ${Ct.cyan(v)}`)}Xo(Ct.green("Ready"))};process.env.NODE_ENV!=="test"&&sc().catch(n=>{let t=(n instanceof Error?n.message:String(n)).replace(/\b(?:postgres(?:ql)?|mysql2?|mssql|sqlserver|mongodb(?:\+srv)?|sqlite|rediss?):\/\/\S+/gi,"the configured database");Xo(Ct.red(`Startup failed: ${t}`)),process.exit(1)});var Yy=void 0;export{Yy as default,sc as main};
443
+ `),console.log(Qe.bold("Supported Databases:")),console.log(` PostgreSQL, MySQL, SQL Server, MongoDB, SQLite, Redis
444
+ `),console.log(Qe.bold("Options:")),console.log(" -e, --env <path> Path to custom .env file"),console.log(" -p, --port <port> Port to run the server on (default: 3333)"),console.log(" -d, --database-url <url> Database URL to use"),console.log(" --open Open db-studio in the default browser (off by default)"),console.log(" --no-open Do not open db-studio in the default browser"),console.log(" -n, --var-name <name> Custom environment variable name (default: DATABASE_URL)"),console.log(" -s, --status Show status of the database connection"),console.log(" -h, --help Show this help message"),console.log(` -v, --version Show version number
445
+ `),console.log(Qe.bold("Examples:")),console.log(" db-studio"),console.log(" db-studio -e .env.local"),console.log(" db-studio -p 4000"),console.log(" db-studio -d postgresql://user:pass@localhost:5432/mydb"),console.log(" db-studio -n MY_DATABASE_URL"),console.log(" db-studio -e .env.production -n PROD_DB_URL"),console.log(` db-studio --status
446
+ `),Ds(Qe.green(`For more information, visit: ${La.SITE_DOCS_LINK}`))};b();ut();import{intro as _s,note as xs,outro as Va}from"@clack/prompts";import _e from"picocolors";var za=async(a,e,t)=>{_s(_e.inverse(" db-studio "));let r=t||ke.VAR_NAME,n=null;if(e)n=e;else{let o=a?await Ge(a):await Ge();o?.[r]?n=o[r]:process.env[r]&&(n=process.env[r]??null)}n?Va(_e.green(`\u2713 Database connection configured (using ${r})`)):(xs(_e.red(`\u2717 ${r} not found`),"Status"),console.log(_e.yellow(`
447
+ To configure database connection:`)),console.log(_e.dim(" \u2022 Supported databases: PostgreSQL, MySQL, SQL Server, MongoDB, SQLite, Redis")),console.log(_e.dim(` \u2022 Add ${r} to your .env file or set it in process.env`)),console.log(_e.dim(" \u2022 Use -d flag: db-studio -d <url>")),console.log(_e.dim(" \u2022 Use -e flag: db-studio -e <path-to-env>")),console.log(_e.dim(` \u2022 Use -n flag: db-studio -n <var-name>
448
+ `)),Va(_e.yellow("\u26A0 No database connection configured")))};b();Er();import{intro as Os,outro as $s}from"@clack/prompts";import Wa from"picocolors";var Ya=()=>{Os(Wa.inverse(" db-studio ")),$s(Wa.green(`\u{1F680} db-studio v${je.version}`))};var _c=async()=>{let{env:a,port:e,databaseUrl:t,varName:r,open:n,status:o,help:s,version:c}=Ma();s&&(Ka(),process.exit(0)),c&&(Ya(),process.exit(0)),o&&(await za(a,t,r),process.exit(0)),Nc(Dt.inverse(" db-studio "));let i=a?await Ge(a):await Ge();if(i)for(let[$,P]of Object.entries(i))process.env[$]===void 0&&(process.env[$]=P);let l=Number.parseInt(e??process.env.PORT??String(ke.PORT),10),u=process.env.HOST,m=r||ke.VAR_NAME,p=!!i?.[m],d=!!process.env[m],f=t||await Ba(i,m),y=t?"Using database URL from --database-url":p?`Found ${m} in ${a??".env"}`:d?`Found ${m} in environment`:"Using database URL provided interactively";fr.success(y),process.env.DATABASE_URL=f;let{initServerObservability:g}=await Promise.resolve().then(()=>(dt(),en));g();let{checkDatabaseConnection:E,getDatabaseConnectionDetails:w}=await Promise.resolve().then(()=>(ln(),sn)),{type:A,name:N,destination:R}=w(f),S=Ac();S.start(`Connecting to ${N}...`);try{await E(A),S.stop(`Connected to ${N} at ${R}`)}catch($){throw S.stop(`Could not connect to ${N} at ${R}`),$}let{createServer:D}=await Promise.resolve().then(()=>(ms(),us)),{app:v}=D();Dc({fetch:v.fetch,hostname:u,port:l});let x=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${l}`;if(fr.success(`Server listening at ${Dt.cyan(x)}`),Fa(n))try{await ja(x),fr.success("Opened db-studio in your browser")}catch{fr.warn(`Could not open your browser. Visit ${Dt.cyan(x)}`)}ds(Dt.green("Ready"))};process.env.NODE_ENV!=="test"&&_c().catch(a=>{let e=a instanceof Error?a.message:String(a);ds(Dt.red(`Startup failed: ${Ha(e)}`)),process.exit(1)});var vb=void 0;export{vb as default,_c as main};
428
449
  //# sourceMappingURL=index.js.map