db-studio 1.14.1 → 1.14.2

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 (42) hide show
  1. package/dist/index.js +2 -2
  2. package/dist/index.js.map +1 -1
  3. package/dist/web-dist/assets/{_pathlessLayout-CdSIARYp.js → _pathlessLayout-BHGufnSc.js} +1 -1
  4. package/dist/web-dist/assets/{_pathlessLayout-BYQmoqT2.js → _pathlessLayout-yNuiTElQ.js} +4 -4
  5. package/dist/web-dist/assets/{_queryId-IoOxUaz6.js → _queryId-LnHerkD-.js} +1 -1
  6. package/dist/web-dist/assets/{_table-BI9E6-Je.js → _table-BIRl7wsf.js} +1 -1
  7. package/dist/web-dist/assets/{_table-ClkqBjYZ.js → _table-DKdWkgl_.js} +1 -1
  8. package/dist/web-dist/assets/{badge-SEQODpjR.js → badge-D_Kx6BmG.js} +1 -1
  9. package/dist/web-dist/assets/{browser-CHG4p052.js → browser-LLDBA7Jr.js} +1 -1
  10. package/dist/web-dist/assets/{bundle-mjs-BZOM22--.js → bundle-mjs-DVXBR05F.js} +1 -1
  11. package/dist/web-dist/assets/{code-editor-BIfiMFMb.js → code-editor-BpkXdVns.js} +1 -1
  12. package/dist/web-dist/assets/{database.store-OsasuLJl.js → database.store-Djdh7lNO.js} +1 -1
  13. package/dist/web-dist/assets/{dist-D_0esNxp.js → dist-C-SdF-L-.js} +1 -1
  14. package/dist/web-dist/assets/{format-cell-value-D41tFXxV.js → format-cell-value-BtrAFpQa.js} +1 -1
  15. package/dist/web-dist/assets/{highlighted-body-OFNGDK62-DBl3trdK.js → highlighted-body-OFNGDK62-D860IMcy.js} +1 -1
  16. package/dist/web-dist/assets/{icons-rRDRsZcq.js → icons-De4HOb_l.js} +1 -1
  17. package/dist/web-dist/assets/index-DGaShyKg.css +2 -0
  18. package/dist/web-dist/assets/{index-CJ2YPwW4.js → index-DUbs819O.js} +5 -5
  19. package/dist/web-dist/assets/{indexes-DMAVA8iJ.js → indexes-Cp3DqRz7.js} +1 -1
  20. package/dist/web-dist/assets/{logs-DCMuv22K.js → logs-BiM3MAXO.js} +1 -1
  21. package/dist/web-dist/assets/{mermaid-GHXKKRXX-DJ7TvQxw.js → mermaid-GHXKKRXX-DQBwS7h_.js} +1 -1
  22. package/dist/web-dist/assets/{middleware-Y6OdmOWR.js → middleware-BbNmPIW8.js} +1 -1
  23. package/dist/web-dist/assets/{monaco-editor-BO3WVEVM.js → monaco-editor-CNMPKLoW.js} +1 -1
  24. package/dist/web-dist/assets/{monitoring-BtlIcl3k.js → monitoring-Bv8YDvqU.js} +1 -1
  25. package/dist/web-dist/assets/{overlay.store-DjYsesE7.js → overlay.store-Cni3_SHg.js} +1 -1
  26. package/dist/web-dist/assets/{queries.store-CxkLh1ra.js → queries.store-Z6EhVY9R.js} +1 -1
  27. package/dist/web-dist/assets/{query-runner-keHo7IiI.js → query-runner-CRfNq31h.js} +3 -3
  28. package/dist/web-dist/assets/{radix-ui-C1Z_SoKk.js → radix-ui-Bk380HgZ.js} +1 -1
  29. package/dist/web-dist/assets/{react-1gU4DcpZ.js → react-CfXK6joe.js} +1 -1
  30. package/dist/web-dist/assets/{react-dom-DkH0eaTq.js → react-dom-Y-FhvvJI.js} +1 -1
  31. package/dist/web-dist/assets/{redis-value-BmLGJf9X.js → redis-value-dNWQPX9M.js} +1 -1
  32. package/dist/web-dist/assets/{rolldown-runtime-DY1mqKjv.js → rolldown-runtime-BGAbM2vM.js} +1 -1
  33. package/dist/web-dist/assets/{runner-CvUPs6q4.js → runner-CT8TXCWe.js} +1 -1
  34. package/dist/web-dist/assets/{schema-C-10JjXl.js → schema--myTsN4I.js} +1 -1
  35. package/dist/web-dist/assets/schema-Cd61GWLb.js +57 -0
  36. package/dist/web-dist/assets/{table-C75Kr4aI.js → table-DznwPkbx.js} +1 -1
  37. package/dist/web-dist/assets/{tanstack-C3XvOIUf.js → tanstack-CJCyKnhp.js} +1 -1
  38. package/dist/web-dist/assets/{visualizer-CiiH2acP.js → visualizer-CsHwq2yx.js} +1 -1
  39. package/dist/web-dist/index.html +18 -18
  40. package/package.json +1 -1
  41. package/dist/web-dist/assets/index-Be5YdcX5.css +0 -2
  42. package/dist/web-dist/assets/schema-9nf0q_01.js +0 -57
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
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(`
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.2"}}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.2",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
3
  `).slice(1).filter(n=>/^\s*at\s/.test(n));t.stack=[`${e}: Server operation failed`,...r].join(`
4
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
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 $$
@@ -438,7 +438,7 @@ This will return the 5 customers with the highest total order value. You might a
438
438
  `)}if(a.relationships&&a.relationships.length>0){t+=`
439
439
  **Relationships:**
440
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(`
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]="ef089fe5-5bd2-4f71-8ba5-b302819c75d7",a._sentryDebugIdIdentifier="sentry-dbid-ef089fe5-5bd2-4f71-8ba5-b302819c75d7")}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(`
442
442
  Usage:`)),console.log(` db-studio [options]
443
443
  `),console.log(Qe.bold("Supported Databases:")),console.log(` PostgreSQL, MySQL, SQL Server, MongoDB, SQLite, Redis
444
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