db-studio 1.4.0 → 1.5.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.
- package/README.md +44 -0
- package/dist/core-dist/assets/_pathlessLayout-B3hOmNOY.js +1 -0
- package/dist/core-dist/assets/_queryId-B-Yx8vY8.js +1 -0
- package/dist/core-dist/assets/_table-C9ZV09Jc.js +8 -0
- package/dist/core-dist/assets/_table-DIbBLMgY.js +39 -0
- package/dist/core-dist/assets/{cdoe-editor-BCFPgj4h.js → cdoe-editor-BUyGnaMR.js} +1 -1
- package/dist/core-dist/assets/dialog-BtqI2R7E.js +1 -0
- package/dist/core-dist/assets/icons-B2mES2Qq.js +1 -0
- package/dist/core-dist/assets/index-BV7euJxs.js +1 -0
- package/dist/core-dist/assets/index-C7KJNEv-.js +1 -0
- package/dist/core-dist/assets/index-CESnXcY7.js +1 -0
- package/dist/core-dist/assets/index-CTFnCamQ.js +1 -0
- package/dist/core-dist/assets/index-CwHrvESi.css +1 -0
- package/dist/core-dist/assets/index-DO_12lzR.js +58 -0
- package/dist/core-dist/assets/index-DQOVykiS.js +1 -0
- package/dist/core-dist/assets/{indexes-Dowc1Q3x.js → indexes-DESnDRwn.js} +1 -1
- package/dist/core-dist/assets/logs-DKdQRaOz.js +1 -0
- package/dist/core-dist/assets/queries.store-DCqn9r_M.js +1 -0
- package/dist/core-dist/assets/radix-ui-c-7GrHMM.js +51 -0
- package/dist/core-dist/assets/{react-dom-C-8vY09X.js → react-dom-BcUZDRtY.js} +1 -1
- package/dist/core-dist/assets/runner-tab-CloOoJUy.js +3 -0
- package/dist/core-dist/assets/scroll-area-D613A-kL.js +1 -0
- package/dist/core-dist/assets/tanstack-BaWakKkc.js +7 -0
- package/dist/core-dist/assets/tooltip-B4cd0H8Q.js +1 -0
- package/dist/core-dist/assets/use-delete-column-DxoXObaz.js +1 -0
- package/dist/core-dist/assets/{visualizer-DRuf8l7V.js → visualizer-CQGMZpWZ.js} +1 -1
- package/dist/core-dist/index.html +7 -7
- package/dist/index.js +99 -54
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
- package/dist/core-dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/core-dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/core-dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/core-dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/core-dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/core-dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/core-dist/assets/_baseUniq-C7A7fsQ-.js +0 -1
- package/dist/core-dist/assets/_pathlessLayout-BErOoJBf.js +0 -2
- package/dist/core-dist/assets/_queryId-B1LaFAmm.js +0 -1
- package/dist/core-dist/assets/_table-4nxpgHEz.js +0 -8
- package/dist/core-dist/assets/abap-BdImnpbu.js +0 -1
- package/dist/core-dist/assets/actionscript-3-CfeIJUat.js +0 -1
- package/dist/core-dist/assets/ada-bCR0ucgS.js +0 -1
- package/dist/core-dist/assets/andromeeda-C-Jbm3Hp.js +0 -1
- package/dist/core-dist/assets/angular-html-CU67Zn6k.js +0 -1
- package/dist/core-dist/assets/angular-ts-BwZT4LLn.js +0 -1
- package/dist/core-dist/assets/apache-Pmp26Uib.js +0 -1
- package/dist/core-dist/assets/apex-D8_7TLub.js +0 -1
- package/dist/core-dist/assets/apl-dKokRX4l.js +0 -1
- package/dist/core-dist/assets/applescript-Co6uUVPk.js +0 -1
- package/dist/core-dist/assets/ara-BRHolxvo.js +0 -1
- package/dist/core-dist/assets/arc-Clvi5rzR.js +0 -1
- package/dist/core-dist/assets/architectureDiagram-VXUJARFQ-DkipSmLb.js +0 -36
- package/dist/core-dist/assets/asciidoc-Dv7Oe6Be.js +0 -1
- package/dist/core-dist/assets/asm-D_Q5rh1f.js +0 -1
- package/dist/core-dist/assets/astro-CbQHKStN.js +0 -1
- package/dist/core-dist/assets/aurora-x-D-2ljcwZ.js +0 -1
- package/dist/core-dist/assets/awk-DMzUqQB5.js +0 -1
- package/dist/core-dist/assets/ayu-dark-CmMr59Fi.js +0 -1
- package/dist/core-dist/assets/ballerina-BFfxhgS-.js +0 -1
- package/dist/core-dist/assets/bat-BkioyH1T.js +0 -1
- package/dist/core-dist/assets/beancount-k_qm7-4y.js +0 -1
- package/dist/core-dist/assets/berry-uYugtg8r.js +0 -1
- package/dist/core-dist/assets/bibtex-CHM0blh-.js +0 -1
- package/dist/core-dist/assets/bicep-Bmn6On1c.js +0 -1
- package/dist/core-dist/assets/blade-D4QpJJKB.js +0 -1
- package/dist/core-dist/assets/blockDiagram-VD42YOAC-DV8KUj94.js +0 -122
- package/dist/core-dist/assets/bsl-BO_Y6i37.js +0 -1
- package/dist/core-dist/assets/c-BIGW1oBm.js +0 -1
- package/dist/core-dist/assets/c3-VCDPK7BO.js +0 -1
- package/dist/core-dist/assets/c4Diagram-YG6GDRKO-CIKSfaF1.js +0 -10
- package/dist/core-dist/assets/cadence-Bv_4Rxtq.js +0 -1
- package/dist/core-dist/assets/cairo-KRGpt6FW.js +0 -1
- package/dist/core-dist/assets/catppuccin-frappe-DFWUc33u.js +0 -1
- package/dist/core-dist/assets/catppuccin-latte-C9dUb6Cb.js +0 -1
- package/dist/core-dist/assets/catppuccin-macchiato-DQyhUUbL.js +0 -1
- package/dist/core-dist/assets/catppuccin-mocha-D87Tk5Gz.js +0 -1
- package/dist/core-dist/assets/channel-B2Rh1omC.js +0 -1
- package/dist/core-dist/assets/chunk-4BX2VUAB-DcvB4_uV.js +0 -1
- package/dist/core-dist/assets/chunk-55IACEB6-EG9AyKaq.js +0 -1
- package/dist/core-dist/assets/chunk-B4BG7PRW-KK8IJqzV.js +0 -165
- package/dist/core-dist/assets/chunk-DI55MBZ5-TpII66YZ.js +0 -220
- package/dist/core-dist/assets/chunk-FMBD7UC4-IEg5SEkW.js +0 -15
- package/dist/core-dist/assets/chunk-QN33PNHL-DOQqAhwZ.js +0 -1
- package/dist/core-dist/assets/chunk-QZHKN3VN-CQD63wVo.js +0 -1
- package/dist/core-dist/assets/chunk-TZMSLE5B-Ck8unx9M.js +0 -1
- package/dist/core-dist/assets/clarity-D53aC0YG.js +0 -1
- package/dist/core-dist/assets/classDiagram-2ON5EDUG-yB0lDqQ_.js +0 -1
- package/dist/core-dist/assets/classDiagram-v2-WZHVMYZB-yB0lDqQ_.js +0 -1
- package/dist/core-dist/assets/clojure-P80f7IUj.js +0 -1
- package/dist/core-dist/assets/clone-DMtL-4i6.js +0 -1
- package/dist/core-dist/assets/cmake-D1j8_8rp.js +0 -1
- package/dist/core-dist/assets/cobol-nwyudZeR.js +0 -1
- package/dist/core-dist/assets/code-block-IT6T5CEO-BkhPLTN-.js +0 -154
- package/dist/core-dist/assets/codeowners-Bp6g37R7.js +0 -1
- package/dist/core-dist/assets/codeql-DsOJ9woJ.js +0 -1
- package/dist/core-dist/assets/coffee-Ch7k5sss.js +0 -1
- package/dist/core-dist/assets/common-lisp-Cg-RD9OK.js +0 -1
- package/dist/core-dist/assets/coq-DkFqJrB1.js +0 -1
- package/dist/core-dist/assets/cose-bilkent-S5V4N54A-BU01uPeb.js +0 -1
- package/dist/core-dist/assets/cpp-CofmeUqb.js +0 -1
- package/dist/core-dist/assets/crystal-tKQVLTB8.js +0 -1
- package/dist/core-dist/assets/csharp-K5feNrxe.js +0 -1
- package/dist/core-dist/assets/css-DPfMkruS.js +0 -1
- package/dist/core-dist/assets/csv-fuZLfV_i.js +0 -1
- package/dist/core-dist/assets/cue-D82EKSYY.js +0 -1
- package/dist/core-dist/assets/cypher-COkxafJQ.js +0 -1
- package/dist/core-dist/assets/cytoscape.esm-5J0xJHOV.js +0 -321
- package/dist/core-dist/assets/d-85-TOEBH.js +0 -1
- package/dist/core-dist/assets/dagre-6UL2VRFP-DgGR46yM.js +0 -4
- package/dist/core-dist/assets/dark-plus-C3mMm8J8.js +0 -1
- package/dist/core-dist/assets/dart-CF10PKvl.js +0 -1
- package/dist/core-dist/assets/dax-CEL-wOlO.js +0 -1
- package/dist/core-dist/assets/defaultLocale-DX6XiGOO.js +0 -1
- package/dist/core-dist/assets/desktop-BmXAJ9_W.js +0 -1
- package/dist/core-dist/assets/diagram-PSM6KHXK-D_opTgTY.js +0 -24
- package/dist/core-dist/assets/diagram-QEK2KX5R-C8q65IvQ.js +0 -43
- package/dist/core-dist/assets/diagram-S2PKOQOG-DideTxM7.js +0 -24
- package/dist/core-dist/assets/diff-D97Zzqfu.js +0 -1
- package/dist/core-dist/assets/docker-BcOcwvcX.js +0 -1
- package/dist/core-dist/assets/dotenv-Da5cRb03.js +0 -1
- package/dist/core-dist/assets/dracula-BzJJZx-M.js +0 -1
- package/dist/core-dist/assets/dracula-soft-BXkSAIEj.js +0 -1
- package/dist/core-dist/assets/dream-maker-BtqSS_iP.js +0 -1
- package/dist/core-dist/assets/edge-BkV0erSs.js +0 -1
- package/dist/core-dist/assets/elixir-CDX3lj18.js +0 -1
- package/dist/core-dist/assets/elm-DbKCFpqz.js +0 -1
- package/dist/core-dist/assets/emacs-lisp-C9XAeP06.js +0 -1
- package/dist/core-dist/assets/erDiagram-Q2GNP2WA-CRAdUMHH.js +0 -60
- package/dist/core-dist/assets/erb-BOJIQeun.js +0 -1
- package/dist/core-dist/assets/erlang-DsQrWhSR.js +0 -1
- package/dist/core-dist/assets/everforest-dark-BgDCqdQA.js +0 -1
- package/dist/core-dist/assets/everforest-light-C8M2exoo.js +0 -1
- package/dist/core-dist/assets/fennel-BYunw83y.js +0 -1
- package/dist/core-dist/assets/fish-BvzEVeQv.js +0 -1
- package/dist/core-dist/assets/flowDiagram-NV44I4VS-BZhEr3Uj.js +0 -162
- package/dist/core-dist/assets/fluent-C4IJs8-o.js +0 -1
- package/dist/core-dist/assets/fortran-fixed-form-CkoXwp7k.js +0 -1
- package/dist/core-dist/assets/fortran-free-form-BxgE0vQu.js +0 -1
- package/dist/core-dist/assets/fsharp-CXgrBDvD.js +0 -1
- package/dist/core-dist/assets/ganttDiagram-JELNMOA3-v6QMKJx4.js +0 -267
- package/dist/core-dist/assets/gdresource-B7Tvp0Sc.js +0 -1
- package/dist/core-dist/assets/gdscript-DTMYz4Jt.js +0 -1
- package/dist/core-dist/assets/gdshader-DkwncUOv.js +0 -1
- package/dist/core-dist/assets/genie-D0YGMca9.js +0 -1
- package/dist/core-dist/assets/gherkin-DyxjwDmM.js +0 -1
- package/dist/core-dist/assets/git-commit-F4YmCXRG.js +0 -1
- package/dist/core-dist/assets/git-rebase-r7XF79zn.js +0 -1
- package/dist/core-dist/assets/gitGraphDiagram-NY62KEGX-A1MEr8uU.js +0 -65
- package/dist/core-dist/assets/github-dark-DHJKELXO.js +0 -1
- package/dist/core-dist/assets/github-dark-default-Cuk6v7N8.js +0 -1
- package/dist/core-dist/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
- package/dist/core-dist/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
- package/dist/core-dist/assets/github-light-DAi9KRSo.js +0 -1
- package/dist/core-dist/assets/github-light-default-D7oLnXFd.js +0 -1
- package/dist/core-dist/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
- package/dist/core-dist/assets/gleam-BspZqrRM.js +0 -1
- package/dist/core-dist/assets/glimmer-js-Rg0-pVw9.js +0 -1
- package/dist/core-dist/assets/glimmer-ts-U6CK756n.js +0 -1
- package/dist/core-dist/assets/glsl-DplSGwfg.js +0 -1
- package/dist/core-dist/assets/gn-n2N0HUVH.js +0 -1
- package/dist/core-dist/assets/gnuplot-DdkO51Og.js +0 -1
- package/dist/core-dist/assets/go-Dn2_MT6a.js +0 -1
- package/dist/core-dist/assets/graph-C6dXmhID.js +0 -1
- package/dist/core-dist/assets/graphql-ChdNCCLP.js +0 -1
- package/dist/core-dist/assets/groovy-gcz8RCvz.js +0 -1
- package/dist/core-dist/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -1
- package/dist/core-dist/assets/gruvbox-dark-medium-GsRaNv29.js +0 -1
- package/dist/core-dist/assets/gruvbox-dark-soft-CVdnzihN.js +0 -1
- package/dist/core-dist/assets/gruvbox-light-hard-CH1njM8p.js +0 -1
- package/dist/core-dist/assets/gruvbox-light-medium-DRw_LuNl.js +0 -1
- package/dist/core-dist/assets/gruvbox-light-soft-hJgmCMqR.js +0 -1
- package/dist/core-dist/assets/hack-CaT9iCJl.js +0 -1
- package/dist/core-dist/assets/haml-B8DHNrY2.js +0 -1
- package/dist/core-dist/assets/handlebars-BL8al0AC.js +0 -1
- package/dist/core-dist/assets/haskell-Df6bDoY_.js +0 -1
- package/dist/core-dist/assets/haxe-CzTSHFRz.js +0 -1
- package/dist/core-dist/assets/hcl-BWvSN4gD.js +0 -1
- package/dist/core-dist/assets/hjson-D5-asLiD.js +0 -1
- package/dist/core-dist/assets/hlsl-D3lLCCz7.js +0 -1
- package/dist/core-dist/assets/houston-DnULxvSX.js +0 -1
- package/dist/core-dist/assets/html-GMplVEZG.js +0 -1
- package/dist/core-dist/assets/html-derivative-BFtXZ54Q.js +0 -1
- package/dist/core-dist/assets/http-jrhK8wxY.js +0 -1
- package/dist/core-dist/assets/hurl-irOxFIW8.js +0 -1
- package/dist/core-dist/assets/hxml-Bvhsp5Yf.js +0 -1
- package/dist/core-dist/assets/hy-DFXneXwc.js +0 -1
- package/dist/core-dist/assets/icons-CThL5JLu.js +0 -1
- package/dist/core-dist/assets/imba-DGztddWO.js +0 -1
- package/dist/core-dist/assets/index-B7-ICZ0j.js +0 -1
- package/dist/core-dist/assets/index-BMkY85Cs.js +0 -58
- package/dist/core-dist/assets/index-BXF4gXVp.js +0 -1
- package/dist/core-dist/assets/index-Bgk4PJE4.js +0 -1
- package/dist/core-dist/assets/index-CI-PCTpD.css +0 -1
- package/dist/core-dist/assets/index-DVnhzasD.js +0 -1
- package/dist/core-dist/assets/infoDiagram-WHAUD3N6-CJkR0w30.js +0 -2
- package/dist/core-dist/assets/ini-BEwlwnbL.js +0 -1
- package/dist/core-dist/assets/init-Gi6I4Gst.js +0 -1
- package/dist/core-dist/assets/java-CylS5w8V.js +0 -1
- package/dist/core-dist/assets/javascript-wDzz0qaB.js +0 -1
- package/dist/core-dist/assets/jinja-4LBKfQ-Z.js +0 -1
- package/dist/core-dist/assets/jison-wvAkD_A8.js +0 -1
- package/dist/core-dist/assets/journeyDiagram-XKPGCS4Q-SAEhBpzZ.js +0 -139
- package/dist/core-dist/assets/json-Cp-IABpG.js +0 -1
- package/dist/core-dist/assets/json5-C9tS-k6U.js +0 -1
- package/dist/core-dist/assets/jsonc-Des-eS-w.js +0 -1
- package/dist/core-dist/assets/jsonl-DcaNXYhu.js +0 -1
- package/dist/core-dist/assets/jsonnet-DFQXde-d.js +0 -1
- package/dist/core-dist/assets/jssm-C2t-YnRu.js +0 -1
- package/dist/core-dist/assets/jsx-g9-lgVsj.js +0 -1
- package/dist/core-dist/assets/julia-CxzCAyBv.js +0 -1
- package/dist/core-dist/assets/kanagawa-dragon-CkXjmgJE.js +0 -1
- package/dist/core-dist/assets/kanagawa-lotus-CfQXZHmo.js +0 -1
- package/dist/core-dist/assets/kanagawa-wave-DWedfzmr.js +0 -1
- package/dist/core-dist/assets/kanban-definition-3W4ZIXB7-CTjwDgKD.js +0 -89
- package/dist/core-dist/assets/katex-DvXFAOB1.css +0 -1
- package/dist/core-dist/assets/kdl-DV7GczEv.js +0 -1
- package/dist/core-dist/assets/kotlin-BdnUsdx6.js +0 -1
- package/dist/core-dist/assets/kusto-DZf3V79B.js +0 -1
- package/dist/core-dist/assets/laserwave-DUszq2jm.js +0 -1
- package/dist/core-dist/assets/latex-B4uzh10-.js +0 -1
- package/dist/core-dist/assets/layout-BC4bIyCj.js +0 -1
- package/dist/core-dist/assets/lean-BZvkOJ9d.js +0 -1
- package/dist/core-dist/assets/less-B1dDrJ26.js +0 -1
- package/dist/core-dist/assets/light-plus-B7mTdjB0.js +0 -1
- package/dist/core-dist/assets/linear-aOQP6b5O.js +0 -1
- package/dist/core-dist/assets/liquid-DYVedYrR.js +0 -1
- package/dist/core-dist/assets/llvm-BtvRca6l.js +0 -1
- package/dist/core-dist/assets/log-2UxHyX5q.js +0 -1
- package/dist/core-dist/assets/logo-BtOb2qkB.js +0 -1
- package/dist/core-dist/assets/logs-BlD66J6V.js +0 -1
- package/dist/core-dist/assets/lua-BbnMAYS6.js +0 -1
- package/dist/core-dist/assets/luau-C-HG3fhB.js +0 -1
- package/dist/core-dist/assets/make-CHLpvVh8.js +0 -1
- package/dist/core-dist/assets/markdown-Cvjx9yec.js +0 -1
- package/dist/core-dist/assets/marko-DZsq8hO1.js +0 -1
- package/dist/core-dist/assets/material-theme-D5KoaKCx.js +0 -1
- package/dist/core-dist/assets/material-theme-darker-BfHTSMKl.js +0 -1
- package/dist/core-dist/assets/material-theme-lighter-B0m2ddpp.js +0 -1
- package/dist/core-dist/assets/material-theme-ocean-CyktbL80.js +0 -1
- package/dist/core-dist/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
- package/dist/core-dist/assets/matlab-D7o27uSR.js +0 -1
- package/dist/core-dist/assets/mdc-DUICxH0z.js +0 -1
- package/dist/core-dist/assets/mdx-Cmh6b_Ma.js +0 -1
- package/dist/core-dist/assets/mermaid-VLURNSYL-Bk83Yp1q.js +0 -377
- package/dist/core-dist/assets/mermaid-mWjccvbQ.js +0 -1
- package/dist/core-dist/assets/mermaid.core-VvKZ2mCx.js +0 -191
- package/dist/core-dist/assets/min-BiqQDxvT.js +0 -1
- package/dist/core-dist/assets/min-dark-CafNBF8u.js +0 -1
- package/dist/core-dist/assets/min-light-CTRr51gU.js +0 -1
- package/dist/core-dist/assets/mindmap-definition-VGOIOE7T-DjjEGOvH.js +0 -68
- package/dist/core-dist/assets/mipsasm-CKIfxQSi.js +0 -1
- package/dist/core-dist/assets/mojo-B93PlW-d.js +0 -1
- package/dist/core-dist/assets/monokai-D4h5O-jR.js +0 -1
- package/dist/core-dist/assets/moonbit-Ba13S78F.js +0 -1
- package/dist/core-dist/assets/move-Bu9oaDYs.js +0 -1
- package/dist/core-dist/assets/narrat-DRg8JJMk.js +0 -1
- package/dist/core-dist/assets/nextflow-BrzmwbiE.js +0 -1
- package/dist/core-dist/assets/nginx-DknmC5AR.js +0 -1
- package/dist/core-dist/assets/night-owl-C39BiMTA.js +0 -1
- package/dist/core-dist/assets/nim-CVrawwO9.js +0 -1
- package/dist/core-dist/assets/nix-CwoSXNpI.js +0 -1
- package/dist/core-dist/assets/nord-Ddv68eIx.js +0 -1
- package/dist/core-dist/assets/nushell-C-sUppwS.js +0 -1
- package/dist/core-dist/assets/objective-c-DXmwc3jG.js +0 -1
- package/dist/core-dist/assets/objective-cpp-CLxacb5B.js +0 -1
- package/dist/core-dist/assets/ocaml-C0hk2d4L.js +0 -1
- package/dist/core-dist/assets/one-dark-pro-DVMEJ2y_.js +0 -1
- package/dist/core-dist/assets/one-light-PoHY5YXO.js +0 -1
- package/dist/core-dist/assets/openscad-C4EeE6gA.js +0 -1
- package/dist/core-dist/assets/ordinal-BENe2yWM.js +0 -1
- package/dist/core-dist/assets/pascal-D93ZcfNL.js +0 -1
- package/dist/core-dist/assets/perl-C0TMdlhV.js +0 -1
- package/dist/core-dist/assets/php-CDn_0X-4.js +0 -1
- package/dist/core-dist/assets/pieDiagram-ADFJNKIX-AUM01WmV.js +0 -30
- package/dist/core-dist/assets/pkl-u5AG7uiY.js +0 -1
- package/dist/core-dist/assets/plastic-3e1v2bzS.js +0 -1
- package/dist/core-dist/assets/plsql-ChMvpjG-.js +0 -1
- package/dist/core-dist/assets/po-BTJTHyun.js +0 -1
- package/dist/core-dist/assets/poimandres-CS3Unz2-.js +0 -1
- package/dist/core-dist/assets/polar-C0HS_06l.js +0 -1
- package/dist/core-dist/assets/postcss-CXtECtnM.js +0 -1
- package/dist/core-dist/assets/powerquery-CEu0bR-o.js +0 -1
- package/dist/core-dist/assets/powershell-Dpen1YoG.js +0 -1
- package/dist/core-dist/assets/prisma-Dd19v3D-.js +0 -1
- package/dist/core-dist/assets/prolog-CbFg5uaA.js +0 -1
- package/dist/core-dist/assets/proto-C7zT0LnQ.js +0 -1
- package/dist/core-dist/assets/pug-CGlum2m_.js +0 -1
- package/dist/core-dist/assets/puppet-BMWR74SV.js +0 -1
- package/dist/core-dist/assets/purescript-CklMAg4u.js +0 -1
- package/dist/core-dist/assets/python-B6aJPvgy.js +0 -1
- package/dist/core-dist/assets/qml-3beO22l8.js +0 -1
- package/dist/core-dist/assets/qmldir-C8lEn-DE.js +0 -1
- package/dist/core-dist/assets/qss-IeuSbFQv.js +0 -1
- package/dist/core-dist/assets/quadrantDiagram-AYHSOK5B-MpcGOIDU.js +0 -7
- package/dist/core-dist/assets/queries.store-DjOPk8vF.js +0 -1
- package/dist/core-dist/assets/r-Dspwwk_N.js +0 -1
- package/dist/core-dist/assets/racket-BqYA7rlc.js +0 -1
- package/dist/core-dist/assets/radix-ui-bzITMjAn.js +0 -51
- package/dist/core-dist/assets/raku-DXvB9xmW.js +0 -1
- package/dist/core-dist/assets/razor-C1TweQQi.js +0 -1
- package/dist/core-dist/assets/red-bN70gL4F.js +0 -1
- package/dist/core-dist/assets/reg-C-SQnVFl.js +0 -1
- package/dist/core-dist/assets/regexp-CDVJQ6XC.js +0 -1
- package/dist/core-dist/assets/rel-C3B-1QV4.js +0 -1
- package/dist/core-dist/assets/requirementDiagram-UZGBJVZJ-DTgvy-oh.js +0 -64
- package/dist/core-dist/assets/riscv-BM1_JUlF.js +0 -1
- package/dist/core-dist/assets/rose-pine-dawn-DHQR4-dF.js +0 -1
- package/dist/core-dist/assets/rose-pine-moon-D4_iv3hh.js +0 -1
- package/dist/core-dist/assets/rose-pine-qdsjHGoJ.js +0 -1
- package/dist/core-dist/assets/rosmsg-BJDFO7_C.js +0 -1
- package/dist/core-dist/assets/rst-B0xPkSld.js +0 -1
- package/dist/core-dist/assets/ruby-BvKwtOVI.js +0 -1
- package/dist/core-dist/assets/runner-tab-2NkPdwaD.js +0 -3
- package/dist/core-dist/assets/rust-B1yitclQ.js +0 -1
- package/dist/core-dist/assets/sankeyDiagram-TZEHDZUN-Coy7Jnu4.js +0 -10
- package/dist/core-dist/assets/sas-cz2c8ADy.js +0 -1
- package/dist/core-dist/assets/sass-Cj5Yp3dK.js +0 -1
- package/dist/core-dist/assets/scala-C151Ov-r.js +0 -1
- package/dist/core-dist/assets/schema-C9usm3AO.js +0 -1
- package/dist/core-dist/assets/scheme-C98Dy4si.js +0 -1
- package/dist/core-dist/assets/scroll-area-DuacQlkg.js +0 -1
- package/dist/core-dist/assets/scss-OYdSNvt2.js +0 -1
- package/dist/core-dist/assets/sdbl-DVxCFoDh.js +0 -1
- package/dist/core-dist/assets/sequenceDiagram-WL72ISMW-DWol0BxA.js +0 -145
- package/dist/core-dist/assets/shaderlab-Dg9Lc6iA.js +0 -1
- package/dist/core-dist/assets/shellscript-Yzrsuije.js +0 -1
- package/dist/core-dist/assets/shellsession-BADoaaVG.js +0 -1
- package/dist/core-dist/assets/slack-dark-BthQWCQV.js +0 -1
- package/dist/core-dist/assets/slack-ochin-DqwNpetd.js +0 -1
- package/dist/core-dist/assets/smalltalk-BERRCDM3.js +0 -1
- package/dist/core-dist/assets/snazzy-light-Bw305WKR.js +0 -1
- package/dist/core-dist/assets/solarized-dark-DXbdFlpD.js +0 -1
- package/dist/core-dist/assets/solarized-light-L9t79GZl.js +0 -1
- package/dist/core-dist/assets/solidity-rGO070M0.js +0 -1
- package/dist/core-dist/assets/soy-Brmx7dQM.js +0 -1
- package/dist/core-dist/assets/sparql-rVzFXLq3.js +0 -1
- package/dist/core-dist/assets/splunk-BtCnVYZw.js +0 -1
- package/dist/core-dist/assets/sql-BLtJtn59.js +0 -1
- package/dist/core-dist/assets/ssh-config-_ykCGR6B.js +0 -1
- package/dist/core-dist/assets/stata-BH5u7GGu.js +0 -1
- package/dist/core-dist/assets/stateDiagram-FKZM4ZOC-B4qm6ej0.js +0 -1
- package/dist/core-dist/assets/stateDiagram-v2-4FDKWEC3-BuP2exNa.js +0 -1
- package/dist/core-dist/assets/stylus-BEDo0Tqx.js +0 -1
- package/dist/core-dist/assets/svelte-zxCyuUbr.js +0 -1
- package/dist/core-dist/assets/swift-Dg5xB15N.js +0 -1
- package/dist/core-dist/assets/synthwave-84-CbfX1IO0.js +0 -1
- package/dist/core-dist/assets/system-verilog-CnnmHF94.js +0 -1
- package/dist/core-dist/assets/systemd-4A_iFExJ.js +0 -1
- package/dist/core-dist/assets/talonscript-CkByrt1z.js +0 -1
- package/dist/core-dist/assets/tanstack-Be3yNbjx.js +0 -9
- package/dist/core-dist/assets/tasl-QIJgUcNo.js +0 -1
- package/dist/core-dist/assets/tcl-dwOrl1Do.js +0 -1
- package/dist/core-dist/assets/templ-W15q3VgB.js +0 -1
- package/dist/core-dist/assets/terraform-BETggiCN.js +0 -1
- package/dist/core-dist/assets/tex-CvyZ59Mk.js +0 -1
- package/dist/core-dist/assets/timeline-definition-IT6M3QCI-DZ5Afuno.js +0 -61
- package/dist/core-dist/assets/tokyo-night-hegEt444.js +0 -1
- package/dist/core-dist/assets/toml-vGWfd6FD.js +0 -1
- package/dist/core-dist/assets/treemap-KMMF4GRG-Cxy-aurk.js +0 -128
- package/dist/core-dist/assets/ts-tags-zn1MmPIZ.js +0 -1
- package/dist/core-dist/assets/tsv-B_m7g4N7.js +0 -1
- package/dist/core-dist/assets/tsx-COt5Ahok.js +0 -1
- package/dist/core-dist/assets/turtle-BsS91CYL.js +0 -1
- package/dist/core-dist/assets/twig-CO9l9SDP.js +0 -1
- package/dist/core-dist/assets/typescript-BPQ3VLAy.js +0 -1
- package/dist/core-dist/assets/typespec-BGHnOYBU.js +0 -1
- package/dist/core-dist/assets/typst-DHCkPAjA.js +0 -1
- package/dist/core-dist/assets/v-BcVCzyr7.js +0 -1
- package/dist/core-dist/assets/vala-CsfeWuGM.js +0 -1
- package/dist/core-dist/assets/vb-D17OF-Vu.js +0 -1
- package/dist/core-dist/assets/verilog-BQ8w6xss.js +0 -1
- package/dist/core-dist/assets/vesper-DU1UobuO.js +0 -1
- package/dist/core-dist/assets/vhdl-CeAyd5Ju.js +0 -1
- package/dist/core-dist/assets/viml-CJc9bBzg.js +0 -1
- package/dist/core-dist/assets/vitesse-black-Bkuqu6BP.js +0 -1
- package/dist/core-dist/assets/vitesse-dark-D0r3Knsf.js +0 -1
- package/dist/core-dist/assets/vitesse-light-CVO1_9PV.js +0 -1
- package/dist/core-dist/assets/vue-DN_0RTcg.js +0 -1
- package/dist/core-dist/assets/vue-html-AaS7Mt5G.js +0 -1
- package/dist/core-dist/assets/vue-vine-CQOfvN7w.js +0 -1
- package/dist/core-dist/assets/vyper-CDx5xZoG.js +0 -1
- package/dist/core-dist/assets/wasm-CG6Dc4jp.js +0 -1
- package/dist/core-dist/assets/wasm-MzD3tlZU.js +0 -1
- package/dist/core-dist/assets/wenyan-BV7otONQ.js +0 -1
- package/dist/core-dist/assets/wgsl-Dx-B1_4e.js +0 -1
- package/dist/core-dist/assets/wikitext-BhOHFoWU.js +0 -1
- package/dist/core-dist/assets/wit-5i3qLPDT.js +0 -1
- package/dist/core-dist/assets/wolfram-lXgVvXCa.js +0 -1
- package/dist/core-dist/assets/xml-sdJ4AIDG.js +0 -1
- package/dist/core-dist/assets/xsl-CtQFsRM5.js +0 -1
- package/dist/core-dist/assets/xychartDiagram-PRI3JC2R-yhq_s0e5.js +0 -7
- package/dist/core-dist/assets/yaml-Buea-lGh.js +0 -1
- package/dist/core-dist/assets/zenscript-DVFEvuxE.js +0 -1
- package/dist/core-dist/assets/zig-VOosw3JB.js +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../shared/src/constants/chat.ts","../../shared/src/constants/column-types-mysql.ts","../../shared/src/constants/column-types-pgsql.ts","../../shared/src/constants/defaults.ts","../../shared/src/constants/links.ts","../../shared/src/constants/meta.ts","../../shared/src/constants/proxy-limits.ts","../../shared/src/constants/index.ts","../../shared/src/types/add-record.types.ts","../../shared/src/types/api-response.types.ts","../../shared/src/types/bulk-insert-records.type.ts","../../shared/src/types/database.types.ts","../../shared/src/types/chat.types.ts","../../shared/src/types/cmd-args.types.ts","../../shared/src/types/column-info.types.ts","../../shared/src/types/column.type.ts","../../shared/src/types/create-table.types.ts","../../shared/src/types/database-list.types.ts","../../shared/src/types/database-schema.type.ts","../../shared/src/types/delete-column.types.ts","../../shared/src/types/delete-record.types.ts","../../shared/src/types/delete-table.types.ts","../../shared/src/types/execute-query.types.ts","../../shared/src/types/export-table.types.ts","../../shared/src/types/rate-limit-response.type.ts","../../shared/src/types/table-data.types.ts","../../shared/src/types/table-info.type.ts","../../shared/src/types/table-schema.types.ts","../../shared/src/types/update-recors.types.ts","../../shared/src/types/index.ts","../src/middlewares/error-handler.ts","../src/db.ts","../src/db-manager.ts","../src/dao/table-columns.dao.ts","../src/dao/table-details-schema.ts","../src/utils/system-prompt-generator.ts","../src/routes/chat.routes.ts","../src/utils/parse-database-url.ts","../src/dao/database-list.dao.ts","../src/dao/mysql/database-list.mysql.dao.ts","../src/routes/databases.routes.ts","../src/dao/mysql/query.mysql.dao.ts","../src/dao/query.dao.ts","../src/routes/query.routes.ts","../src/dao/add-record.dao.ts","../src/dao/bulk-insert-records.dao.ts","../src/dao/delete-records.dao.ts","../src/dao/mysql/table-columns.mysql.dao.ts","../src/dao/mysql/add-record.mysql.dao.ts","../src/dao/mysql/bulk-insert-records.mysql.dao.ts","../src/dao/mysql/delete-records.mysql.dao.ts","../src/dao/mysql/update-records.mysql.dao.ts","../src/dao/update-records.dao.ts","../src/routes/records.routes.ts","../src/dao/create-table.dao.ts","../src/dao/delete-column.dao.ts","../src/dao/delete-table.dao.ts","../src/dao/export-table.dao.ts","../src/dao/mysql/create-table.mysql.dao.ts","../src/dao/mysql/delete-column.mysql.dao.ts","../src/dao/mysql/delete-table.mysql.dao.ts","../src/dao/mysql/export-table.mysql.dao.ts","../src/dao/mysql/table-list.mysql.dao.ts","../src/dao/mysql/table-schema.mysql.dao.ts","../src/utils/build-clauses-mysql.ts","../src/dao/mysql/tables-data.mysql.dao.ts","../src/dao/table-list.dao.ts","../src/dao/table-schema.dao.ts","../src/utils/build-clauses.ts","../src/dao/tables-data.dao.ts","../src/utils/get-export-file.ts","../src/routes/tables.routes.ts","../src/utils/create-server.ts","../src/index.ts","../src/cmd/args.ts","../src/cmd/get-db-url.ts","../src/cmd/load-env.ts","../src/cmd/show-help.ts","../src/cmd/show-status.ts","../src/cmd/show-version.ts","../package.json"],"sourcesContent":["export const CHAT_SUGGESTIONS = [\n\t\"Show me all tables in my database\",\n\t\"What columns are in the users table?\",\n\t\"Write a query to find all active users\",\n\t\"How many orders were placed last month?\",\n\t\"Find top 5 customers by total spend\",\n\t\"Write a JOIN between users and orders\",\n\t\"Users who haven't made any purchase yet\",\n\t\"Generate monthly revenue summary query\",\n\t\"Suggest useful indexes for better performance\",\n\t\"Show schema of the products / inventory table\",\n\t\"Latest 20 orders with customer names\",\n\t\"Help me write a safe UPDATE query\",\n];\n\n// const MODEL_LIST = [\n// \t{\n// \t\tid: \"gpt-4o\",\n// \t\tname: \"GPT-4o\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"gpt-4o-mini\",\n// \t\tname: \"GPT-4o Mini\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"claude-opus-4-20250514\",\n// \t\tname: \"Claude 4 Opus\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"claude-sonnet-4-20250514\",\n// \t\tname: \"Claude 4 Sonnet\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"gemini-2.0-flash-exp\",\n// \t\tname: \"Gemini 2.0 Flash\",\n// \t\tchef: \"Google\",\n// \t\tchefSlug: \"google\",\n// \t},\n// ];\n","export const MYSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"tinyint\", label: \"tinyint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"mediumint\", label: \"mediumint\" },\n\t{ value: \"int\", label: \"int\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"decimal\", label: \"decimal\" },\n\t{ value: \"float\", label: \"float\" },\n\t{ value: \"double\", label: \"double\" },\n\t{ value: \"bit\", label: \"bit\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"char\", label: \"char\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"tinytext\", label: \"tinytext\" },\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"mediumtext\", label: \"mediumtext\" },\n\t{ value: \"longtext\", label: \"longtext\" },\n\t// Binary\n\t{ value: \"binary\", label: \"binary\" },\n\t{ value: \"varbinary\", label: \"varbinary\" },\n\t{ value: \"tinyblob\", label: \"tinyblob\" },\n\t{ value: \"blob\", label: \"blob\" },\n\t{ value: \"mediumblob\", label: \"mediumblob\" },\n\t{ value: \"longblob\", label: \"longblob\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"datetime\", label: \"datetime\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"year\", label: \"year\" },\n\t// Complex\n\t{ value: \"enum\", label: \"enum\" },\n\t{ value: \"set\", label: \"set\" },\n] as const;\n\nexport type MysqlColumnType = (typeof MYSQL_COLUMN_TYPES)[number][\"value\"];\n","export const PGSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"integer\", label: \"integer\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"numeric\", label: \"numeric\" },\n\t{ value: \"real\", label: \"real\" },\n\t{ value: \"double precision\", label: \"double precision\" },\n\t{ value: \"money\", label: \"money\" },\n\t{ value: \"serial\", label: \"serial\" },\n\t{ value: \"bigserial\", label: \"bigserial\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"char\", label: \"char\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t{ value: \"jsonb\", label: \"jsonb\" },\n\t{ value: \"xml\", label: \"xml\" },\n\t// UUID\n\t{ value: \"uuid\", label: \"uuid\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"timestamptz\", label: \"timestamptz\" },\n\t{ value: \"interval\", label: \"interval\" },\n\t// Binary\n\t{ value: \"bytea\", label: \"bytea\" },\n\t// Network\n\t{ value: \"inet\", label: \"inet\" },\n\t{ value: \"cidr\", label: \"cidr\" },\n\t{ value: \"macaddr\", label: \"macaddr\" },\n\t{ value: \"macaddr8\", label: \"macaddr8\" },\n\t// Geometric\n\t{ value: \"point\", label: \"point\" },\n\t{ value: \"line\", label: \"line\" },\n\t{ value: \"polygon\", label: \"polygon\" },\n] as const;\n\nexport type PgsqlColumnType = (typeof PGSQL_COLUMN_TYPES)[number][\"value\"];\n","export const DEFAULTS = {\n\tPORT: 3333,\n\tENV: \".env\",\n\tVAR_NAME: \"DATABASE_URL\",\n\tBASE_URL: \"http://localhost:3333\",\n\tPROXY_URL:\n\t\tprocess.env.NODE_ENV === \"development\"\n\t\t\t? \"http://localhost:8787\"\n\t\t\t: \"https://db-studio-proxy.husamql3.workers.dev\",\n};\n","export const HEADER_LINKS = [\n\t{ label: \"Home\", href: \"/\" },\n\t{ label: \"Roadmap\", href: \"/roadmap\" },\n\t{ label: \"Docs\", href: \"/docs/$\" },\n\t{ label: \"Changelog\", href: \"/changelog\" },\n];\n","export const META = {\n\t//* author\n\tAUTHOR: \"Hüsam 🥑 <devhsmq@gmail.com>\",\n\tAUTHOR_NAME: \"Hüsam\",\n\tAUTHOR_AVATAR: \"/avocado.png\",\n\tAUTHOR_USERNAME: \"husamql3\",\n\tAUTHOR_GITHUB_LINK: \"https://github.com/husamql3\",\n\t//* site\n\tSITE_DESCRIPTION: \"The modern pgAdmin alternative that works with every database.\",\n\tSITE_KEYWORDS: [\"database\", \"management\", \"studio\", \"spreadsheet\", \"ai\", \"sql\"],\n\tSITE_TITLE: \"DB Studio\",\n\tSITE_NAME: \"dbstudio.sh\",\n\tSITE_URL: \"https://dbstudio.sh\",\n\tSITE_X_LINK: \"https://x.com/dbstudio_sh\",\n\tSITE_GITHUB_LINK: \"https://github.com/husamql3/db-studio\",\n\tSITE_DOCS_LINK: \"https://dbstudio.sh/docs\",\n\tSITE_CHANGELOG_LINK: \"https://dbstudio.sh/changelog\",\n\tSITE_ROADMAP_LINK: \"https://dbstudio.sh/roadmap\",\n\tSITE_IMAGE: \"https://dbstudio.sh/og-image.png\",\n\tSITE_IMAGE_WIDTH: \"1200\",\n\tSITE_IMAGE_HEIGHT: \"630\",\n\tSITE_IMAGE_ALT: \"dbstudio.sh – Modern database management studio\",\n\tSITE_COLOR: \"#1447e6\",\n};\n","export const ONE_DAY = 24 * 60 * 60 * 1000;\nexport const LIMIT = 3;\n","export * from \"./chat.js\";\nexport * from \"./column-types-mysql.js\";\nexport * from \"./column-types-pgsql.js\";\nexport * from \"./defaults.js\";\nexport * from \"./links.js\";\nexport * from \"./meta.js\";\nexport * from \"./proxy-limits.js\";\n","import { z } from \"zod\";\n\nexport const addRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tdata: z.record(z.string(\"Column name is required\"), z.any()),\n});\n\nexport type AddRecordSchemaType = z.infer<typeof addRecordSchema>;\n","/**\n * Standard API success response wrapper type\n * Used by both server and client\n */\nexport type BaseResponse<T> = {\n\tdata: T;\n\tmessage?: string;\n};\n\n/**\n * Standard API error response type\n */\nexport type ApiError = {\n\terror: string;\n\tdetails?: string;\n};\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport type BulkInsertRecordsParams = {\n\ttableName: string;\n\trecords: Record<string, unknown>[];\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type BulkInsertResult = {\n\tsuccess: boolean;\n\tmessage: string;\n\tsuccessCount: number;\n\tfailureCount: number;\n\terrors?: Array<{ recordIndex: number; error: string }>;\n};\n\nexport const bulkInsertRecordsSchema = z.object({\n\ttableName: z.string().min(1, \"Table name is required\"),\n\trecords: z.array(z.record(z.string(), z.any())).min(1, \"At least one record is required\"),\n});\n","import { z } from \"zod\";\n\nexport const databaseSchema = z.object({\n\tdb: z.string(\"Database name is required\"),\n});\n\nexport type DatabaseSchemaType = z.infer<typeof databaseSchema>;\n\nexport const DATABASE_TYPES = [\"pg\", \"mysql\"] as const;\n\nexport const databaseTypeSchema = z.enum(DATABASE_TYPES, {\n\tmessage: \"Invalid database type\",\n});\nexport type DatabaseTypeSchema = z.infer<typeof databaseTypeSchema>;\n\nexport const currentDatabaseSchema = databaseSchema.extend({\n\tdbType: databaseTypeSchema,\n});\nexport type CurrentDatabaseSchemaType = z.infer<typeof currentDatabaseSchema>;\n\nexport const databaseTypeParamSchema = z.object({\n\tdbType: databaseTypeSchema,\n});\n\nexport const tableNameSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n});\n\nexport type TableNameSchemaType = z.infer<typeof tableNameSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const chatSchema = z.object({\n\tmessages: z.array(\n\t\tz.object({\n\t\t\trole: z.enum([\"user\", \"assistant\"]),\n\t\t\tcontent: z.string(\"Content is required\"),\n\t\t}),\n\t),\n\tconversationId: z.string().optional(),\n\tdb: databaseSchema.shape.db,\n});\n","export type Args = {\n\tenv?: string;\n\tport?: string;\n\tdatabaseUrl?: string;\n\tvarName?: string;\n\tstatus?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n};\n","import { z } from \"zod\";\n\nconst dataTypes = [\"text\", \"boolean\", \"number\", \"enum\", \"json\", \"date\", \"array\"] as const;\n\nexport const dataTypesSchema = z.enum(dataTypes);\nexport type DataTypes = z.infer<typeof dataTypesSchema>;\n\nexport const DataTypes = {\n\ttext: \"text\",\n\tboolean: \"boolean\",\n\tnumber: \"number\",\n\tenum: \"enum\",\n\tjson: \"json\",\n\tdate: \"date\",\n\tarray: \"array\",\n} as const satisfies Record<DataTypes, string>;\n\nconst standardizedDataTypes = [\n\t// PostgreSQL numeric types\n\t\"int\",\n\t\"bigint\",\n\t\"smallint\",\n\t\"numeric\",\n\t\"float\",\n\t\"double\",\n\t\"money\",\n\t// MySQL numeric types\n\t\"tinyint\",\n\t\"mediumint\",\n\t\"bit\",\n\t// Boolean\n\t\"boolean\",\n\t// Text types (shared)\n\t\"text\",\n\t\"varchar\",\n\t\"char\",\n\t// MySQL text types\n\t\"tinytext\",\n\t\"mediumtext\",\n\t\"longtext\",\n\t// JSON types\n\t\"json\",\n\t\"jsonb\",\n\t\"xml\",\n\t// UUID\n\t\"uuid\",\n\t// Date/Time types (shared)\n\t\"date\",\n\t\"time\",\n\t\"timestamp\",\n\t// PostgreSQL date/time\n\t\"timestamptz\",\n\t\"interval\",\n\t// MySQL date/time\n\t\"datetime\",\n\t\"year\",\n\t// PostgreSQL binary/network/geometric types\n\t\"bytea\",\n\t\"inet\",\n\t\"cidr\",\n\t\"macaddr\",\n\t\"macaddr8\",\n\t\"point\",\n\t\"line\",\n\t\"polygon\",\n\t// MySQL binary types\n\t\"binary\",\n\t\"varbinary\",\n\t\"blob\",\n\t\"tinyblob\",\n\t\"mediumblob\",\n\t\"longblob\",\n\t// Complex types (shared)\n\t\"array\",\n\t\"enum\",\n\t// MySQL set type\n\t\"set\",\n] as const;\n\nexport const standardizedDataTypeSchema = z.enum(standardizedDataTypes);\n\nexport const columnInfoSchema = z.object({\n\tcolumnName: z.string(),\n\tdataType: dataTypesSchema,\n\tdataTypeLabel: standardizedDataTypeSchema,\n\tisNullable: z.boolean(),\n\tcolumnDefault: z.string().nullable(),\n\tisPrimaryKey: z.boolean(),\n\tisForeignKey: z.boolean(),\n\treferencedTable: z.string().nullable(),\n\treferencedColumn: z.string().nullable(),\n\tenumValues: z.array(z.string()).nullable(),\n});\n\nexport type ColumnInfoSchemaType = z.infer<typeof columnInfoSchema>;\n","import { DataTypes } from \"./column-info.types.js\";\n\n/**\n * Maps PostgreSQL data types to generic DataType enum\n */\nexport function mapPostgresToDataType(pgType: string): DataTypes {\n\tconst normalized = pgType?.toLowerCase().trim() || \"\";\n\n\t// Handle array types and date/time types\n\tif (\n\t\tnormalized.includes(\"[]\") ||\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\") ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\") ||\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"int2\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\") ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"float4\" ||\n\t\tnormalized === \"double precision\" ||\n\t\tnormalized === \"float8\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\" ||\n\t\tnormalized === \"money\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\" || normalized === \"jsonb\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum types and long text types\n\tif (\n\t\tnormalized.startsWith(\"user-defined\") ||\n\t\tnormalized === \"enum\" ||\n\t\tnormalized === \"text\" ||\n\t\tnormalized === \"xml\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Short string types (varchar, char, uuid, etc.)\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\") ||\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\" ||\n\t\tnormalized === \"uuid\" ||\n\t\tnormalized === \"interval\" ||\n\t\tnormalized.startsWith(\"interval\") ||\n\t\tnormalized === \"bytea\" ||\n\t\tnormalized === \"point\" ||\n\t\tnormalized === \"line\" ||\n\t\tnormalized === \"polygon\" ||\n\t\tnormalized === \"inet\" ||\n\t\tnormalized === \"cidr\" ||\n\t\tnormalized === \"macaddr\" ||\n\t\tnormalized === \"macaddr8\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Default to short for unrecognized types\n\treturn DataTypes.text;\n}\n\n/**\n * Standardized data type labels\n */\nexport const StandardizedDataType = {\n\t// PostgreSQL numeric types\n\tint: \"int\",\n\tbigint: \"bigint\",\n\tsmallint: \"smallint\",\n\tnumeric: \"numeric\",\n\tfloat: \"float\",\n\tdouble: \"double\",\n\tmoney: \"money\",\n\t// MySQL numeric types\n\ttinyint: \"tinyint\",\n\tmediumint: \"mediumint\",\n\tbit: \"bit\",\n\t// Boolean\n\tboolean: \"boolean\",\n\t// Text types (shared)\n\ttext: \"text\",\n\tvarchar: \"varchar\",\n\tchar: \"char\",\n\t// MySQL text types\n\ttinytext: \"tinytext\",\n\tmediumtext: \"mediumtext\",\n\tlongtext: \"longtext\",\n\t// JSON types\n\tjson: \"json\",\n\tjsonb: \"jsonb\",\n\txml: \"xml\",\n\t// UUID\n\tuuid: \"uuid\",\n\t// Date/Time types (shared)\n\tdate: \"date\",\n\ttime: \"time\",\n\ttimestamp: \"timestamp\",\n\t// PostgreSQL date/time\n\ttimestamptz: \"timestamptz\",\n\tinterval: \"interval\",\n\t// MySQL date/time\n\tdatetime: \"datetime\",\n\tyear: \"year\",\n\t// PostgreSQL binary/network/geometric types\n\tbytea: \"bytea\",\n\tinet: \"inet\",\n\tcidr: \"cidr\",\n\tmacaddr: \"macaddr\",\n\tmacaddr8: \"macaddr8\",\n\tpoint: \"point\",\n\tline: \"line\",\n\tpolygon: \"polygon\",\n\t// MySQL binary types\n\tbinary: \"binary\",\n\tvarbinary: \"varbinary\",\n\tblob: \"blob\",\n\ttinyblob: \"tinyblob\",\n\tmediumblob: \"mediumblob\",\n\tlongblob: \"longblob\",\n\t// Complex types (shared)\n\tarray: \"array\",\n\tenum: \"enum\",\n\t// MySQL set type\n\tset: \"set\",\n} as const;\n\nexport type StandardizedDataType =\n\t(typeof StandardizedDataType)[keyof typeof StandardizedDataType];\n\n/**\n * Maps PostgreSQL data types to standardized display labels\n */\nexport function standardizeDataTypeLabel(\n\tpgType: string | null | undefined,\n): StandardizedDataType {\n\tif (!pgType) {\n\t\treturn StandardizedDataType.text; // Default fallback\n\t}\n\tconst normalized = pgType.toLowerCase().trim();\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\"\n\t) {\n\t\treturn StandardizedDataType.int;\n\t}\n\n\tif (\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\"\n\t) {\n\t\treturn StandardizedDataType.bigint;\n\t}\n\n\tif (normalized === \"smallint\" || normalized === \"int2\") {\n\t\treturn StandardizedDataType.smallint;\n\t}\n\n\tif (\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\")\n\t) {\n\t\treturn StandardizedDataType.numeric;\n\t}\n\n\tif (normalized === \"real\" || normalized === \"float4\") {\n\t\treturn StandardizedDataType.float;\n\t}\n\n\tif (normalized === \"double precision\" || normalized === \"float8\" || normalized === \"float\") {\n\t\treturn StandardizedDataType.double;\n\t}\n\n\tif (normalized === \"money\") {\n\t\treturn StandardizedDataType.money;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn StandardizedDataType.boolean;\n\t}\n\n\t// Text types\n\tif (normalized === \"text\") {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\")\n\t) {\n\t\treturn StandardizedDataType.varchar;\n\t}\n\n\tif (\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\"\n\t) {\n\t\treturn StandardizedDataType.char;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\") {\n\t\treturn StandardizedDataType.json;\n\t}\n\n\tif (normalized === \"jsonb\") {\n\t\treturn StandardizedDataType.jsonb;\n\t}\n\n\tif (normalized === \"xml\") {\n\t\treturn StandardizedDataType.xml;\n\t}\n\n\t// UUID\n\tif (normalized === \"uuid\") {\n\t\treturn StandardizedDataType.uuid;\n\t}\n\n\t// Date/Time types\n\tif (normalized === \"date\") {\n\t\treturn StandardizedDataType.date;\n\t}\n\n\tif (\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\")\n\t) {\n\t\treturn StandardizedDataType.time;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\")\n\t) {\n\t\treturn StandardizedDataType.timestamp;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn StandardizedDataType.timestamptz;\n\t}\n\n\tif (normalized === \"interval\" || normalized.startsWith(\"interval\")) {\n\t\treturn StandardizedDataType.interval;\n\t}\n\n\t// Binary\n\tif (normalized === \"bytea\") {\n\t\treturn StandardizedDataType.bytea;\n\t}\n\n\t// Network types\n\tif (normalized === \"inet\") {\n\t\treturn StandardizedDataType.inet;\n\t}\n\n\tif (normalized === \"cidr\") {\n\t\treturn StandardizedDataType.cidr;\n\t}\n\n\tif (normalized === \"macaddr\") {\n\t\treturn StandardizedDataType.macaddr;\n\t}\n\n\tif (normalized === \"macaddr8\") {\n\t\treturn StandardizedDataType.macaddr8;\n\t}\n\n\t// Geometric types\n\tif (normalized === \"point\") {\n\t\treturn StandardizedDataType.point;\n\t}\n\n\tif (normalized === \"line\") {\n\t\treturn StandardizedDataType.line;\n\t}\n\n\tif (normalized === \"polygon\") {\n\t\treturn StandardizedDataType.polygon;\n\t}\n\n\t// Array types\n\t// todo: handle array types\n\tif (normalized.startsWith(\"array\") || normalized.includes(\"[]\")) {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\t// User-defined types (enums)\n\tif (normalized.startsWith(\"user-defined\") || normalized === \"enum\") {\n\t\treturn StandardizedDataType.enum;\n\t}\n\n\t// Default: return the original type\n\treturn StandardizedDataType.text;\n}\n\n/**\n * Maps MySQL data types to generic DataType enum (used for cell rendering)\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\", \"enum('a','b')\") for finer mapping\n */\nexport function mapMysqlToDataType(mysqlDataType: string, columnType?: string): DataTypes {\n\tconst normalized = mysqlDataType?.toLowerCase().trim() || \"\";\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"tinyint\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"mediumint\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"double\" ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"bit\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean (explicit)\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Date/time types\n\tif (\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"datetime\" ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"year\"\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// JSON\n\tif (normalized === \"json\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum and set (set behaves like enum for display)\n\tif (normalized === \"enum\" || normalized === \"set\") {\n\t\treturn DataTypes.enum;\n\t}\n\n\t// All text and binary types default to text\n\treturn DataTypes.text;\n}\n\n/**\n * Maps MySQL data types to standardized display labels\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\") for finer mapping\n */\nexport function standardizeMysqlDataTypeLabel(\n\tmysqlDataType: string,\n\tcolumnType?: string,\n): StandardizedDataType {\n\tif (!mysqlDataType) {\n\t\treturn StandardizedDataType.text;\n\t}\n\tconst normalized = mysqlDataType.toLowerCase().trim();\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\")\n\t\treturn StandardizedDataType.boolean;\n\n\t// Numeric types\n\tif (normalized === \"tinyint\") return StandardizedDataType.tinyint;\n\tif (normalized === \"smallint\") return StandardizedDataType.smallint;\n\tif (normalized === \"mediumint\") return StandardizedDataType.mediumint;\n\tif (normalized === \"int\" || normalized === \"integer\") return StandardizedDataType.int;\n\tif (normalized === \"bigint\") return StandardizedDataType.bigint;\n\tif (normalized === \"decimal\" || normalized === \"numeric\")\n\t\treturn StandardizedDataType.numeric;\n\tif (normalized === \"float\" || normalized === \"real\") return StandardizedDataType.float;\n\tif (normalized === \"double\") return StandardizedDataType.double;\n\tif (normalized === \"bit\") return StandardizedDataType.bit;\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") return StandardizedDataType.boolean;\n\n\t// Text types\n\tif (normalized === \"char\") return StandardizedDataType.char;\n\tif (normalized === \"varchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"tinytext\") return StandardizedDataType.tinytext;\n\tif (normalized === \"text\") return StandardizedDataType.text;\n\tif (normalized === \"mediumtext\") return StandardizedDataType.mediumtext;\n\tif (normalized === \"longtext\") return StandardizedDataType.longtext;\n\n\t// Binary types\n\tif (normalized === \"binary\") return StandardizedDataType.binary;\n\tif (normalized === \"varbinary\") return StandardizedDataType.varbinary;\n\tif (normalized === \"tinyblob\") return StandardizedDataType.tinyblob;\n\tif (normalized === \"blob\") return StandardizedDataType.blob;\n\tif (normalized === \"mediumblob\") return StandardizedDataType.mediumblob;\n\tif (normalized === \"longblob\") return StandardizedDataType.longblob;\n\n\t// JSON\n\tif (normalized === \"json\") return StandardizedDataType.json;\n\n\t// Date/time types\n\tif (normalized === \"date\") return StandardizedDataType.date;\n\tif (normalized === \"time\") return StandardizedDataType.time;\n\tif (normalized === \"datetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"timestamp\") return StandardizedDataType.timestamp;\n\tif (normalized === \"year\") return StandardizedDataType.year;\n\n\t// Complex types\n\tif (normalized === \"enum\") return StandardizedDataType.enum;\n\tif (normalized === \"set\") return StandardizedDataType.set;\n\n\t// Default\n\treturn StandardizedDataType.text;\n}\n","import { z } from \"zod\";\n\nexport const FOREIGN_KEY_ACTIONS = [\n\t\"CASCADE\",\n\t\"SET NULL\",\n\t\"SET DEFAULT\",\n\t\"RESTRICT\",\n\t\"NO ACTION\",\n] as const;\nexport const foreignKeyActionSchema = z.enum(FOREIGN_KEY_ACTIONS);\n\nexport const fieldDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\tcolumnType: z.string(\"Column type is required\"),\n\tdefaultValue: z.string().optional(),\n\tisPrimaryKey: z.boolean().default(false),\n\tisNullable: z.boolean().default(false),\n\tisUnique: z.boolean().default(false),\n\tisIdentity: z.boolean().default(false),\n\tisArray: z.boolean().default(false),\n});\nexport type FieldDataType = z.infer<typeof fieldDataSchema>;\n\nexport const foreignKeyDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\treferencedTable: z.string(\"Referenced table is required\"),\n\treferencedColumn: z.string(\"Referenced column is required\"),\n\tonUpdate: foreignKeyActionSchema.default(\"NO ACTION\"),\n\tonDelete: foreignKeyActionSchema.default(\"NO ACTION\"),\n});\nexport type ForeignKeyDataType = z.infer<typeof foreignKeyDataSchema>;\n\nexport const createTableSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tfields: z.array(fieldDataSchema).min(1, \"At least one field is required\"),\n\tforeignKeys: z.array(foreignKeyDataSchema).optional(),\n});\n\nexport type CreateTableSchemaType = z.infer<typeof createTableSchema>;\n","import { z } from \"zod\";\nimport { databaseTypeSchema } from \"./database.types.js\";\n\nexport const databaseInfoSchema = z.object({\n\tname: z.string(\"Name is required\"),\n\tsize: z.string(\"Size is required\"),\n\towner: z.string(\"Owner is required\"),\n\tencoding: z.string(\"Encoding is required\"),\n});\n\nexport type DatabaseInfoSchemaType = z.infer<typeof databaseInfoSchema>;\n\nexport const databaseListSchema = z.object({\n\tdatabases: z.array(databaseInfoSchema),\n\tdbType: databaseTypeSchema,\n});\n\nexport type DatabaseListSchemaType = z.infer<typeof databaseListSchema>;\n\nexport const connectionInfoSchema = z.object({\n\tversion: z.string(\"Version is required\"),\n\tdatabase: z.string(\"Database is required\"),\n\tuser: z.string(\"User is required\"),\n\thost: z.string(\"Host is required\").nullable(),\n\tport: z.number(\"Port is required\").nullable(),\n\tactive_connections: z.coerce.number(\"Active connections is required\"),\n\tmax_connections: z.coerce.number(\"Max connections is required\"),\n});\n\nexport type ConnectionInfoSchemaType = z.infer<typeof connectionInfoSchema>;\n","import type { DatabaseTypeSchema } from \"./database.types\";\n\nexport type DatabaseSchema = {\n\tdbType: DatabaseTypeSchema;\n\ttables: Table[];\n\trelationships: Relationship[];\n};\n\nexport type Table = {\n\tname: string;\n\tdescription?: string;\n\tcolumns: Column[];\n\tsampleData?: Record<string, string>[];\n};\n\nexport type Column = {\n\tname: string;\n\ttype: string;\n\tnullable: boolean;\n\tisPrimaryKey?: boolean;\n\tforeignKey?: string;\n\tdescription?: string;\n\tenumValues?: string[];\n};\n\nexport type Relationship = {\n\tfromTable: string;\n\tfromColumn: string;\n\ttoTable: string;\n\ttoColumn: string;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\n\nexport const deleteColumnQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteColumnQuerySchemaType = z.infer<typeof deleteColumnQuerySchema>;\n\nexport const deleteColumnParamSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n});\n\nexport const deleteColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tcascade: z.boolean().optional(),\n});\n\nexport type DeleteColumnParamsSchemaType = z.infer<typeof deleteColumnParamsSchema>;\n\nexport const deleteColumnSuccessResponseSchema = z.object({\n\tmessage: z.string(\"Message is required\"),\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n\tdeletedCount: z.number(\"Deleted count is required\").default(0),\n});\n\nexport type DeleteColumnResponseType = z.infer<typeof deleteColumnSuccessResponseSchema>;\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport const deleteRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKeys: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\tvalue: z.any(),\n\t\t\t}),\n\t\t)\n\t\t.min(1, \"At least one primary key is required\"),\n});\n\nexport type DeleteRecordSchemaType = z.infer<typeof deleteRecordSchema>;\n\nexport type DeleteRecordParams = DeleteRecordSchemaType & {\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type DeleteRecordResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n\nexport type ForeignKeyConstraint = {\n\tconstraintName: string;\n\treferencingTable: string;\n\treferencingColumn: string;\n\treferencedTable: string;\n\treferencedColumn: string;\n};\n\nexport type ForeignKeyConstraintRow = {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n};\n\nexport type RelatedRecord = {\n\ttableName: string;\n\tcolumnName: string;\n\tconstraintName: string;\n\trecords: Array<Record<string, unknown>>;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport type { RelatedRecord } from \"./delete-record.types\";\n\nexport const deleteTableQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteTableQuerySchemaType = z.infer<typeof deleteTableQuerySchema>;\n\nexport type DeleteTableParams = {\n\ttableName: string;\n\tdb: string;\n\tcascade?: boolean;\n};\n\nexport type DeleteTableResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n","import { z } from \"zod\";\n\nexport const executeQuerySchema = z.object({\n\tquery: z.string(\"Query is required\"),\n});\n\nexport type ExecuteQueryParams = z.infer<typeof executeQuerySchema>;\n\nexport type ExecuteQueryResult = {\n\tcolumns: string[];\n\trows: Record<string, unknown>[];\n\trowCount: number;\n\tduration: number;\n\tmessage?: string;\n\terror?: string;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const FORMAT_TYPES = [\"csv\", \"xlsx\", \"json\"] as const;\nexport type FormatType = (typeof FORMAT_TYPES)[number];\n\nexport const exportTableSchema = databaseSchema.extend({\n\tformat: z.enum(FORMAT_TYPES, {\n\t\tmessage: \"Invalid format. Supported formats: csv, xlsx, json\",\n\t}),\n});\nexport type ExportTableSchemaType = z.infer<typeof exportTableSchema>;\n\nexport type CellValue = string | number | boolean | Date | null | undefined;\n","export type RateLimitResponse = {\n\tlimit: number;\n\tused: number;\n\tremaining: number;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const filterSchema = z.object({\n\tcolumnName: z.string(),\n\toperator: z.string(),\n\tvalue: z.string(),\n});\n\nexport type FilterType = z.infer<typeof filterSchema>;\n\nexport const sortDirections = [\"asc\", \"desc\"] as const;\nexport type SortDirection = (typeof sortDirections)[number];\n\nexport const sortSchema = z.object({\n\tcolumnName: z.string(),\n\tdirection: z.enum(sortDirections),\n});\n\nexport type SortType = z.infer<typeof sortSchema>;\n\nexport const tableDataMetaSchema = z.object({\n\tlimit: z.number(),\n\ttotal: z.number(),\n\thasNextPage: z.boolean(),\n\thasPreviousPage: z.boolean(),\n\tnextCursor: z.string().nullable(),\n\tprevCursor: z.string().nullable(),\n});\n\nexport const tableDataResultSchema = z.object({\n\tdata: z.array(z.record(z.string(), z.unknown())),\n\tmeta: tableDataMetaSchema,\n});\n\nexport type TableDataResultSchemaType = z.infer<typeof tableDataResultSchema>;\n\nexport const tableDataQuerySchema = z.object({\n\tdb: databaseSchema.shape.db,\n\tcursor: z.string().optional(), // Base64 encoded cursor for pagination\n\tlimit: z.string().optional().default(\"50\").transform(Number),\n\tdirection: z.enum(sortDirections).optional().default(sortDirections[0]), // Pagination direction\n\tsort: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return \"\";\n\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(val);\n\t\t\t\tif (Array.isArray(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t\treturn val;\n\t\t\t} catch {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t}),\n\torder: z.enum(sortDirections).optional(),\n\tfilters: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return [];\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(val);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}),\n});\n\nexport type TableDataQuerySchemaType = z.infer<typeof tableDataQuerySchema>;\n\nexport interface CursorData {\n\tvalues: Record<string, unknown>;\n\tsortColumns: string[];\n}\n","import { z } from \"zod\";\n\nexport const tableInfoSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\trowCount: z.coerce.number(\"Row count is required\"),\n});\n\nexport type TableInfoSchemaType = z.infer<typeof tableInfoSchema>;\n","import { z } from \"zod\";\n\nexport const tableSchemaResultSchema = z.object({\n\tschema: z.string(),\n});\n\nexport type TableSchemaResult = z.infer<typeof tableSchemaResultSchema>;\n","import { z } from \"zod\";\n\nexport const updateRecordsSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKey: z.string(\"Primary key is required\").default(\"id\"),\n\tupdates: z\n\t\t.array(\n\t\t\tz.object(\n\t\t\t\t{\n\t\t\t\t\trowData: z.record(z.string(\"Column name is required\"), z.any()),\n\t\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\t\tvalue: z.any(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmessage: \"Each update must have a row data, column name, and value.\",\n\t\t\t\t},\n\t\t\t),\n\t\t)\n\t\t.min(1, \"At least one update is required\"),\n});\n\nexport type UpdateRecordsSchemaType = z.infer<typeof updateRecordsSchema>;\n","export * from \"./add-record.types.js\"; // done\nexport * from \"./api-response.types.js\";\nexport * from \"./bulk-insert-records.type.js\";\nexport * from \"./chat.types.js\"; // done\nexport * from \"./cmd-args.types.js\"; // done\nexport * from \"./column.type.js\";\nexport * from \"./column-info.types.js\";\nexport * from \"./create-table.types.js\"; // done\nexport * from \"./database.types.js\"; // done\nexport * from \"./database-list.types.js\"; // done\nexport * from \"./database-schema.type.js\"; // done\nexport * from \"./delete-column.types.js\"; // done\nexport * from \"./delete-record.types.js\"; // done\nexport * from \"./delete-table.types.js\"; // done\nexport * from \"./execute-query.types.js\"; // done\nexport * from \"./export-table.types.js\";\nexport * from \"./rate-limit-response.type.js\";\nexport * from \"./table-data.types.js\"; // done\nexport * from \"./table-info.type.js\"; // done\nexport * from \"./table-schema.types.js\"; // done\nexport * from \"./update-recors.types.js\"; // done\n","import type { Context } from \"hono\";\nimport { HTTPException } from \"hono/http-exception\";\nimport { DatabaseError } from \"pg\";\nimport type { ApiError } from \"shared/types/api-response.types.js\";\nimport { ZodError } from \"zod\";\n\n/**\n * Centralized error handler for the application\n */\nexport function handleError(e: Error | unknown, c: Context) {\n\tconsole.error(\"handleError:\", e);\n\n\tif (e instanceof HTTPException) {\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: e.message ?? \"Internal server error\",\n\t\t\t},\n\t\t\te.status,\n\t\t);\n\t}\n\n\tif (e instanceof ZodError) {\n\t\tconst issue = e.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue.message,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tif (e instanceof Error) {\n\t\t// MySQL-specific error codes\n\t\tconst mysqlError = e as { code?: string; errno?: number };\n\t\tconst isMysqlConnectionError =\n\t\t\tmysqlError.code === \"ECONNREFUSED\" ||\n\t\t\tmysqlError.code === \"ENOTFOUND\" ||\n\t\t\tmysqlError.code === \"ETIMEDOUT\" ||\n\t\t\tmysqlError.code === \"ER_ACCESS_DENIED_ERROR\" ||\n\t\t\tmysqlError.code === \"ER_BAD_HOST_ERROR\" ||\n\t\t\tmysqlError.code === \"ECONNRESET\" ||\n\t\t\tmysqlError.errno === 1045 || // ER_ACCESS_DENIED_ERROR\n\t\t\tmysqlError.errno === 2003 || // Can't connect to MySQL server\n\t\t\tmysqlError.errno === 2002; // Can't connect to local MySQL server\n\n\t\tconst isConnectionError =\n\t\t\tisMysqlConnectionError ||\n\t\t\te.message.includes(\"ECONNREFUSED\") ||\n\t\t\te.message.includes(\"connection refused\") ||\n\t\t\te.message.includes(\"timeout expired\") ||\n\t\t\te.message.includes(\"Connection terminated\") ||\n\t\t\t(e instanceof DatabaseError && e.code?.startsWith(\"08\")); // PostgreSQL connection exception class\n\n\t\tif (isConnectionError) {\n\t\t\treturn c.json<ApiError>(\n\t\t\t\t{ error: \"Database connection failed\", details: e.message },\n\t\t\t\t503,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn c.json<ApiError>(\n\t\t{\n\t\t\terror: e instanceof Error ? e.message : \"Internal server error\",\n\t\t},\n\t\t500,\n\t);\n}\n\nexport const validationHook = (\n\tresult: {\n\t\tsuccess: boolean;\n\t\tdata?: unknown;\n\t\terror?: { issues: { message: string }[] };\n\t},\n\tc: Context,\n): Response | undefined => {\n\tif (!result.success) {\n\t\tconst issue = result.error?.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue?.message ?? \"Unknown validation error\",\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n};\n","import { Pool } from \"pg\";\n\nlet dbInstance: Pool | null = null;\n\nconst getPool = (): Pool => {\n\tif (!dbInstance) {\n\t\tif (!process.env.DATABASE_URL) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\t\ttry {\n\t\t\tdbInstance = new Pool({\n\t\t\t\tconnectionString: process.env.DATABASE_URL,\n\t\t\t});\n\n\t\t\t// Handle pool errors to prevent server crashes\n\t\t\t// This catches connection errors, idle client errors, etc.\n\t\t\tdbInstance.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\"Unexpected database pool error:\", err.message);\n\t\t\t\t// Don't throw - just log the error to prevent server crash\n\t\t\t\t// The pool will automatically retry connections\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to create database pool:\", error);\n\t\t\t// Re-throw initialization errors as they indicate a configuration problem\n\t\t\tthrow error;\n\t\t}\n\t}\n\treturn dbInstance;\n};\n\n// Export db as a Proxy that lazily initializes the pool\n// This allows process.env.DATABASE_URL to be set after module import\nexport const db = new Proxy({} as Pool, {\n\tget(_target, prop) {\n\t\ttry {\n\t\t\treturn getPool()[prop as keyof Pool];\n\t\t} catch (error) {\n\t\t\t// If pool initialization fails, log and re-throw\n\t\t\tconsole.error(\"Database pool access error:\", error);\n\t\t\tthrow error;\n\t\t}\n\t},\n});\n","import type { Pool as MysqlPool } from \"mysql2/promise\";\nimport { createPool as createMysqlPool } from \"mysql2/promise\";\nimport { Pool, type PoolConfig } from \"pg\";\nimport type { DatabaseTypeSchema } from \"shared/types\";\n\n/**\n * DatabaseManager - Manages multiple database connection pools for both PostgreSQL and MySQL\n */\nclass DatabaseManager {\n\tprivate pgPools: Map<string, Pool> = new Map();\n\tprivate mysqlPools: Map<string, MysqlPool> = new Map();\n\tprivate baseConfig: {\n\t\turl: string;\n\t\thost: string;\n\t\tport: number;\n\t\tuser: string;\n\t\tpassword: string;\n\t\tdbType: DatabaseTypeSchema;\n\t} | null = null;\n\n\tconstructor() {\n\t\tthis.initializeBaseConfig();\n\t}\n\n\t/**\n\t * Detect database type from URL protocol\n\t */\n\tprivate detectDbType(url: URL): DatabaseTypeSchema {\n\t\tconst protocol = url.protocol.replace(\":\", \"\");\n\t\tif (protocol === \"postgres\" || protocol === \"postgresql\") {\n\t\t\treturn \"pg\";\n\t\t}\n\t\tif (protocol === \"mysql\" || protocol === \"mysql2\") {\n\t\t\treturn \"mysql\";\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Unsupported database type: ${protocol}. Supported types: PostgreSQL (postgres://) and MySQL (mysql://).`,\n\t\t);\n\t}\n\n\t/**\n\t * Parse DATABASE_URL and extract connection details\n\t */\n\tprivate initializeBaseConfig() {\n\t\tconst databaseUrl = process.env.DATABASE_URL;\n\t\tif (!databaseUrl) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(databaseUrl);\n\t\t\tthis.baseConfig = {\n\t\t\t\turl: databaseUrl,\n\t\t\t\thost: url.hostname,\n\t\t\t\tport:\n\t\t\t\t\tNumber.parseInt(url.port, 10) || (this.detectDbType(url) === \"mysql\" ? 3306 : 5432),\n\t\t\t\tuser: url.username,\n\t\t\t\tpassword: url.password,\n\t\t\t\tdbType: this.detectDbType(url),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new Error(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\t/**\n\t * Get the detected database type\n\t */\n\tgetDbType(): DatabaseTypeSchema {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\t\treturn this.baseConfig.dbType;\n\t}\n\n\t/**\n\t * Build a connection string for the specified database\n\t */\n\tbuildConnectionString(database?: string): string {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tif (!database) {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\tdatabase = url.pathname.slice(1);\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\turl.pathname = `/${database}`;\n\t\t\treturn url.toString();\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to build connection string for database \"${database}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get or create a PostgreSQL connection pool for the specified database\n\t */\n\tgetPgPool(database?: string): Pool {\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.pgPools.has(connectionString)) {\n\t\t\tconst poolConfig: PoolConfig = {\n\t\t\t\tconnectionString,\n\t\t\t\tmax: 10,\n\t\t\t\tidleTimeoutMillis: 30000,\n\t\t\t\tconnectionTimeoutMillis: 2000,\n\t\t\t};\n\n\t\t\tconst pool = new Pool(poolConfig);\n\n\t\t\tpool.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Unexpected error on PostgreSQL pool for \"${connectionString}\":`,\n\t\t\t\t\terr.message,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.pgPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.pgPools.get(connectionString) ?? new Pool({ connectionString });\n\t}\n\n\t/**\n\t * Get or create a MySQL connection pool for the specified database\n\t */\n\tgetMysqlPool(database?: string): MysqlPool {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.mysqlPools.has(connectionString)) {\n\t\t\tconst url = new URL(connectionString);\n\t\t\tconst dbName = url.pathname.slice(1);\n\n\t\t\tconst pool = createMysqlPool({\n\t\t\t\thost: this.baseConfig.host,\n\t\t\t\tport: this.baseConfig.port,\n\t\t\t\tuser: this.baseConfig.user,\n\t\t\t\tpassword: this.baseConfig.password,\n\t\t\t\tdatabase: dbName || undefined,\n\t\t\t\twaitForConnections: true,\n\t\t\t\tconnectionLimit: 10,\n\t\t\t\tidleTimeout: 30000,\n\t\t\t\tconnectTimeout: 2000,\n\t\t\t\t// Enable multiple statements for raw query support\n\t\t\t\tmultipleStatements: false,\n\t\t\t});\n\n\t\t\tthis.mysqlPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created MySQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.mysqlPools.get(connectionString) as MysqlPool;\n\t}\n\n\t/**\n\t * Get the appropriate pool based on database type (legacy/PG-only helper)\n\t */\n\tgetPool(database?: string): Pool {\n\t\treturn this.getPgPool(database);\n\t}\n\n\t/**\n\t * Close a specific PostgreSQL pool by connection string\n\t */\n\tasync closePgPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.pgPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.pgPools.delete(connectionString);\n\t\t\tconsole.log(`Closed PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific MySQL pool by connection string\n\t */\n\tasync closeMysqlPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.mysqlPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.mysqlPools.delete(connectionString);\n\t\t\tconsole.log(`Closed MySQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific database pool by connection string (both types)\n\t */\n\tasync closePool(connectionString: string): Promise<void> {\n\t\tawait this.closePgPool(connectionString);\n\t\tawait this.closeMysqlPool(connectionString);\n\t}\n\n\t/**\n\t * Close a specific database pool by database name\n\t */\n\tasync closePoolByDatabase(database: string): Promise<void> {\n\t\tconst connectionString = this.buildConnectionString(database);\n\t\tawait this.closePool(connectionString);\n\t}\n\n\t/**\n\t * Close all database pools\n\t */\n\tasync closeAll(): Promise<void> {\n\t\tconst pgClosePromises = Array.from(this.pgPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed PostgreSQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tconst mysqlClosePromises = Array.from(this.mysqlPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed MySQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all([...pgClosePromises, ...mysqlClosePromises]);\n\t\tthis.pgPools.clear();\n\t\tthis.mysqlPools.clear();\n\t}\n\n\t/**\n\t * Get all active pool connection strings\n\t */\n\tgetActivePools(): string[] {\n\t\treturn [...Array.from(this.pgPools.keys()), ...Array.from(this.mysqlPools.keys())];\n\t}\n}\n\n// Singleton instance\nconst databaseManager = new DatabaseManager();\n\n/**\n * Get a PostgreSQL pool for the specified database\n */\nexport const getDbPool = (database?: string): Pool => {\n\treturn databaseManager.getPgPool(database);\n};\n\n/**\n * Get a MySQL pool for the specified database\n */\nexport const getMysqlPool = (database?: string): MysqlPool => {\n\treturn databaseManager.getMysqlPool(database);\n};\n\n/**\n * Get the detected database type from DATABASE_URL\n */\nexport const getDbType = (): DatabaseTypeSchema => {\n\treturn databaseManager.getDbType();\n};\n\n/**\n * Build a connection string for the specified database\n */\nconst _buildDbConnectionString = (database?: string): string => {\n\treturn databaseManager.buildConnectionString(database);\n};\n\n/**\n * Close a specific database pool by database name\n */\nconst _closeDbPool = async (database: string): Promise<void> => {\n\treturn databaseManager.closePoolByDatabase(database);\n};\n\n/**\n * Close a specific database pool by connection string\n */\nconst _closeDbPoolByConnectionString = async (connectionString: string): Promise<void> => {\n\treturn databaseManager.closePool(connectionString);\n};\n\n/**\n * Close all database pools\n */\nconst _closeAllDbPools = async (): Promise<void> => {\n\treturn databaseManager.closeAll();\n};\n\n/**\n * Get list of active pool connection strings\n */\nconst _getActivePools = (): string[] => {\n\treturn databaseManager.getActivePools();\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ColumnInfoSchemaType,\n\ttype DatabaseSchemaType,\n\tmapPostgresToDataType,\n\tstandardizeDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n SELECT \n c.column_name as \"columnName\",\n c.data_type as \"dataType\",\n c.udt_name as \"udtName\",\n c.is_nullable = 'YES' as \"isNullable\",\n c.column_default as \"columnDefault\",\n CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as \"isPrimaryKey\",\n CASE WHEN fk.column_name IS NOT NULL THEN true ELSE false END as \"isForeignKey\",\n fk.referenced_table as \"referencedTable\",\n fk.referenced_column as \"referencedColumn\",\n CASE \n WHEN c.data_type = 'USER-DEFINED' THEN \n (SELECT array_agg(e.enumlabel ORDER BY e.enumsortorder)\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n WHERE t.typname = c.udt_name)\n ELSE NULL\n END as \"enumValues\"\n FROM information_schema.columns c\n LEFT JOIN (\n SELECT ku.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage ku\n ON tc.constraint_name = ku.constraint_name\n AND tc.table_schema = ku.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) pk ON c.column_name = pk.column_name\n LEFT JOIN (\n SELECT \n kcu.column_name,\n ccu.table_name AS referenced_table,\n ccu.column_name AS referenced_column\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.table_schema = ccu.table_schema\n WHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) fk ON c.column_name = fk.column_name\n WHERE c.table_schema = 'public'\n AND c.table_name = $1\n ORDER BY c.ordinal_position;\n `;\n\n\tconst { rows } = await pool.query(query, [tableName]);\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\t// Parse enumValues to always return string[] | null\n\t\tlet parsedEnumValues: string[] | null = null;\n\t\tif (r.enumValues) {\n\t\t\tif (Array.isArray(r.enumValues)) {\n\t\t\t\t// Already an array, use as-is\n\t\t\t\tparsedEnumValues = r.enumValues;\n\t\t\t} else if (typeof r.enumValues === \"string\") {\n\t\t\t\t// Parse PostgreSQL array format: \"{VALUE1,VALUE2,VALUE3}\"\n\t\t\t\tparsedEnumValues = r.enumValues.replace(/[{}]/g, \"\").split(\",\").filter(Boolean);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapPostgresToDataType(r.dataType),\n\t\t\tdataTypeLabel: standardizeDataTypeLabel(r.dataType),\n\t\t\tisNullable: r.isNullable,\n\t\t\tcolumnDefault: r.columnDefault,\n\t\t\tisPrimaryKey: r.isPrimaryKey,\n\t\t\tisForeignKey: r.isForeignKey,\n\t\t\treferencedTable: r.referencedTable,\n\t\t\treferencedColumn: r.referencedColumn,\n\t\t\tenumValues: parsedEnumValues,\n\t\t};\n\t});\n}\n","import type {\n\tColumn,\n\tColumnInfoSchemaType,\n\tDatabaseSchema,\n\tDatabaseSchemaType,\n\tRelationship,\n\tTable,\n} from \"shared/types\";\nimport { db } from \"@/db.js\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.dao.js\";\n\n/**\n * Get all table names from the database\n */\nasync function getTableNames(db: DatabaseSchemaType[\"db\"]): Promise<string[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n\t\tSELECT table_name\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = 'public'\n\t\t\tAND table_type = 'BASE TABLE'\n\t\tORDER BY table_name;\n\t`;\n\tconst { rows } = await pool.query(query);\n\treturn rows.map((r) => r.table_name);\n}\n\n/**\n * Get table comment/description if available\n */\nasync function getTableDescription(tableName: string): Promise<string | undefined> {\n\tconst client = await db.connect();\n\ttry {\n\t\tconst res = await client.query(\n\t\t\t`\n SELECT obj_description(oid) as description\n FROM pg_class\n WHERE relname = $1\n AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');\n `,\n\t\t\t[tableName],\n\t\t);\n\t\treturn res.rows[0]?.description || undefined;\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Get sample data from a table (first 3 rows)\n */\nasync function getSampleData(tableName: string): Promise<Record<string, unknown>[]> {\n\tconst client = await db.connect();\n\ttry {\n\t\t// Sanitize table name to prevent SQL injection\n\t\t// In production, validate tableName against known tables list\n\t\tconst res = await client.query(`SELECT * FROM \"${tableName}\" LIMIT 3`);\n\t\treturn res.rows;\n\t} catch (error) {\n\t\tconsole.warn(`Could not fetch sample data for table ${tableName}:`, error);\n\t\treturn [];\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Convert ColumnInfo to the schema Column format\n */\nfunction convertColumnInfo(col: ColumnInfoSchemaType): Column {\n\tconst column: Column = {\n\t\tname: col.columnName,\n\t\ttype: col.dataTypeLabel,\n\t\tnullable: col.isNullable,\n\t};\n\n\tif (col.isPrimaryKey) {\n\t\tcolumn.isPrimaryKey = true;\n\t}\n\n\tif (col.isForeignKey && col.referencedTable && col.referencedColumn) {\n\t\tcolumn.foreignKey = `${col.referencedTable}.${col.referencedColumn}`;\n\t}\n\n\tif (col.enumValues && col.enumValues.length > 0) {\n\t\tcolumn.enumValues = col.enumValues;\n\t\tcolumn.description = `Enum values: ${col.enumValues.join(\", \")}`;\n\t}\n\n\treturn column;\n}\n\n/**\n * Extract all relationships from table columns\n */\nfunction extractRelationships(tables: Table[]): Relationship[] {\n\tconst relationships: Relationship[] = [];\n\n\tfor (const table of tables) {\n\t\tfor (const column of table.columns) {\n\t\t\tif (column.foreignKey) {\n\t\t\t\tconst [toTable, toColumn] = column.foreignKey.split(\".\");\n\t\t\t\trelationships.push({\n\t\t\t\t\tfromTable: table.name,\n\t\t\t\t\tfromColumn: column.name,\n\t\t\t\t\ttoTable,\n\t\t\t\t\ttoColumn,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn relationships;\n}\n\n/**\n * Get complete database schema with all tables, columns, and relationships\n */\nasync function getDatabaseSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n\toptions: {\n\t\tincludeSampleData?: boolean;\n\t\tincludeDescriptions?: boolean;\n\t\tmaxTables?: number;\n\t} = {},\n): Promise<DatabaseSchema> {\n\tconst {\n\t\tincludeSampleData = false,\n\t\tincludeDescriptions = true,\n\t\t// maxTables = 50, // Prevent overwhelming the context\n\t} = options;\n\n\ttry {\n\t\tconst tableNames = await getTableNames(db);\n\n\t\t// Fetch schema info for each table in parallel\n\t\tconst tablePromises = tableNames.map(async (tableName) => {\n\t\t\tconst [columns, description, sampleData] = await Promise.all([\n\t\t\t\tgetTableColumns({ tableName, db }),\n\t\t\t\tincludeDescriptions ? getTableDescription(tableName) : Promise.resolve(undefined),\n\t\t\t\tincludeSampleData ? getSampleData(tableName) : Promise.resolve([]),\n\t\t\t]);\n\n\t\t\tconst table: Table = {\n\t\t\t\tname: tableName,\n\t\t\t\tcolumns: columns.map(convertColumnInfo),\n\t\t\t};\n\n\t\t\tif (description) {\n\t\t\t\ttable.description = description;\n\t\t\t}\n\n\t\t\tif (sampleData.length > 0) {\n\t\t\t\ttable.sampleData = sampleData.map((row) =>\n\t\t\t\t\tObject.fromEntries(Object.entries(row).map(([key, value]) => [key, String(value)])),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn table;\n\t\t});\n\n\t\tconst tables = await Promise.all(tablePromises);\n\n\t\t// Extract relationships from foreign keys\n\t\tconst relationships = extractRelationships(tables);\n\n\t\treturn {\n\t\t\tdbType: \"PostgreSQL\",\n\t\t\ttables,\n\t\t\trelationships,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Error fetching database schema:\", error);\n\t\tthrow new Error(\n\t\t\t`Failed to fetch database schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n\n/**\n * Get detailed schema with sample data (for initial conversation context)\n */\nexport async function getDetailedSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<DatabaseSchema> {\n\treturn getDatabaseSchema(db, {\n\t\tincludeSampleData: true,\n\t\tincludeDescriptions: true,\n\t\t// maxTables: 30, // todo: DELETE THIS AFTER TESTING\n\t});\n}\n","import type { DatabaseSchema } from \"shared/types\";\n\n/**\n * Generate system prompt with database context\n */\nexport function generateSystemPrompt(schema: DatabaseSchema): string {\n\treturn `You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.\n\n**Your Role:**\n1. Keep responses SHORT - 2-3 sentences maximum unless generating SQL\n2. When generating SQL:\n - Provide 1 sentence explanation\n - The SQL query in a code block\n - 1 sentence about expected results\n - NO verbose explanations\n3. Use exact table/column names from the schema\n4. Generate valid ${schema.dbType} syntax\n5. If query is unclear, ask ONE specific clarifying question\n6. No preamble, no apologies, get straight to the answer\n\n**Database Context:**\n${formatSchemaForPrompt(schema)}\n\n**Guidelines:**\n1. Always generate syntactically correct SQL for the database type (${schema.dbType})\n2. Use proper table/column names exactly as defined in the schema\n3. When generating queries, wrap them in \\`\\`\\`sql code blocks\n4. Explain what the query does in plain language\n5. Suggest relevant follow-up questions or analyses\n6. If a request is ambiguous, ask clarifying questions\n7. For complex queries, break down the logic step-by-step\n8. Warn about potentially expensive operations (full table scans, etc.)\n9. Consider data privacy - remind users not to share sensitive data externally\n\n**Response Format:**\nWhen generating queries, use this structure:\n- Brief explanation of what you'll do\n- The SQL query in a code block\n- Expected results description\n- Optional: suggestions for related queries\n\n**Example:**\nUser: \"Show me the top 5 customers by revenue\"\n\nResponse: \"I'll query the orders and customers tables to find your highest-value customers.\n\n\\`\\`\\`sql\nSELECT \n c.customer_name,\n SUM(o.total_amount) as total_revenue\nFROM customers c\nJOIN orders o ON c.id = o.customer_id\nGROUP BY c.id, c.customer_name\nORDER BY total_revenue DESC\nLIMIT 5;\n\\`\\`\\`\n\nThis will return the 5 customers with the highest total order value. You might also want to see:\n- Revenue trends over time for these customers\n- Their most frequently ordered products\"`;\n}\n\n/**\n * Format schema information for the prompt\n */\nfunction formatSchemaForPrompt(schema: DatabaseSchema): string {\n\tlet output = `Database Type: ${schema.dbType}\\n\\n`;\n\n\toutput += \"**Tables and Columns:**\\n\";\n\tfor (const table of schema.tables) {\n\t\toutput += `\\n### ${table.name}\\n`;\n\t\tif (table.description) {\n\t\t\toutput += `Description: ${table.description}\\n`;\n\t\t}\n\t\toutput += \"Columns:\\n\";\n\n\t\tfor (const col of table.columns) {\n\t\t\tconst pkIndicator = col.isPrimaryKey ? \" [PRIMARY KEY]\" : \"\";\n\t\t\tconst fkIndicator = col.foreignKey ? ` [FK -> ${col.foreignKey}]` : \"\";\n\t\t\tconst nullable = col.nullable ? \"NULL\" : \"NOT NULL\";\n\n\t\t\toutput += ` - ${col.name}: ${col.type} ${nullable}${pkIndicator}${fkIndicator}\\n`;\n\t\t\tif (col.description) {\n\t\t\t\toutput += ` ${col.description}\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Add sample data if available\n\t\tif (table.sampleData && table.sampleData.length > 0) {\n\t\t\toutput += `Sample data (${table.sampleData.length} rows):\\n`;\n\t\t\toutput += `${JSON.stringify(table.sampleData.slice(0, 3), null, 2)}\\n`;\n\t\t}\n\t}\n\n\t// Add relationships\n\tif (schema.relationships && schema.relationships.length > 0) {\n\t\toutput += \"\\n**Relationships:**\\n\";\n\t\tfor (const rel of schema.relationships) {\n\t\t\toutput += ` - ${rel.fromTable}.${rel.fromColumn} -> ${rel.toTable}.${rel.toColumn}\\n`;\n\t\t}\n\t}\n\n\treturn output;\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { chatSchema } from \"shared/types\";\nimport { getDetailedSchema } from \"@/dao/table-details-schema.js\";\nimport { generateSystemPrompt } from \"@/utils/system-prompt-generator.js\";\n\nexport const chatRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /:dbType/chat/...\n\t */\n\t.basePath(\"/chat\")\n\n\t/**\n\t * POST /chat - Handle AI chat requests with streaming\n\t * Proxies to the Cloudflare Worker which has the Gemini API key\n\t */\n\t.post(\"/\", zValidator(\"json\", chatSchema), async (c) => {\n\t\tconst { messages, conversationId, db } = c.req.valid(\"json\");\n\t\tconsole.log(\"POST /chat messages\", messages);\n\n\t\t// Get the database schema and generate system prompt\n\t\tconst schema = await getDetailedSchema(db);\n\t\tconst systemPrompt = generateSystemPrompt(schema);\n\n\t\tconst payload = {\n\t\t\tmessages,\n\t\t\tconversationId,\n\t\t\tsystemPrompt,\n\t\t};\n\n\t\t// Forward request to the proxy with the system prompt\n\t\tconst proxyResponse = await fetch(`${DEFAULTS.PROXY_URL}/chat`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\n\t\tif (!proxyResponse.ok) {\n\t\t\tconst errorData = await proxyResponse.json();\n\t\t\treturn c.json(\n\t\t\t\t{ error: errorData.error || \"Proxy request failed\" },\n\t\t\t\tproxyResponse.status as 400 | 500,\n\t\t\t);\n\t\t}\n\n\t\t// Stream the SSE response back to the client\n\t\tconst { readable, writable } = new TransformStream();\n\t\tproxyResponse.body?.pipeTo(writable);\n\n\t\treturn new Response(readable, {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\tConnection: \"keep-alive\",\n\t\t\t},\n\t\t});\n\t});\n\nexport type ChatRoutes = typeof chatRoutes;\n","/**\n * Parse DATABASE_URL to extract host and port\n */\nexport function parseDatabaseUrl(): { host: string; port: number } {\n\tconst databaseUrl = process.env.DATABASE_URL;\n\n\tif (!databaseUrl) {\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n\n\ttry {\n\t\tconst url = new URL(databaseUrl);\n\t\treturn {\n\t\t\thost: url.hostname || \"localhost\",\n\t\t\tport: Number.parseInt(url.port, 10) || 5432,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Failed to parse DATABASE_URL:\", error);\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ConnectionInfoSchemaType,\n\tconnectionInfoSchema,\n\ttype DatabaseInfoSchemaType,\n\ttype DatabaseSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all normal databases on the PostgreSQL server.\n * Returns name, size (human readable), owner, and encoding.\n *\n * @returns List of database information objects\n * @throws Error if query fails or no databases are found\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n d.datname as name,\n pg_size_pretty(pg_database_size(d.datname)) as size,\n pg_catalog.pg_get_userbyid(d.datdba) as owner,\n pg_encoding_to_char(d.encoding) as encoding\n FROM pg_catalog.pg_database d\n WHERE d.datistemplate = false\n ORDER BY d.datname;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from database\",\n\t\t});\n\t}\n\n\treturn rows;\n}\n\n/**\n * Gets the name of the database we are currently using.\n *\n * @returns Object with current database name\n * @throws Error if query fails or no name is returned\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = \"SELECT current_database() as database;\";\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from database\",\n\t\t});\n\t}\n\n\treturn rows[0];\n}\n\n/**\n * Gets useful information about the connection and PostgreSQL server.\n * Includes version, host, port, user, database name, active connections, etc.\n *\n * Uses fallback values from DATABASE_URL if some fields are missing.\n *\n * @returns Connection and server information object\n * @throws Error if query fails or result is invalid\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n version() as version,\n current_database() as database,\n current_user as user,\n inet_server_addr() as host,\n inet_server_port() as port,\n (SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,\n (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from database\",\n\t\t});\n\t}\n\n\t// Validate main result\n\tconst result = connectionInfoSchema.parse(rows[0]);\n\n\t// Use DATABASE_URL as backup for host/port if needed\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: result.host || urlDefaults.host,\n\t\tport: result.port || urlDefaults.port,\n\t\tuser: result.user,\n\t\tdatabase: result.database,\n\t\tversion: result.version.toString(),\n\t\tactive_connections: result.active_connections,\n\t\tmax_connections: result.max_connections,\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all databases (schemas) on the MySQL server.\n * Returns name, size (human-readable), owner (connected user), and encoding (charset).\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getMysqlPool();\n\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t s.SCHEMA_NAME AS name,\n\t\t CONCAT(\n\t\t ROUND(\n\t\t COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024,\n\t\t 2\n\t\t ),\n\t\t ' MB'\n\t\t ) AS size,\n\t\t CURRENT_USER() AS owner,\n\t\t s.DEFAULT_CHARACTER_SET_NAME AS encoding\n\t\tFROM information_schema.SCHEMATA s\n\t\tLEFT JOIN information_schema.TABLES t\n\t\t ON t.TABLE_SCHEMA = s.SCHEMA_NAME\n\t\tGROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME\n\t\tORDER BY s.SCHEMA_NAME\n\t`);\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from server\",\n\t\t});\n\t}\n\n\treturn rows as DatabaseInfoSchemaType[];\n}\n\n/**\n * Gets the name of the database currently in use.\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getMysqlPool();\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\"SELECT DATABASE() AS db\");\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from server\",\n\t\t});\n\t}\n\n\treturn (rows as Array<{ db: string }>)[0] as DatabaseSchemaType;\n}\n\n/**\n * Gets connection and server information for MySQL.\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getMysqlPool();\n\n\tconst [infoRows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t VERSION() AS version,\n\t\t DATABASE() AS database_name,\n\t\t CURRENT_USER() AS user,\n\t\t @@hostname AS host,\n\t\t @@port AS port,\n\t\t @@max_connections AS max_connections\n\t`);\n\n\tconst [connRows] = await pool.execute<RowDataPacket[]>(\n\t\t\"SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST\",\n\t);\n\n\tif (!infoRows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from server\",\n\t\t});\n\t}\n\n\tconst info = (infoRows as Array<Record<string, string | number>>)[0];\n\tconst activeConnections = Number((connRows as Array<{ cnt: number }>)[0]?.cnt ?? 0);\n\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: String(info.host || urlDefaults.host),\n\t\tport: Number(info.port || urlDefaults.port),\n\t\tuser: String(info.user),\n\t\tdatabase: String(info.database_name ?? \"\"),\n\t\tversion: String(info.version),\n\t\tactive_connections: activeConnections,\n\t\tmax_connections: Number(info.max_connections),\n\t};\n}\n","import { Hono } from \"hono\";\nimport type {\n\tConnectionInfoSchemaType,\n\tCurrentDatabaseSchemaType,\n\tDatabaseListSchemaType,\n} from \"shared/types\";\nimport type { ApiHandler } from \"@/app.types.js\";\nimport {\n\tgetCurrentDatabase as pgGetCurrentDatabase,\n\tgetDatabaseConnectionInfo as pgGetDatabaseConnectionInfo,\n\tgetDatabasesList as pgGetDatabasesList,\n} from \"@/dao/database-list.dao.js\";\nimport {\n\tgetCurrentDatabase as mysqlGetCurrentDatabase,\n\tgetDatabaseConnectionInfo as mysqlGetDatabaseConnectionInfo,\n\tgetDatabasesList as mysqlGetDatabasesList,\n} from \"@/dao/mysql/database-list.mysql.dao.js\";\nimport { getDbType } from \"@/db-manager.js\";\n\n/**\n * /databases routes (at root level, no dbType required)\n * GET /databases - Get list of all databases on the server (name, size, owner, encoding)\n * GET /databases/current - Get the name of the database we are currently connected to\n * GET /databases/connection - Get connection details and server information\n */\nexport const databasesRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /databases/...\n\t */\n\t.basePath(\"/databases\")\n\n\t/**\n\t * GET /databases\n\t * Returns list of all databases on the server (name, size, owner, encoding) and the database type\n\t */\n\t.get(\"/\", async (c): ApiHandler<DatabaseListSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst databases =\n\t\t\tdbType === \"mysql\" ? await mysqlGetDatabasesList() : await pgGetDatabasesList();\n\t\treturn c.json({ data: { databases, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/current\n\t * Returns the name of the database we are currently connected to and the database type\n\t */\n\t.get(\"/current\", async (c): ApiHandler<CurrentDatabaseSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst current =\n\t\t\tdbType === \"mysql\" ? await mysqlGetCurrentDatabase() : await pgGetCurrentDatabase();\n\t\treturn c.json({ data: { db: current.db, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/connection\n\t * Returns connection details and server information\n\t */\n\t.get(\"/connection\", async (c): ApiHandler<ConnectionInfoSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst info =\n\t\t\tdbType === \"mysql\"\n\t\t\t\t? await mysqlGetDatabaseConnectionInfo()\n\t\t\t\t: await pgGetDatabaseConnectionInfo();\n\t\treturn c.json({ data: info }, 200);\n\t});\n\nexport type DatabasesRoutes = typeof databasesRoutes.routes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { FieldPacket, ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getMysqlPool(db);\n\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\t// mysql2 returns [rows, fields] for SELECT and [ResultSetHeader, fields] for DML\n\tconst [result, fields] = (await pool.execute(cleanedQuery)) as [\n\t\tRowDataPacket[] | ResultSetHeader,\n\t\tFieldPacket[],\n\t];\n\tconst duration = performance.now() - startTime;\n\n\t// SELECT-like results have an array of rows\n\tif (Array.isArray(result)) {\n\t\tconst rows = result as RowDataPacket[];\n\t\tconst columns = fields ? fields.map((f) => f.name) : Object.keys(rows[0] ?? {});\n\t\treturn {\n\t\t\tcolumns,\n\t\t\trows: rows as Record<string, unknown>[],\n\t\t\trowCount: rows.length,\n\t\t\tduration,\n\t\t\tmessage: rows.length === 0 ? \"OK\" : undefined,\n\t\t};\n\t}\n\n\t// DML results (INSERT, UPDATE, DELETE)\n\tconst dmlResult = result as ResultSetHeader;\n\treturn {\n\t\tcolumns: [],\n\t\trows: [],\n\t\trowCount: dmlResult.affectedRows,\n\t\tduration,\n\t\tmessage: `OK — ${dmlResult.affectedRows} row(s) affected`,\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getDbPool(db);\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\t// Clean the query - remove trailing semicolons and whitespace\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\tconst result = await pool.query(cleanedQuery);\n\tconst duration = performance.now() - startTime;\n\n\tconst columns = result.fields.map((field) => field.name);\n\n\treturn {\n\t\tcolumns,\n\t\trows: result.rows,\n\t\trowCount: result.rows.length,\n\t\tduration,\n\t\tmessage: result.rows.length === 0 ? \"OK\" : undefined,\n\t};\n};\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { databaseSchema, type ExecuteQueryResult, executeQuerySchema } from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { executeQuery as mysqlExecuteQuery } from \"@/dao/mysql/query.mysql.dao.js\";\nimport { executeQuery as pgExecuteQuery } from \"@/dao/query.dao.js\";\n\nexport const queryRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/query/...\n\t */\n\t.basePath(\"/query\")\n\n\t/**\n\t * POST /query\n\t * Executes a SQL query on the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", executeQuerySchema),\n\t\tasync (c): ApiHandler<ExecuteQueryResult> => {\n\t\t\tconst { query } = c.req.valid(\"json\");\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst data =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlExecuteQuery({ query, db })\n\t\t\t\t\t: await pgExecuteQuery({ query, db });\n\t\t\treturn c.json({ data }, 200);\n\t\t},\n\t);\n\nexport type QueryRoutes = typeof queryRoutes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getDbPool(db);\n\n\t// Extract column names and values\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data);\n\n\t// Build the INSERT query\n\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\tconst query = `\n\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\tVALUES (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\tconst result = await pool.query(query, values);\n\tif (result.rowCount === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getDbPool(db);\n\tconst client = await pool.connect();\n\n\ttry {\n\t\t// Get column names from the first record\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\t\tlet successCount = 0;\n\t\tconst failureCount = 0;\n\t\tconst errors: Array<{ recordIndex: number; error: string }> = [];\n\n\t\t// Execute inserts in a transaction\n\t\tawait client.query(\"BEGIN\");\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => record[col]);\n\n\t\t\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\tawait client.query(insertSQL, values);\n\t\t\t\tsuccessCount++;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait client.query(\"COMMIT\");\n\n\t\treturn {\n\t\t\tsuccess: failureCount === 0,\n\t\t\tmessage: `Bulk insert completed: ${successCount} records inserted${failureCount > 0 ? `, ${failureCount} failed` : \"\"}`,\n\t\t\tsuccessCount,\n\t\t\tfailureCount,\n\t\t\terrors: errors.length > 0 ? errors : undefined,\n\t\t};\n\t} catch (error) {\n\t\tawait client.query(\"ROLLBACK\");\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tclient.release();\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Finds all records in other tables that reference the given primary key values\n */\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\t// Group constraints by referencing table and column for efficiency\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) {\n\t\t\tconstraintsByTable.set(key, []);\n\t\t}\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\t// Get the primary key values that we're looking for\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\t// Find which primary key column matches this FK's referenced column\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\t// Build query to find related records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tWHERE \"${constraint.referencingColumn}\" IN (${placeholders})\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery, pkValues);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Attempts to delete records. If FK violation occurs, returns related records.\n */\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\n\tconst query = `\n\t\tDELETE FROM \"${tableName}\"\n\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\tRETURNING *\n\t`;\n\n\ttry {\n\t\tawait pool.query(\"BEGIN\");\n\t\tconst result = await pool.query(query, pkValues);\n\t\tawait pool.query(\"COMMIT\");\n\t\treturn { deletedCount: result.rowCount ?? 0, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\t// Check if this is a foreign key violation\n\t\tconst pgError = error as {\n\t\t\tcode?: string;\n\t\t\tdetail?: string;\n\t\t\tconstraint?: string;\n\t\t};\n\n\t\tif (pgError.code === \"23503\") {\n\t\t\t// Fetch related records to show the user\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n\n/**\n * Force deletes records by first deleting all related records in referencing tables (cascade)\n */\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\t// Get all FK constraints that reference this table\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\t\tlet totalRelatedDeleted = 0;\n\n\t\t// Delete related records in reverse dependency order\n\t\t// We need to handle nested FKs recursively\n\t\tconst deletedTables = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t) => {\n\t\t\t// First, find if there are tables referencing the target table\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\t// Get the values that will be deleted from the target table\n\t\t\t\tconst nestedPlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\t\tconst selectQuery = `\n\t\t\t\t\tSELECT \"${nestedFk.referencedColumn}\" FROM \"${targetTable}\"\n\t\t\t\t\tWHERE \"${targetColumn}\" IN (${nestedPlaceholders})\n\t\t\t\t`;\n\n\t\t\t\tconst selectResult = await pool.query(selectQuery, values);\n\t\t\t\tconst nestedValues = selectResult.rows.map(\n\t\t\t\t\t({ row }: { row: { [nestedFk.referencedColumn]: unknown } }) =>\n\t\t\t\t\t\trow[nestedFk.referencedColumn],\n\t\t\t\t);\n\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Now delete from the target table\n\t\t\tconst deletePlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\tconst deleteQuery = `\n\t\t\t\tDELETE FROM \"${targetTable}\"\n\t\t\t\tWHERE \"${targetColumn}\" IN (${deletePlaceholders})\n\t\t\t`;\n\n\t\t\tconst deleteResult = await pool.query(deleteQuery, values);\n\t\t\ttotalRelatedDeleted += deleteResult.rowCount ?? 0;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\t// Delete from all referencing tables first\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t);\n\t\t}\n\n\t\t// Finally delete the main records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst query = `\n\t\t\tDELETE FROM \"${tableName}\"\n\t\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\t\tconst result = await pool.query(query, pkValues);\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\tconst mainDeleted = result.rowCount ?? 0;\n\n\t\treturn { deletedCount: mainDeleted + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport {\n\ttype ColumnInfoSchemaType,\n\tmapMysqlToDataType,\n\tstandardizeMysqlDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\ninterface ColumnRow extends RowDataPacket {\n\tcolumnName: string;\n\tdataType: string;\n\tcolumnType: string;\n\tisNullable: number | boolean;\n\tcolumnDefault: string | null;\n\tisPrimaryKey: number | boolean;\n\tisForeignKey: number | boolean;\n\treferencedTable: string | null;\n\treferencedColumn: string | null;\n}\n\n/**\n * Parse MySQL enum/set values from COLUMN_TYPE, e.g. \"enum('a','b','c')\" → [\"a\",\"b\",\"c\"]\n */\nfunction parseMysqlEnumValues(columnType: string): string[] | null {\n\tconst match = columnType.match(/^(?:enum|set)\\((.+)\\)$/i);\n\tif (!match?.[1]) return null;\n\treturn match[1].split(\",\").map((v) => v.trim().replace(/^'|'$/g, \"\"));\n}\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst query = `\n\t\tSELECT\n\t\t c.COLUMN_NAME AS columnName,\n\t\t c.DATA_TYPE AS dataType,\n\t\t c.COLUMN_TYPE AS columnType,\n\t\t (c.IS_NULLABLE = 'YES') AS isNullable,\n\t\t c.COLUMN_DEFAULT AS columnDefault,\n\t\t (c.COLUMN_KEY = 'PRI') AS isPrimaryKey,\n\t\t (kcu.REFERENCED_TABLE_NAME IS NOT NULL) AS isForeignKey,\n\t\t kcu.REFERENCED_TABLE_NAME AS referencedTable,\n\t\t kcu.REFERENCED_COLUMN_NAME AS referencedColumn\n\t\tFROM information_schema.COLUMNS c\n\t\tLEFT JOIN information_schema.KEY_COLUMN_USAGE kcu\n\t\t ON c.TABLE_SCHEMA = kcu.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = kcu.TABLE_NAME\n\t\t AND c.COLUMN_NAME = kcu.COLUMN_NAME\n\t\t AND kcu.REFERENCED_TABLE_NAME IS NOT NULL\n\t\tWHERE c.TABLE_SCHEMA = DATABASE()\n\t\t AND c.TABLE_NAME = ?\n\t\tORDER BY c.ORDINAL_POSITION\n\t`;\n\n\tconst [rows] = await pool.execute<ColumnRow[]>(query, [tableName]);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\tconst dataType = r.dataType as string;\n\t\tconst columnType = r.columnType as string;\n\t\tconst isEnum = dataType === \"enum\" || dataType === \"set\";\n\t\tconst enumValues = isEnum ? parseMysqlEnumValues(columnType) : null;\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapMysqlToDataType(dataType, columnType),\n\t\t\tdataTypeLabel: standardizeMysqlDataTypeLabel(dataType, columnType),\n\t\t\tisNullable: Boolean(r.isNullable),\n\t\t\tcolumnDefault: r.columnDefault ?? null,\n\t\t\tisPrimaryKey: Boolean(r.isPrimaryKey),\n\t\t\tisForeignKey: Boolean(r.isForeignKey),\n\t\t\treferencedTable: r.referencedTable ?? null,\n\t\t\treferencedColumn: r.referencedColumn ?? null,\n\t\t\tenumValues,\n\t\t};\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data).map((value, index) => {\n\t\tconst columnName = columns[index];\n\t\tif (booleanColumns.has(columnName) && typeof value === \"string\") {\n\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t}\n\t\treturn value;\n\t});\n\n\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\tconst query = `\n\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\tVALUES (${placeholders})\n\t`;\n\n\tconst [result] = await pool.execute<ResultSetHeader>(query, values);\n\n\tif (result.affectedRows === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getMysqlPool(db);\n\tconst connection = await pool.getConnection();\n\n\ttry {\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\t\tconst tableColumns = await getTableColumns({ tableName, db });\n\t\tconst booleanColumns = new Set(\n\t\t\ttableColumns\n\t\t\t\t.filter((col) => col.dataTypeLabel === \"boolean\")\n\t\t\t\t.map((col) => col.columnName),\n\t\t);\n\n\t\tawait connection.beginTransaction();\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => {\n\t\t\t\tconst value = record[col];\n\t\t\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\t\tawait connection.execute<ResultSetHeader>(insertSQL, values as any);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed to insert record ${i + 1}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait connection.commit();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${records.length} record${records.length !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: records.length,\n\t\t\tfailureCount: 0,\n\t\t};\n\t} catch (error) {\n\t\tawait connection.rollback();\n\t\tif (error instanceof HTTPException) throw error;\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL FK violation error number\nconst MYSQL_FK_VIOLATION = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) constraintsByTable.set(key, []);\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\`\n\t\t\t WHERE \\`${constraint.referencingColumn}\\` IN (${placeholders})\n\t\t\t LIMIT 100`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${placeholders})`,\n\t\t\tpkValues,\n\t\t);\n\t\tawait connection.commit();\n\t\treturn { deletedCount: result.affectedRows, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (mysqlError.errno === MYSQL_FK_VIOLATION) {\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\t// Disable FK checks temporarily for cascade delete\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\tlet totalRelatedDeleted = 0;\n\t\tconst deletedTables = new Set<string>();\n\t\tconst visited = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t\tvisitedSet: Set<string>,\n\t\t) => {\n\t\t\tconst key = `${targetTable}.${targetColumn}`;\n\t\t\tif (visitedSet.has(key)) return;\n\t\t\tvisitedSet.add(key);\n\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\tconst nestedPlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\t\tconst [selectRows] = await connection.execute<RowDataPacket[]>(\n\t\t\t\t\t`SELECT \\`${nestedFk.referencedColumn}\\` FROM \\`${targetTable}\\`\n\t\t\t\t\t WHERE \\`${targetColumn}\\` IN (${nestedPlaceholders})`,\n\t\t\t\t\tvalues as any[],\n\t\t\t\t);\n\t\t\t\tconst nestedValues = (selectRows as Record<string, unknown>[]).map(\n\t\t\t\t\t(row) => row[nestedFk.referencedColumn],\n\t\t\t\t);\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t\tvisitedSet,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deletePlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\tconst [deleteResult] = await connection.execute<ResultSetHeader>(\n\t\t\t\t`DELETE FROM \\`${targetTable}\\` WHERE \\`${targetColumn}\\` IN (${deletePlaceholders})`,\n\t\t\t\tvalues as any[],\n\t\t\t);\n\t\t\ttotalRelatedDeleted += deleteResult.affectedRows;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t\tvisited,\n\t\t\t);\n\t\t}\n\n\t\tconst mainPlaceholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${mainPlaceholders})`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\tawait connection.commit();\n\n\t\treturn { deletedCount: result.affectedRows + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u) => `\\`${u.columnName}\\` = ?`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\tif (booleanColumns.has(u.columnName) && typeof u.value === \"string\") {\n\t\t\t\t\treturn u.value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \\`${tableName}\\`\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \\`${primaryKey}\\` = ?\n\t\t\t`;\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\tconst [result] = await connection.execute<ResultSetHeader>(query, values as any);\n\n\t\t\tif (result.affectedRows === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.affectedRows;\n\t\t}\n\n\t\tawait connection.commit();\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Updates multiple cells in a table. Can update multiple rows or multiple cells in the same row.\n * Groups updates by row and executes them efficiently.\n */\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getDbPool(db);\n\n\t// Group updates by row (using the primary key value)\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data. Please ensure the row has a \"${primaryKey}\" column.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\t// Use transaction for multiple updates\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\t// Execute updates for each row\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u, index) => `\"${u.columnName}\" = $${index + 1}`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\t// If the value is an object or array, stringify it for JSON/JSONB columns\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\t// Add the primary key value as the last parameter\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \"${tableName}\"\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \"${primaryKey}\" = $${values.length}\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\tconst result = await pool.query(query, values);\n\t\t\tif (result.rowCount === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.rowCount ?? 0;\n\t\t}\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\taddRecordSchema,\n\tbulkInsertRecordsSchema,\n\ttype DeleteRecordResult,\n\tdatabaseSchema,\n\tdeleteRecordSchema,\n\tupdateRecordsSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { addRecord as pgAddRecord } from \"@/dao/add-record.dao.js\";\nimport { bulkInsertRecords as pgBulkInsertRecords } from \"@/dao/bulk-insert-records.dao.js\";\nimport {\n\tdeleteRecords as pgDeleteRecords,\n\tforceDeleteRecords as pgForceDeleteRecords,\n} from \"@/dao/delete-records.dao.js\";\nimport { addRecord as mysqlAddRecord } from \"@/dao/mysql/add-record.mysql.dao.js\";\nimport { bulkInsertRecords as mysqlBulkInsertRecords } from \"@/dao/mysql/bulk-insert-records.mysql.dao.js\";\nimport {\n\tdeleteRecords as mysqlDeleteRecords,\n\tforceDeleteRecords as mysqlForceDeleteRecords,\n} from \"@/dao/mysql/delete-records.mysql.dao.js\";\nimport { updateRecords as mysqlUpdateRecords } from \"@/dao/mysql/update-records.mysql.dao.js\";\nimport { updateRecords as pgUpdateRecords } from \"@/dao/update-records.dao.js\";\n\nexport const recordsRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/records/...\n\t */\n\t.basePath(\"/records\")\n\n\t/**\n\t * POST /records\n\t * Adds a new record into a table\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", addRecordSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, data } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { insertedCount } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlAddRecord({ db, params: { tableName, data } })\n\t\t\t\t\t: await pgAddRecord({ db, params: { tableName, data } });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Record inserted into \"${tableName}\" with ${insertedCount} rows inserted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /records\n\t * Updates one or more cells in a table\n\t */\n\t.patch(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", updateRecordsSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKey, updates } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { updatedCount } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlUpdateRecords({ params: { tableName, primaryKey, updates }, db })\n\t\t\t\t\t: await pgUpdateRecords({ params: { tableName, primaryKey, updates }, db });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Updated ${updatedCount} records in \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records\n\t * Deletes records from a table\n\t */\n\t.delete(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<DeleteRecordResult, 409 | 200> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { deletedCount, fkViolation, relatedRecords } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlDeleteRecords({ tableName, primaryKeys, db })\n\t\t\t\t\t: await pgDeleteRecords({ tableName, primaryKeys, db });\n\t\t\tif (fkViolation) {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdeletedCount: 0,\n\t\t\t\t\t\t\tfkViolation: true,\n\t\t\t\t\t\t\trelatedRecords,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t409,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdeletedCount,\n\t\t\t\t\t\tfkViolation: false,\n\t\t\t\t\t\trelatedRecords: [],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records/force\n\t * Force deletes records and all related FK records\n\t */\n\t.delete(\n\t\t\"/force\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<{ deletedCount: number }> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst deletedCount =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlForceDeleteRecords({ tableName, primaryKeys, db })\n\t\t\t\t\t: await pgForceDeleteRecords({ tableName, primaryKeys, db });\n\t\t\treturn c.json({ data: deletedCount }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /records/bulk\n\t * Bulk inserts multiple records into a table\n\t */\n\t.post(\n\t\t\"/bulk\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", bulkInsertRecordsSchema),\n\t\tasync (c): ApiHandler<object> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, records } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst result =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlBulkInsertRecords({ tableName, records, db })\n\t\t\t\t\t: await pgBulkInsertRecords({ tableName, records, db });\n\t\t\tconsole.log(\"result\", result);\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t);\n\nexport type RecordsRoutes = typeof recordsRoutes;\n","import type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tFieldDataType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getDbPool(db);\n\n\t// Build column definitions\n\tconst columnDefinitions = fields.map((field: FieldDataType) => {\n\t\tlet columnDef = `\"${field.columnName}\" ${field.columnType}`;\n\n\t\t// Add array suffix if needed\n\t\tif (field.isArray) {\n\t\t\tcolumnDef += \"[]\";\n\t\t}\n\n\t\t// Add PRIMARY KEY constraint\n\t\tif (field.isPrimaryKey) {\n\t\t\tcolumnDef += \" PRIMARY KEY\";\n\t\t}\n\n\t\t// Add UNIQUE constraint\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tcolumnDef += \" UNIQUE\";\n\t\t}\n\n\t\t// Add NOT NULL constraint (if not nullable)\n\t\tif (!field.isNullable) {\n\t\t\tcolumnDef += \" NOT NULL\";\n\t\t}\n\n\t\t// Add GENERATED ALWAYS AS IDENTITY for identity columns\n\t\tif (field.isIdentity) {\n\t\t\tcolumnDef += \" GENERATED ALWAYS AS IDENTITY\";\n\t\t}\n\n\t\t// Add default value\n\t\tif (field.defaultValue && !field.isIdentity) {\n\t\t\tcolumnDef += ` DEFAULT ${field.defaultValue}`;\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\t// Build foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \"${constraintName}\" FOREIGN KEY (\"${fk.columnName}\") REFERENCES \"${fk.referencedTable}\" (\"${fk.referencedColumn}\") ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\t// Combine column definitions and foreign key constraints\n\tconst allDefinitions = [...columnDefinitions, ...foreignKeyConstraints];\n\n\t// Create the table\n\tconst createTableSQL = `\n\t\t\tCREATE TABLE \"${tableName}\" (\n\t\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\\t\")}\n\t\t\t);\n\t\t`;\n\n\tawait pool.query(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a table using ALTER TABLE DROP COLUMN.\n * Uses CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies.\n *\n * @param params.tableName - Name of the table containing the column\n * @param params.columnName - Name of the column to delete\n * @param params.cascade - If true, uses CASCADE; if false, uses RESTRICT\n * @param params.db - Optional database name to connect to\n * @returns {Object} Object with deleted count\n * @throws HTTPException if table or column does not exist\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, cascade, db } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check if column exists\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns \n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (!columnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Use CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies\n\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\tconst dropColumnSQL = `ALTER TABLE \"${tableName}\" DROP COLUMN \"${columnName}\" ${dropMode}`;\n\n\tconst { rowCount } = await pool.query(dropColumnSQL);\n\n\treturn { deletedCount: rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Gets related records from tables that reference this table\n */\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Gets the total row count for a table\n */\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(`SELECT COUNT(*) as count FROM \"${tableName}\"`);\n\treturn Number.parseInt(result.rows[0]?.count ?? \"0\", 10);\n}\n\n/**\n * Deletes a table from the database.\n * If there are FK constraints referencing this table, returns the related records.\n *\n * @param params.tableName - Name of the table to delete\n * @param params.db - Database name\n * @param params.cascade - If true, uses CASCADE to drop dependent objects\n * @returns DeleteTableResult with deletedCount, fkViolation flag, and relatedRecords\n */\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get row count before deletion\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\t// If not cascade, check for FK constraints first\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\t}\n\n\ttry {\n\t\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\t\tconst dropTableSQL = `DROP TABLE \"${tableName}\" ${dropMode}`;\n\n\t\tawait pool.query(dropTableSQL);\n\n\t\treturn {\n\t\t\tdeletedCount: rowCount,\n\t\t\tfkViolation: false,\n\t\t\trelatedRecords: [],\n\t\t};\n\t} catch (error) {\n\t\tconst pgError = error as { code?: string; detail?: string };\n\n\t\t// Check if this is a dependency error (foreign key constraint)\n\t\tif (pgError.code === \"2BP01\") {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getDbPool(db);\n\tconst { rows } = await pool.query(`SELECT * FROM \"${tableName}\"`);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows };\n}\n","import type { ResultSetHeader } from \"mysql2\";\nimport type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tFieldDataType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Formats default values for MySQL compatibility.\n * MySQL requires function calls in DEFAULT clauses to be wrapped in parentheses.\n */\nfunction formatMysqlDefaultValue(defaultValue: string, columnType: string): string | null {\n\tconst trimmed = defaultValue.trim().toLowerCase();\n\n\t// Check if it's a function call (contains parentheses)\n\tif (trimmed.includes(\"(\") && trimmed.includes(\")\")) {\n\t\t// MySQL 8.0+ requires function calls to be wrapped in parentheses for DEFAULT\n\t\t// But UUID() returns a string, not compatible with INT columns\n\t\tif (trimmed.includes(\"uuid()\")) {\n\t\t\t// UUID() only makes sense for CHAR(36) or VARCHAR columns\n\t\t\tif (\n\t\t\t\t!columnType.toUpperCase().includes(\"CHAR\") &&\n\t\t\t\t!columnType.toUpperCase().includes(\"TEXT\")\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn \"(UUID())\";\n\t\t}\n\n\t\t// Other function calls like CURRENT_TIMESTAMP, NOW(), etc.\n\t\tif (trimmed.includes(\"current_timestamp\") || trimmed.includes(\"now()\")) {\n\t\t\treturn \"(CURRENT_TIMESTAMP)\";\n\t\t}\n\n\t\tif (trimmed.includes(\"current_date\")) {\n\t\t\treturn \"(CURRENT_DATE)\";\n\t\t}\n\n\t\t// Wrap other function calls in parentheses\n\t\treturn `(${defaultValue.trim()})`;\n\t}\n\n\t// For non-function defaults (literals), return as-is\n\t// Handle special keywords\n\tif (trimmed === \"null\") {\n\t\treturn \"NULL\";\n\t}\n\n\tif (trimmed === \"true\" || trimmed === \"false\") {\n\t\treturn trimmed === \"true\" ? \"1\" : \"0\";\n\t}\n\n\t// Return the value as-is (could be a number, quoted string, etc.)\n\treturn defaultValue.trim();\n}\n\n/**\n * Maps PG-style column types from the UI schema to MySQL-compatible types.\n * The UI uses PostgreSQL-style type names, so we translate them for MySQL.\n */\nfunction mapColumnTypeToMysql(columnType: string, isArray: boolean): string {\n\tif (isArray) {\n\t\t// MySQL does not support native array types — use JSON as fallback\n\t\treturn \"JSON\";\n\t}\n\n\tconst normalized = columnType.toLowerCase().trim();\n\n\tconst typeMap: Record<string, string> = {\n\t\t// Integer types\n\t\tserial: \"INT AUTO_INCREMENT\",\n\t\tserial4: \"INT AUTO_INCREMENT\",\n\t\tbigserial: \"BIGINT AUTO_INCREMENT\",\n\t\tserial8: \"BIGINT AUTO_INCREMENT\",\n\t\tint: \"INT\",\n\t\tint4: \"INT\",\n\t\tinteger: \"INT\",\n\t\tbigint: \"BIGINT\",\n\t\tint8: \"BIGINT\",\n\t\tsmallint: \"SMALLINT\",\n\t\tint2: \"SMALLINT\",\n\t\t// Decimal / numeric\n\t\tnumeric: \"DECIMAL\",\n\t\tdecimal: \"DECIMAL\",\n\t\treal: \"FLOAT\",\n\t\tfloat4: \"FLOAT\",\n\t\tfloat: \"FLOAT\",\n\t\t\"double precision\": \"DOUBLE\",\n\t\tfloat8: \"DOUBLE\",\n\t\tmoney: \"DECIMAL(19, 4)\",\n\t\t// Boolean\n\t\tboolean: \"TINYINT(1)\",\n\t\tbool: \"TINYINT(1)\",\n\t\t// Text\n\t\ttext: \"LONGTEXT\",\n\t\tvarchar: \"VARCHAR(255)\",\n\t\t\"character varying\": \"VARCHAR(255)\",\n\t\tchar: \"CHAR(1)\",\n\t\tcharacter: \"CHAR(1)\",\n\t\tbpchar: \"CHAR\",\n\t\tuuid: \"CHAR(36)\",\n\t\t// JSON\n\t\tjson: \"JSON\",\n\t\tjsonb: \"JSON\",\n\t\txml: \"LONGTEXT\",\n\t\t// Date/time\n\t\tdate: \"DATE\",\n\t\ttime: \"TIME\",\n\t\t\"time without time zone\": \"TIME\",\n\t\ttimestamp: \"DATETIME\",\n\t\t\"timestamp without time zone\": \"DATETIME\",\n\t\t\"timestamp with time zone\": \"DATETIME\",\n\t\ttimestamptz: \"DATETIME\",\n\t\tinterval: \"VARCHAR(255)\",\n\t\t// Binary\n\t\tbytea: \"LONGBLOB\",\n\t\t// Network / geometric — store as text in MySQL\n\t\tinet: \"VARCHAR(45)\",\n\t\tcidr: \"VARCHAR(45)\",\n\t\tmacaddr: \"VARCHAR(17)\",\n\t\tmacaddr8: \"VARCHAR(23)\",\n\t\tpoint: \"POINT\",\n\t\tline: \"LINESTRING\",\n\t\tpolygon: \"POLYGON\",\n\t};\n\n\treturn typeMap[normalized] || columnType.toUpperCase();\n}\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getMysqlPool(db);\n\n\tconst columnDefinitions = fields.map((field: FieldDataType) => {\n\t\tconst mappedType = mapColumnTypeToMysql(field.columnType, field.isArray ?? false);\n\t\tlet columnDef = `\\`${field.columnName}\\` ${mappedType}`;\n\n\t\t// NOT NULL\n\t\tif (!field.isNullable && !field.isPrimaryKey) {\n\t\t\tcolumnDef += \" NOT NULL\";\n\t\t}\n\n\t\t// Default value (skip for AUTO_INCREMENT columns)\n\t\tif (field.defaultValue && !mappedType.includes(\"AUTO_INCREMENT\")) {\n\t\t\tconst defaultValue = formatMysqlDefaultValue(field.defaultValue, mappedType);\n\t\t\tif (defaultValue !== null) {\n\t\t\t\tcolumnDef += ` DEFAULT ${defaultValue}`;\n\t\t\t}\n\t\t}\n\n\t\t// isIdentity → AUTO_INCREMENT (already embedded in type map via SERIAL mapping)\n\t\tif (field.isIdentity && !mappedType.includes(\"AUTO_INCREMENT\")) {\n\t\t\tcolumnDef += \" AUTO_INCREMENT\";\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\t// Primary key constraint\n\tconst primaryKeyFields = fields.filter((f) => f.isPrimaryKey);\n\tconst constraintDefs: string[] = [];\n\n\tif (primaryKeyFields.length > 0) {\n\t\tconst pkColumns = primaryKeyFields.map((f) => `\\`${f.columnName}\\``).join(\", \");\n\t\tconstraintDefs.push(`PRIMARY KEY (${pkColumns})`);\n\t}\n\n\t// Unique constraints\n\tfor (const field of fields) {\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tconstraintDefs.push(\n\t\t\t\t`UNIQUE KEY \\`uq_${tableName}_${field.columnName}\\` (\\`${field.columnName}\\`)`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \\`${constraintName}\\` FOREIGN KEY (\\`${fk.columnName}\\`) REFERENCES \\`${fk.referencedTable}\\` (\\`${fk.referencedColumn}\\`) ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\tconst allDefinitions = [...columnDefinitions, ...constraintDefs, ...foreignKeyConstraints];\n\n\tconst createTableSQL = `\n\t\tCREATE TABLE \\`${tableName}\\` (\n\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\")}\n\t\t) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci\n\t`;\n\n\tawait pool.execute<ResultSetHeader>(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a MySQL table using ALTER TABLE DROP COLUMN.\n * Note: MySQL does not support CASCADE/RESTRICT on DROP COLUMN — the cascade param is accepted\n * for API compatibility but does not change behavior.\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check column exists\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnExists = Number((columnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!columnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst [result] = await pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` DROP COLUMN \\`${columnName}\\``,\n\t);\n\n\treturn { deletedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL error number for FK dependency preventing DROP TABLE\nconst MYSQL_FK_DEPENDENCY = 1217;\nconst MYSQL_FK_ROW_REFERENCED = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\` LIMIT 100`,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as count FROM \\`${tableName}\\``,\n\t);\n\treturn Number((rows as Array<{ count: number }>)[0]?.count ?? 0);\n}\n\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\t}\n\n\ttry {\n\t\tif (cascade) {\n\t\t\t// MySQL doesn't support CASCADE on DROP TABLE natively the same way PG does.\n\t\t\t// We disable FK checks, drop the table, then re-enable.\n\t\t\tconst connection = await pool.getConnection();\n\t\t\ttry {\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\t\t\t\tawait connection.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\t\t} finally {\n\t\t\t\tconnection.release();\n\t\t\t}\n\t\t} else {\n\t\t\tawait pool.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t}\n\n\t\treturn { deletedCount: rowCount, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\t// Re-enable FK checks in case we disabled them\n\t\tawait pool.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (\n\t\t\tmysqlError.errno === MYSQL_FK_DEPENDENCY ||\n\t\t\tmysqlError.errno === MYSQL_FK_ROW_REFERENCED\n\t\t) {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SELECT * FROM \\`${tableName}\\``);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows: rows as Record<string, CellValue>[] };\n}\n","import type { RowDataPacket } from \"mysql2\";\nimport type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst tablesQuery = `\n\t\tSELECT table_name as tableName\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = DATABASE()\n\t\t AND table_type = 'BASE TABLE'\n\t\tORDER BY table_name\n\t`;\n\n\tconst [tables] = await pool.execute<RowDataPacket[]>(tablesQuery);\n\tif (!tables || tables.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\t(tables as Array<{ tableName: string }>).map(async (table) => {\n\t\t\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t\t`SELECT COUNT(*) as count FROM \\`${table.tableName}\\``,\n\t\t\t);\n\t\t\tconst countRow = (countRows as Array<{ count: number }>)[0];\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: countRow?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// SHOW CREATE TABLE returns the full DDL including column types, indexes, FK constraints\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SHOW CREATE TABLE \\`${tableName}\\``);\n\tconst row = (rows as Array<Record<string, string>>)[0];\n\n\t// The result row has \"Create Table\" key\n\tconst createTableSql = row?.[\"Create Table\"] ?? row?.create_table ?? \"\";\n\tif (!createTableSql) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to retrieve schema for table \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn createTableSql;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\n/**\n * MySQL-specific WHERE clause builder.\n * Uses ? placeholders and backtick identifiers.\n * ILIKE/NOT ILIKE map to LIKE/NOT LIKE (MySQL is case-insensitive by default on most collations).\n */\nexport function buildWhereClauseMysql(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst columnName = `\\`${filter.columnName}\\``;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\tcase \"ilike\":\n\t\t\t\t// MySQL LIKE is case-insensitive by default on most collations\n\t\t\t\tconditions.push(`${columnName} LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName} NOT LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\n/**\n * MySQL-specific ORDER BY clause builder.\n * Uses backtick identifiers.\n */\nexport function buildSortClauseMysql(\n\tsorts: SortType[] | string,\n\torder: SortDirection,\n): string {\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\\`${sort.columnName}\\` ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \\`${sorts}\\` ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\n/**\n * MySQL-specific cursor WHERE clause builder.\n * Uses ? placeholders (no index tracking needed since all placeholders are ?).\n */\nexport function buildCursorWhereClauseMysql(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\\`${col}\\``).join(\", \");\n\t\tconst placeholders = sortColumns.map(() => \"?\").join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type { RowDataPacket } from \"mysql2\";\nimport type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClauseMysql,\n\tbuildSortClauseMysql,\n\tbuildWhereClauseMysql,\n} from \"@/utils/build-clauses-mysql.js\";\n\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getMysqlPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COLUMN_NAME as column_name\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE()\n\t\t AND TABLE_NAME = ?\n\t\t AND COLUMN_KEY = 'PRI'\n\t\t ORDER BY ORDINAL_POSITION`,\n\t\t[tableName],\n\t);\n\treturn (rows as Array<{ column_name: string }>).map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getMysqlPool(db);\n\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// MySQL has no ctid equivalent — if no cursor columns, use empty (rely on natural order)\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClauseMysql(filters);\n\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClauseMysql(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\tconst sortClause = buildSortClauseMysql(Array.isArray(sort) ? sort : sort, order);\n\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else if (cursorColumns.length > 0) {\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as total FROM \\`${tableName}\\` ${filterWhereClause}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\tfilterValues as any,\n\t);\n\tconst totalRows = Number((countRows as Array<{ total: number }>)[0]?.total ?? 0);\n\n\tconst fetchLimit = Math.floor(limit) + 1;\n\tconst [dataRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT * FROM \\`${tableName}\\` ${combinedWhereClause} ${effectiveSortClause} LIMIT ${fetchLimit}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t[...filterValues, ...cursorValues] as any,\n\t);\n\n\tlet rows = dataRows as Record<string, unknown>[];\n\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\n\tif (rows.length > 0 && cursorColumns.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\n\t\tif (direction === \"asc\") {\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\n\t// First, get all table names\n\tconst tablesQuery = `\n\t\tSELECT table_name as \"tableName\"\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = 'public'\n\t\t AND table_type = 'BASE TABLE'\n\t\tORDER BY table_name;\n\t`;\n\n\tconst { rows: tables } = await pool.query(tablesQuery);\n\tif (!tables[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No tables returned from database\",\n\t\t});\n\t}\n\n\t// Get accurate row count for each table\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\ttables.map(async (table: { tableName: string }) => {\n\t\t\tconst countQuery = `SELECT COUNT(*)::integer as count FROM \"${table.tableName}\"`;\n\t\t\tconst { rows } = await pool.query(countQuery);\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: rows[0]?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\ninterface ColumnInfo {\n\tcolumn_name: string;\n\tdata_type: string;\n\tudt_name: string;\n\tis_nullable: string;\n\tcolumn_default: string | null;\n\tcharacter_maximum_length: number | null;\n\tnumeric_precision: number | null;\n\tnumeric_scale: number | null;\n}\n\ninterface ConstraintInfo {\n\tconstraint_name: string;\n\tconstraint_type: string;\n\tcolumn_name: string;\n\tforeign_table_name: string | null;\n\tforeign_column_name: string | null;\n}\n\ninterface IndexInfo {\n\tindexname: string;\n\tindexdef: string;\n}\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\t) as exists\n\t`;\n\tconst { rows: tableExistsRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableExistsRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get column information\n\tconst columnsQuery = `\n\t\tSELECT \n\t\t\tcolumn_name,\n\t\t\tdata_type,\n\t\t\tudt_name,\n\t\t\tis_nullable,\n\t\t\tcolumn_default,\n\t\t\tcharacter_maximum_length,\n\t\t\tnumeric_precision,\n\t\t\tnumeric_scale\n\t\tFROM information_schema.columns\n\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\tORDER BY ordinal_position\n\t`;\n\tconst { rows: columns } = await pool.query<ColumnInfo>(columnsQuery, [tableName]);\n\n\t// Get constraints (primary keys, foreign keys, unique)\n\tconst constraintsQuery = `\n\t\tSELECT \n\t\t\ttc.constraint_name,\n\t\t\ttc.constraint_type,\n\t\t\tkcu.column_name,\n\t\t\tccu.table_name AS foreign_table_name,\n\t\t\tccu.column_name AS foreign_column_name\n\t\tFROM information_schema.table_constraints tc\n\t\tJOIN information_schema.key_column_usage kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tLEFT JOIN information_schema.constraint_column_usage ccu\n\t\t\tON tc.constraint_name = ccu.constraint_name\n\t\t\tAND tc.table_schema = ccu.table_schema\n\t\t\tAND tc.constraint_type = 'FOREIGN KEY'\n\t\tWHERE tc.table_schema = 'public' AND tc.table_name = $1\n\t\tORDER BY tc.constraint_type, tc.constraint_name\n\t`;\n\tconst { rows: constraints } = await pool.query<ConstraintInfo>(constraintsQuery, [\n\t\ttableName,\n\t]);\n\n\t// Get indexes (excluding primary key indexes which are auto-created)\n\tconst indexesQuery = `\n\t\tSELECT indexname, indexdef\n\t\tFROM pg_indexes\n\t\tWHERE schemaname = 'public' AND tablename = $1\n\t\tAND indexname NOT IN (\n\t\t\tSELECT constraint_name \n\t\t\tFROM information_schema.table_constraints \n\t\t\tWHERE table_schema = 'public' AND table_name = $1 AND constraint_type = 'PRIMARY KEY'\n\t\t)\n\t`;\n\tconst { rows: indexes } = await pool.query<IndexInfo>(indexesQuery, [tableName]);\n\n\t// Build the CREATE TABLE statement\n\tconst schemaLines: string[] = [];\n\tschemaLines.push(`create table public.${tableName} (`);\n\n\t// Add columns\n\tconst columnDefs: string[] = [];\n\tfor (const col of columns) {\n\t\tlet colDef = ` ${col.column_name} ${formatDataType(col)}`;\n\n\t\tif (col.is_nullable === \"NO\") {\n\t\t\tcolDef += \" not null\";\n\t\t}\n\n\t\tif (col.column_default !== null) {\n\t\t\tcolDef += ` default ${col.column_default}`;\n\t\t}\n\n\t\tcolumnDefs.push(colDef);\n\t}\n\n\t// Group constraints by name to handle composite keys\n\tconst constraintMap = new Map<string, ConstraintInfo[]>();\n\tfor (const constraint of constraints) {\n\t\tconst existing = constraintMap.get(constraint.constraint_name) || [];\n\t\texisting.push(constraint);\n\t\tconstraintMap.set(constraint.constraint_name, existing);\n\t}\n\n\t// Add constraints\n\tconst constraintDefs: string[] = [];\n\tfor (const [constraintName, constraintColumns] of constraintMap) {\n\t\tconst firstConstraint = constraintColumns[0];\n\t\tconst columnNames = constraintColumns.map((c) => c.column_name).join(\", \");\n\n\t\tif (firstConstraint.constraint_type === \"PRIMARY KEY\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} primary key (${columnNames})`);\n\t\t} else if (firstConstraint.constraint_type === \"FOREIGN KEY\") {\n\t\t\tconst foreignTable = firstConstraint.foreign_table_name;\n\t\t\tconst foreignColumn = firstConstraint.foreign_column_name;\n\t\t\tconstraintDefs.push(\n\t\t\t\t` constraint ${constraintName} foreign key (${columnNames}) references ${foreignTable} (${foreignColumn})`,\n\t\t\t);\n\t\t} else if (firstConstraint.constraint_type === \"UNIQUE\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} unique (${columnNames})`);\n\t\t}\n\t}\n\n\t// Combine column and constraint definitions\n\tconst allDefs = [...columnDefs, ...constraintDefs];\n\tschemaLines.push(allDefs.join(\",\\n\"));\n\n\tschemaLines.push(\") tablespace pg_default;\");\n\n\t// Add indexes as separate statements\n\tfor (const index of indexes) {\n\t\t// Skip unique indexes that are already covered by unique constraints\n\t\tconst isUniqueConstraint = Array.from(constraintMap.values()).some(\n\t\t\t(c) => c[0].constraint_type === \"UNIQUE\" && c[0].constraint_name === index.indexname,\n\t\t);\n\t\tif (!isUniqueConstraint) {\n\t\t\tschemaLines.push(\"\");\n\t\t\tschemaLines.push(`${index.indexdef};`);\n\t\t}\n\t}\n\n\treturn schemaLines.join(\"\\n\");\n}\n\nfunction formatDataType(col: ColumnInfo): string {\n\tconst { data_type, udt_name, character_maximum_length, numeric_precision, numeric_scale } =\n\t\tcol;\n\n\t// Handle user-defined types (enums)\n\tif (data_type === \"USER-DEFINED\") {\n\t\treturn udt_name;\n\t}\n\n\t// Handle array types\n\tif (data_type === \"ARRAY\") {\n\t\treturn `${udt_name.replace(/^_/, \"\")}[]`;\n\t}\n\n\t// Handle character types with length\n\tif (\n\t\t(data_type === \"character varying\" || data_type === \"varchar\") &&\n\t\tcharacter_maximum_length\n\t) {\n\t\treturn `varchar(${character_maximum_length})`;\n\t}\n\n\tif (data_type === \"character\" && character_maximum_length) {\n\t\treturn `char(${character_maximum_length})`;\n\t}\n\n\t// Handle numeric with precision and scale\n\tif (data_type === \"numeric\" && numeric_precision !== null) {\n\t\tif (numeric_scale !== null && numeric_scale > 0) {\n\t\t\treturn `numeric(${numeric_precision}, ${numeric_scale})`;\n\t\t}\n\t\treturn `numeric(${numeric_precision})`;\n\t}\n\n\t// Handle timestamp types\n\tif (data_type === \"timestamp with time zone\") {\n\t\treturn \"timestamp with time zone\";\n\t}\n\n\tif (data_type === \"timestamp without time zone\") {\n\t\treturn \"timestamp\";\n\t}\n\n\t// Map common data types\n\tconst typeMap: Record<string, string> = {\n\t\t\"character varying\": \"varchar\",\n\t\tcharacter: \"char\",\n\t\t\"double precision\": \"float8\",\n\t\tinteger: \"integer\",\n\t\tbigint: \"bigint\",\n\t\tsmallint: \"smallint\",\n\t\tboolean: \"boolean\",\n\t\ttext: \"text\",\n\t\tuuid: \"uuid\",\n\t\tjson: \"json\",\n\t\tjsonb: \"jsonb\",\n\t\tdate: \"date\",\n\t\ttime: \"time\",\n\t\tbytea: \"bytea\",\n\t};\n\n\treturn typeMap[data_type] || data_type;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\nexport function buildWhereClause(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst paramIndex = values.length + 1;\n\t\tconst columnName = `\"${filter.columnName}\"`;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\t// Handle NULL values\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\t\tconditions.push(`${columnName}::text LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\t\tconditions.push(`${columnName}::text NOT LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"ilike\":\n\t\t\t\tconditions.push(`${columnName}::text ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName}::text NOT ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Unknown operator, skip\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\nexport function buildSortClause(sorts: SortType[] | string, order: SortDirection): string {\n\t// Handle array of Sort objects (new format for referenced tables)\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\"${sort.columnName}\" ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\t// Handle legacy format (string column name + order)\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \"${sorts}\" ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\nexport function buildCursorWhereClause(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n\tstartParamIndex: number,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\t// Determine comparison operator based on direction and sort order\n\t// Forward + ASC = >, Forward + DESC = <\n\t// Backward + ASC = <, Backward + DESC = >\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\t// Build row comparison for multi-column cursor\n\t// Uses tuple comparison: (col1, col2, ...) > (val1, val2, ...)\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\"${col}\"`).join(\", \");\n\t\tconst placeholders = sortColumns.map((_, i) => `$${startParamIndex + i}`).join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClause,\n\tbuildSortClause,\n\tbuildWhereClause,\n} from \"@/utils/build-clauses.js\";\n\n// Encode cursor data to base64 string\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\n// Decode base64 cursor string to cursor data\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n// Get primary key column(s) for a table\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getDbPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\t// Quote the table name to preserve case sensitivity in PostgreSQL\n\tconst quotedTableName = `\"${tableName}\"`;\n\tconst result = await pool.query(\n\t\t`SELECT a.attname as column_name\n\t\t FROM pg_index i\n\t\t JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n\t\t WHERE i.indrelid = $1::regclass AND i.indisprimary\n\t\t ORDER BY array_position(i.indkey, a.attnum)`,\n\t\t[quotedTableName],\n\t);\n\treturn result.rows.map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getDbPool(db);\n\n\t// Get primary key columns for stable cursor pagination\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\t// Determine sort columns - use provided sort or fall back to primary key\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\t// Always include primary key columns for stable pagination\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// If no sort columns and no primary key, fall back to ctid (PostgreSQL internal row id)\n\tif (cursorColumns.length === 0) {\n\t\tcursorColumns.push(\"ctid\");\n\t}\n\t// Build filter WHERE clause\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClause(filters);\n\t// Build cursor WHERE clause if cursor is provided\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClause(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t\tfilterValues.length + 1,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\t// Combine WHERE clauses\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\t// Remove \"WHERE \" prefix from filterWhereClause and combine\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\t// Build sort clause\n\tconst sortClause = buildSortClause(Array.isArray(sort) ? sort : sort, order);\n\n\t// For backward pagination, reverse the sort order\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else {\n\t\t\t// Default sort by cursor columns in reverse\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\"${col}\" ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\t// Default sort by cursor columns\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\"${col}\" ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\t// Get total count (with filters only, not cursor)\n\tconst countRes = await pool.query(\n\t\t`SELECT COUNT(*) as total FROM \"${tableName}\" ${filterWhereClause}`,\n\t\tfilterValues,\n\t);\n\tconst totalRows = Number(countRes.rows[0].total);\n\t// Fetch one extra row to determine if there are more results\n\tconst limitParamIndex = filterValues.length + cursorValues.length + 1;\n\tconst dataRes = await pool.query(\n\t\t`SELECT * FROM \"${tableName}\" ${combinedWhereClause} ${effectiveSortClause} LIMIT $${limitParamIndex}`,\n\t\t[...filterValues, ...cursorValues, limit + 1],\n\t);\n\t// Check if table has columns\n\tconst hasColumns = dataRes.fields && dataRes.fields.length > 0;\n\t// Filter out empty objects\n\tlet rows = hasColumns\n\t\t? dataRes.rows.filter((row) => Object.keys(row).length > 0)\n\t\t: dataRes.rows;\n\t// Determine if there are more results\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\t// For backward pagination, reverse the results to maintain correct order\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\t// Build cursors for next/previous pages\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\tif (rows.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\t\t// Create cursor from row values\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\t\t// For forward pagination\n\t\tif (direction === \"asc\") {\n\t\t\t// Next cursor: if there are more results, encode the last row\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if we used a cursor to get here, encode the first row\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\t// For backward pagination\n\t\t\t// Next cursor: if we used a cursor, encode the last row (to go forward again)\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if there are more results going backward, encode the first row\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import type { CellValue, FormatType } from \"shared/types\";\nimport { utils, write } from \"xlsx\";\n\ninterface ExportFileOptions {\n\tcols: string[];\n\trows: Record<string, CellValue>[];\n\tformat: FormatType;\n\ttableName: string;\n}\n\n/**\n * Converts table data to the specified export format (CSV, XLSX, or JSON)\n *\n * @param options - The export options\n * @param options.cols - Array of column names\n * @param options.rows - Array of row data objects\n * @param options.format - The export format ('csv', 'xlsx', or 'json')\n * @param options.tableName - The name of the table being exported\n * @returns The file content as a Uint8Array\n */\nexport function getExportFile({ cols, rows, format, tableName }: ExportFileOptions): BodyInit {\n\tswitch (format) {\n\t\tcase \"json\": {\n\t\t\tconst jsonContent = JSON.stringify(rows ?? [], null, 2);\n\t\t\treturn new Uint8Array(Buffer.from(jsonContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"csv\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst csvContent = utils.sheet_to_csv(worksheet);\n\t\t\treturn new Uint8Array(Buffer.from(csvContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"xlsx\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst workbook = utils.book_new();\n\t\t\tutils.book_append_sheet(workbook, worksheet, tableName.slice(0, 31));\n\t\t\tconst buffer = write(workbook, {\n\t\t\t\tbookType: \"xlsx\",\n\t\t\t\ttype: \"buffer\",\n\t\t\t}) as Buffer;\n\t\t\treturn new Uint8Array(buffer);\n\t\t}\n\t}\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\ttype ColumnInfoSchemaType,\n\tcreateTableSchema,\n\ttype DeleteTableResult,\n\tdatabaseSchema,\n\tdeleteColumnParamSchema,\n\tdeleteColumnQuerySchema,\n\tdeleteTableQuerySchema,\n\texportTableSchema,\n\ttype TableDataResultSchemaType,\n\ttype TableInfoSchemaType,\n\ttype TableSchemaResult,\n\ttableDataQuerySchema,\n\ttableNameSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { createTable as pgCreateTable } from \"@/dao/create-table.dao.js\";\nimport { deleteColumn as pgDeleteColumn } from \"@/dao/delete-column.dao.js\";\nimport { deleteTable as pgDeleteTable } from \"@/dao/delete-table.dao.js\";\nimport { exportTableData as pgExportTableData } from \"@/dao/export-table.dao.js\";\nimport { createTable as mysqlCreateTable } from \"@/dao/mysql/create-table.mysql.dao.js\";\nimport { deleteColumn as mysqlDeleteColumn } from \"@/dao/mysql/delete-column.mysql.dao.js\";\nimport { deleteTable as mysqlDeleteTable } from \"@/dao/mysql/delete-table.mysql.dao.js\";\nimport { exportTableData as mysqlExportTableData } from \"@/dao/mysql/export-table.mysql.dao.js\";\nimport { getTableColumns as mysqlGetTableColumns } from \"@/dao/mysql/table-columns.mysql.dao.js\";\nimport { getTablesList as mysqlGetTablesList } from \"@/dao/mysql/table-list.mysql.dao.js\";\nimport { getTableSchema as mysqlGetTableSchema } from \"@/dao/mysql/table-schema.mysql.dao.js\";\nimport { getTableData as mysqlGetTableData } from \"@/dao/mysql/tables-data.mysql.dao.js\";\nimport { getTableColumns as pgGetTableColumns } from \"@/dao/table-columns.dao.js\";\nimport { getTablesList as pgGetTablesList } from \"@/dao/table-list.dao.js\";\nimport { getTableSchema as pgGetTableSchema } from \"@/dao/table-schema.dao.js\";\nimport { getTableData as pgGetTableData } from \"@/dao/tables-data.dao.js\";\nimport { getExportFile } from \"@/utils/get-export-file.js\";\n\nexport const tablesRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/tables/...\n\t */\n\t.basePath(\"/tables\")\n\n\t/**\n\t * GET /tables\n\t * Returns list of all tables in the currently connected database\n\t */\n\t.get(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tasync (c): ApiHandler<TableInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst tablesList =\n\t\t\t\tdbType === \"mysql\" ? await mysqlGetTablesList(db) : await pgGetTablesList(db);\n\t\t\treturn c.json({ data: tablesList }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /tables\n\t * Creates a new table in the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", createTableSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlCreateTable({ tableData: body, db });\n\t\t\t} else {\n\t\t\t\tawait pgCreateTable({ tableData: body, db });\n\t\t\t}\n\t\t\treturn c.json({ data: `Table ${body.tableName} created successfully` }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName\n\t * Deletes a table from the database\n\t */\n\t.delete(\n\t\t\"/:tableName\",\n\t\tzValidator(\"query\", deleteTableQuerySchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<DeleteTableResult> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst result =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlDeleteTable({ tableName, db, cascade })\n\t\t\t\t\t: await pgDeleteTable({ tableName, db, cascade });\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName/columns/:columnName\n\t * Deletes a column from a table\n\t */\n\t.delete(\n\t\t\"/:tableName/columns/:columnName\",\n\t\tzValidator(\"query\", deleteColumnQuerySchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { deletedCount } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlDeleteColumn({ tableName, columnName, cascade, db })\n\t\t\t\t\t: await pgDeleteColumn({ tableName, columnName, cascade, db });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" deleted successfully from table \"${tableName}\" with ${deletedCount} rows deleted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/columns\n\t * Returns list of all columns in a table\n\t */\n\t.get(\n\t\t\"/:tableName/columns\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<ColumnInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst columns =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlGetTableColumns({ tableName, db })\n\t\t\t\t\t: await pgGetTableColumns({ tableName, db });\n\t\t\treturn c.json({ data: columns }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/schema\n\t * Returns the CREATE TABLE schema for a table\n\t */\n\t.get(\n\t\t\"/:tableName/schema\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<TableSchemaResult> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst schema =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlGetTableSchema({ tableName, db })\n\t\t\t\t\t: await pgGetTableSchema({ tableName, db });\n\t\t\treturn c.json({ data: { schema } }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/data\n\t * Get cursor-paginated data for a table\n\t */\n\t.get(\n\t\t\"/:tableName/data\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", tableDataQuerySchema),\n\t\tasync (c): ApiHandler<TableDataResultSchemaType> => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { cursor, limit, direction, sort, order, filters, db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst tableData =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlGetTableData({\n\t\t\t\t\t\t\ttableName,\n\t\t\t\t\t\t\tcursor,\n\t\t\t\t\t\t\tlimit,\n\t\t\t\t\t\t\tdirection,\n\t\t\t\t\t\t\tsort,\n\t\t\t\t\t\t\torder,\n\t\t\t\t\t\t\tfilters,\n\t\t\t\t\t\t\tdb,\n\t\t\t\t\t\t})\n\t\t\t\t\t: await pgGetTableData({\n\t\t\t\t\t\t\ttableName,\n\t\t\t\t\t\t\tcursor,\n\t\t\t\t\t\t\tlimit,\n\t\t\t\t\t\t\tdirection,\n\t\t\t\t\t\t\tsort,\n\t\t\t\t\t\t\torder,\n\t\t\t\t\t\t\tfilters,\n\t\t\t\t\t\t\tdb,\n\t\t\t\t\t\t});\n\t\t\treturn c.json({ data: tableData }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/export\n\t * Export table data to CSV or XLSX format\n\t */\n\t.get(\n\t\t\"/:tableName/export\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", exportTableSchema),\n\t\tasync (c) => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { db, format } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tconst { cols, rows } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlExportTableData({ tableName, db })\n\t\t\t\t\t: await pgExportTableData({ tableName, db });\n\t\t\tconst fileContent = getExportFile({ cols, rows, format, tableName });\n\t\t\tlet contentType: string | undefined;\n\n\t\t\tswitch (format) {\n\t\t\t\tcase \"csv\":\n\t\t\t\t\tcontentType = \"text/csv\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"xlsx\":\n\t\t\t\t\tcontentType = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"json\":\n\t\t\t\t\tcontentType = \"application/json\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn new Response(fileContent, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": contentType ?? \"\",\n\t\t\t\t\t\"Content-Disposition\": `attachment; filename=\"${tableName}_export.${format}\"`,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t);\n\nexport type TablesRoutes = typeof tablesRoutes.routes;\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { logger } from \"hono/logger\";\nimport { prettyJSON } from \"hono/pretty-json\";\nimport { type DatabaseTypeSchema, databaseTypeParamSchema } from \"shared/types\";\nimport type { AppType } from \"@/app.types.js\";\nimport { handleError, validationHook } from \"@/middlewares/error-handler.js\";\nimport { chatRoutes } from \"@/routes/chat.routes.js\";\nimport { databasesRoutes } from \"@/routes/databases.routes.js\";\nimport { queryRoutes } from \"@/routes/query.routes.js\";\nimport { recordsRoutes } from \"@/routes/records.routes.js\";\nimport { tablesRoutes } from \"@/routes/tables.routes.js\";\n\n/**\n * Get the path to the core distribution directory.\n */\nconst getCoreDistPath = () => {\n\tif (process.env.NODE_ENV === \"development\") {\n\t\treturn path.resolve(process.cwd(), \"../core/dist\");\n\t}\n\n\tconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\treturn path.resolve(__dirname, \"./core-dist\");\n};\n\nexport const createServer = () => {\n\tconst app = new Hono<AppType>({ strict: false })\n\t\t/**\n\t\t * Enable CORS\n\t\t */\n\t\t.use(\"/*\", cors())\n\n\t\t/**\n\t\t * Pretty print the JSON response\n\t\t */\n\t\t.use(prettyJSON({ space: 2 }))\n\n\t\t/**\n\t\t * Enable logger in development mode\n\t\t */\n\t\t.use(process.env.NODE_ENV === \"development\" ? logger() : (_, next) => next())\n\n\t\t/**\n\t\t * Serve the favicon.ico file\n\t\t */\n\t\t.use(\n\t\t\t\"/favicon.ico\",\n\t\t\tserveStatic({\n\t\t\t\tpath: path.resolve(getCoreDistPath(), \"favicon.ico\"),\n\t\t\t}),\n\t\t)\n\n\t\t/**\n\t\t * Handle CORS requests\n\t\t */\n\t\t.use(\"*\", async (c, next) => {\n\t\t\tc.header(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\tc.header(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n\t\t\tc.header(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\t\t\tawait next();\n\t\t})\n\n\t\t/**\n\t\t * Handle errors\n\t\t */\n\t\t.onError(handleError)\n\n\t\t/**\n\t\t * Database routes - available at root level (no dbType required)\n\t\t */\n\t\t.route(\"/\", databasesRoutes)\n\n\t\t/**\n\t\t * Serve static assets (before dbType validation to avoid conflicts)\n\t\t */\n\t\t.use(\"/assets/*\", serveStatic({ root: getCoreDistPath() }))\n\t\t.use(\"/image.png\", serveStatic({ root: getCoreDistPath() }))\n\n\t\t/**\n\t\t * Routes that require dbType validation - under /:dbType/...\n\t\t */\n\t\t.use(\"/:dbType/*\", zValidator(\"param\", databaseTypeParamSchema, validationHook))\n\t\t.use(\"/:dbType/*\", async (c, next) => {\n\t\t\tconst dbType = c.req.param(\"dbType\") as DatabaseTypeSchema;\n\t\t\tc.set(\"dbType\", dbType);\n\t\t\tawait next();\n\t\t})\n\t\t.route(\"/:dbType\", tablesRoutes)\n\t\t.route(\"/:dbType\", recordsRoutes)\n\t\t.route(\"/:dbType\", queryRoutes)\n\t\t.route(\"/:dbType\", chatRoutes)\n\n\t\t/**\n\t\t * Serve all other static files as fallback (for SPA)\n\t\t */\n\t\t.use(\"/*\", serveStatic({ root: getCoreDistPath() }));\n\n\treturn { app };\n};\n\nexport type { AppType };\n\n// Export the app type for hc client\nexport type AppRoutes = ReturnType<typeof createServer>[\"app\"];\n","import { intro, outro } from \"@clack/prompts\";\nimport { serve } from \"@hono/node-server\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { args } from \"@/cmd/args.js\";\nimport { getDatabaseUrl } from \"@/cmd/get-db-url.js\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\nimport { showHelp } from \"@/cmd/show-help.js\";\nimport { showStatus } from \"@/cmd/show-status.js\";\nimport { showVersion } from \"@/cmd/show-version.js\";\n\nexport const main = async () => {\n\tconst { env, port, databaseUrl, varName, status, help, version } = args();\n\n\t// Handle help flag\n\tif (help) {\n\t\tshowHelp();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle version flag\n\tif (version) {\n\t\tshowVersion();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle status flag\n\tif (status) {\n\t\tawait showStatus(env, databaseUrl, varName);\n\t\tprocess.exit(0);\n\t}\n\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst PORT = port ? parseInt(port, 10) : DEFAULTS.PORT;\n\tconst VAR_NAME = varName || DEFAULTS.VAR_NAME;\n\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\tconst DATABASE_URL = databaseUrl ? databaseUrl : await getDatabaseUrl(ENV, VAR_NAME);\n\n\t// Set DATABASE_URL in process.env before importing createServer\n\t// This ensures the db pool is initialized with the correct connection string\n\tprocess.env.DATABASE_URL = DATABASE_URL;\n\n\t// Import createServer dynamically after setting DATABASE_URL\n\tconst { createServer } = await import(\"./utils/create-server.js\");\n\tconst { app } = createServer();\n\tserve({\n\t\tfetch: app.fetch,\n\t\tport: PORT,\n\t});\n\n\toutro(color.green(`Server running at ${color.cyan(`http://localhost:${PORT}`)}`));\n};\n\nmain().catch((err) => {\n\tconsole.error(color.red(`❌ Unexpected error: ${err.message}`));\n\tprocess.exit(1);\n});\n","import { program } from \"commander\";\nimport type { Args } from \"shared/types\";\n\n/**\n * Get the arguments from the command line\n */\nexport const args = () => {\n\tprogram\n\t\t.name(\"db-studio\")\n\t\t.option(\"-e, --env <path>\", \"Path to custom .env file\")\n\t\t.option(\"-p, --port <port>\", \"Port to run the server on\")\n\t\t.option(\"-d, --database-url <url>\", \"Database URL to use\")\n\t\t.option(\n\t\t\t\"-n, --var-name <name>\",\n\t\t\t\"Custom environment variable name (default: DATABASE_URL)\",\n\t\t)\n\t\t.option(\"-s, --status\", \"Show status of the server\")\n\t\t.option(\"-h, --help\", \"Show help\")\n\t\t.option(\"-v, --version\", \"Show version\")\n\t\t.parse(process.argv);\n\n\treturn program.opts<Args>();\n};\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { cancel, isCancel, note, select, spinner, text } from \"@clack/prompts\";\nimport { type DotenvParseOutput, parse as parseDotenv } from \"dotenv\";\nimport color from \"picocolors\";\n\n/**\n * Get the database URL from .env file, then process.env\n */\nexport const getDatabaseUrl = async (env?: DotenvParseOutput | null, varName?: string) => {\n\tconst envVarName = varName || \"DATABASE_URL\";\n\n\tif (env?.[envVarName]) {\n\t\treturn env[envVarName];\n\t}\n\n\t// Fall back to process.env (e.g. from shell or package.json script)\n\tif (process.env[envVarName]) {\n\t\treturn process.env[envVarName];\n\t}\n\n\tconst s = spinner();\n\ts.start(\"Looking for database connection...\");\n\n\tif (!env) {\n\t\tnote(color.red(`No .env file found and ${envVarName} not set in process.env`));\n\t} else {\n\t\tnote(color.red(`${envVarName} not found in .env or process.env`));\n\t}\n\n\tconst choice = await select({\n\t\tmessage: `How do you want to provide ${envVarName}?`,\n\t\toptions: [\n\t\t\t{ value: \"manual\", label: \"Enter connection string manually\" },\n\t\t\t{ value: \"other-env\", label: \"Use different .env file\" },\n\t\t\t// todo: add multiple db connections support\n\t\t\t{ value: \"cancel\", label: \"Cancel / Exit\" },\n\t\t],\n\t\tinitialValue: \"manual\",\n\t});\n\tif (isCancel(choice) || choice === \"cancel\") {\n\t\tcancel(\"No database connection provided. Exiting...\");\n\t\tprocess.exit(0);\n\t}\n\n\tif (choice === \"other-env\") {\n\t\ts.start(\"Waiting for path...\");\n\t\tconst customPath = await text({\n\t\t\tmessage: \"Enter path to .env file\",\n\t\t\tplaceholder: \"~/projects/myapp/.env.local or ./special.env\",\n\t\t\tvalidate(value?: string) {\n\t\t\t\tif (!value?.trim()) return \"Path is required\";\n\t\t\t},\n\t\t});\n\n\t\tif (isCancel(customPath)) {\n\t\t\tcancel(\"Cancelled.\");\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\ts.stop(\"Trying custom .env...\");\n\n\t\tconst customEnvPath = resolve(customPath);\n\t\ttry {\n\t\t\tconst content = await readFile(customEnvPath, \"utf-8\");\n\t\t\tconst parsed = parseDotenv(content);\n\t\t\tif (parsed[envVarName]) {\n\t\t\t\treturn parsed[envVarName];\n\t\t\t}\n\t\t\tthrow new Error(`${envVarName} still missing in custom file`);\n\t\t} catch (e: unknown) {\n\t\t\tconst error = e as Error;\n\t\t\tcancel(`Cannot read or parse file: ${color.dim(error.message)}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// 3. Manual input\n\ts.stop(\"Manual input...\");\n\n\tconst dbUrl = await text({\n\t\tmessage: `Paste your ${envVarName}`,\n\t\tplaceholder: \"postgresql://user:password@localhost:5432/mydb\",\n\t\tvalidate(value?: string) {\n\t\t\tif (!value?.trim()) return \"Connection string is required!\";\n\t\t\ttry {\n\t\t\t\tnew URL(value); // very basic check\n\t\t\t\treturn undefined;\n\t\t\t} catch {\n\t\t\t\treturn \"Must be a valid URL format\";\n\t\t\t}\n\t\t},\n\t});\n\n\tif (isCancel(dbUrl)) {\n\t\tcancel(\"Cancelled.\");\n\t\tprocess.exit(0);\n\t}\n\n\treturn dbUrl.trim();\n};\n","import { access, readFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport { parse as parseDotenv } from \"dotenv\";\n\n/**\n * Find .env path: try cwd, then walk up parent directories until root.\n */\nconst findEnvPath = async (startDir: string): Promise<string | null> => {\n\tlet dir = resolve(startDir);\n\tfor (;;) {\n\t\tconst envPath = resolve(dir, \".env\");\n\t\ttry {\n\t\t\tawait access(envPath);\n\t\t\treturn envPath;\n\t\t} catch {\n\t\t\t// ENOENT or other: try parent\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n};\n\n/**\n * Load the environment variables from the file.\n * When no path is given: tries current directory, then parent directories until a .env is found.\n * When --env path is given: uses that path only (no walk).\n */\nexport const loadEnv = async (env?: string) => {\n\tlet envPath: string | null;\n\n\tif (env) {\n\t\tenvPath = resolve(env);\n\t} else {\n\t\tenvPath = await findEnvPath(process.cwd());\n\t}\n\n\tif (!envPath) return null;\n\n\ttry {\n\t\tconst content = await readFile(envPath, \"utf-8\");\n\t\treturn parseDotenv(content);\n\t} catch (err) {\n\t\tif (err instanceof Error && err.message.includes(\"ENOENT\")) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow err;\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { META } from \"shared/constants/meta.js\";\n\n/**\n * Display help information\n */\nexport const showHelp = () => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconsole.log(color.bold(\"\\nUsage:\"));\n\tconsole.log(\" db-studio [options]\\n\");\n\n\tconsole.log(color.bold(\"Supported Databases:\"));\n\tconsole.log(\" MySQL, PostgreSQL\\n\");\n\n\tconsole.log(color.bold(\"Options:\"));\n\tconsole.log(\" -e, --env <path> Path to custom .env file\");\n\tconsole.log(\" -p, --port <port> Port to run the server on (default: 3333)\");\n\tconsole.log(\" -d, --database-url <url> Database URL to use\");\n\tconsole.log(\n\t\t\" -n, --var-name <name> Custom environment variable name (default: DATABASE_URL)\",\n\t);\n\tconsole.log(\" -s, --status Show status of the database connection\");\n\tconsole.log(\" -h, --help Show this help message\");\n\tconsole.log(\" -v, --version Show version number\\n\");\n\n\tconsole.log(color.bold(\"Examples:\"));\n\tconsole.log(\" db-studio\");\n\tconsole.log(\" db-studio -e .env.local\");\n\tconsole.log(\" db-studio -p 4000\");\n\tconsole.log(\" db-studio -d postgresql://user:pass@localhost:5432/mydb\");\n\tconsole.log(\" db-studio -n MY_DATABASE_URL\");\n\tconsole.log(\" db-studio -e .env.production -n PROD_DB_URL\");\n\tconsole.log(\" db-studio --status\\n\");\n\n\toutro(color.green(`For more information, visit: ${META.SITE_DOCS_LINK}`));\n};\n","import { intro, note, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\n\n/**\n * Show connection status\n */\nexport const showStatus = async (env?: string, databaseUrl?: string, varName?: string) => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst envVarName = varName || DEFAULTS.VAR_NAME;\n\tlet foundUrl: string | null = null;\n\n\t// Check if DATABASE_URL is provided via CLI\n\tif (databaseUrl) {\n\t\tfoundUrl = databaseUrl;\n\t} else {\n\t\t// Try .env file, then process.env\n\t\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\t\tif (ENV?.[envVarName]) {\n\t\t\tfoundUrl = ENV[envVarName];\n\t\t} else if (process.env[envVarName]) {\n\t\t\tfoundUrl = process.env[envVarName] ?? null;\n\t\t}\n\t}\n\n\tif (foundUrl) {\n\t\toutro(color.green(`✓ Database connection configured (using ${envVarName})`));\n\t} else {\n\t\tnote(color.red(`✗ ${envVarName} not found`), \"Status\");\n\t\tconsole.log(color.yellow(\"\\n To configure database connection:\"));\n\t\tconsole.log(color.dim(\" • Supported databases: MySQL, PostgreSQL\"));\n\t\tconsole.log(color.dim(` • Add ${envVarName} to your .env file or set it in process.env`));\n\t\tconsole.log(color.dim(\" • Use -d flag: db-studio -d <url>\"));\n\t\tconsole.log(color.dim(\" • Use -e flag: db-studio -e <path-to-env>\"));\n\t\tconsole.log(color.dim(\" • Use -n flag: db-studio -n <var-name>\\n\"));\n\n\t\toutro(color.yellow(\"⚠ No database connection configured\"));\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\n/**\n * Display version information\n */\nexport const showVersion = () => {\n\tintro(color.inverse(\" db-studio \"));\n\toutro(color.green(`🚀 db-studio v${packageJson.version}`));\n};\n","{\n \"name\": \"db-studio\",\n \"type\": \"module\",\n \"version\": \"1.4.0\",\n \"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.\",\n \"keywords\": [\n \"database\",\n \"database client\",\n \"postgres\",\n \"postgresql\",\n \"database gui\",\n \"sql client\",\n \"database studio\",\n \"postgres gui\",\n \"ai sql\",\n \"sql editor\",\n \"er diagram\",\n \"database management\",\n \"data browser\",\n \"spreadsheet database\",\n \"postgres admin\",\n \"mysql client\",\n \"sqlite client\",\n \"database tool\",\n \"developer tools\"\n ],\n \"author\": \"Hüsam 🥑 <devhsmq@gmail.com>\",\n \"homepage\": \"https://dbstudio.sh\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/husamql3/db-studio.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/husamql3/db-studio/issues\"\n },\n \"license\": \"MIT\",\n \"bin\": {\n \"db-studio\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"NODE_ENV=development tsx watch src/index.ts\",\n \"build\": \"tsup --minify --sourcemap\",\n \"prepack\": \"cd ../core && bun run build && cd ../server && bun run build\",\n \"start\": \"node dist/index.js\",\n \"check\": \"biome check --write --unsafe\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.0.1\",\n \"@hono/node-server\": \"^1.19.7\",\n \"@hono/zod-validator\": \"^0.7.6\",\n \"commander\": \"^14.0.3\",\n \"dotenv\": \"^17.3.1\",\n \"hono\": \"^4.10.4\",\n \"mysql2\": \"^3.18.2\",\n \"pg\": \"^8.13.1\",\n \"picocolors\": \"^1.1.1\",\n \"xlsx\": \"^0.18.5\",\n \"zod\": \"^4.2.1\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.2.6\",\n \"@types/node\": \"^20.11.17\",\n \"@types/pg\": \"^8.16.0\",\n \"@vitest/coverage-v8\": \"^4.0.17\",\n \"shared\": \"workspace:*\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.7.1\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"^4.0.17\"\n }\n}"],"mappings":"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","names":["init_chat","__esmMin","init_column_types_mysql","__esmMin","init_column_types_pgsql","__esmMin","DEFAULTS","init_defaults","__esmMin","init_links","__esmMin","META","init_meta","__esmMin","init_proxy_limits","__esmMin","init_constants","__esmMin","init_chat","init_column_types_mysql","init_column_types_pgsql","init_defaults","init_links","init_meta","init_proxy_limits","z","addRecordSchema","init_add_record_types","__esmMin","init_api_response_types","__esmMin","z","bulkInsertRecordsSchema","init_bulk_insert_records_type","__esmMin","z","databaseSchema","DATABASE_TYPES","databaseTypeSchema","currentDatabaseSchema","databaseTypeParamSchema","tableNameSchema","init_database_types","__esmMin","z","chatSchema","init_chat_types","__esmMin","init_database_types","databaseSchema","init_cmd_args_types","__esmMin","z","dataTypes","dataTypesSchema","DataTypes","standardizedDataTypes","standardizedDataTypeSchema","columnInfoSchema","init_column_info_types","__esmMin","mapPostgresToDataType","pgType","normalized","DataTypes","standardizeDataTypeLabel","StandardizedDataType","mapMysqlToDataType","mysqlDataType","columnType","fullType","standardizeMysqlDataTypeLabel","init_column_type","__esmMin","init_column_info_types","z","FOREIGN_KEY_ACTIONS","foreignKeyActionSchema","fieldDataSchema","foreignKeyDataSchema","createTableSchema","init_create_table_types","__esmMin","z","databaseInfoSchema","databaseListSchema","connectionInfoSchema","init_database_list_types","__esmMin","init_database_types","databaseTypeSchema","init_database_schema_type","__esmMin","z","deleteColumnQuerySchema","deleteColumnParamSchema","deleteColumnParamsSchema","deleteColumnSuccessResponseSchema","init_delete_column_types","__esmMin","init_database_types","databaseSchema","val","z","deleteRecordSchema","init_delete_record_types","__esmMin","z","deleteTableQuerySchema","init_delete_table_types","__esmMin","init_database_types","databaseSchema","val","z","executeQuerySchema","init_execute_query_types","__esmMin","z","FORMAT_TYPES","exportTableSchema","init_export_table_types","__esmMin","init_database_types","databaseSchema","init_rate_limit_response_type","__esmMin","z","filterSchema","sortDirections","sortSchema","tableDataMetaSchema","tableDataResultSchema","tableDataQuerySchema","init_table_data_types","__esmMin","init_database_types","databaseSchema","val","parsed","z","tableInfoSchema","init_table_info_type","__esmMin","z","tableSchemaResultSchema","init_table_schema_types","__esmMin","z","updateRecordsSchema","init_update_recors_types","__esmMin","init_types","__esmMin","init_add_record_types","init_api_response_types","init_bulk_insert_records_type","init_chat_types","init_cmd_args_types","init_column_type","init_column_info_types","init_create_table_types","init_database_types","init_database_list_types","init_database_schema_type","init_delete_column_types","init_delete_record_types","init_delete_table_types","init_execute_query_types","init_export_table_types","init_rate_limit_response_type","init_table_data_types","init_table_info_type","init_table_schema_types","init_update_recors_types","HTTPException","DatabaseError","ZodError","handleError","e","c","issue","mysqlError","validationHook","init_error_handler","__esmMin","result","Pool","dbInstance","getPool","db","init_db","__esmMin","err","error","_target","prop","createMysqlPool","Pool","DatabaseManager","databaseManager","getDbPool","getMysqlPool","getDbType","init_db_manager","__esmMin","url","protocol","databaseUrl","error","database","connectionString","poolConfig","pool","err","dbName","pgClosePromises","mysqlClosePromises","HTTPException","getTableColumns","tableName","db","pool","getDbPool","query","rows","r","parsedEnumValues","mapPostgresToDataType","standardizeDataTypeLabel","init_table_columns_dao","__esmMin","init_types","init_db_manager","getTableNames","db","pool","getDbPool","query","rows","getTableDescription","tableName","client","getSampleData","convertColumnInfo","col","column","extractRelationships","tables","relationships","table","toTable","toColumn","getDatabaseSchema","options","includeSampleData","includeDescriptions","tablePromises","columns","description","sampleData","getTableColumns","row","key","value","error","getDetailedSchema","init_table_details_schema","__esmMin","init_db","init_db_manager","init_table_columns_dao","generateSystemPrompt","schema","formatSchemaForPrompt","output","table","col","pkIndicator","fkIndicator","nullable","rel","init_system_prompt_generator","__esmMin","zValidator","Hono","chatRoutes","init_chat_routes","__esmMin","init_constants","init_types","init_table_details_schema","init_system_prompt_generator","chatSchema","c","messages","conversationId","db","schema","getDetailedSchema","systemPrompt","generateSystemPrompt","payload","proxyResponse","DEFAULTS","errorData","readable","writable","parseDatabaseUrl","databaseUrl","url","init_parse_database_url","__esmMin","HTTPException","getDatabasesList","pool","getDbPool","query","rows","getCurrentDatabase","getDatabaseConnectionInfo","result","connectionInfoSchema","urlDefaults","parseDatabaseUrl","init_database_list_dao","__esmMin","init_types","init_db_manager","init_parse_database_url","HTTPException","getDatabasesList","pool","getMysqlPool","rows","getCurrentDatabase","getDatabaseConnectionInfo","infoRows","connRows","info","activeConnections","urlDefaults","parseDatabaseUrl","init_database_list_mysql_dao","__esmMin","init_db_manager","init_parse_database_url","Hono","databasesRoutes","init_databases_routes","__esmMin","init_database_list_dao","init_database_list_mysql_dao","init_db_manager","c","dbType","getDbType","databases","getDatabasesList","current","getCurrentDatabase","info","getDatabaseConnectionInfo","HTTPException","executeQuery","init_query_mysql_dao","__esmMin","init_db_manager","query","db","pool","getMysqlPool","cleanedQuery","startTime","result","fields","duration","rows","dmlResult","HTTPException","executeQuery","init_query_dao","__esmMin","init_db_manager","query","db","pool","getDbPool","cleanedQuery","startTime","result","duration","field","zValidator","Hono","queryRoutes","init_query_routes","__esmMin","init_types","init_query_mysql_dao","init_query_dao","databaseSchema","executeQuerySchema","c","query","db","data","executeQuery","HTTPException","addRecord","db","params","tableName","data","pool","getDbPool","columns","values","placeholders","_","index","columnNames","col","query","result","init_add_record_dao","__esmMin","init_db_manager","HTTPException","bulkInsertRecords","init_bulk_insert_records_dao","__esmMin","init_db_manager","tableName","records","db","client","getDbPool","columns","columnNames","col","successCount","failureCount","errors","i","record","values","placeholders","_","index","insertSQL","error","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pool","constraintsByTable","constraint","key","pkValues","pk","_tableColumn","constraints","placeholders","_","i","relatedQuery","relatedResult","deleteRecords","pkColumn","query","result","error","forceDeleteRecords","totalRelatedDeleted","deletedTables","deleteRelatedRecursively","targetTable","targetColumn","values","nestedFks","nestedFk","nestedPlaceholders","selectQuery","nestedValues","deletePlaceholders","deleteQuery","deleteResult","init_delete_records_dao","__esmMin","init_db_manager","HTTPException","parseMysqlEnumValues","columnType","match","v","getTableColumns","tableName","db","pool","getMysqlPool","query","rows","r","dataType","enumValues","mapMysqlToDataType","standardizeMysqlDataTypeLabel","init_table_columns_mysql_dao","__esmMin","init_types","init_db_manager","HTTPException","addRecord","db","params","tableName","data","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","columns","values","value","index","columnName","placeholders","columnNames","query","result","init_add_record_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","bulkInsertRecords","init_bulk_insert_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","tableName","records","db","connection","getMysqlPool","columns","columnNames","col","tableColumns","getTableColumns","booleanColumns","i","record","values","value","placeholders","insertSQL","error","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pkValues","pk","constraintsByTable","constraint","key","_tableColumn","constraints","placeholders","relatedRows","deleteRecords","pkColumn","connection","result","error","MYSQL_FK_VIOLATION","forceDeleteRecords","totalRelatedDeleted","deletedTables","visited","deleteRelatedRecursively","targetTable","targetColumn","values","visitedSet","nestedFks","nestedFk","nestedPlaceholders","selectRows","nestedValues","deletePlaceholders","deleteResult","mainPlaceholders","init_delete_records_mysql_dao","__esmMin","init_db_manager","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","updatesByRow","update","pkValue","connection","totalUpdated","rowUpdates","setClauses","u","values","query","result","error","init_update_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getDbPool","updatesByRow","update","pkValue","totalUpdated","rowUpdates","setClauses","u","index","values","query","result","error","init_update_records_dao","__esmMin","init_db_manager","zValidator","Hono","recordsRoutes","init_records_routes","__esmMin","init_types","init_add_record_dao","init_bulk_insert_records_dao","init_delete_records_dao","init_add_record_mysql_dao","init_bulk_insert_records_mysql_dao","init_delete_records_mysql_dao","init_update_records_mysql_dao","init_update_records_dao","databaseSchema","addRecordSchema","c","db","tableName","data","dbType","insertedCount","addRecord","updateRecordsSchema","primaryKey","updates","updatedCount","updateRecords","deleteRecordSchema","primaryKeys","deletedCount","fkViolation","relatedRecords","deleteRecords","forceDeleteRecords","bulkInsertRecordsSchema","records","result","bulkInsertRecords","createTable","tableData","db","tableName","fields","foreignKeys","pool","getDbPool","columnDefinitions","field","columnDef","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_dao","__esmMin","init_db_manager","HTTPException","deleteColumn","params","tableName","columnName","cascade","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","dropColumnSQL","rowCount","init_delete_column_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","pool","constraint","relatedQuery","relatedResult","getTableRowCount","result","deleteTable","params","cascade","tableExistsQuery","tableRows","rowCount","dropTableSQL","error","init_delete_table_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getDbPool","rows","init_export_table_dao","__esmMin","init_db_manager","formatMysqlDefaultValue","defaultValue","columnType","trimmed","mapColumnTypeToMysql","isArray","normalized","createTable","tableData","db","tableName","fields","foreignKeys","pool","getMysqlPool","columnDefinitions","field","mappedType","columnDef","primaryKeyFields","f","constraintDefs","pkColumns","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_mysql_dao","__esmMin","init_db_manager","HTTPException","deleteColumn","params","tableName","columnName","db","pool","getMysqlPool","tableRows","columnRows","result","init_delete_column_mysql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","constraint","relatedRows","getTableRowCount","deleteTable","params","cascade","tableRows","rowCount","connection","error","mysqlError","MYSQL_FK_DEPENDENCY","MYSQL_FK_ROW_REFERENCED","init_delete_table_mysql_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getMysqlPool","rows","init_export_table_mysql_dao","__esmMin","init_db_manager","getTablesList","db","pool","getMysqlPool","tablesQuery","tables","table","countRows","countRow","init_table_list_mysql_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getMysqlPool","tableRows","rows","row","createTableSql","init_table_schema_mysql_dao","__esmMin","init_db_manager","buildWhereClauseMysql","filters","conditions","values","filter","columnName","buildSortClauseMysql","sorts","order","sort","buildCursorWhereClauseMysql","cursorData","direction","sortDirection","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","operator","init_build_clauses_mysql","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_mysql_dao","__esmMin","init_db_manager","init_build_clauses_mysql","data","cursor","pool","tableName","rows","row","limit","direction","sort","order","filters","db","getMysqlPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClauseMysql","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClauseMysql","combinedWhereClause","sortClause","buildSortClauseMysql","effectiveSortClause","col","countRows","totalRows","fetchLimit","dataRows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","HTTPException","getTablesList","db","pool","getDbPool","tablesQuery","tables","table","countQuery","rows","init_table_list_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getDbPool","tableExistsQuery","tableExistsRows","columnsQuery","columns","constraintsQuery","constraints","indexesQuery","indexes","schemaLines","columnDefs","col","colDef","formatDataType","constraintMap","constraint","existing","constraintDefs","constraintName","constraintColumns","firstConstraint","columnNames","c","foreignTable","foreignColumn","allDefs","index","data_type","udt_name","character_maximum_length","numeric_precision","numeric_scale","init_table_schema_dao","__esmMin","init_db_manager","buildWhereClause","filters","conditions","values","filter","paramIndex","columnName","buildSortClause","sorts","order","sort","buildCursorWhereClause","cursorData","direction","sortDirection","startParamIndex","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","_","i","operator","init_build_clauses","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_dao","__esmMin","init_db_manager","init_build_clauses","data","cursor","pool","tableName","quotedTableName","row","limit","direction","sort","order","filters","db","getDbPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClause","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClause","combinedWhereClause","sortClause","buildSortClause","effectiveSortClause","col","countRes","totalRows","limitParamIndex","dataRes","rows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","utils","write","getExportFile","cols","rows","format","tableName","jsonContent","data","row","col","worksheet","csvContent","workbook","buffer","init_get_export_file","__esmMin","zValidator","Hono","tablesRoutes","init_tables_routes","__esmMin","init_types","init_create_table_dao","init_delete_column_dao","init_delete_table_dao","init_export_table_dao","init_create_table_mysql_dao","init_delete_column_mysql_dao","init_delete_table_mysql_dao","init_export_table_mysql_dao","init_table_columns_mysql_dao","init_table_list_mysql_dao","init_table_schema_mysql_dao","init_tables_data_mysql_dao","init_table_columns_dao","init_table_list_dao","init_table_schema_dao","init_tables_data_dao","init_get_export_file","databaseSchema","c","db","tablesList","getTablesList","createTableSchema","body","createTable","deleteTableQuerySchema","tableNameSchema","cascade","tableName","result","deleteTable","deleteColumnQuerySchema","deleteColumnParamSchema","columnName","dbType","deletedCount","deleteColumn","columns","getTableColumns","schema","getTableSchema","tableDataQuerySchema","cursor","limit","direction","sort","order","filters","tableData","getTableData","exportTableSchema","format","cols","rows","exportTableData","fileContent","getExportFile","contentType","create_server_exports","__export","createServer","path","fileURLToPath","serveStatic","zValidator","Hono","cors","logger","prettyJSON","getCoreDistPath","init_create_server","__esmMin","init_types","init_error_handler","init_chat_routes","init_databases_routes","init_query_routes","init_records_routes","init_tables_routes","__dirname","_","next","c","handleError","databasesRoutes","databaseTypeParamSchema","validationHook","dbType","tablesRoutes","recordsRoutes","queryRoutes","chatRoutes","init_constants","intro","outro","serve","color","program","args","readFile","resolve","cancel","isCancel","note","select","spinner","text","parseDotenv","color","getDatabaseUrl","env","varName","envVarName","s","choice","customPath","value","customEnvPath","content","parsed","e","error","dbUrl","access","readFile","dirname","resolve","parseDotenv","findEnvPath","startDir","dir","envPath","parent","loadEnv","env","content","err","init_meta","intro","outro","color","showHelp","META","init_constants","intro","note","outro","color","showStatus","env","databaseUrl","varName","intro","color","envVarName","DEFAULTS","foundUrl","ENV","loadEnv","outro","note","intro","outro","color","package_default","showVersion","intro","color","outro","package_default","main","env","port","databaseUrl","varName","status","help","version","args","showHelp","showVersion","showStatus","intro","color","PORT","DEFAULTS","VAR_NAME","ENV","loadEnv","DATABASE_URL","getDatabaseUrl","createServer","app","serve","outro","err"]}
|
|
1
|
+
{"version":3,"sources":["../../shared/src/constants/chat.ts","../../shared/src/constants/column-types-mysql.ts","../../shared/src/constants/column-types-pgsql.ts","../../shared/src/constants/defaults.ts","../../shared/src/constants/links.ts","../../shared/src/constants/meta.ts","../../shared/src/constants/proxy-limits.ts","../../shared/src/constants/index.ts","../../shared/src/types/database.types.ts","../../shared/src/types/add-column.types.ts","../../shared/src/types/add-record.types.ts","../../shared/src/types/delete-column.types.ts","../../shared/src/types/alter-column.types.ts","../../shared/src/types/api-response.types.ts","../../shared/src/types/bulk-insert-records.type.ts","../../shared/src/types/chat.types.ts","../../shared/src/types/cmd-args.types.ts","../../shared/src/types/column-info.types.ts","../../shared/src/types/column.type.ts","../../shared/src/types/create-table.types.ts","../../shared/src/types/database-list.types.ts","../../shared/src/types/database-schema.type.ts","../../shared/src/types/delete-record.types.ts","../../shared/src/types/delete-table.types.ts","../../shared/src/types/execute-query.types.ts","../../shared/src/types/export-table.types.ts","../../shared/src/types/rate-limit-response.type.ts","../../shared/src/types/rename-column.types.ts","../../shared/src/types/table-data.types.ts","../../shared/src/types/table-info.type.ts","../../shared/src/types/table-schema.types.ts","../../shared/src/types/update-recors.types.ts","../../shared/src/types/index.ts","../src/middlewares/error-handler.ts","../src/db.ts","../src/db-manager.ts","../src/dao/table-columns.dao.ts","../src/dao/table-details-schema.ts","../src/utils/system-prompt-generator.ts","../src/routes/chat.routes.ts","../src/utils/parse-database-url.ts","../src/dao/database-list.dao.ts","../src/dao/mysql/database-list.mysql.dao.ts","../src/routes/databases.routes.ts","../src/dao/mysql/query.mysql.dao.ts","../src/dao/query.dao.ts","../src/routes/query.routes.ts","../src/dao/add-record.dao.ts","../src/dao/bulk-insert-records.dao.ts","../src/dao/delete-records.dao.ts","../src/dao/mysql/table-columns.mysql.dao.ts","../src/dao/mysql/add-record.mysql.dao.ts","../src/dao/mysql/bulk-insert-records.mysql.dao.ts","../src/dao/mysql/delete-records.mysql.dao.ts","../src/dao/mysql/update-records.mysql.dao.ts","../src/dao/update-records.dao.ts","../src/routes/records.routes.ts","../src/dao/add-column.dao.ts","../src/dao/alter-column.dao.ts","../src/dao/create-table.dao.ts","../src/dao/delete-column.dao.ts","../src/dao/delete-table.dao.ts","../src/dao/export-table.dao.ts","../src/dao/mysql/mysql-column.utils.ts","../src/dao/mysql/add-column.mysql.dao.ts","../src/dao/mysql/alter-column.mysql.dao.ts","../src/dao/mysql/create-table.mysql.dao.ts","../src/dao/mysql/delete-column.mysql.dao.ts","../src/dao/mysql/delete-table.mysql.dao.ts","../src/dao/mysql/export-table.mysql.dao.ts","../src/dao/mysql/rename-column.mysql.dao.ts","../src/dao/mysql/table-list.mysql.dao.ts","../src/dao/mysql/table-schema.mysql.dao.ts","../src/utils/build-clauses-mysql.ts","../src/dao/mysql/tables-data.mysql.dao.ts","../src/dao/rename-column.dao.ts","../src/dao/table-list.dao.ts","../src/dao/table-schema.dao.ts","../src/utils/build-clauses.ts","../src/dao/tables-data.dao.ts","../src/utils/get-export-file.ts","../src/routes/tables.routes.ts","../src/utils/create-server.ts","../src/index.ts","../src/cmd/args.ts","../src/cmd/get-db-url.ts","../src/cmd/load-env.ts","../src/cmd/show-help.ts","../src/cmd/show-status.ts","../src/cmd/show-version.ts","../package.json"],"sourcesContent":["export const CHAT_SUGGESTIONS = [\n\t\"Show me all tables in my database\",\n\t\"What columns are in the users table?\",\n\t\"Write a query to find all active users\",\n\t\"How many orders were placed last month?\",\n\t\"Find top 5 customers by total spend\",\n\t\"Write a JOIN between users and orders\",\n\t\"Users who haven't made any purchase yet\",\n\t\"Generate monthly revenue summary query\",\n\t\"Suggest useful indexes for better performance\",\n\t\"Show schema of the products / inventory table\",\n\t\"Latest 20 orders with customer names\",\n\t\"Help me write a safe UPDATE query\",\n];\n\n// const MODEL_LIST = [\n// \t{\n// \t\tid: \"gpt-4o\",\n// \t\tname: \"GPT-4o\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"gpt-4o-mini\",\n// \t\tname: \"GPT-4o Mini\",\n// \t\tchef: \"OpenAI\",\n// \t\tchefSlug: \"openai\",\n// \t},\n// \t{\n// \t\tid: \"claude-opus-4-20250514\",\n// \t\tname: \"Claude 4 Opus\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"claude-sonnet-4-20250514\",\n// \t\tname: \"Claude 4 Sonnet\",\n// \t\tchef: \"Anthropic\",\n// \t\tchefSlug: \"anthropic\",\n// \t},\n// \t{\n// \t\tid: \"gemini-2.0-flash-exp\",\n// \t\tname: \"Gemini 2.0 Flash\",\n// \t\tchef: \"Google\",\n// \t\tchefSlug: \"google\",\n// \t},\n// ];\n","export const MYSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"tinyint\", label: \"tinyint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"mediumint\", label: \"mediumint\" },\n\t{ value: \"int\", label: \"int\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"decimal\", label: \"decimal\" },\n\t{ value: \"float\", label: \"float\" },\n\t{ value: \"double\", label: \"double\" },\n\t{ value: \"bit\", label: \"bit\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"char\", label: \"char\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"tinytext\", label: \"tinytext\" },\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"mediumtext\", label: \"mediumtext\" },\n\t{ value: \"longtext\", label: \"longtext\" },\n\t// Binary\n\t{ value: \"binary\", label: \"binary\" },\n\t{ value: \"varbinary\", label: \"varbinary\" },\n\t{ value: \"tinyblob\", label: \"tinyblob\" },\n\t{ value: \"blob\", label: \"blob\" },\n\t{ value: \"mediumblob\", label: \"mediumblob\" },\n\t{ value: \"longblob\", label: \"longblob\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"datetime\", label: \"datetime\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"year\", label: \"year\" },\n\t// Complex\n\t{ value: \"enum\", label: \"enum\" },\n\t{ value: \"set\", label: \"set\" },\n] as const;\n\nexport type MysqlColumnType = (typeof MYSQL_COLUMN_TYPES)[number][\"value\"];\n","export const PGSQL_COLUMN_TYPES = [\n\t// Numeric\n\t{ value: \"integer\", label: \"integer\" },\n\t{ value: \"bigint\", label: \"bigint\" },\n\t{ value: \"smallint\", label: \"smallint\" },\n\t{ value: \"numeric\", label: \"numeric\" },\n\t{ value: \"real\", label: \"real\" },\n\t{ value: \"double precision\", label: \"double precision\" },\n\t{ value: \"money\", label: \"money\" },\n\t{ value: \"serial\", label: \"serial\" },\n\t{ value: \"bigserial\", label: \"bigserial\" },\n\t// Boolean\n\t{ value: \"boolean\", label: \"boolean\" },\n\t// Text\n\t{ value: \"text\", label: \"text\" },\n\t{ value: \"varchar\", label: \"varchar\" },\n\t{ value: \"char\", label: \"char\" },\n\t// JSON\n\t{ value: \"json\", label: \"json\" },\n\t{ value: \"jsonb\", label: \"jsonb\" },\n\t{ value: \"xml\", label: \"xml\" },\n\t// UUID\n\t{ value: \"uuid\", label: \"uuid\" },\n\t// Date / Time\n\t{ value: \"date\", label: \"date\" },\n\t{ value: \"time\", label: \"time\" },\n\t{ value: \"timestamp\", label: \"timestamp\" },\n\t{ value: \"timestamptz\", label: \"timestamptz\" },\n\t{ value: \"interval\", label: \"interval\" },\n\t// Binary\n\t{ value: \"bytea\", label: \"bytea\" },\n\t// Network\n\t{ value: \"inet\", label: \"inet\" },\n\t{ value: \"cidr\", label: \"cidr\" },\n\t{ value: \"macaddr\", label: \"macaddr\" },\n\t{ value: \"macaddr8\", label: \"macaddr8\" },\n\t// Geometric\n\t{ value: \"point\", label: \"point\" },\n\t{ value: \"line\", label: \"line\" },\n\t{ value: \"polygon\", label: \"polygon\" },\n] as const;\n\nexport type PgsqlColumnType = (typeof PGSQL_COLUMN_TYPES)[number][\"value\"];\n","export const DEFAULTS = {\n\tPORT: 3333,\n\tENV: \".env\",\n\tVAR_NAME: \"DATABASE_URL\",\n\tBASE_URL: \"http://localhost:3333\",\n\tPROXY_URL:\n\t\tprocess.env.NODE_ENV === \"development\"\n\t\t\t? \"http://localhost:8787\"\n\t\t\t: \"https://db-studio-proxy.husamql3.workers.dev\",\n};\n","export const HEADER_LINKS = [\n\t{ label: \"Home\", href: \"/\" },\n\t{ label: \"Roadmap\", href: \"/roadmap\" },\n\t{ label: \"Docs\", href: \"/docs/$\" },\n\t{ label: \"Changelog\", href: \"/changelog\" },\n];\n","export const META = {\n\t//* author\n\tAUTHOR: \"Hüsam 🥑 <devhsmq@gmail.com>\",\n\tAUTHOR_NAME: \"Hüsam\",\n\tAUTHOR_AVATAR: \"/avocado.png\",\n\tAUTHOR_USERNAME: \"husamql3\",\n\tAUTHOR_GITHUB_LINK: \"https://github.com/husamql3\",\n\t//* site\n\tSITE_DESCRIPTION: \"The modern pgAdmin alternative that works with every database.\",\n\tSITE_KEYWORDS: [\n\t\t\"pgadmin alternative\",\n\t\t\"database client\",\n\t\t\"database gui\",\n\t\t\"database browser\",\n\t\t\"sql editor\",\n\t\t\"postgresql client\",\n\t\t\"mysql client\",\n\t\t\"table editor\",\n\t\t\"ai sql\",\n\t\t\"er diagram\",\n\t],\n\tSITE_TITLE: \"DB Studio\",\n\tSITE_NAME: \"dbstudio.sh\",\n\tSITE_URL: \"https://dbstudio.sh\",\n\tSITE_X_LINK: \"https://x.com/dbstudio_sh\",\n\tSITE_GITHUB_LINK: \"https://github.com/husamql3/db-studio\",\n\tSITE_GITHUB_NEW_ISSUE_LINK: \"https://github.com/husamql3/db-studio/issues/new/choose\",\n\tSITE_DOCS_LINK: \"https://dbstudio.sh/docs\",\n\tSITE_CHANGELOG_LINK: \"https://dbstudio.sh/changelog\",\n\tSITE_ROADMAP_LINK: \"https://dbstudio.sh/roadmap\",\n\tSITE_IMAGE: \"https://dbstudio.sh/og-image.png\",\n\tSITE_IMAGE_WIDTH: \"1200\",\n\tSITE_IMAGE_HEIGHT: \"630\",\n\tSITE_IMAGE_ALT: \"dbstudio.sh – Modern database management studio\",\n\tSITE_COLOR: \"#1447e6\",\n};\n","export const ONE_DAY = 24 * 60 * 60 * 1000;\nexport const LIMIT = 3;\n","export * from \"./chat.js\";\nexport * from \"./column-types-mysql.js\";\nexport * from \"./column-types-pgsql.js\";\nexport * from \"./defaults.js\";\nexport * from \"./links.js\";\nexport * from \"./meta.js\";\nexport * from \"./proxy-limits.js\";\n","import { z } from \"zod\";\n\nexport const databaseSchema = z.object({\n\tdb: z.string(\"Database name is required\"),\n});\n\nexport type DatabaseSchemaType = z.infer<typeof databaseSchema>;\n\nexport const DATABASE_TYPES = [\"pg\", \"mysql\"] as const;\n\nexport const databaseTypeSchema = z.enum(DATABASE_TYPES, {\n\tmessage: \"Invalid database type\",\n});\nexport type DatabaseTypeSchema = z.infer<typeof databaseTypeSchema>;\n\nexport const currentDatabaseSchema = databaseSchema.extend({\n\tdbType: databaseTypeSchema,\n});\nexport type CurrentDatabaseSchemaType = z.infer<typeof currentDatabaseSchema>;\n\nexport const databaseTypeParamSchema = z.object({\n\tdbType: databaseTypeSchema,\n});\n\nexport const tableNameSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n});\n\nexport type TableNameSchemaType = z.infer<typeof tableNameSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema, tableNameSchema } from \"./database.types\";\n\nexport const addColumnSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\tcolumnType: z.string(\"Column type is required\"),\n\tdefaultValue: z.string().optional(),\n\tisPrimaryKey: z.boolean().default(false),\n\tisNullable: z.boolean().default(false),\n\tisUnique: z.boolean().default(false),\n\tisIdentity: z.boolean().default(false),\n\tisArray: z.boolean().default(false),\n});\n\nexport type AddColumnSchemaType = z.infer<typeof addColumnSchema>;\n\nexport const addColumnParamSchema = tableNameSchema;\n\nexport type AddColumnParamSchemaType = z.infer<typeof addColumnParamSchema>;\n\nexport const addColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: tableNameSchema.shape.tableName,\n\tcolumnName: addColumnSchema.shape.columnName,\n\tcolumnType: addColumnSchema.shape.columnType,\n\tdefaultValue: addColumnSchema.shape.defaultValue,\n\tisPrimaryKey: addColumnSchema.shape.isPrimaryKey,\n\tisNullable: addColumnSchema.shape.isNullable,\n\tisUnique: addColumnSchema.shape.isUnique,\n\tisIdentity: addColumnSchema.shape.isIdentity,\n\tisArray: addColumnSchema.shape.isArray,\n});\n\nexport type AddColumnParamsSchemaType = z.infer<typeof addColumnParamsSchema>;\n","import { z } from \"zod\";\n\nexport const addRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tdata: z.record(z.string(\"Column name is required\"), z.any()),\n});\n\nexport type AddRecordSchemaType = z.infer<typeof addRecordSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\n\nexport const deleteColumnQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteColumnQuerySchemaType = z.infer<typeof deleteColumnQuerySchema>;\n\nexport const deleteColumnParamSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n});\n\nexport const deleteColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tcascade: z.boolean().optional(),\n});\n\nexport type DeleteColumnParamsSchemaType = z.infer<typeof deleteColumnParamsSchema>;\n\nexport const deleteColumnSuccessResponseSchema = z.object({\n\tmessage: z.string(\"Message is required\"),\n\ttableName: z.string(\"Table name is required\"),\n\tcolumnName: z.string(\"Column name is required\"),\n\tdeletedCount: z.number(\"Deleted count is required\").default(0),\n});\n\nexport type DeleteColumnResponseType = z.infer<typeof deleteColumnSuccessResponseSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport { deleteColumnParamSchema } from \"./delete-column.types\";\n\nexport const alterColumnSchema = z.object({\n\tcolumnType: z.string(\"Column type is required\"),\n\tisNullable: z.boolean(),\n\tdefaultValue: z.string().nullable().optional(),\n});\n\nexport type AlterColumnSchemaType = z.infer<typeof alterColumnSchema>;\n\nexport const alterColumnParamSchema = deleteColumnParamSchema;\n\nexport type AlterColumnParamSchemaType = z.infer<typeof alterColumnParamSchema>;\n\nexport const alterColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tcolumnType: alterColumnSchema.shape.columnType,\n\tisNullable: alterColumnSchema.shape.isNullable,\n\tdefaultValue: alterColumnSchema.shape.defaultValue,\n});\n\nexport type AlterColumnParamsSchemaType = z.infer<typeof alterColumnParamsSchema>;\n","/**\n * Standard API success response wrapper type\n * Used by both server and client\n */\nexport type BaseResponse<T> = {\n\tdata: T;\n\tmessage?: string;\n};\n\n/**\n * Standard API error response type\n */\nexport type ApiError = {\n\terror: string;\n\tdetails?: string;\n};\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport type BulkInsertRecordsParams = {\n\ttableName: string;\n\trecords: Record<string, unknown>[];\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type BulkInsertResult = {\n\tsuccess: boolean;\n\tmessage: string;\n\tsuccessCount: number;\n\tfailureCount: number;\n\terrors?: Array<{ recordIndex: number; error: string }>;\n};\n\nexport const bulkInsertRecordsSchema = z.object({\n\ttableName: z.string().min(1, \"Table name is required\"),\n\trecords: z.array(z.record(z.string(), z.any())).min(1, \"At least one record is required\"),\n});\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const chatSchema = z.object({\n\tmessages: z.array(\n\t\tz.object({\n\t\t\trole: z.enum([\"user\", \"assistant\"]),\n\t\t\tcontent: z.string(\"Content is required\"),\n\t\t}),\n\t),\n\tconversationId: z.string().optional(),\n\tdb: databaseSchema.shape.db,\n});\n","export type Args = {\n\tenv?: string;\n\tport?: string;\n\tdatabaseUrl?: string;\n\tvarName?: string;\n\tstatus?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n};\n","import { z } from \"zod\";\n\nconst dataTypes = [\"text\", \"boolean\", \"number\", \"enum\", \"json\", \"date\", \"array\"] as const;\n\nexport const dataTypesSchema = z.enum(dataTypes);\nexport type DataTypes = z.infer<typeof dataTypesSchema>;\n\nexport const DataTypes = {\n\ttext: \"text\",\n\tboolean: \"boolean\",\n\tnumber: \"number\",\n\tenum: \"enum\",\n\tjson: \"json\",\n\tdate: \"date\",\n\tarray: \"array\",\n} as const satisfies Record<DataTypes, string>;\n\nconst standardizedDataTypes = [\n\t// PostgreSQL numeric types\n\t\"int\",\n\t\"bigint\",\n\t\"smallint\",\n\t\"numeric\",\n\t\"float\",\n\t\"double\",\n\t\"money\",\n\t// MySQL numeric types\n\t\"tinyint\",\n\t\"mediumint\",\n\t\"bit\",\n\t// Boolean\n\t\"boolean\",\n\t// Text types (shared)\n\t\"text\",\n\t\"varchar\",\n\t\"char\",\n\t// MySQL text types\n\t\"tinytext\",\n\t\"mediumtext\",\n\t\"longtext\",\n\t// JSON types\n\t\"json\",\n\t\"jsonb\",\n\t\"xml\",\n\t// UUID\n\t\"uuid\",\n\t// Date/Time types (shared)\n\t\"date\",\n\t\"time\",\n\t\"timestamp\",\n\t// PostgreSQL date/time\n\t\"timestamptz\",\n\t\"interval\",\n\t// MySQL date/time\n\t\"datetime\",\n\t\"year\",\n\t// PostgreSQL binary/network/geometric types\n\t\"bytea\",\n\t\"inet\",\n\t\"cidr\",\n\t\"macaddr\",\n\t\"macaddr8\",\n\t\"point\",\n\t\"line\",\n\t\"polygon\",\n\t// MySQL binary types\n\t\"binary\",\n\t\"varbinary\",\n\t\"blob\",\n\t\"tinyblob\",\n\t\"mediumblob\",\n\t\"longblob\",\n\t// Complex types (shared)\n\t\"array\",\n\t\"enum\",\n\t// MySQL set type\n\t\"set\",\n] as const;\n\nexport const standardizedDataTypeSchema = z.enum(standardizedDataTypes);\n\nexport const columnInfoSchema = z.object({\n\tcolumnName: z.string(),\n\tdataType: dataTypesSchema,\n\tdataTypeLabel: standardizedDataTypeSchema,\n\tisNullable: z.boolean(),\n\tcolumnDefault: z.string().nullable(),\n\tisPrimaryKey: z.boolean(),\n\tisForeignKey: z.boolean(),\n\treferencedTable: z.string().nullable(),\n\treferencedColumn: z.string().nullable(),\n\tenumValues: z.array(z.string()).nullable(),\n});\n\nexport type ColumnInfoSchemaType = z.infer<typeof columnInfoSchema>;\n","import { DataTypes } from \"./column-info.types.js\";\n\n/**\n * Maps PostgreSQL data types to generic DataType enum\n */\nexport function mapPostgresToDataType(pgType: string): DataTypes {\n\tconst normalized = pgType?.toLowerCase().trim() || \"\";\n\n\t// Handle array types and date/time types\n\tif (\n\t\tnormalized.includes(\"[]\") ||\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\") ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\") ||\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"int2\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\") ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"float4\" ||\n\t\tnormalized === \"double precision\" ||\n\t\tnormalized === \"float8\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\" ||\n\t\tnormalized === \"money\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\" || normalized === \"jsonb\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum types and long text types\n\tif (\n\t\tnormalized.startsWith(\"user-defined\") ||\n\t\tnormalized === \"enum\" ||\n\t\tnormalized === \"text\" ||\n\t\tnormalized === \"xml\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Short string types (varchar, char, uuid, etc.)\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\") ||\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\" ||\n\t\tnormalized === \"uuid\" ||\n\t\tnormalized === \"interval\" ||\n\t\tnormalized.startsWith(\"interval\") ||\n\t\tnormalized === \"bytea\" ||\n\t\tnormalized === \"point\" ||\n\t\tnormalized === \"line\" ||\n\t\tnormalized === \"polygon\" ||\n\t\tnormalized === \"inet\" ||\n\t\tnormalized === \"cidr\" ||\n\t\tnormalized === \"macaddr\" ||\n\t\tnormalized === \"macaddr8\"\n\t) {\n\t\treturn DataTypes.text;\n\t}\n\n\t// Default to short for unrecognized types\n\treturn DataTypes.text;\n}\n\n/**\n * Standardized data type labels\n */\nexport const StandardizedDataType = {\n\t// PostgreSQL numeric types\n\tint: \"int\",\n\tbigint: \"bigint\",\n\tsmallint: \"smallint\",\n\tnumeric: \"numeric\",\n\tfloat: \"float\",\n\tdouble: \"double\",\n\tmoney: \"money\",\n\t// MySQL numeric types\n\ttinyint: \"tinyint\",\n\tmediumint: \"mediumint\",\n\tbit: \"bit\",\n\t// Boolean\n\tboolean: \"boolean\",\n\t// Text types (shared)\n\ttext: \"text\",\n\tvarchar: \"varchar\",\n\tchar: \"char\",\n\t// MySQL text types\n\ttinytext: \"tinytext\",\n\tmediumtext: \"mediumtext\",\n\tlongtext: \"longtext\",\n\t// JSON types\n\tjson: \"json\",\n\tjsonb: \"jsonb\",\n\txml: \"xml\",\n\t// UUID\n\tuuid: \"uuid\",\n\t// Date/Time types (shared)\n\tdate: \"date\",\n\ttime: \"time\",\n\ttimestamp: \"timestamp\",\n\t// PostgreSQL date/time\n\ttimestamptz: \"timestamptz\",\n\tinterval: \"interval\",\n\t// MySQL date/time\n\tdatetime: \"datetime\",\n\tyear: \"year\",\n\t// PostgreSQL binary/network/geometric types\n\tbytea: \"bytea\",\n\tinet: \"inet\",\n\tcidr: \"cidr\",\n\tmacaddr: \"macaddr\",\n\tmacaddr8: \"macaddr8\",\n\tpoint: \"point\",\n\tline: \"line\",\n\tpolygon: \"polygon\",\n\t// MySQL binary types\n\tbinary: \"binary\",\n\tvarbinary: \"varbinary\",\n\tblob: \"blob\",\n\ttinyblob: \"tinyblob\",\n\tmediumblob: \"mediumblob\",\n\tlongblob: \"longblob\",\n\t// Complex types (shared)\n\tarray: \"array\",\n\tenum: \"enum\",\n\t// MySQL set type\n\tset: \"set\",\n} as const;\n\nexport type StandardizedDataType =\n\t(typeof StandardizedDataType)[keyof typeof StandardizedDataType];\n\n/**\n * Maps PostgreSQL data types to standardized display labels\n */\nexport function standardizeDataTypeLabel(\n\tpgType: string | null | undefined,\n): StandardizedDataType {\n\tif (!pgType) {\n\t\treturn StandardizedDataType.text; // Default fallback\n\t}\n\tconst normalized = pgType.toLowerCase().trim();\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"int4\" ||\n\t\tnormalized === \"serial\" ||\n\t\tnormalized === \"serial4\"\n\t) {\n\t\treturn StandardizedDataType.int;\n\t}\n\n\tif (\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"int8\" ||\n\t\tnormalized === \"bigserial\" ||\n\t\tnormalized === \"serial8\"\n\t) {\n\t\treturn StandardizedDataType.bigint;\n\t}\n\n\tif (normalized === \"smallint\" || normalized === \"int2\") {\n\t\treturn StandardizedDataType.smallint;\n\t}\n\n\tif (\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized.startsWith(\"decimal(\") ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized.startsWith(\"numeric(\")\n\t) {\n\t\treturn StandardizedDataType.numeric;\n\t}\n\n\tif (normalized === \"real\" || normalized === \"float4\") {\n\t\treturn StandardizedDataType.float;\n\t}\n\n\tif (normalized === \"double precision\" || normalized === \"float8\" || normalized === \"float\") {\n\t\treturn StandardizedDataType.double;\n\t}\n\n\tif (normalized === \"money\") {\n\t\treturn StandardizedDataType.money;\n\t}\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn StandardizedDataType.boolean;\n\t}\n\n\t// Text types\n\tif (normalized === \"text\") {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\tif (\n\t\tnormalized === \"character varying\" ||\n\t\tnormalized.startsWith(\"varchar\") ||\n\t\tnormalized.startsWith(\"character varying(\")\n\t) {\n\t\treturn StandardizedDataType.varchar;\n\t}\n\n\tif (\n\t\tnormalized === \"character\" ||\n\t\tnormalized.startsWith(\"char\") ||\n\t\tnormalized.startsWith(\"character(\") ||\n\t\tnormalized === \"bpchar\"\n\t) {\n\t\treturn StandardizedDataType.char;\n\t}\n\n\t// JSON types\n\tif (normalized === \"json\") {\n\t\treturn StandardizedDataType.json;\n\t}\n\n\tif (normalized === \"jsonb\") {\n\t\treturn StandardizedDataType.jsonb;\n\t}\n\n\tif (normalized === \"xml\") {\n\t\treturn StandardizedDataType.xml;\n\t}\n\n\t// UUID\n\tif (normalized === \"uuid\") {\n\t\treturn StandardizedDataType.uuid;\n\t}\n\n\t// Date/Time types\n\tif (normalized === \"date\") {\n\t\treturn StandardizedDataType.date;\n\t}\n\n\tif (\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"time without time zone\" ||\n\t\tnormalized.startsWith(\"time(\")\n\t) {\n\t\treturn StandardizedDataType.time;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"timestamp without time zone\" ||\n\t\tnormalized.startsWith(\"timestamp(\")\n\t) {\n\t\treturn StandardizedDataType.timestamp;\n\t}\n\n\tif (\n\t\tnormalized === \"timestamp with time zone\" ||\n\t\tnormalized === \"timestamptz\" ||\n\t\tnormalized.startsWith(\"timestamp with time zone(\")\n\t) {\n\t\treturn StandardizedDataType.timestamptz;\n\t}\n\n\tif (normalized === \"interval\" || normalized.startsWith(\"interval\")) {\n\t\treturn StandardizedDataType.interval;\n\t}\n\n\t// Binary\n\tif (normalized === \"bytea\") {\n\t\treturn StandardizedDataType.bytea;\n\t}\n\n\t// Network types\n\tif (normalized === \"inet\") {\n\t\treturn StandardizedDataType.inet;\n\t}\n\n\tif (normalized === \"cidr\") {\n\t\treturn StandardizedDataType.cidr;\n\t}\n\n\tif (normalized === \"macaddr\") {\n\t\treturn StandardizedDataType.macaddr;\n\t}\n\n\tif (normalized === \"macaddr8\") {\n\t\treturn StandardizedDataType.macaddr8;\n\t}\n\n\t// Geometric types\n\tif (normalized === \"point\") {\n\t\treturn StandardizedDataType.point;\n\t}\n\n\tif (normalized === \"line\") {\n\t\treturn StandardizedDataType.line;\n\t}\n\n\tif (normalized === \"polygon\") {\n\t\treturn StandardizedDataType.polygon;\n\t}\n\n\t// Array types\n\t// todo: handle array types\n\tif (normalized.startsWith(\"array\") || normalized.includes(\"[]\")) {\n\t\treturn StandardizedDataType.text;\n\t}\n\n\t// User-defined types (enums)\n\tif (normalized.startsWith(\"user-defined\") || normalized === \"enum\") {\n\t\treturn StandardizedDataType.enum;\n\t}\n\n\t// Default: return the original type\n\treturn StandardizedDataType.text;\n}\n\n/**\n * Maps MySQL data types to generic DataType enum (used for cell rendering)\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\", \"enum('a','b')\") for finer mapping\n */\nexport function mapMysqlToDataType(mysqlDataType: string, columnType?: string): DataTypes {\n\tconst normalized = mysqlDataType?.toLowerCase().trim() || \"\";\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Numeric types\n\tif (\n\t\tnormalized === \"tinyint\" ||\n\t\tnormalized === \"smallint\" ||\n\t\tnormalized === \"mediumint\" ||\n\t\tnormalized === \"int\" ||\n\t\tnormalized === \"integer\" ||\n\t\tnormalized === \"bigint\" ||\n\t\tnormalized === \"decimal\" ||\n\t\tnormalized === \"numeric\" ||\n\t\tnormalized === \"float\" ||\n\t\tnormalized === \"double\" ||\n\t\tnormalized === \"real\" ||\n\t\tnormalized === \"bit\"\n\t) {\n\t\treturn DataTypes.number;\n\t}\n\n\t// Boolean (explicit)\n\tif (normalized === \"boolean\" || normalized === \"bool\") {\n\t\treturn DataTypes.boolean;\n\t}\n\n\t// Date/time types\n\tif (\n\t\tnormalized === \"date\" ||\n\t\tnormalized === \"datetime\" ||\n\t\tnormalized === \"timestamp\" ||\n\t\tnormalized === \"time\" ||\n\t\tnormalized === \"year\"\n\t) {\n\t\treturn DataTypes.date;\n\t}\n\n\t// JSON\n\tif (normalized === \"json\") {\n\t\treturn DataTypes.json;\n\t}\n\n\t// Enum and set (set behaves like enum for display)\n\tif (normalized === \"enum\" || normalized === \"set\") {\n\t\treturn DataTypes.enum;\n\t}\n\n\t// All text and binary types default to text\n\treturn DataTypes.text;\n}\n\n/**\n * Maps MySQL data types to standardized display labels\n * @param mysqlDataType - The DATA_TYPE field from information_schema.COLUMNS\n * @param columnType - The COLUMN_TYPE field (e.g., \"tinyint(1)\") for finer mapping\n */\nexport function standardizeMysqlDataTypeLabel(\n\tmysqlDataType: string,\n\tcolumnType?: string,\n): StandardizedDataType {\n\tif (!mysqlDataType) {\n\t\treturn StandardizedDataType.text;\n\t}\n\tconst normalized = mysqlDataType.toLowerCase().trim();\n\tconst fullType = columnType?.toLowerCase().trim() || \"\";\n\n\t// tinyint(1) is MySQL's boolean convention\n\tif (normalized === \"tinyint\" && fullType === \"tinyint(1)\")\n\t\treturn StandardizedDataType.boolean;\n\n\t// Numeric types\n\tif (normalized === \"tinyint\") return StandardizedDataType.tinyint;\n\tif (normalized === \"smallint\") return StandardizedDataType.smallint;\n\tif (normalized === \"mediumint\") return StandardizedDataType.mediumint;\n\tif (normalized === \"int\" || normalized === \"integer\") return StandardizedDataType.int;\n\tif (normalized === \"bigint\") return StandardizedDataType.bigint;\n\tif (normalized === \"decimal\" || normalized === \"numeric\")\n\t\treturn StandardizedDataType.numeric;\n\tif (normalized === \"float\" || normalized === \"real\") return StandardizedDataType.float;\n\tif (normalized === \"double\") return StandardizedDataType.double;\n\tif (normalized === \"bit\") return StandardizedDataType.bit;\n\n\t// Boolean\n\tif (normalized === \"boolean\" || normalized === \"bool\") return StandardizedDataType.boolean;\n\n\t// Text types\n\tif (normalized === \"char\") return StandardizedDataType.char;\n\tif (normalized === \"varchar\") return StandardizedDataType.varchar;\n\tif (normalized === \"tinytext\") return StandardizedDataType.tinytext;\n\tif (normalized === \"text\") return StandardizedDataType.text;\n\tif (normalized === \"mediumtext\") return StandardizedDataType.mediumtext;\n\tif (normalized === \"longtext\") return StandardizedDataType.longtext;\n\n\t// Binary types\n\tif (normalized === \"binary\") return StandardizedDataType.binary;\n\tif (normalized === \"varbinary\") return StandardizedDataType.varbinary;\n\tif (normalized === \"tinyblob\") return StandardizedDataType.tinyblob;\n\tif (normalized === \"blob\") return StandardizedDataType.blob;\n\tif (normalized === \"mediumblob\") return StandardizedDataType.mediumblob;\n\tif (normalized === \"longblob\") return StandardizedDataType.longblob;\n\n\t// JSON\n\tif (normalized === \"json\") return StandardizedDataType.json;\n\n\t// Date/time types\n\tif (normalized === \"date\") return StandardizedDataType.date;\n\tif (normalized === \"time\") return StandardizedDataType.time;\n\tif (normalized === \"datetime\") return StandardizedDataType.datetime;\n\tif (normalized === \"timestamp\") return StandardizedDataType.timestamp;\n\tif (normalized === \"year\") return StandardizedDataType.year;\n\n\t// Complex types\n\tif (normalized === \"enum\") return StandardizedDataType.enum;\n\tif (normalized === \"set\") return StandardizedDataType.set;\n\n\t// Default\n\treturn StandardizedDataType.text;\n}\n","import { z } from \"zod\";\n\nexport const FOREIGN_KEY_ACTIONS = [\n\t\"CASCADE\",\n\t\"SET NULL\",\n\t\"SET DEFAULT\",\n\t\"RESTRICT\",\n\t\"NO ACTION\",\n] as const;\nexport const foreignKeyActionSchema = z.enum(FOREIGN_KEY_ACTIONS);\n\nexport const fieldDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\tcolumnType: z.string(\"Column type is required\"),\n\tdefaultValue: z.string().optional(),\n\tisPrimaryKey: z.boolean().default(false),\n\tisNullable: z.boolean().default(false),\n\tisUnique: z.boolean().default(false),\n\tisIdentity: z.boolean().default(false),\n\tisArray: z.boolean().default(false),\n});\nexport type FieldDataType = z.infer<typeof fieldDataSchema>;\n\nexport const foreignKeyDataSchema = z.object({\n\tcolumnName: z.string(\"Column name is required\"),\n\treferencedTable: z.string(\"Referenced table is required\"),\n\treferencedColumn: z.string(\"Referenced column is required\"),\n\tonUpdate: foreignKeyActionSchema.default(\"NO ACTION\"),\n\tonDelete: foreignKeyActionSchema.default(\"NO ACTION\"),\n});\nexport type ForeignKeyDataType = z.infer<typeof foreignKeyDataSchema>;\n\nexport const createTableSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tfields: z.array(fieldDataSchema).min(1, \"At least one field is required\"),\n\tforeignKeys: z.array(foreignKeyDataSchema).optional(),\n});\n\nexport type CreateTableSchemaType = z.infer<typeof createTableSchema>;\n","import { z } from \"zod\";\nimport { databaseTypeSchema } from \"./database.types.js\";\n\nexport const databaseInfoSchema = z.object({\n\tname: z.string(\"Name is required\"),\n\tsize: z.string(\"Size is required\"),\n\towner: z.string(\"Owner is required\"),\n\tencoding: z.string(\"Encoding is required\"),\n});\n\nexport type DatabaseInfoSchemaType = z.infer<typeof databaseInfoSchema>;\n\nexport const databaseListSchema = z.object({\n\tdatabases: z.array(databaseInfoSchema),\n\tdbType: databaseTypeSchema,\n});\n\nexport type DatabaseListSchemaType = z.infer<typeof databaseListSchema>;\n\nexport const connectionInfoSchema = z.object({\n\tversion: z.string(\"Version is required\"),\n\tdatabase: z.string(\"Database is required\"),\n\tuser: z.string(\"User is required\"),\n\thost: z.string(\"Host is required\").nullable(),\n\tport: z.number(\"Port is required\").nullable(),\n\tactive_connections: z.coerce.number(\"Active connections is required\"),\n\tmax_connections: z.coerce.number(\"Max connections is required\"),\n});\n\nexport type ConnectionInfoSchemaType = z.infer<typeof connectionInfoSchema>;\n","import type { DatabaseTypeSchema } from \"./database.types\";\n\nexport type DatabaseSchema = {\n\tdbType: DatabaseTypeSchema;\n\ttables: Table[];\n\trelationships: Relationship[];\n};\n\nexport type Table = {\n\tname: string;\n\tdescription?: string;\n\tcolumns: Column[];\n\tsampleData?: Record<string, string>[];\n};\n\nexport type Column = {\n\tname: string;\n\ttype: string;\n\tnullable: boolean;\n\tisPrimaryKey?: boolean;\n\tforeignKey?: string;\n\tdescription?: string;\n\tenumValues?: string[];\n};\n\nexport type Relationship = {\n\tfromTable: string;\n\tfromColumn: string;\n\ttoTable: string;\n\ttoColumn: string;\n};\n","import { z } from \"zod\";\nimport type { DatabaseSchemaType } from \"./database.types\";\n\nexport const deleteRecordSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKeys: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\tvalue: z.any(),\n\t\t\t}),\n\t\t)\n\t\t.min(1, \"At least one primary key is required\"),\n});\n\nexport type DeleteRecordSchemaType = z.infer<typeof deleteRecordSchema>;\n\nexport type DeleteRecordParams = DeleteRecordSchemaType & {\n\tdb: DatabaseSchemaType[\"db\"];\n};\n\nexport type DeleteRecordResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n\nexport type ForeignKeyConstraint = {\n\tconstraintName: string;\n\treferencingTable: string;\n\treferencingColumn: string;\n\treferencedTable: string;\n\treferencedColumn: string;\n};\n\nexport type ForeignKeyConstraintRow = {\n\tconstraint_name: string;\n\treferencing_table: string;\n\treferencing_column: string;\n\treferenced_table: string;\n\treferenced_column: string;\n};\n\nexport type RelatedRecord = {\n\ttableName: string;\n\tcolumnName: string;\n\tconstraintName: string;\n\trecords: Array<Record<string, unknown>>;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport type { RelatedRecord } from \"./delete-record.types\";\n\nexport const deleteTableQuerySchema = databaseSchema.extend({\n\tcascade: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => val === \"true\"),\n});\n\nexport type DeleteTableQuerySchemaType = z.infer<typeof deleteTableQuerySchema>;\n\nexport type DeleteTableParams = {\n\ttableName: string;\n\tdb: string;\n\tcascade?: boolean;\n};\n\nexport type DeleteTableResult = {\n\tdeletedCount: number;\n\tfkViolation: boolean;\n\trelatedRecords: RelatedRecord[];\n};\n","import { z } from \"zod\";\n\nexport const executeQuerySchema = z.object({\n\tquery: z.string(\"Query is required\"),\n});\n\nexport type ExecuteQueryParams = z.infer<typeof executeQuerySchema>;\n\nexport type ExecuteQueryResult = {\n\tcolumns: string[];\n\trows: Record<string, unknown>[];\n\trowCount: number;\n\tduration: number;\n\tmessage?: string;\n\terror?: string;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const FORMAT_TYPES = [\"csv\", \"xlsx\", \"json\"] as const;\nexport type FormatType = (typeof FORMAT_TYPES)[number];\n\nexport const exportTableSchema = databaseSchema.extend({\n\tformat: z.enum(FORMAT_TYPES, {\n\t\tmessage: \"Invalid format. Supported formats: csv, xlsx, json\",\n\t}),\n});\nexport type ExportTableSchemaType = z.infer<typeof exportTableSchema>;\n\nexport type CellValue = string | number | boolean | Date | null | undefined;\n","export type RateLimitResponse = {\n\tlimit: number;\n\tused: number;\n\tremaining: number;\n};\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types\";\nimport { deleteColumnParamSchema } from \"./delete-column.types\";\n\nexport const renameColumnSchema = z.object({\n\tnewColumnName: z.string(\"New column name is required\"),\n});\n\nexport type RenameColumnSchemaType = z.infer<typeof renameColumnSchema>;\n\nexport const renameColumnParamSchema = deleteColumnParamSchema;\n\nexport type RenameColumnParamSchemaType = z.infer<typeof renameColumnParamSchema>;\n\nexport const renameColumnParamsSchema = z.object({\n\tdb: databaseSchema.shape.db,\n\ttableName: deleteColumnParamSchema.shape.tableName,\n\tcolumnName: deleteColumnParamSchema.shape.columnName,\n\tnewColumnName: renameColumnSchema.shape.newColumnName,\n});\n\nexport type RenameColumnParamsSchemaType = z.infer<typeof renameColumnParamsSchema>;\n","import { z } from \"zod\";\nimport { databaseSchema } from \"./database.types.js\";\n\nexport const filterSchema = z.object({\n\tcolumnName: z.string(),\n\toperator: z.string(),\n\tvalue: z.string(),\n});\n\nexport type FilterType = z.infer<typeof filterSchema>;\n\nexport const sortDirections = [\"asc\", \"desc\"] as const;\nexport type SortDirection = (typeof sortDirections)[number];\n\nexport const sortSchema = z.object({\n\tcolumnName: z.string(),\n\tdirection: z.enum(sortDirections),\n});\n\nexport type SortType = z.infer<typeof sortSchema>;\n\nexport const tableDataMetaSchema = z.object({\n\tlimit: z.number(),\n\ttotal: z.number(),\n\thasNextPage: z.boolean(),\n\thasPreviousPage: z.boolean(),\n\tnextCursor: z.string().nullable(),\n\tprevCursor: z.string().nullable(),\n});\n\nexport const tableDataResultSchema = z.object({\n\tdata: z.array(z.record(z.string(), z.unknown())),\n\tmeta: tableDataMetaSchema,\n});\n\nexport type TableDataResultSchemaType = z.infer<typeof tableDataResultSchema>;\n\nexport const tableDataQuerySchema = z.object({\n\tdb: databaseSchema.shape.db,\n\tcursor: z.string().optional(), // Base64 encoded cursor for pagination\n\tlimit: z.string().optional().default(\"50\").transform(Number),\n\tdirection: z.enum(sortDirections).optional().default(sortDirections[0]), // Pagination direction\n\tsort: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return \"\";\n\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(val);\n\t\t\t\tif (Array.isArray(parsed)) {\n\t\t\t\t\treturn parsed;\n\t\t\t\t}\n\t\t\t\treturn val;\n\t\t\t} catch {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t}),\n\torder: z.enum(sortDirections).optional(),\n\tfilters: z\n\t\t.string()\n\t\t.optional()\n\t\t.transform((val) => {\n\t\t\tif (!val) return [];\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(val);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}),\n});\n\nexport type TableDataQuerySchemaType = z.infer<typeof tableDataQuerySchema>;\n\nexport interface CursorData {\n\tvalues: Record<string, unknown>;\n\tsortColumns: string[];\n}\n","import { z } from \"zod\";\n\nexport const tableInfoSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\trowCount: z.coerce.number(\"Row count is required\"),\n});\n\nexport type TableInfoSchemaType = z.infer<typeof tableInfoSchema>;\n","import { z } from \"zod\";\n\nexport const tableSchemaResultSchema = z.object({\n\tschema: z.string(),\n});\n\nexport type TableSchemaResult = z.infer<typeof tableSchemaResultSchema>;\n","import { z } from \"zod\";\n\nexport const updateRecordsSchema = z.object({\n\ttableName: z.string(\"Table name is required\"),\n\tprimaryKey: z.string(\"Primary key is required\").default(\"id\"),\n\tupdates: z\n\t\t.array(\n\t\t\tz.object(\n\t\t\t\t{\n\t\t\t\t\trowData: z.record(z.string(\"Column name is required\"), z.any()),\n\t\t\t\t\tcolumnName: z.string(\"Column name is required\"),\n\t\t\t\t\tvalue: z.any(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmessage: \"Each update must have a row data, column name, and value.\",\n\t\t\t\t},\n\t\t\t),\n\t\t)\n\t\t.min(1, \"At least one update is required\"),\n});\n\nexport type UpdateRecordsSchemaType = z.infer<typeof updateRecordsSchema>;\n","export * from \"./add-column.types.js\";\nexport * from \"./add-record.types.js\"; // done\nexport * from \"./alter-column.types.js\";\nexport * from \"./api-response.types.js\";\nexport * from \"./bulk-insert-records.type.js\";\nexport * from \"./chat.types.js\"; // done\nexport * from \"./cmd-args.types.js\"; // done\nexport * from \"./column.type.js\";\nexport * from \"./column-info.types.js\";\nexport * from \"./create-table.types.js\"; // done\nexport * from \"./database.types.js\"; // done\nexport * from \"./database-list.types.js\"; // done\nexport * from \"./database-schema.type.js\"; // done\nexport * from \"./delete-column.types.js\"; // done\nexport * from \"./delete-record.types.js\"; // done\nexport * from \"./delete-table.types.js\"; // done\nexport * from \"./execute-query.types.js\"; // done\nexport * from \"./export-table.types.js\";\nexport * from \"./rate-limit-response.type.js\";\nexport * from \"./rename-column.types.js\";\nexport * from \"./table-data.types.js\"; // done\nexport * from \"./table-info.type.js\"; // done\nexport * from \"./table-schema.types.js\"; // done\nexport * from \"./update-recors.types.js\"; // done\n","import type { Context } from \"hono\";\nimport { HTTPException } from \"hono/http-exception\";\nimport { DatabaseError } from \"pg\";\nimport type { ApiError } from \"shared/types/api-response.types.js\";\nimport { ZodError } from \"zod\";\n\n/**\n * Centralized error handler for the application\n */\nexport function handleError(e: Error | unknown, c: Context) {\n\tconsole.error(\"handleError:\", e);\n\n\tif (e instanceof HTTPException) {\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: e.message ?? \"Internal server error\",\n\t\t\t},\n\t\t\te.status,\n\t\t);\n\t}\n\n\tif (e instanceof ZodError) {\n\t\tconst issue = e.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue.message,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tif (e instanceof Error) {\n\t\t// MySQL-specific error codes\n\t\tconst mysqlError = e as { code?: string; errno?: number };\n\t\tconst isMysqlConnectionError =\n\t\t\tmysqlError.code === \"ECONNREFUSED\" ||\n\t\t\tmysqlError.code === \"ENOTFOUND\" ||\n\t\t\tmysqlError.code === \"ETIMEDOUT\" ||\n\t\t\tmysqlError.code === \"ER_ACCESS_DENIED_ERROR\" ||\n\t\t\tmysqlError.code === \"ER_BAD_HOST_ERROR\" ||\n\t\t\tmysqlError.code === \"ECONNRESET\" ||\n\t\t\tmysqlError.errno === 1045 || // ER_ACCESS_DENIED_ERROR\n\t\t\tmysqlError.errno === 2003 || // Can't connect to MySQL server\n\t\t\tmysqlError.errno === 2002; // Can't connect to local MySQL server\n\n\t\tconst isConnectionError =\n\t\t\tisMysqlConnectionError ||\n\t\t\te.message.includes(\"ECONNREFUSED\") ||\n\t\t\te.message.includes(\"connection refused\") ||\n\t\t\te.message.includes(\"timeout expired\") ||\n\t\t\te.message.includes(\"Connection terminated\") ||\n\t\t\t(e instanceof DatabaseError && e.code?.startsWith(\"08\")); // PostgreSQL connection exception class\n\n\t\tif (isConnectionError) {\n\t\t\treturn c.json<ApiError>(\n\t\t\t\t{ error: \"Database connection failed\", details: e.message },\n\t\t\t\t503,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn c.json<ApiError>(\n\t\t{\n\t\t\terror: e instanceof Error ? e.message : \"Internal server error\",\n\t\t},\n\t\t500,\n\t);\n}\n\nexport const validationHook = (\n\tresult: {\n\t\tsuccess: boolean;\n\t\tdata?: unknown;\n\t\terror?: { issues: { message: string }[] };\n\t},\n\tc: Context,\n): Response | undefined => {\n\tif (!result.success) {\n\t\tconst issue = result.error?.issues[0];\n\t\treturn c.json<ApiError>(\n\t\t\t{\n\t\t\t\terror: \"Validation error\",\n\t\t\t\tdetails: issue?.message ?? \"Unknown validation error\",\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n};\n","import { Pool } from \"pg\";\n\nlet dbInstance: Pool | null = null;\n\nconst getPool = (): Pool => {\n\tif (!dbInstance) {\n\t\tif (!process.env.DATABASE_URL) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\t\ttry {\n\t\t\tdbInstance = new Pool({\n\t\t\t\tconnectionString: process.env.DATABASE_URL,\n\t\t\t});\n\n\t\t\t// Handle pool errors to prevent server crashes\n\t\t\t// This catches connection errors, idle client errors, etc.\n\t\t\tdbInstance.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\"Unexpected database pool error:\", err.message);\n\t\t\t\t// Don't throw - just log the error to prevent server crash\n\t\t\t\t// The pool will automatically retry connections\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to create database pool:\", error);\n\t\t\t// Re-throw initialization errors as they indicate a configuration problem\n\t\t\tthrow error;\n\t\t}\n\t}\n\treturn dbInstance;\n};\n\n// Export db as a Proxy that lazily initializes the pool\n// This allows process.env.DATABASE_URL to be set after module import\nexport const db = new Proxy({} as Pool, {\n\tget(_target, prop) {\n\t\ttry {\n\t\t\treturn getPool()[prop as keyof Pool];\n\t\t} catch (error) {\n\t\t\t// If pool initialization fails, log and re-throw\n\t\t\tconsole.error(\"Database pool access error:\", error);\n\t\t\tthrow error;\n\t\t}\n\t},\n});\n","import type { Pool as MysqlPool } from \"mysql2/promise\";\nimport { createPool as createMysqlPool } from \"mysql2/promise\";\nimport { Pool, type PoolConfig } from \"pg\";\nimport type { DatabaseTypeSchema } from \"shared/types\";\n\n/**\n * DatabaseManager - Manages multiple database connection pools for both PostgreSQL and MySQL\n */\nclass DatabaseManager {\n\tprivate pgPools: Map<string, Pool> = new Map();\n\tprivate mysqlPools: Map<string, MysqlPool> = new Map();\n\tprivate baseConfig: {\n\t\turl: string;\n\t\thost: string;\n\t\tport: number;\n\t\tuser: string;\n\t\tpassword: string;\n\t\tdbType: DatabaseTypeSchema;\n\t} | null = null;\n\n\tconstructor() {\n\t\tthis.initializeBaseConfig();\n\t}\n\n\t/**\n\t * Detect database type from URL protocol\n\t */\n\tprivate detectDbType(url: URL): DatabaseTypeSchema {\n\t\tconst protocol = url.protocol.replace(\":\", \"\");\n\t\tif (protocol === \"postgres\" || protocol === \"postgresql\") {\n\t\t\treturn \"pg\";\n\t\t}\n\t\tif (protocol === \"mysql\" || protocol === \"mysql2\") {\n\t\t\treturn \"mysql\";\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Unsupported database type: ${protocol}. Supported types: PostgreSQL (postgres://) and MySQL (mysql://).`,\n\t\t);\n\t}\n\n\t/**\n\t * Parse DATABASE_URL and extract connection details\n\t */\n\tprivate initializeBaseConfig() {\n\t\tconst databaseUrl = process.env.DATABASE_URL;\n\t\tif (!databaseUrl) {\n\t\t\tthrow new Error(\"DATABASE_URL is not set. Please provide a database connection string.\");\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(databaseUrl);\n\t\t\tthis.baseConfig = {\n\t\t\t\turl: databaseUrl,\n\t\t\t\thost: url.hostname,\n\t\t\t\tport:\n\t\t\t\t\tNumber.parseInt(url.port, 10) || (this.detectDbType(url) === \"mysql\" ? 3306 : 5432),\n\t\t\t\tuser: url.username,\n\t\t\t\tpassword: url.password,\n\t\t\t\tdbType: this.detectDbType(url),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new Error(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\t/**\n\t * Get the detected database type\n\t */\n\tgetDbType(): DatabaseTypeSchema {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\t\treturn this.baseConfig.dbType;\n\t}\n\n\t/**\n\t * Build a connection string for the specified database\n\t */\n\tbuildConnectionString(database?: string): string {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tif (!database) {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\tdatabase = url.pathname.slice(1);\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(this.baseConfig.url);\n\t\t\turl.pathname = `/${database}`;\n\t\t\treturn url.toString();\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to build connection string for database \"${database}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get or create a PostgreSQL connection pool for the specified database\n\t */\n\tgetPgPool(database?: string): Pool {\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.pgPools.has(connectionString)) {\n\t\t\tconst poolConfig: PoolConfig = {\n\t\t\t\tconnectionString,\n\t\t\t\tmax: 10,\n\t\t\t\tidleTimeoutMillis: 30000,\n\t\t\t\tconnectionTimeoutMillis: 2000,\n\t\t\t};\n\n\t\t\tconst pool = new Pool(poolConfig);\n\n\t\t\tpool.on(\"error\", (err) => {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Unexpected error on PostgreSQL pool for \"${connectionString}\":`,\n\t\t\t\t\terr.message,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tthis.pgPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.pgPools.get(connectionString) ?? new Pool({ connectionString });\n\t}\n\n\t/**\n\t * Get or create a MySQL connection pool for the specified database\n\t */\n\tgetMysqlPool(database?: string): MysqlPool {\n\t\tif (!this.baseConfig) {\n\t\t\tthrow new Error(\"Base configuration not initialized\");\n\t\t}\n\n\t\tconst connectionString = this.buildConnectionString(database);\n\n\t\tif (!this.mysqlPools.has(connectionString)) {\n\t\t\tconst url = new URL(connectionString);\n\t\t\tconst dbName = url.pathname.slice(1);\n\n\t\t\tconst pool = createMysqlPool({\n\t\t\t\thost: this.baseConfig.host,\n\t\t\t\tport: this.baseConfig.port,\n\t\t\t\tuser: this.baseConfig.user,\n\t\t\t\tpassword: this.baseConfig.password,\n\t\t\t\tdatabase: dbName || undefined,\n\t\t\t\twaitForConnections: true,\n\t\t\t\tconnectionLimit: 10,\n\t\t\t\tidleTimeout: 30000,\n\t\t\t\tconnectTimeout: 2000,\n\t\t\t\t// Enable multiple statements for raw query support\n\t\t\t\tmultipleStatements: false,\n\t\t\t});\n\n\t\t\tthis.mysqlPools.set(connectionString, pool);\n\t\t\tconsole.log(`Created MySQL connection pool for: ${connectionString}`);\n\t\t}\n\n\t\treturn this.mysqlPools.get(connectionString) as MysqlPool;\n\t}\n\n\t/**\n\t * Get the appropriate pool based on database type (legacy/PG-only helper)\n\t */\n\tgetPool(database?: string): Pool {\n\t\treturn this.getPgPool(database);\n\t}\n\n\t/**\n\t * Close a specific PostgreSQL pool by connection string\n\t */\n\tasync closePgPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.pgPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.pgPools.delete(connectionString);\n\t\t\tconsole.log(`Closed PostgreSQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific MySQL pool by connection string\n\t */\n\tasync closeMysqlPool(connectionString: string): Promise<void> {\n\t\tconst pool = this.mysqlPools.get(connectionString);\n\t\tif (pool) {\n\t\t\tawait pool.end();\n\t\t\tthis.mysqlPools.delete(connectionString);\n\t\t\tconsole.log(`Closed MySQL connection pool for: ${connectionString}`);\n\t\t}\n\t}\n\n\t/**\n\t * Close a specific database pool by connection string (both types)\n\t */\n\tasync closePool(connectionString: string): Promise<void> {\n\t\tawait this.closePgPool(connectionString);\n\t\tawait this.closeMysqlPool(connectionString);\n\t}\n\n\t/**\n\t * Close a specific database pool by database name\n\t */\n\tasync closePoolByDatabase(database: string): Promise<void> {\n\t\tconst connectionString = this.buildConnectionString(database);\n\t\tawait this.closePool(connectionString);\n\t}\n\n\t/**\n\t * Close all database pools\n\t */\n\tasync closeAll(): Promise<void> {\n\t\tconst pgClosePromises = Array.from(this.pgPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed PostgreSQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tconst mysqlClosePromises = Array.from(this.mysqlPools.entries()).map(\n\t\t\tasync ([connectionString, pool]) => {\n\t\t\t\tawait pool.end();\n\t\t\t\tconsole.log(`Closed MySQL pool for: ${connectionString}`);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all([...pgClosePromises, ...mysqlClosePromises]);\n\t\tthis.pgPools.clear();\n\t\tthis.mysqlPools.clear();\n\t}\n\n\t/**\n\t * Get all active pool connection strings\n\t */\n\tgetActivePools(): string[] {\n\t\treturn [...Array.from(this.pgPools.keys()), ...Array.from(this.mysqlPools.keys())];\n\t}\n}\n\n// Singleton instance\nconst databaseManager = new DatabaseManager();\n\n/**\n * Get a PostgreSQL pool for the specified database\n */\nexport const getDbPool = (database?: string): Pool => {\n\treturn databaseManager.getPgPool(database);\n};\n\n/**\n * Get a MySQL pool for the specified database\n */\nexport const getMysqlPool = (database?: string): MysqlPool => {\n\treturn databaseManager.getMysqlPool(database);\n};\n\n/**\n * Get the detected database type from DATABASE_URL\n */\nexport const getDbType = (): DatabaseTypeSchema => {\n\treturn databaseManager.getDbType();\n};\n\n/**\n * Build a connection string for the specified database\n */\nconst _buildDbConnectionString = (database?: string): string => {\n\treturn databaseManager.buildConnectionString(database);\n};\n\n/**\n * Close a specific database pool by database name\n */\nconst _closeDbPool = async (database: string): Promise<void> => {\n\treturn databaseManager.closePoolByDatabase(database);\n};\n\n/**\n * Close a specific database pool by connection string\n */\nconst _closeDbPoolByConnectionString = async (connectionString: string): Promise<void> => {\n\treturn databaseManager.closePool(connectionString);\n};\n\n/**\n * Close all database pools\n */\nconst _closeAllDbPools = async (): Promise<void> => {\n\treturn databaseManager.closeAll();\n};\n\n/**\n * Get list of active pool connection strings\n */\nconst _getActivePools = (): string[] => {\n\treturn databaseManager.getActivePools();\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ColumnInfoSchemaType,\n\ttype DatabaseSchemaType,\n\tmapPostgresToDataType,\n\tstandardizeDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n SELECT \n c.column_name as \"columnName\",\n c.data_type as \"dataType\",\n c.udt_name as \"udtName\",\n c.is_nullable = 'YES' as \"isNullable\",\n c.column_default as \"columnDefault\",\n CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as \"isPrimaryKey\",\n CASE WHEN fk.column_name IS NOT NULL THEN true ELSE false END as \"isForeignKey\",\n fk.referenced_table as \"referencedTable\",\n fk.referenced_column as \"referencedColumn\",\n CASE \n WHEN c.data_type = 'USER-DEFINED' THEN \n (SELECT array_agg(e.enumlabel ORDER BY e.enumsortorder)\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n WHERE t.typname = c.udt_name)\n ELSE NULL\n END as \"enumValues\"\n FROM information_schema.columns c\n LEFT JOIN (\n SELECT ku.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage ku\n ON tc.constraint_name = ku.constraint_name\n AND tc.table_schema = ku.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) pk ON c.column_name = pk.column_name\n LEFT JOIN (\n SELECT \n kcu.column_name,\n ccu.table_name AS referenced_table,\n ccu.column_name AS referenced_column\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.table_schema = ccu.table_schema\n WHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = 'public'\n AND tc.table_name = $1\n ) fk ON c.column_name = fk.column_name\n WHERE c.table_schema = 'public'\n AND c.table_name = $1\n ORDER BY c.ordinal_position;\n `;\n\n\tconst { rows } = await pool.query(query, [tableName]);\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\t// Parse enumValues to always return string[] | null\n\t\tlet parsedEnumValues: string[] | null = null;\n\t\tif (r.enumValues) {\n\t\t\tif (Array.isArray(r.enumValues)) {\n\t\t\t\t// Already an array, use as-is\n\t\t\t\tparsedEnumValues = r.enumValues;\n\t\t\t} else if (typeof r.enumValues === \"string\") {\n\t\t\t\t// Parse PostgreSQL array format: \"{VALUE1,VALUE2,VALUE3}\"\n\t\t\t\tparsedEnumValues = r.enumValues.replace(/[{}]/g, \"\").split(\",\").filter(Boolean);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapPostgresToDataType(r.dataType),\n\t\t\tdataTypeLabel: standardizeDataTypeLabel(r.dataType),\n\t\t\tisNullable: r.isNullable,\n\t\t\tcolumnDefault: r.columnDefault,\n\t\t\tisPrimaryKey: r.isPrimaryKey,\n\t\t\tisForeignKey: r.isForeignKey,\n\t\t\treferencedTable: r.referencedTable,\n\t\t\treferencedColumn: r.referencedColumn,\n\t\t\tenumValues: parsedEnumValues,\n\t\t};\n\t});\n}\n","import type {\n\tColumn,\n\tColumnInfoSchemaType,\n\tDatabaseSchema,\n\tDatabaseSchemaType,\n\tRelationship,\n\tTable,\n} from \"shared/types\";\nimport { db } from \"@/db.js\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.dao.js\";\n\n/**\n * Get all table names from the database\n */\nasync function getTableNames(db: DatabaseSchemaType[\"db\"]): Promise<string[]> {\n\tconst pool = getDbPool(db);\n\tconst query = `\n\t\tSELECT table_name\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = 'public'\n\t\t\tAND table_type = 'BASE TABLE'\n\t\tORDER BY table_name;\n\t`;\n\tconst { rows } = await pool.query(query);\n\treturn rows.map((r) => r.table_name);\n}\n\n/**\n * Get table comment/description if available\n */\nasync function getTableDescription(tableName: string): Promise<string | undefined> {\n\tconst client = await db.connect();\n\ttry {\n\t\tconst res = await client.query(\n\t\t\t`\n SELECT obj_description(oid) as description\n FROM pg_class\n WHERE relname = $1\n AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');\n `,\n\t\t\t[tableName],\n\t\t);\n\t\treturn res.rows[0]?.description || undefined;\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Get sample data from a table (first 3 rows)\n */\nasync function getSampleData(tableName: string): Promise<Record<string, unknown>[]> {\n\tconst client = await db.connect();\n\ttry {\n\t\t// Sanitize table name to prevent SQL injection\n\t\t// In production, validate tableName against known tables list\n\t\tconst res = await client.query(`SELECT * FROM \"${tableName}\" LIMIT 3`);\n\t\treturn res.rows;\n\t} catch (error) {\n\t\tconsole.warn(`Could not fetch sample data for table ${tableName}:`, error);\n\t\treturn [];\n\t} finally {\n\t\tclient.release();\n\t}\n}\n\n/**\n * Convert ColumnInfo to the schema Column format\n */\nfunction convertColumnInfo(col: ColumnInfoSchemaType): Column {\n\tconst column: Column = {\n\t\tname: col.columnName,\n\t\ttype: col.dataTypeLabel,\n\t\tnullable: col.isNullable,\n\t};\n\n\tif (col.isPrimaryKey) {\n\t\tcolumn.isPrimaryKey = true;\n\t}\n\n\tif (col.isForeignKey && col.referencedTable && col.referencedColumn) {\n\t\tcolumn.foreignKey = `${col.referencedTable}.${col.referencedColumn}`;\n\t}\n\n\tif (col.enumValues && col.enumValues.length > 0) {\n\t\tcolumn.enumValues = col.enumValues;\n\t\tcolumn.description = `Enum values: ${col.enumValues.join(\", \")}`;\n\t}\n\n\treturn column;\n}\n\n/**\n * Extract all relationships from table columns\n */\nfunction extractRelationships(tables: Table[]): Relationship[] {\n\tconst relationships: Relationship[] = [];\n\n\tfor (const table of tables) {\n\t\tfor (const column of table.columns) {\n\t\t\tif (column.foreignKey) {\n\t\t\t\tconst [toTable, toColumn] = column.foreignKey.split(\".\");\n\t\t\t\trelationships.push({\n\t\t\t\t\tfromTable: table.name,\n\t\t\t\t\tfromColumn: column.name,\n\t\t\t\t\ttoTable,\n\t\t\t\t\ttoColumn,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn relationships;\n}\n\n/**\n * Get complete database schema with all tables, columns, and relationships\n */\nasync function getDatabaseSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n\toptions: {\n\t\tincludeSampleData?: boolean;\n\t\tincludeDescriptions?: boolean;\n\t\tmaxTables?: number;\n\t} = {},\n): Promise<DatabaseSchema> {\n\tconst {\n\t\tincludeSampleData = false,\n\t\tincludeDescriptions = true,\n\t\t// maxTables = 50, // Prevent overwhelming the context\n\t} = options;\n\n\ttry {\n\t\tconst tableNames = await getTableNames(db);\n\n\t\t// Fetch schema info for each table in parallel\n\t\tconst tablePromises = tableNames.map(async (tableName) => {\n\t\t\tconst [columns, description, sampleData] = await Promise.all([\n\t\t\t\tgetTableColumns({ tableName, db }),\n\t\t\t\tincludeDescriptions ? getTableDescription(tableName) : Promise.resolve(undefined),\n\t\t\t\tincludeSampleData ? getSampleData(tableName) : Promise.resolve([]),\n\t\t\t]);\n\n\t\t\tconst table: Table = {\n\t\t\t\tname: tableName,\n\t\t\t\tcolumns: columns.map(convertColumnInfo),\n\t\t\t};\n\n\t\t\tif (description) {\n\t\t\t\ttable.description = description;\n\t\t\t}\n\n\t\t\tif (sampleData.length > 0) {\n\t\t\t\ttable.sampleData = sampleData.map((row) =>\n\t\t\t\t\tObject.fromEntries(Object.entries(row).map(([key, value]) => [key, String(value)])),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn table;\n\t\t});\n\n\t\tconst tables = await Promise.all(tablePromises);\n\n\t\t// Extract relationships from foreign keys\n\t\tconst relationships = extractRelationships(tables);\n\n\t\treturn {\n\t\t\tdbType: \"PostgreSQL\",\n\t\t\ttables,\n\t\t\trelationships,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Error fetching database schema:\", error);\n\t\tthrow new Error(\n\t\t\t`Failed to fetch database schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n\n/**\n * Get detailed schema with sample data (for initial conversation context)\n */\nexport async function getDetailedSchema(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<DatabaseSchema> {\n\treturn getDatabaseSchema(db, {\n\t\tincludeSampleData: true,\n\t\tincludeDescriptions: true,\n\t\t// maxTables: 30, // todo: DELETE THIS AFTER TESTING\n\t});\n}\n","import type { DatabaseSchema } from \"shared/types\";\n\n/**\n * Generate system prompt with database context\n */\nexport function generateSystemPrompt(schema: DatabaseSchema): string {\n\treturn `You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.\n\n**Your Role:**\n1. Keep responses SHORT - 2-3 sentences maximum unless generating SQL\n2. When generating SQL:\n - Provide 1 sentence explanation\n - The SQL query in a code block\n - 1 sentence about expected results\n - NO verbose explanations\n3. Use exact table/column names from the schema\n4. Generate valid ${schema.dbType} syntax\n5. If query is unclear, ask ONE specific clarifying question\n6. No preamble, no apologies, get straight to the answer\n\n**Database Context:**\n${formatSchemaForPrompt(schema)}\n\n**Guidelines:**\n1. Always generate syntactically correct SQL for the database type (${schema.dbType})\n2. Use proper table/column names exactly as defined in the schema\n3. When generating queries, wrap them in \\`\\`\\`sql code blocks\n4. Explain what the query does in plain language\n5. Suggest relevant follow-up questions or analyses\n6. If a request is ambiguous, ask clarifying questions\n7. For complex queries, break down the logic step-by-step\n8. Warn about potentially expensive operations (full table scans, etc.)\n9. Consider data privacy - remind users not to share sensitive data externally\n\n**Response Format:**\nWhen generating queries, use this structure:\n- Brief explanation of what you'll do\n- The SQL query in a code block\n- Expected results description\n- Optional: suggestions for related queries\n\n**Example:**\nUser: \"Show me the top 5 customers by revenue\"\n\nResponse: \"I'll query the orders and customers tables to find your highest-value customers.\n\n\\`\\`\\`sql\nSELECT \n c.customer_name,\n SUM(o.total_amount) as total_revenue\nFROM customers c\nJOIN orders o ON c.id = o.customer_id\nGROUP BY c.id, c.customer_name\nORDER BY total_revenue DESC\nLIMIT 5;\n\\`\\`\\`\n\nThis will return the 5 customers with the highest total order value. You might also want to see:\n- Revenue trends over time for these customers\n- Their most frequently ordered products\"`;\n}\n\n/**\n * Format schema information for the prompt\n */\nfunction formatSchemaForPrompt(schema: DatabaseSchema): string {\n\tlet output = `Database Type: ${schema.dbType}\\n\\n`;\n\n\toutput += \"**Tables and Columns:**\\n\";\n\tfor (const table of schema.tables) {\n\t\toutput += `\\n### ${table.name}\\n`;\n\t\tif (table.description) {\n\t\t\toutput += `Description: ${table.description}\\n`;\n\t\t}\n\t\toutput += \"Columns:\\n\";\n\n\t\tfor (const col of table.columns) {\n\t\t\tconst pkIndicator = col.isPrimaryKey ? \" [PRIMARY KEY]\" : \"\";\n\t\t\tconst fkIndicator = col.foreignKey ? ` [FK -> ${col.foreignKey}]` : \"\";\n\t\t\tconst nullable = col.nullable ? \"NULL\" : \"NOT NULL\";\n\n\t\t\toutput += ` - ${col.name}: ${col.type} ${nullable}${pkIndicator}${fkIndicator}\\n`;\n\t\t\tif (col.description) {\n\t\t\t\toutput += ` ${col.description}\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Add sample data if available\n\t\tif (table.sampleData && table.sampleData.length > 0) {\n\t\t\toutput += `Sample data (${table.sampleData.length} rows):\\n`;\n\t\t\toutput += `${JSON.stringify(table.sampleData.slice(0, 3), null, 2)}\\n`;\n\t\t}\n\t}\n\n\t// Add relationships\n\tif (schema.relationships && schema.relationships.length > 0) {\n\t\toutput += \"\\n**Relationships:**\\n\";\n\t\tfor (const rel of schema.relationships) {\n\t\t\toutput += ` - ${rel.fromTable}.${rel.fromColumn} -> ${rel.toTable}.${rel.toColumn}\\n`;\n\t\t}\n\t}\n\n\treturn output;\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { chatSchema } from \"shared/types\";\nimport { getDetailedSchema } from \"@/dao/table-details-schema.js\";\nimport { generateSystemPrompt } from \"@/utils/system-prompt-generator.js\";\n\nexport const chatRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /:dbType/chat/...\n\t */\n\t.basePath(\"/chat\")\n\n\t/**\n\t * POST /chat - Handle AI chat requests with streaming\n\t * Proxies to the Cloudflare Worker which has the Gemini API key\n\t */\n\t.post(\"/\", zValidator(\"json\", chatSchema), async (c) => {\n\t\tconst { messages, conversationId, db } = c.req.valid(\"json\");\n\t\tconsole.log(\"POST /chat messages\", messages);\n\n\t\t// Get the database schema and generate system prompt\n\t\tconst schema = await getDetailedSchema(db);\n\t\tconst systemPrompt = generateSystemPrompt(schema);\n\n\t\tconst payload = {\n\t\t\tmessages,\n\t\t\tconversationId,\n\t\t\tsystemPrompt,\n\t\t};\n\n\t\t// Forward request to the proxy with the system prompt\n\t\tconst proxyResponse = await fetch(`${DEFAULTS.PROXY_URL}/chat`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload),\n\t\t});\n\n\t\tif (!proxyResponse.ok) {\n\t\t\tconst errorData = await proxyResponse.json();\n\t\t\treturn c.json(\n\t\t\t\t{ error: errorData.error || \"Proxy request failed\" },\n\t\t\t\tproxyResponse.status as 400 | 500,\n\t\t\t);\n\t\t}\n\n\t\t// Stream the SSE response back to the client\n\t\tconst { readable, writable } = new TransformStream();\n\t\tproxyResponse.body?.pipeTo(writable);\n\n\t\treturn new Response(readable, {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\tConnection: \"keep-alive\",\n\t\t\t},\n\t\t});\n\t});\n\nexport type ChatRoutes = typeof chatRoutes;\n","/**\n * Parse DATABASE_URL to extract host and port\n */\nexport function parseDatabaseUrl(): { host: string; port: number } {\n\tconst databaseUrl = process.env.DATABASE_URL;\n\n\tif (!databaseUrl) {\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n\n\ttry {\n\t\tconst url = new URL(databaseUrl);\n\t\treturn {\n\t\t\thost: url.hostname || \"localhost\",\n\t\t\tport: Number.parseInt(url.port, 10) || 5432,\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(\"Failed to parse DATABASE_URL:\", error);\n\t\treturn { host: \"localhost\", port: 5432 };\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport {\n\ttype ConnectionInfoSchemaType,\n\tconnectionInfoSchema,\n\ttype DatabaseInfoSchemaType,\n\ttype DatabaseSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all normal databases on the PostgreSQL server.\n * Returns name, size (human readable), owner, and encoding.\n *\n * @returns List of database information objects\n * @throws Error if query fails or no databases are found\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n d.datname as name,\n pg_size_pretty(pg_database_size(d.datname)) as size,\n pg_catalog.pg_get_userbyid(d.datdba) as owner,\n pg_encoding_to_char(d.encoding) as encoding\n FROM pg_catalog.pg_database d\n WHERE d.datistemplate = false\n ORDER BY d.datname;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from database\",\n\t\t});\n\t}\n\n\treturn rows;\n}\n\n/**\n * Gets the name of the database we are currently using.\n *\n * @returns Object with current database name\n * @throws Error if query fails or no name is returned\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = \"SELECT current_database() as database;\";\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from database\",\n\t\t});\n\t}\n\n\treturn rows[0];\n}\n\n/**\n * Gets useful information about the connection and PostgreSQL server.\n * Includes version, host, port, user, database name, active connections, etc.\n *\n * Uses fallback values from DATABASE_URL if some fields are missing.\n *\n * @returns Connection and server information object\n * @throws Error if query fails or result is invalid\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getDbPool();\n\tconst query = `\n SELECT \n version() as version,\n current_database() as database,\n current_user as user,\n inet_server_addr() as host,\n inet_server_port() as port,\n (SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,\n (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;\n `;\n\n\tconst { rows } = await pool.query(query);\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from database\",\n\t\t});\n\t}\n\n\t// Validate main result\n\tconst result = connectionInfoSchema.parse(rows[0]);\n\n\t// Use DATABASE_URL as backup for host/port if needed\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: result.host || urlDefaults.host,\n\t\tport: result.port || urlDefaults.port,\n\t\tuser: result.user,\n\t\tdatabase: result.database,\n\t\tversion: result.version.toString(),\n\t\tactive_connections: result.active_connections,\n\t\tmax_connections: result.max_connections,\n\t};\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tConnectionInfoSchemaType,\n\tDatabaseInfoSchemaType,\n\tDatabaseSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { parseDatabaseUrl } from \"@/utils/parse-database-url.js\";\n\n/**\n * Gets list of all databases (schemas) on the MySQL server.\n * Returns name, size (human-readable), owner (connected user), and encoding (charset).\n */\nexport async function getDatabasesList(): Promise<DatabaseInfoSchemaType[]> {\n\tconst pool = getMysqlPool();\n\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t s.SCHEMA_NAME AS name,\n\t\t CONCAT(\n\t\t ROUND(\n\t\t COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024,\n\t\t 2\n\t\t ),\n\t\t ' MB'\n\t\t ) AS size,\n\t\t CURRENT_USER() AS owner,\n\t\t s.DEFAULT_CHARACTER_SET_NAME AS encoding\n\t\tFROM information_schema.SCHEMATA s\n\t\tLEFT JOIN information_schema.TABLES t\n\t\t ON t.TABLE_SCHEMA = s.SCHEMA_NAME\n\t\tGROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME\n\t\tORDER BY s.SCHEMA_NAME\n\t`);\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No databases returned from server\",\n\t\t});\n\t}\n\n\treturn rows as DatabaseInfoSchemaType[];\n}\n\n/**\n * Gets the name of the database currently in use.\n */\nexport async function getCurrentDatabase(): Promise<DatabaseSchemaType> {\n\tconst pool = getMysqlPool();\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\"SELECT DATABASE() AS db\");\n\n\tif (!rows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No current database returned from server\",\n\t\t});\n\t}\n\n\treturn (rows as Array<{ db: string }>)[0] as DatabaseSchemaType;\n}\n\n/**\n * Gets connection and server information for MySQL.\n */\nexport async function getDatabaseConnectionInfo(): Promise<ConnectionInfoSchemaType> {\n\tconst pool = getMysqlPool();\n\n\tconst [infoRows] = await pool.execute<RowDataPacket[]>(`\n\t\tSELECT\n\t\t VERSION() AS version,\n\t\t DATABASE() AS database_name,\n\t\t CURRENT_USER() AS user,\n\t\t @@hostname AS host,\n\t\t @@port AS port,\n\t\t @@max_connections AS max_connections\n\t`);\n\n\tconst [connRows] = await pool.execute<RowDataPacket[]>(\n\t\t\"SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST\",\n\t);\n\n\tif (!infoRows[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No connection information returned from server\",\n\t\t});\n\t}\n\n\tconst info = (infoRows as Array<Record<string, string | number>>)[0];\n\tconst activeConnections = Number((connRows as Array<{ cnt: number }>)[0]?.cnt ?? 0);\n\n\tconst urlDefaults = parseDatabaseUrl();\n\n\treturn {\n\t\thost: String(info.host || urlDefaults.host),\n\t\tport: Number(info.port || urlDefaults.port),\n\t\tuser: String(info.user),\n\t\tdatabase: String(info.database_name ?? \"\"),\n\t\tversion: String(info.version),\n\t\tactive_connections: activeConnections,\n\t\tmax_connections: Number(info.max_connections),\n\t};\n}\n","import { Hono } from \"hono\";\nimport type {\n\tConnectionInfoSchemaType,\n\tCurrentDatabaseSchemaType,\n\tDatabaseListSchemaType,\n} from \"shared/types\";\nimport type { ApiHandler } from \"@/app.types.js\";\nimport {\n\tgetCurrentDatabase as pgGetCurrentDatabase,\n\tgetDatabaseConnectionInfo as pgGetDatabaseConnectionInfo,\n\tgetDatabasesList as pgGetDatabasesList,\n} from \"@/dao/database-list.dao.js\";\nimport {\n\tgetCurrentDatabase as mysqlGetCurrentDatabase,\n\tgetDatabaseConnectionInfo as mysqlGetDatabaseConnectionInfo,\n\tgetDatabasesList as mysqlGetDatabasesList,\n} from \"@/dao/mysql/database-list.mysql.dao.js\";\nimport { getDbType } from \"@/db-manager.js\";\n\n/**\n * /databases routes (at root level, no dbType required)\n * GET /databases - Get list of all databases on the server (name, size, owner, encoding)\n * GET /databases/current - Get the name of the database we are currently connected to\n * GET /databases/connection - Get connection details and server information\n */\nexport const databasesRoutes = new Hono()\n\t/**\n\t * Base path for the endpoints, /databases/...\n\t */\n\t.basePath(\"/databases\")\n\n\t/**\n\t * GET /databases\n\t * Returns list of all databases on the server (name, size, owner, encoding) and the database type\n\t */\n\t.get(\"/\", async (c): ApiHandler<DatabaseListSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst databases =\n\t\t\tdbType === \"mysql\" ? await mysqlGetDatabasesList() : await pgGetDatabasesList();\n\t\treturn c.json({ data: { databases, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/current\n\t * Returns the name of the database we are currently connected to and the database type\n\t */\n\t.get(\"/current\", async (c): ApiHandler<CurrentDatabaseSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst current =\n\t\t\tdbType === \"mysql\" ? await mysqlGetCurrentDatabase() : await pgGetCurrentDatabase();\n\t\treturn c.json({ data: { db: current.db, dbType } }, 200);\n\t})\n\n\t/**\n\t * GET /databases/connection\n\t * Returns connection details and server information\n\t */\n\t.get(\"/connection\", async (c): ApiHandler<ConnectionInfoSchemaType> => {\n\t\tconst dbType = getDbType();\n\t\tconst info =\n\t\t\tdbType === \"mysql\"\n\t\t\t\t? await mysqlGetDatabaseConnectionInfo()\n\t\t\t\t: await pgGetDatabaseConnectionInfo();\n\t\treturn c.json({ data: info }, 200);\n\t});\n\nexport type DatabasesRoutes = typeof databasesRoutes.routes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { FieldPacket, ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getMysqlPool(db);\n\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\t// mysql2 returns [rows, fields] for SELECT and [ResultSetHeader, fields] for DML\n\tconst [result, fields] = (await pool.execute(cleanedQuery)) as [\n\t\tRowDataPacket[] | ResultSetHeader,\n\t\tFieldPacket[],\n\t];\n\tconst duration = performance.now() - startTime;\n\n\t// SELECT-like results have an array of rows\n\tif (Array.isArray(result)) {\n\t\tconst rows = result as RowDataPacket[];\n\t\tconst columns = fields ? fields.map((f) => f.name) : Object.keys(rows[0] ?? {});\n\t\treturn {\n\t\t\tcolumns,\n\t\t\trows: rows as Record<string, unknown>[],\n\t\t\trowCount: rows.length,\n\t\t\tduration,\n\t\t\tmessage: rows.length === 0 ? \"OK\" : undefined,\n\t\t};\n\t}\n\n\t// DML results (INSERT, UPDATE, DELETE)\n\tconst dmlResult = result as ResultSetHeader;\n\treturn {\n\t\tcolumns: [],\n\t\trows: [],\n\t\trowCount: dmlResult.affectedRows,\n\t\tduration,\n\t\tmessage: `OK — ${dmlResult.affectedRows} row(s) affected`,\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, ExecuteQueryParams, ExecuteQueryResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const executeQuery = async ({\n\tquery,\n\tdb,\n}: {\n\tquery: ExecuteQueryParams[\"query\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ExecuteQueryResult> => {\n\tconst pool = getDbPool(db);\n\tif (!query || !query.trim()) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Query is required\",\n\t\t});\n\t}\n\n\t// Clean the query - remove trailing semicolons and whitespace\n\tconst cleanedQuery = query.trim().replace(/;+$/, \"\");\n\n\tconst startTime = performance.now();\n\tconst result = await pool.query(cleanedQuery);\n\tconst duration = performance.now() - startTime;\n\n\tconst columns = result.fields.map((field) => field.name);\n\n\treturn {\n\t\tcolumns,\n\t\trows: result.rows,\n\t\trowCount: result.rows.length,\n\t\tduration,\n\t\tmessage: result.rows.length === 0 ? \"OK\" : undefined,\n\t};\n};\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { databaseSchema, type ExecuteQueryResult, executeQuerySchema } from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { executeQuery as mysqlExecuteQuery } from \"@/dao/mysql/query.mysql.dao.js\";\nimport { executeQuery as pgExecuteQuery } from \"@/dao/query.dao.js\";\n\nexport const queryRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/query/...\n\t */\n\t.basePath(\"/query\")\n\n\t/**\n\t * POST /query\n\t * Executes a SQL query on the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", executeQuerySchema),\n\t\tasync (c): ApiHandler<ExecuteQueryResult> => {\n\t\t\tconst { query } = c.req.valid(\"json\");\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst data =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlExecuteQuery({ query, db })\n\t\t\t\t\t: await pgExecuteQuery({ query, db });\n\t\t\treturn c.json({ data }, 200);\n\t\t},\n\t);\n\nexport type QueryRoutes = typeof queryRoutes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getDbPool(db);\n\n\t// Extract column names and values\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data);\n\n\t// Build the INSERT query\n\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\tconst query = `\n\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\tVALUES (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\tconst result = await pool.query(query, values);\n\tif (result.rowCount === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getDbPool(db);\n\tconst client = await pool.connect();\n\n\ttry {\n\t\t// Get column names from the first record\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\"${col}\"`).join(\", \");\n\n\t\tlet successCount = 0;\n\t\tconst failureCount = 0;\n\t\tconst errors: Array<{ recordIndex: number; error: string }> = [];\n\n\t\t// Execute inserts in a transaction\n\t\tawait client.query(\"BEGIN\");\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => record[col]);\n\n\t\t\tconst placeholders = columns.map((_, index) => `$${index + 1}`).join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \"${tableName}\" (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\tawait client.query(insertSQL, values);\n\t\t\t\tsuccessCount++;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait client.query(\"COMMIT\");\n\n\t\treturn {\n\t\t\tsuccess: failureCount === 0,\n\t\t\tmessage: `Bulk insert completed: ${successCount} records inserted${failureCount > 0 ? `, ${failureCount} failed` : \"\"}`,\n\t\t\tsuccessCount,\n\t\t\tfailureCount,\n\t\t\terrors: errors.length > 0 ? errors : undefined,\n\t\t};\n\t} catch (error) {\n\t\tawait client.query(\"ROLLBACK\");\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tclient.release();\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Finds all records in other tables that reference the given primary key values\n */\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\t// Group constraints by referencing table and column for efficiency\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) {\n\t\t\tconstraintsByTable.set(key, []);\n\t\t}\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\t// Get the primary key values that we're looking for\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\t// Find which primary key column matches this FK's referenced column\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\t// Build query to find related records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tWHERE \"${constraint.referencingColumn}\" IN (${placeholders})\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery, pkValues);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Attempts to delete records. If FK violation occurs, returns related records.\n */\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\n\tconst query = `\n\t\tDELETE FROM \"${tableName}\"\n\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\tRETURNING *\n\t`;\n\n\ttry {\n\t\tawait pool.query(\"BEGIN\");\n\t\tconst result = await pool.query(query, pkValues);\n\t\tawait pool.query(\"COMMIT\");\n\t\treturn { deletedCount: result.rowCount ?? 0, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\t// Check if this is a foreign key violation\n\t\tconst pgError = error as {\n\t\t\tcode?: string;\n\t\t\tdetail?: string;\n\t\t\tconstraint?: string;\n\t\t};\n\n\t\tif (pgError.code === \"23503\") {\n\t\t\t// Fetch related records to show the user\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n\n/**\n * Force deletes records by first deleting all related records in referencing tables (cascade)\n */\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getDbPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"Primary key column name is required\",\n\t\t});\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\t// Get all FK constraints that reference this table\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\t\tlet totalRelatedDeleted = 0;\n\n\t\t// Delete related records in reverse dependency order\n\t\t// We need to handle nested FKs recursively\n\t\tconst deletedTables = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t) => {\n\t\t\t// First, find if there are tables referencing the target table\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\t// Get the values that will be deleted from the target table\n\t\t\t\tconst nestedPlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\t\tconst selectQuery = `\n\t\t\t\t\tSELECT \"${nestedFk.referencedColumn}\" FROM \"${targetTable}\"\n\t\t\t\t\tWHERE \"${targetColumn}\" IN (${nestedPlaceholders})\n\t\t\t\t`;\n\n\t\t\t\tconst selectResult = await pool.query(selectQuery, values);\n\t\t\t\tconst nestedValues = selectResult.rows.map(\n\t\t\t\t\t({ row }: { row: { [nestedFk.referencedColumn]: unknown } }) =>\n\t\t\t\t\t\trow[nestedFk.referencedColumn],\n\t\t\t\t);\n\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Now delete from the target table\n\t\t\tconst deletePlaceholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n\t\t\tconst deleteQuery = `\n\t\t\t\tDELETE FROM \"${targetTable}\"\n\t\t\t\tWHERE \"${targetColumn}\" IN (${deletePlaceholders})\n\t\t\t`;\n\n\t\t\tconst deleteResult = await pool.query(deleteQuery, values);\n\t\t\ttotalRelatedDeleted += deleteResult.rowCount ?? 0;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\t// Delete from all referencing tables first\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t);\n\t\t}\n\n\t\t// Finally delete the main records\n\t\tconst placeholders = pkValues.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst query = `\n\t\t\tDELETE FROM \"${tableName}\"\n\t\t\tWHERE \"${pkColumn}\" IN (${placeholders})\n\t\t\tRETURNING *\n\t\t`;\n\n\t\tconst result = await pool.query(query, pkValues);\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\tconst mainDeleted = result.rowCount ?? 0;\n\n\t\treturn { deletedCount: mainDeleted + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport {\n\ttype ColumnInfoSchemaType,\n\tmapMysqlToDataType,\n\tstandardizeMysqlDataTypeLabel,\n\ttype TableNameSchemaType,\n} from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\ninterface ColumnRow extends RowDataPacket {\n\tcolumnName: string;\n\tdataType: string;\n\tcolumnType: string;\n\tisNullable: number | boolean;\n\tcolumnDefault: string | null;\n\tisPrimaryKey: number | boolean;\n\tisForeignKey: number | boolean;\n\treferencedTable: string | null;\n\treferencedColumn: string | null;\n}\n\n/**\n * Parse MySQL enum/set values from COLUMN_TYPE, e.g. \"enum('a','b','c')\" → [\"a\",\"b\",\"c\"]\n */\nfunction parseMysqlEnumValues(columnType: string): string[] | null {\n\tconst match = columnType.match(/^(?:enum|set)\\((.+)\\)$/i);\n\tif (!match?.[1]) return null;\n\treturn match[1].split(\",\").map((v) => v.trim().replace(/^'|'$/g, \"\"));\n}\n\nexport async function getTableColumns({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<ColumnInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst query = `\n\t\tSELECT\n\t\t c.COLUMN_NAME AS columnName,\n\t\t c.DATA_TYPE AS dataType,\n\t\t c.COLUMN_TYPE AS columnType,\n\t\t (c.IS_NULLABLE = 'YES') AS isNullable,\n\t\t c.COLUMN_DEFAULT AS columnDefault,\n\t\t (c.COLUMN_KEY = 'PRI') AS isPrimaryKey,\n\t\t (kcu.REFERENCED_TABLE_NAME IS NOT NULL) AS isForeignKey,\n\t\t kcu.REFERENCED_TABLE_NAME AS referencedTable,\n\t\t kcu.REFERENCED_COLUMN_NAME AS referencedColumn\n\t\tFROM information_schema.COLUMNS c\n\t\tLEFT JOIN information_schema.KEY_COLUMN_USAGE kcu\n\t\t ON c.TABLE_SCHEMA = kcu.TABLE_SCHEMA\n\t\t AND c.TABLE_NAME = kcu.TABLE_NAME\n\t\t AND c.COLUMN_NAME = kcu.COLUMN_NAME\n\t\t AND kcu.REFERENCED_TABLE_NAME IS NOT NULL\n\t\tWHERE c.TABLE_SCHEMA = DATABASE()\n\t\t AND c.TABLE_NAME = ?\n\t\tORDER BY c.ORDINAL_POSITION\n\t`;\n\n\tconst [rows] = await pool.execute<ColumnRow[]>(query, [tableName]);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\treturn rows.map((r) => {\n\t\tconst dataType = r.dataType as string;\n\t\tconst columnType = r.columnType as string;\n\t\tconst isEnum = dataType === \"enum\" || dataType === \"set\";\n\t\tconst enumValues = isEnum ? parseMysqlEnumValues(columnType) : null;\n\n\t\treturn {\n\t\t\tcolumnName: r.columnName,\n\t\t\tdataType: mapMysqlToDataType(dataType, columnType),\n\t\t\tdataTypeLabel: standardizeMysqlDataTypeLabel(dataType, columnType),\n\t\t\tisNullable: Boolean(r.isNullable),\n\t\t\tcolumnDefault: r.columnDefault ?? null,\n\t\t\tisPrimaryKey: Boolean(r.isPrimaryKey),\n\t\t\tisForeignKey: Boolean(r.isForeignKey),\n\t\t\treferencedTable: r.referencedTable ?? null,\n\t\t\treferencedColumn: r.referencedColumn ?? null,\n\t\t\tenumValues,\n\t\t};\n\t});\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { AddRecordSchemaType, DatabaseSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function addRecord({\n\tdb,\n\tparams,\n}: {\n\tdb: DatabaseSchemaType[\"db\"];\n\tparams: AddRecordSchemaType;\n}): Promise<{ insertedCount: number }> {\n\tconst { tableName, data } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst columns = Object.keys(data);\n\tconst values = Object.values(data).map((value, index) => {\n\t\tconst columnName = columns[index];\n\t\tif (booleanColumns.has(columnName) && typeof value === \"string\") {\n\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t}\n\t\treturn value;\n\t});\n\n\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\tconst query = `\n\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\tVALUES (${placeholders})\n\t`;\n\n\tconst [result] = await pool.execute<ResultSetHeader>(query, values);\n\n\tif (result.affectedRows === 0) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to insert record into \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn { insertedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { BulkInsertRecordsParams, BulkInsertResult } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport const bulkInsertRecords = async ({\n\ttableName,\n\trecords,\n\tdb,\n}: BulkInsertRecordsParams): Promise<BulkInsertResult> => {\n\tif (!records || records.length === 0) {\n\t\tthrow new HTTPException(400, {\n\t\t\tmessage: \"At least one record is required\",\n\t\t});\n\t}\n\n\tconst pool = getMysqlPool(db);\n\tconst connection = await pool.getConnection();\n\n\ttry {\n\t\tconst columns = Object.keys(records[0]);\n\t\tconst columnNames = columns.map((col) => `\\`${col}\\``).join(\", \");\n\n\t\tconst tableColumns = await getTableColumns({ tableName, db });\n\t\tconst booleanColumns = new Set(\n\t\t\ttableColumns\n\t\t\t\t.filter((col) => col.dataTypeLabel === \"boolean\")\n\t\t\t\t.map((col) => col.columnName),\n\t\t);\n\n\t\tawait connection.beginTransaction();\n\n\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\tconst record = records[i];\n\t\t\tconst values = columns.map((col) => {\n\t\t\t\tconst value = record[col];\n\t\t\t\tif (booleanColumns.has(col) && typeof value === \"string\") {\n\t\t\t\t\treturn value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t\tconst placeholders = columns.map(() => \"?\").join(\", \");\n\n\t\t\tconst insertSQL = `\n\t\t\t\tINSERT INTO \\`${tableName}\\` (${columnNames})\n\t\t\t\tVALUES (${placeholders})\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\t\tawait connection.execute<ResultSetHeader>(insertSQL, values as any);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new HTTPException(500, {\n\t\t\t\t\tmessage: `Failed to insert record ${i + 1}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait connection.commit();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: `Successfully inserted ${records.length} record${records.length !== 1 ? \"s\" : \"\"}`,\n\t\t\tsuccessCount: records.length,\n\t\t\tfailureCount: 0,\n\t\t};\n\t} catch (error) {\n\t\tawait connection.rollback();\n\t\tif (error instanceof HTTPException) throw error;\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to bulk insert records into \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type {\n\tDatabaseSchemaType,\n\tDeleteRecordParams,\n\tDeleteRecordResult,\n\tDeleteRecordSchemaType,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL FK violation error number\nconst MYSQL_FK_VIOLATION = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecords(\n\ttableName: string,\n\tprimaryKeys: DeleteRecordSchemaType[\"primaryKeys\"],\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\n\tconst constraintsByTable = new Map<string, ForeignKeyConstraint[]>();\n\tfor (const constraint of fkConstraints) {\n\t\tconst key = `${constraint.referencingTable}.${constraint.referencingColumn}`;\n\t\tif (!constraintsByTable.has(key)) constraintsByTable.set(key, []);\n\t\tconstraintsByTable.get(key)?.push(constraint);\n\t}\n\n\tfor (const [_tableColumn, constraints] of constraintsByTable) {\n\t\tconst constraint = constraints[0];\n\t\tif (!constraint) continue;\n\n\t\tconst matchingPk = primaryKeys.find((pk) => pk.columnName === constraint.referencedColumn);\n\t\tif (!matchingPk) continue;\n\n\t\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\`\n\t\t\t WHERE \\`${constraint.referencingColumn}\\` IN (${placeholders})\n\t\t\t LIMIT 100`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nexport async function deleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<DeleteRecordResult> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst placeholders = pkValues.map(() => \"?\").join(\", \");\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${placeholders})`,\n\t\t\tpkValues,\n\t\t);\n\t\tawait connection.commit();\n\t\treturn { deletedCount: result.affectedRows, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (mysqlError.errno === MYSQL_FK_VIOLATION) {\n\t\t\tconst relatedRecords = await getRelatedRecords(tableName, primaryKeys, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n\nexport async function forceDeleteRecords({\n\ttableName,\n\tprimaryKeys,\n\tdb,\n}: DeleteRecordParams): Promise<{ deletedCount: number }> {\n\tconst pool = getMysqlPool(db);\n\n\tconst pkColumn = primaryKeys[0]?.columnName;\n\tif (!pkColumn) {\n\t\tthrow new HTTPException(400, { message: \"Primary key column name is required\" });\n\t}\n\n\tconst pkValues = primaryKeys.map((pk) => pk.value);\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\t// Disable FK checks temporarily for cascade delete\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\n\t\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\t\tlet totalRelatedDeleted = 0;\n\t\tconst deletedTables = new Set<string>();\n\t\tconst visited = new Set<string>();\n\n\t\tconst deleteRelatedRecursively = async (\n\t\t\ttargetTable: string,\n\t\t\ttargetColumn: string,\n\t\t\tvalues: unknown[],\n\t\t\tvisitedSet: Set<string>,\n\t\t) => {\n\t\t\tconst key = `${targetTable}.${targetColumn}`;\n\t\t\tif (visitedSet.has(key)) return;\n\t\t\tvisitedSet.add(key);\n\n\t\t\tconst nestedFks = await getForeignKeyReferences(targetTable, db);\n\t\t\tfor (const nestedFk of nestedFks) {\n\t\t\t\tconst nestedPlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\t\tconst [selectRows] = await connection.execute<RowDataPacket[]>(\n\t\t\t\t\t`SELECT \\`${nestedFk.referencedColumn}\\` FROM \\`${targetTable}\\`\n\t\t\t\t\t WHERE \\`${targetColumn}\\` IN (${nestedPlaceholders})`,\n\t\t\t\t\tvalues as any[],\n\t\t\t\t);\n\t\t\t\tconst nestedValues = (selectRows as Record<string, unknown>[]).map(\n\t\t\t\t\t(row) => row[nestedFk.referencedColumn],\n\t\t\t\t);\n\t\t\t\tif (nestedValues.length > 0) {\n\t\t\t\t\tawait deleteRelatedRecursively(\n\t\t\t\t\t\tnestedFk.referencingTable,\n\t\t\t\t\t\tnestedFk.referencingColumn,\n\t\t\t\t\t\tnestedValues,\n\t\t\t\t\t\tvisitedSet,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst deletePlaceholders = values.map(() => \"?\").join(\", \");\n\t\t\tconst [deleteResult] = await connection.execute<ResultSetHeader>(\n\t\t\t\t`DELETE FROM \\`${targetTable}\\` WHERE \\`${targetColumn}\\` IN (${deletePlaceholders})`,\n\t\t\t\tvalues as any[],\n\t\t\t);\n\t\t\ttotalRelatedDeleted += deleteResult.affectedRows;\n\t\t\tdeletedTables.add(targetTable);\n\t\t};\n\n\t\tfor (const constraint of fkConstraints) {\n\t\t\tif (deletedTables.has(constraint.referencingTable)) continue;\n\t\t\tawait deleteRelatedRecursively(\n\t\t\t\tconstraint.referencingTable,\n\t\t\t\tconstraint.referencingColumn,\n\t\t\t\tpkValues,\n\t\t\t\tvisited,\n\t\t\t);\n\t\t}\n\n\t\tconst mainPlaceholders = pkValues.map(() => \"?\").join(\", \");\n\t\tconst [result] = await connection.execute<ResultSetHeader>(\n\t\t\t`DELETE FROM \\`${tableName}\\` WHERE \\`${pkColumn}\\` IN (${mainPlaceholders})`,\n\t\t\tpkValues,\n\t\t);\n\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\tawait connection.commit();\n\n\t\treturn { deletedCount: result.affectedRows + totalRelatedDeleted };\n\t} catch (error) {\n\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to force delete records from \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader } from \"mysql2\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { getTableColumns } from \"./table-columns.mysql.dao.js\";\n\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst tableColumns = await getTableColumns({ tableName, db });\n\tconst booleanColumns = new Set(\n\t\ttableColumns.filter((col) => col.dataTypeLabel === \"boolean\").map((col) => col.columnName),\n\t);\n\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\tconst connection = await pool.getConnection();\n\tawait connection.beginTransaction();\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u) => `\\`${u.columnName}\\` = ?`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\tif (booleanColumns.has(u.columnName) && typeof u.value === \"string\") {\n\t\t\t\t\treturn u.value === \"true\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \\`${tableName}\\`\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \\`${primaryKey}\\` = ?\n\t\t\t`;\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t\tconst [result] = await connection.execute<ResultSetHeader>(query, values as any);\n\n\t\t\tif (result.affectedRows === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.affectedRows;\n\t\t}\n\n\t\tawait connection.commit();\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait connection.rollback();\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t} finally {\n\t\tconnection.release();\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, UpdateRecordsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Updates multiple cells in a table. Can update multiple rows or multiple cells in the same row.\n * Groups updates by row and executes them efficiently.\n */\nexport async function updateRecords({\n\tparams,\n\tdb,\n}: {\n\tparams: UpdateRecordsSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ updatedCount: number }> {\n\tconst { tableName, updates, primaryKey } = params;\n\tconst pool = getDbPool(db);\n\n\t// Group updates by row (using the primary key value)\n\tconst updatesByRow = new Map<\n\t\tunknown,\n\t\tArray<{\n\t\t\tcolumnName: string;\n\t\t\tvalue: unknown;\n\t\t\trowData: Record<string, unknown>;\n\t\t}>\n\t>();\n\n\tfor (const update of updates) {\n\t\tconst pkValue = update.rowData[primaryKey];\n\t\tif (pkValue === undefined || pkValue === null) {\n\t\t\tthrow new HTTPException(400, {\n\t\t\t\tmessage: `Primary key \"${primaryKey}\" not found in row data. Please ensure the row has a \"${primaryKey}\" column.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!updatesByRow.has(pkValue)) {\n\t\t\tupdatesByRow.set(pkValue, []);\n\t\t}\n\t\tupdatesByRow.get(pkValue)?.push({\n\t\t\tcolumnName: update.columnName,\n\t\t\tvalue: update.value,\n\t\t\trowData: update.rowData,\n\t\t});\n\t}\n\n\t// Use transaction for multiple updates\n\tawait pool.query(\"BEGIN\");\n\n\ttry {\n\t\tlet totalUpdated = 0;\n\n\t\t// Execute updates for each row\n\t\tfor (const [pkValue, rowUpdates] of updatesByRow.entries()) {\n\t\t\tconst setClauses = rowUpdates.map((u, index) => `\"${u.columnName}\" = $${index + 1}`);\n\t\t\tconst values = rowUpdates.map((u) => {\n\t\t\t\t// If the value is an object or array, stringify it for JSON/JSONB columns\n\t\t\t\tif (u.value !== null && typeof u.value === \"object\") {\n\t\t\t\t\treturn JSON.stringify(u.value);\n\t\t\t\t}\n\t\t\t\treturn u.value;\n\t\t\t});\n\n\t\t\t// Add the primary key value as the last parameter\n\t\t\tvalues.push(pkValue);\n\n\t\t\tconst query = `\n\t\t\t\tUPDATE \"${tableName}\"\n\t\t\t\tSET ${setClauses.join(\", \")}\n\t\t\t\tWHERE \"${primaryKey}\" = $${values.length}\n\t\t\t\tRETURNING *\n\t\t\t`;\n\n\t\t\tconst result = await pool.query(query, values);\n\t\t\tif (result.rowCount === 0) {\n\t\t\t\tthrow new HTTPException(404, {\n\t\t\t\t\tmessage: `Record with ${primaryKey} = ${pkValue} not found in table \"${tableName}\"`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttotalUpdated += result.rowCount ?? 0;\n\t\t}\n\n\t\tawait pool.query(\"COMMIT\");\n\n\t\treturn { updatedCount: totalUpdated };\n\t} catch (error) {\n\t\tawait pool.query(\"ROLLBACK\");\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to update records in \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\taddRecordSchema,\n\tbulkInsertRecordsSchema,\n\ttype DeleteRecordResult,\n\tdatabaseSchema,\n\tdeleteRecordSchema,\n\tupdateRecordsSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { addRecord as pgAddRecord } from \"@/dao/add-record.dao.js\";\nimport { bulkInsertRecords as pgBulkInsertRecords } from \"@/dao/bulk-insert-records.dao.js\";\nimport {\n\tdeleteRecords as pgDeleteRecords,\n\tforceDeleteRecords as pgForceDeleteRecords,\n} from \"@/dao/delete-records.dao.js\";\nimport { addRecord as mysqlAddRecord } from \"@/dao/mysql/add-record.mysql.dao.js\";\nimport { bulkInsertRecords as mysqlBulkInsertRecords } from \"@/dao/mysql/bulk-insert-records.mysql.dao.js\";\nimport {\n\tdeleteRecords as mysqlDeleteRecords,\n\tforceDeleteRecords as mysqlForceDeleteRecords,\n} from \"@/dao/mysql/delete-records.mysql.dao.js\";\nimport { updateRecords as mysqlUpdateRecords } from \"@/dao/mysql/update-records.mysql.dao.js\";\nimport { updateRecords as pgUpdateRecords } from \"@/dao/update-records.dao.js\";\n\nexport const recordsRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/records/...\n\t */\n\t.basePath(\"/records\")\n\n\t/**\n\t * POST /records\n\t * Adds a new record into a table\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", addRecordSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, data } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { insertedCount } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlAddRecord({ db, params: { tableName, data } })\n\t\t\t\t\t: await pgAddRecord({ db, params: { tableName, data } });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Record inserted into \"${tableName}\" with ${insertedCount} rows inserted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /records\n\t * Updates one or more cells in a table\n\t */\n\t.patch(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", updateRecordsSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKey, updates } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { updatedCount } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlUpdateRecords({ params: { tableName, primaryKey, updates }, db })\n\t\t\t\t\t: await pgUpdateRecords({ params: { tableName, primaryKey, updates }, db });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Updated ${updatedCount} records in \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records\n\t * Deletes records from a table\n\t */\n\t.delete(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<DeleteRecordResult, 409 | 200> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { deletedCount, fkViolation, relatedRecords } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlDeleteRecords({ tableName, primaryKeys, db })\n\t\t\t\t\t: await pgDeleteRecords({ tableName, primaryKeys, db });\n\t\t\tif (fkViolation) {\n\t\t\t\treturn c.json(\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tdeletedCount: 0,\n\t\t\t\t\t\t\tfkViolation: true,\n\t\t\t\t\t\t\trelatedRecords,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t409,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdeletedCount,\n\t\t\t\t\t\tfkViolation: false,\n\t\t\t\t\t\trelatedRecords: [],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /records/force\n\t * Force deletes records and all related FK records\n\t */\n\t.delete(\n\t\t\"/force\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", deleteRecordSchema),\n\t\tasync (c): ApiHandler<{ deletedCount: number }> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, primaryKeys } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst deletedCount =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlForceDeleteRecords({ tableName, primaryKeys, db })\n\t\t\t\t\t: await pgForceDeleteRecords({ tableName, primaryKeys, db });\n\t\t\treturn c.json({ data: deletedCount }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /records/bulk\n\t * Bulk inserts multiple records into a table\n\t */\n\t.post(\n\t\t\"/bulk\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", bulkInsertRecordsSchema),\n\t\tasync (c): ApiHandler<object> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, records } = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst result =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlBulkInsertRecords({ tableName, records, db })\n\t\t\t\t\t: await pgBulkInsertRecords({ tableName, records, db });\n\t\t\tconsole.log(\"result\", result);\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t);\n\nexport type RecordsRoutes = typeof recordsRoutes;\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Adds a column to a PostgreSQL table using ALTER TABLE ADD COLUMN.\n */\nexport async function addColumn(params: AddColumnParamsSchemaType): Promise<void> {\n\tconst {\n\t\ttableName,\n\t\tcolumnName,\n\t\tcolumnType,\n\t\tdefaultValue,\n\t\tisPrimaryKey,\n\t\tisNullable,\n\t\tisUnique,\n\t\tisIdentity,\n\t\tisArray,\n\t\tdb,\n\t} = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (columnRows[0]?.exists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${columnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tlet columnDefinition = `\"${columnName}\" ${columnType}`;\n\n\tif (isArray) {\n\t\tcolumnDefinition += \"[]\";\n\t}\n\n\tif (isPrimaryKey) {\n\t\tcolumnDefinition += \" PRIMARY KEY\";\n\t}\n\n\tif (isUnique && !isPrimaryKey) {\n\t\tcolumnDefinition += \" UNIQUE\";\n\t}\n\n\tif (!isNullable) {\n\t\tcolumnDefinition += \" NOT NULL\";\n\t}\n\n\tif (isIdentity) {\n\t\tcolumnDefinition += \" GENERATED ALWAYS AS IDENTITY\";\n\t}\n\n\tif (defaultValue?.trim() && !isIdentity) {\n\t\tcolumnDefinition += ` DEFAULT ${defaultValue.trim()}`;\n\t}\n\n\tawait pool.query(`ALTER TABLE \"${tableName}\" ADD COLUMN ${columnDefinition}`);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { AlterColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Alters a PostgreSQL column's type, nullability, and default value.\n */\nexport async function alterColumn(params: AlterColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, columnType, isNullable, defaultValue, db } = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (!columnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst client = await pool.connect();\n\n\ttry {\n\t\tawait client.query(\"BEGIN\");\n\t\tawait client.query(\n\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" TYPE ${columnType}`,\n\t\t);\n\t\tawait client.query(\n\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" ${isNullable ? \"DROP\" : \"SET\"} NOT NULL`,\n\t\t);\n\n\t\tif (defaultValue?.trim()) {\n\t\t\tawait client.query(\n\t\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" SET DEFAULT ${defaultValue.trim()}`,\n\t\t\t);\n\t\t} else {\n\t\t\tawait client.query(\n\t\t\t\t`ALTER TABLE \"${tableName}\" ALTER COLUMN \"${columnName}\" DROP DEFAULT`,\n\t\t\t);\n\t\t}\n\n\t\tawait client.query(\"COMMIT\");\n\t} catch (error) {\n\t\tawait client.query(\"ROLLBACK\");\n\t\tthrow error;\n\t} finally {\n\t\tclient.release();\n\t}\n}\n","import type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tFieldDataType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getDbPool(db);\n\n\t// Build column definitions\n\tconst columnDefinitions = fields.map((field: FieldDataType) => {\n\t\tlet columnDef = `\"${field.columnName}\" ${field.columnType}`;\n\n\t\t// Add array suffix if needed\n\t\tif (field.isArray) {\n\t\t\tcolumnDef += \"[]\";\n\t\t}\n\n\t\t// Add PRIMARY KEY constraint\n\t\tif (field.isPrimaryKey) {\n\t\t\tcolumnDef += \" PRIMARY KEY\";\n\t\t}\n\n\t\t// Add UNIQUE constraint\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tcolumnDef += \" UNIQUE\";\n\t\t}\n\n\t\t// Add NOT NULL constraint (if not nullable)\n\t\tif (!field.isNullable) {\n\t\t\tcolumnDef += \" NOT NULL\";\n\t\t}\n\n\t\t// Add GENERATED ALWAYS AS IDENTITY for identity columns\n\t\tif (field.isIdentity) {\n\t\t\tcolumnDef += \" GENERATED ALWAYS AS IDENTITY\";\n\t\t}\n\n\t\t// Add default value\n\t\tif (field.defaultValue && !field.isIdentity) {\n\t\t\tcolumnDef += ` DEFAULT ${field.defaultValue}`;\n\t\t}\n\n\t\treturn columnDef;\n\t});\n\n\t// Build foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \"${constraintName}\" FOREIGN KEY (\"${fk.columnName}\") REFERENCES \"${fk.referencedTable}\" (\"${fk.referencedColumn}\") ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\t// Combine column definitions and foreign key constraints\n\tconst allDefinitions = [...columnDefinitions, ...foreignKeyConstraints];\n\n\t// Create the table\n\tconst createTableSQL = `\n\t\t\tCREATE TABLE \"${tableName}\" (\n\t\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\\t\")}\n\t\t\t);\n\t\t`;\n\n\tawait pool.query(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a table using ALTER TABLE DROP COLUMN.\n * Uses CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies.\n *\n * @param params.tableName - Name of the table containing the column\n * @param params.columnName - Name of the column to delete\n * @param params.cascade - If true, uses CASCADE; if false, uses RESTRICT\n * @param params.db - Optional database name to connect to\n * @returns {Object} Object with deleted count\n * @throws HTTPException if table or column does not exist\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, cascade, db } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check if column exists\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns \n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: columnRows } = await pool.query(columnExistsQuery, [tableName, columnName]);\n\tif (!columnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\t// Use CASCADE to drop dependent objects, or RESTRICT to fail if there are dependencies\n\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\tconst dropColumnSQL = `ALTER TABLE \"${tableName}\" DROP COLUMN \"${columnName}\" ${dropMode}`;\n\n\tconst { rowCount } = await pool.query(dropColumnSQL);\n\n\treturn { deletedCount: rowCount ?? 0 };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Gets foreign key constraints that reference the given table\n */\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst query = `\n\t\tSELECT\n\t\t\ttc.constraint_name,\n\t\t\ttc.table_name as referencing_table,\n\t\t\tkcu.column_name as referencing_column,\n\t\t\tccu.table_name AS referenced_table,\n\t\t\tccu.column_name AS referenced_column\n\t\tFROM information_schema.table_constraints AS tc\n\t\tJOIN information_schema.key_column_usage AS kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tJOIN information_schema.constraint_column_usage AS ccu\n\t\t\tON ccu.constraint_name = tc.constraint_name\n\t\t\tAND ccu.table_schema = tc.table_schema\n\t\tWHERE tc.constraint_type = 'FOREIGN KEY'\n\t\t\tAND ccu.table_name = $1\n\t`;\n\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(query, [tableName]);\n\n\treturn result.rows.map((row: ForeignKeyConstraintRow) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\n/**\n * Gets related records from tables that reference this table\n */\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\n\tif (fkConstraints.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getDbPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst relatedQuery = `\n\t\t\tSELECT * FROM \"${constraint.referencingTable}\"\n\t\t\tLIMIT 100\n\t\t`;\n\n\t\tconst relatedResult = await pool.query(relatedQuery);\n\n\t\tif (relatedResult.rows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedResult.rows,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\n/**\n * Gets the total row count for a table\n */\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getDbPool(db);\n\tconst result = await pool.query(`SELECT COUNT(*) as count FROM \"${tableName}\"`);\n\treturn Number.parseInt(result.rows[0]?.count ?? \"0\", 10);\n}\n\n/**\n * Deletes a table from the database.\n * If there are FK constraints referencing this table, returns the related records.\n *\n * @param params.tableName - Name of the table to delete\n * @param params.db - Database name\n * @param params.cascade - If true, uses CASCADE to drop dependent objects\n * @returns DeleteTableResult with deletedCount, fkViolation flag, and relatedRecords\n */\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get row count before deletion\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\t// If not cascade, check for FK constraints first\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\t}\n\n\ttry {\n\t\tconst dropMode = cascade ? \"CASCADE\" : \"RESTRICT\";\n\t\tconst dropTableSQL = `DROP TABLE \"${tableName}\" ${dropMode}`;\n\n\t\tawait pool.query(dropTableSQL);\n\n\t\treturn {\n\t\t\tdeletedCount: rowCount,\n\t\t\tfkViolation: false,\n\t\t\trelatedRecords: [],\n\t\t};\n\t} catch (error) {\n\t\tconst pgError = error as { code?: string; detail?: string };\n\n\t\t// Check if this is a dependency error (foreign key constraint)\n\t\tif (pgError.code === \"2BP01\") {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn {\n\t\t\t\tdeletedCount: 0,\n\t\t\t\tfkViolation: true,\n\t\t\t\trelatedRecords,\n\t\t\t};\n\t\t}\n\n\t\tif (error instanceof HTTPException) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getDbPool(db);\n\tconst { rows } = await pool.query(`SELECT * FROM \"${tableName}\"`);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows };\n}\n","type MysqlColumnDefinitionInput = {\n\tcolumnName: string;\n\tcolumnType: string;\n\tdefaultValue?: string | null;\n\tisPrimaryKey?: boolean;\n\tisNullable?: boolean;\n\tisUnique?: boolean;\n\tisIdentity?: boolean;\n\tisArray?: boolean;\n};\n\ntype BuildMysqlColumnDefinitionOptions = {\n\tincludePrimaryKey?: boolean;\n\tincludeUnique?: boolean;\n\tpreserveAutoIncrement?: boolean;\n};\n\n/**\n * Formats default values for MySQL compatibility.\n * MySQL requires function calls in DEFAULT clauses to be wrapped in parentheses.\n */\nexport function formatMysqlDefaultValue(\n\tdefaultValue: string | null | undefined,\n\tcolumnType: string,\n): string | null {\n\tif (!defaultValue?.trim()) {\n\t\treturn null;\n\t}\n\n\tconst trimmed = defaultValue.trim().toLowerCase();\n\n\t// Check if it's a function call (contains parentheses)\n\tif (trimmed.includes(\"(\") && trimmed.includes(\")\")) {\n\t\t// MySQL 8.0+ requires function calls to be wrapped in parentheses for DEFAULT\n\t\t// But UUID() returns a string, not compatible with INT columns\n\t\tif (trimmed.includes(\"uuid()\")) {\n\t\t\t// UUID() only makes sense for CHAR(36) or VARCHAR columns\n\t\t\tif (\n\t\t\t\t!columnType.toUpperCase().includes(\"CHAR\") &&\n\t\t\t\t!columnType.toUpperCase().includes(\"TEXT\")\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn \"(UUID())\";\n\t\t}\n\n\t\t// Other function calls like CURRENT_TIMESTAMP, NOW(), etc.\n\t\tif (trimmed.includes(\"current_timestamp\") || trimmed.includes(\"now()\")) {\n\t\t\treturn \"(CURRENT_TIMESTAMP)\";\n\t\t}\n\n\t\tif (trimmed.includes(\"current_date\")) {\n\t\t\treturn \"(CURRENT_DATE)\";\n\t\t}\n\n\t\t// Wrap other function calls in parentheses\n\t\treturn `(${defaultValue.trim()})`;\n\t}\n\n\t// For non-function defaults (literals), return as-is\n\t// Handle special keywords\n\tif (trimmed === \"null\") {\n\t\treturn \"NULL\";\n\t}\n\n\tif (trimmed === \"true\" || trimmed === \"false\") {\n\t\treturn trimmed === \"true\" ? \"1\" : \"0\";\n\t}\n\n\t// Return the value as-is (could be a number, quoted string, etc.)\n\treturn defaultValue.trim();\n}\n\n/**\n * Maps PG-style column types from the UI schema to MySQL-compatible types.\n * The UI uses PostgreSQL-style type names, so we translate them for MySQL.\n */\nexport function mapColumnTypeToMysql(columnType: string, isArray: boolean): string {\n\tif (isArray) {\n\t\t// MySQL does not support native array types - use JSON as fallback\n\t\treturn \"JSON\";\n\t}\n\n\tconst normalized = columnType.toLowerCase().trim();\n\n\tconst typeMap: Record<string, string> = {\n\t\t// Integer types\n\t\tserial: \"INT AUTO_INCREMENT\",\n\t\tserial4: \"INT AUTO_INCREMENT\",\n\t\tbigserial: \"BIGINT AUTO_INCREMENT\",\n\t\tserial8: \"BIGINT AUTO_INCREMENT\",\n\t\tint: \"INT\",\n\t\tint4: \"INT\",\n\t\tinteger: \"INT\",\n\t\tbigint: \"BIGINT\",\n\t\tint8: \"BIGINT\",\n\t\tsmallint: \"SMALLINT\",\n\t\tint2: \"SMALLINT\",\n\t\t// Decimal / numeric\n\t\tnumeric: \"DECIMAL\",\n\t\tdecimal: \"DECIMAL\",\n\t\treal: \"FLOAT\",\n\t\tfloat4: \"FLOAT\",\n\t\tfloat: \"FLOAT\",\n\t\t\"double precision\": \"DOUBLE\",\n\t\tfloat8: \"DOUBLE\",\n\t\tmoney: \"DECIMAL(19, 4)\",\n\t\t// Boolean\n\t\tboolean: \"TINYINT(1)\",\n\t\tbool: \"TINYINT(1)\",\n\t\t// Text\n\t\ttext: \"LONGTEXT\",\n\t\tvarchar: \"VARCHAR(255)\",\n\t\t\"character varying\": \"VARCHAR(255)\",\n\t\tchar: \"CHAR(1)\",\n\t\tcharacter: \"CHAR(1)\",\n\t\tbpchar: \"CHAR\",\n\t\tuuid: \"CHAR(36)\",\n\t\t// JSON\n\t\tjson: \"JSON\",\n\t\tjsonb: \"JSON\",\n\t\txml: \"LONGTEXT\",\n\t\t// Date/time\n\t\tdate: \"DATE\",\n\t\ttime: \"TIME\",\n\t\t\"time without time zone\": \"TIME\",\n\t\ttimestamp: \"DATETIME\",\n\t\t\"timestamp without time zone\": \"DATETIME\",\n\t\t\"timestamp with time zone\": \"DATETIME\",\n\t\ttimestamptz: \"DATETIME\",\n\t\tinterval: \"VARCHAR(255)\",\n\t\t// Binary\n\t\tbytea: \"LONGBLOB\",\n\t\t// Network / geometric - store as text in MySQL\n\t\tinet: \"VARCHAR(45)\",\n\t\tcidr: \"VARCHAR(45)\",\n\t\tmacaddr: \"VARCHAR(17)\",\n\t\tmacaddr8: \"VARCHAR(23)\",\n\t\tpoint: \"POINT\",\n\t\tline: \"LINESTRING\",\n\t\tpolygon: \"POLYGON\",\n\t};\n\n\treturn typeMap[normalized] || columnType.toUpperCase();\n}\n\nexport function buildMysqlColumnDefinition(\n\tfield: MysqlColumnDefinitionInput,\n\toptions: BuildMysqlColumnDefinitionOptions = {},\n): string {\n\tconst mappedType = mapColumnTypeToMysql(field.columnType, field.isArray ?? false);\n\tlet columnDef = `\\`${field.columnName}\\` ${mappedType}`;\n\n\t// NOT NULL\n\tif (!field.isNullable && !field.isPrimaryKey) {\n\t\tcolumnDef += \" NOT NULL\";\n\t}\n\n\t// Default value (skip for AUTO_INCREMENT columns)\n\tif (field.defaultValue && !mappedType.includes(\"AUTO_INCREMENT\")) {\n\t\tconst defaultValue = formatMysqlDefaultValue(field.defaultValue, mappedType);\n\t\tif (defaultValue !== null) {\n\t\t\tcolumnDef += ` DEFAULT ${defaultValue}`;\n\t\t}\n\t}\n\n\t// isIdentity -> AUTO_INCREMENT (already embedded in type map via SERIAL mapping)\n\tif (\n\t\t(field.isIdentity || options.preserveAutoIncrement) &&\n\t\t!mappedType.includes(\"AUTO_INCREMENT\")\n\t) {\n\t\tcolumnDef += \" AUTO_INCREMENT\";\n\t}\n\n\tif (options.includeUnique && field.isUnique && !field.isPrimaryKey) {\n\t\tcolumnDef += \" UNIQUE\";\n\t}\n\n\tif (options.includePrimaryKey && field.isPrimaryKey) {\n\t\tcolumnDef += \" PRIMARY KEY\";\n\t}\n\n\treturn columnDef;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { AddColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\n/**\n * Adds a column to a MySQL table using ALTER TABLE ADD COLUMN.\n */\nexport async function addColumn(params: AddColumnParamsSchemaType): Promise<void> {\n\tconst {\n\t\ttableName,\n\t\tcolumnName,\n\t\tcolumnType,\n\t\tdefaultValue,\n\t\tisPrimaryKey,\n\t\tisNullable,\n\t\tisUnique,\n\t\tisIdentity,\n\t\tisArray,\n\t\tdb,\n\t} = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnExists = Number((columnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (columnExists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${columnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst columnDefinition = buildMysqlColumnDefinition(\n\t\t{\n\t\t\tcolumnName,\n\t\t\tcolumnType,\n\t\t\tdefaultValue,\n\t\t\tisPrimaryKey,\n\t\t\tisNullable,\n\t\t\tisUnique,\n\t\t\tisIdentity,\n\t\t\tisArray,\n\t\t},\n\t\t{\n\t\t\tincludePrimaryKey: true,\n\t\t\tincludeUnique: true,\n\t\t},\n\t);\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` ADD COLUMN ${columnDefinition}`,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { AlterColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\n/**\n * Alters a MySQL column's type, nullability, and default value using MODIFY COLUMN.\n */\nexport async function alterColumn(params: AlterColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, columnType, isNullable, defaultValue, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT EXTRA\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?\n\t\t LIMIT 1`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnRow = (columnRows as Array<{ EXTRA?: string | null }>)[0];\n\tif (!columnRow) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst columnDefinition = buildMysqlColumnDefinition(\n\t\t{\n\t\t\tcolumnName,\n\t\t\tcolumnType,\n\t\t\tdefaultValue,\n\t\t\tisNullable,\n\t\t},\n\t\t{\n\t\t\tpreserveAutoIncrement: columnRow.EXTRA?.toLowerCase().includes(\"auto_increment\"),\n\t\t},\n\t);\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` MODIFY COLUMN ${columnDefinition}`,\n\t);\n}\n","import type { ResultSetHeader } from \"mysql2\";\nimport type {\n\tCreateTableSchemaType,\n\tDatabaseSchemaType,\n\tForeignKeyDataType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport { buildMysqlColumnDefinition } from \"./mysql-column.utils.js\";\n\nexport async function createTable({\n\ttableData,\n\tdb,\n}: {\n\ttableData: CreateTableSchemaType;\n\tdb: DatabaseSchemaType[\"db\"];\n}) {\n\tconst { tableName, fields, foreignKeys } = tableData;\n\tconst pool = getMysqlPool(db);\n\n\tconst columnDefinitions = fields.map((field) => buildMysqlColumnDefinition(field));\n\n\t// Primary key constraint\n\tconst primaryKeyFields = fields.filter((f) => f.isPrimaryKey);\n\tconst constraintDefs: string[] = [];\n\n\tif (primaryKeyFields.length > 0) {\n\t\tconst pkColumns = primaryKeyFields.map((f) => `\\`${f.columnName}\\``).join(\", \");\n\t\tconstraintDefs.push(`PRIMARY KEY (${pkColumns})`);\n\t}\n\n\t// Unique constraints\n\tfor (const field of fields) {\n\t\tif (field.isUnique && !field.isPrimaryKey) {\n\t\t\tconstraintDefs.push(\n\t\t\t\t`UNIQUE KEY \\`uq_${tableName}_${field.columnName}\\` (\\`${field.columnName}\\`)`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Foreign key constraints\n\tconst foreignKeyConstraints =\n\t\tforeignKeys?.map((fk: ForeignKeyDataType) => {\n\t\t\tconst constraintName = `fk_${tableName}_${fk.columnName}_${fk.referencedTable}_${fk.referencedColumn}`;\n\t\t\treturn `CONSTRAINT \\`${constraintName}\\` FOREIGN KEY (\\`${fk.columnName}\\`) REFERENCES \\`${fk.referencedTable}\\` (\\`${fk.referencedColumn}\\`) ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}`;\n\t\t}) || [];\n\n\tconst allDefinitions = [...columnDefinitions, ...constraintDefs, ...foreignKeyConstraints];\n\n\tconst createTableSQL = `\n\t\tCREATE TABLE \\`${tableName}\\` (\n\t\t\t${allDefinitions.join(\",\\n\\t\\t\\t\")}\n\t\t) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci\n\t`;\n\n\tawait pool.execute<ResultSetHeader>(createTableSQL);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { DeleteColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Deletes a column from a MySQL table using ALTER TABLE DROP COLUMN.\n * Note: MySQL does not support CASCADE/RESTRICT on DROP COLUMN — the cascade param is accepted\n * for API compatibility but does not change behavior.\n */\nexport async function deleteColumn(\n\tparams: DeleteColumnParamsSchemaType,\n): Promise<{ deletedCount: number }> {\n\tconst { tableName, columnName, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Check column exists\n\tconst [columnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst columnExists = Number((columnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!columnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst [result] = await pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` DROP COLUMN \\`${columnName}\\``,\n\t);\n\n\treturn { deletedCount: result.affectedRows };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type {\n\tDeleteTableParams,\n\tDeleteTableResult,\n\tForeignKeyConstraint,\n\tForeignKeyConstraintRow,\n\tRelatedRecord,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n// MySQL error number for FK dependency preventing DROP TABLE\nconst MYSQL_FK_DEPENDENCY = 1217;\nconst MYSQL_FK_ROW_REFERENCED = 1451;\n\nasync function getForeignKeyReferences(\n\ttableName: string,\n\tdb: string,\n): Promise<ForeignKeyConstraint[]> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT\n\t\t\tkcu.CONSTRAINT_NAME AS constraint_name,\n\t\t\tkcu.TABLE_NAME AS referencing_table,\n\t\t\tkcu.COLUMN_NAME AS referencing_column,\n\t\t\tkcu.REFERENCED_TABLE_NAME AS referenced_table,\n\t\t\tkcu.REFERENCED_COLUMN_NAME AS referenced_column\n\t\tFROM information_schema.KEY_COLUMN_USAGE kcu\n\t\tJOIN information_schema.TABLE_CONSTRAINTS tc\n\t\t ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n\t\t AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA\n\t\t AND kcu.TABLE_NAME = tc.TABLE_NAME\n\t\tWHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'\n\t\t AND kcu.TABLE_SCHEMA = DATABASE()\n\t\t AND kcu.REFERENCED_TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\n\treturn (rows as ForeignKeyConstraintRow[]).map((row) => ({\n\t\tconstraintName: row.constraint_name,\n\t\treferencingTable: row.referencing_table,\n\t\treferencingColumn: row.referencing_column,\n\t\treferencedTable: row.referenced_table,\n\t\treferencedColumn: row.referenced_column,\n\t}));\n}\n\nasync function getRelatedRecordsForTable(\n\ttableName: string,\n\tdb: string,\n): Promise<RelatedRecord[]> {\n\tconst fkConstraints = await getForeignKeyReferences(tableName, db);\n\tif (fkConstraints.length === 0) return [];\n\n\tconst relatedRecords: RelatedRecord[] = [];\n\tconst pool = getMysqlPool(db);\n\n\tfor (const constraint of fkConstraints) {\n\t\tconst [relatedRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t`SELECT * FROM \\`${constraint.referencingTable}\\` LIMIT 100`,\n\t\t);\n\n\t\tif (relatedRows.length > 0) {\n\t\t\trelatedRecords.push({\n\t\t\t\ttableName: constraint.referencingTable,\n\t\t\t\tcolumnName: constraint.referencingColumn,\n\t\t\t\tconstraintName: constraint.constraintName,\n\t\t\t\trecords: relatedRows as Record<string, unknown>[],\n\t\t\t});\n\t\t}\n\t}\n\n\treturn relatedRecords;\n}\n\nasync function getTableRowCount(tableName: string, db: string): Promise<number> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as count FROM \\`${tableName}\\``,\n\t);\n\treturn Number((rows as Array<{ count: number }>)[0]?.count ?? 0);\n}\n\nexport async function deleteTable(params: DeleteTableParams): Promise<DeleteTableResult> {\n\tconst { tableName, db, cascade } = params;\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst rowCount = await getTableRowCount(tableName, db);\n\n\tif (!cascade) {\n\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\tif (relatedRecords.length > 0) {\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\t}\n\n\ttry {\n\t\tif (cascade) {\n\t\t\t// MySQL doesn't support CASCADE on DROP TABLE natively the same way PG does.\n\t\t\t// We disable FK checks, drop the table, then re-enable.\n\t\t\tconst connection = await pool.getConnection();\n\t\t\ttry {\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 0\");\n\t\t\t\tawait connection.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t\t\tawait connection.execute(\"SET FOREIGN_KEY_CHECKS = 1\");\n\t\t\t} finally {\n\t\t\t\tconnection.release();\n\t\t\t}\n\t\t} else {\n\t\t\tawait pool.execute(`DROP TABLE \\`${tableName}\\``);\n\t\t}\n\n\t\treturn { deletedCount: rowCount, fkViolation: false, relatedRecords: [] };\n\t} catch (error) {\n\t\t// Re-enable FK checks in case we disabled them\n\t\tawait pool.execute(\"SET FOREIGN_KEY_CHECKS = 1\").catch(() => {});\n\n\t\tconst mysqlError = error as { errno?: number };\n\t\tif (\n\t\t\tmysqlError.errno === MYSQL_FK_DEPENDENCY ||\n\t\t\tmysqlError.errno === MYSQL_FK_ROW_REFERENCED\n\t\t) {\n\t\t\tconst relatedRecords = await getRelatedRecordsForTable(tableName, db);\n\t\t\treturn { deletedCount: 0, fkViolation: true, relatedRecords };\n\t\t}\n\n\t\tif (error instanceof HTTPException) throw error;\n\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to delete table \"${tableName}\"`,\n\t\t});\n\t}\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { CellValue, DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function exportTableData({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<{ cols: string[]; rows: Record<string, CellValue>[] }> {\n\tconst pool = getMysqlPool(db);\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SELECT * FROM \\`${tableName}\\``);\n\n\tif (!rows || rows.length === 0) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist or has no data`,\n\t\t});\n\t}\n\n\tconst cols = Object.keys(rows[0]);\n\n\treturn { cols, rows: rows as Record<string, CellValue>[] };\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { ResultSetHeader, RowDataPacket } from \"mysql2\";\nimport type { RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\n/**\n * Renames a MySQL column using ALTER TABLE RENAME COLUMN.\n */\nexport async function renameColumn(params: RenameColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, newColumnName, db } = params;\n\tconst pool = getMysqlPool(db);\n\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst [currentColumnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, columnName],\n\t);\n\tconst currentColumnExists =\n\t\tNumber((currentColumnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!currentColumnExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst [nextColumnRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,\n\t\t[tableName, newColumnName],\n\t);\n\tconst nextColumnExists = Number((nextColumnRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (nextColumnExists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${newColumnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait pool.execute<ResultSetHeader>(\n\t\t`ALTER TABLE \\`${tableName}\\` RENAME COLUMN \\`${columnName}\\` TO \\`${newColumnName}\\``,\n\t);\n}\n","import type { RowDataPacket } from \"mysql2\";\nimport type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getMysqlPool(db);\n\n\tconst tablesQuery = `\n\t\tSELECT table_name as tableName\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = DATABASE()\n\t\t AND table_type = 'BASE TABLE'\n\t\tORDER BY table_name\n\t`;\n\n\tconst [tables] = await pool.execute<RowDataPacket[]>(tablesQuery);\n\tif (!tables || tables.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\t(tables as Array<{ tableName: string }>).map(async (table) => {\n\t\t\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t\t\t`SELECT COUNT(*) as count FROM \\`${table.tableName}\\``,\n\t\t\t);\n\t\t\tconst countRow = (countRows as Array<{ count: number }>)[0];\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: countRow?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RowDataPacket } from \"mysql2\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getMysqlPool(db);\n\n\t// Check if table exists\n\tconst [tableRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as cnt\n\t\t FROM information_schema.TABLES\n\t\t WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,\n\t\t[tableName],\n\t);\n\tconst tableExists = Number((tableRows as Array<{ cnt: number }>)[0]?.cnt ?? 0) > 0;\n\tif (!tableExists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// SHOW CREATE TABLE returns the full DDL including column types, indexes, FK constraints\n\tconst [rows] = await pool.execute<RowDataPacket[]>(`SHOW CREATE TABLE \\`${tableName}\\``);\n\tconst row = (rows as Array<Record<string, string>>)[0];\n\n\t// The result row has \"Create Table\" key\n\tconst createTableSql = row?.[\"Create Table\"] ?? row?.create_table ?? \"\";\n\tif (!createTableSql) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: `Failed to retrieve schema for table \"${tableName}\"`,\n\t\t});\n\t}\n\n\treturn createTableSql;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\n/**\n * MySQL-specific WHERE clause builder.\n * Uses ? placeholders and backtick identifiers.\n * ILIKE/NOT ILIKE map to LIKE/NOT LIKE (MySQL is case-insensitive by default on most collations).\n */\nexport function buildWhereClauseMysql(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst columnName = `\\`${filter.columnName}\\``;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != ?`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\tcase \"ilike\":\n\t\t\t\t// MySQL LIKE is case-insensitive by default on most collations\n\t\t\t\tconditions.push(`${columnName} LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName} NOT LIKE ?`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\n/**\n * MySQL-specific ORDER BY clause builder.\n * Uses backtick identifiers.\n */\nexport function buildSortClauseMysql(\n\tsorts: SortType[] | string,\n\torder: SortDirection,\n): string {\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\\`${sort.columnName}\\` ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \\`${sorts}\\` ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\n/**\n * MySQL-specific cursor WHERE clause builder.\n * Uses ? placeholders (no index tracking needed since all placeholders are ?).\n */\nexport function buildCursorWhereClauseMysql(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\\`${col}\\``).join(\", \");\n\t\tconst placeholders = sortColumns.map(() => \"?\").join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type { RowDataPacket } from \"mysql2\";\nimport type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getMysqlPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClauseMysql,\n\tbuildSortClauseMysql,\n\tbuildWhereClauseMysql,\n} from \"@/utils/build-clauses-mysql.js\";\n\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getMysqlPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\tconst [rows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COLUMN_NAME as column_name\n\t\t FROM information_schema.COLUMNS\n\t\t WHERE TABLE_SCHEMA = DATABASE()\n\t\t AND TABLE_NAME = ?\n\t\t AND COLUMN_KEY = 'PRI'\n\t\t ORDER BY ORDINAL_POSITION`,\n\t\t[tableName],\n\t);\n\treturn (rows as Array<{ column_name: string }>).map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getMysqlPool(db);\n\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// MySQL has no ctid equivalent — if no cursor columns, use empty (rely on natural order)\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClauseMysql(filters);\n\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClauseMysql(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\tconst sortClause = buildSortClauseMysql(Array.isArray(sort) ? sort : sort, order);\n\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else if (cursorColumns.length > 0) {\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\\`${col}\\` ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\tconst [countRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT COUNT(*) as total FROM \\`${tableName}\\` ${filterWhereClause}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\tfilterValues as any,\n\t);\n\tconst totalRows = Number((countRows as Array<{ total: number }>)[0]?.total ?? 0);\n\n\tconst fetchLimit = Math.floor(limit) + 1;\n\tconst [dataRows] = await pool.execute<RowDataPacket[]>(\n\t\t`SELECT * FROM \\`${tableName}\\` ${combinedWhereClause} ${effectiveSortClause} LIMIT ${fetchLimit}`,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: mysql2 execute doesn't accept unknown[]\n\t\t[...filterValues, ...cursorValues] as any,\n\t);\n\n\tlet rows = dataRows as Record<string, unknown>[];\n\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\n\tif (rows.length > 0 && cursorColumns.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\n\t\tif (direction === \"asc\") {\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import { HTTPException } from \"hono/http-exception\";\nimport type { RenameColumnParamsSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\n/**\n * Renames a PostgreSQL column using ALTER TABLE RENAME COLUMN.\n */\nexport async function renameColumn(params: RenameColumnParamsSchemaType): Promise<void> {\n\tconst { tableName, columnName, newColumnName, db } = params;\n\tconst pool = getDbPool(db);\n\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\tWHERE table_name = $1 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: tableRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\tconst columnExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\tWHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'\n\t\t) as exists;\n\t`;\n\tconst { rows: currentColumnRows } = await pool.query(columnExistsQuery, [\n\t\ttableName,\n\t\tcolumnName,\n\t]);\n\tif (!currentColumnRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Column \"${columnName}\" does not exist in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tconst { rows: nextColumnRows } = await pool.query(columnExistsQuery, [\n\t\ttableName,\n\t\tnewColumnName,\n\t]);\n\tif (nextColumnRows[0]?.exists) {\n\t\tthrow new HTTPException(409, {\n\t\t\tmessage: `Column \"${newColumnName}\" already exists in table \"${tableName}\"`,\n\t\t});\n\t}\n\n\tawait pool.query(\n\t\t`ALTER TABLE \"${tableName}\" RENAME COLUMN \"${columnName}\" TO \"${newColumnName}\"`,\n\t);\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { TableInfoSchemaType } from \"shared/types\";\nimport type { DatabaseSchemaType } from \"shared/types/database.types.js\";\nimport { getDbPool } from \"@/db-manager.js\";\n\nexport async function getTablesList(\n\tdb: DatabaseSchemaType[\"db\"],\n): Promise<TableInfoSchemaType[]> {\n\tconst pool = getDbPool(db);\n\n\t// First, get all table names\n\tconst tablesQuery = `\n\t\tSELECT table_name as \"tableName\"\n\t\tFROM information_schema.tables\n\t\tWHERE table_schema = 'public'\n\t\t AND table_type = 'BASE TABLE'\n\t\tORDER BY table_name;\n\t`;\n\n\tconst { rows: tables } = await pool.query(tablesQuery);\n\tif (!tables[0]) {\n\t\tthrow new HTTPException(500, {\n\t\t\tmessage: \"No tables returned from database\",\n\t\t});\n\t}\n\n\t// Get accurate row count for each table\n\tconst result: TableInfoSchemaType[] = await Promise.all(\n\t\ttables.map(async (table: { tableName: string }) => {\n\t\t\tconst countQuery = `SELECT COUNT(*)::integer as count FROM \"${table.tableName}\"`;\n\t\t\tconst { rows } = await pool.query(countQuery);\n\t\t\treturn {\n\t\t\t\ttableName: table.tableName,\n\t\t\t\trowCount: rows[0]?.count ?? 0,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn result;\n}\n","import { HTTPException } from \"hono/http-exception\";\nimport type { DatabaseSchemaType, TableNameSchemaType } from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\n\ninterface ColumnInfo {\n\tcolumn_name: string;\n\tdata_type: string;\n\tudt_name: string;\n\tis_nullable: string;\n\tcolumn_default: string | null;\n\tcharacter_maximum_length: number | null;\n\tnumeric_precision: number | null;\n\tnumeric_scale: number | null;\n}\n\ninterface ConstraintInfo {\n\tconstraint_name: string;\n\tconstraint_type: string;\n\tcolumn_name: string;\n\tforeign_table_name: string | null;\n\tforeign_column_name: string | null;\n}\n\ninterface IndexInfo {\n\tindexname: string;\n\tindexdef: string;\n}\n\nexport async function getTableSchema({\n\ttableName,\n\tdb,\n}: {\n\ttableName: TableNameSchemaType[\"tableName\"];\n\tdb: DatabaseSchemaType[\"db\"];\n}): Promise<string> {\n\tconst pool = getDbPool(db);\n\n\t// Check if table exists\n\tconst tableExistsQuery = `\n\t\tSELECT EXISTS (\n\t\t\tSELECT 1 FROM information_schema.tables \n\t\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\t) as exists\n\t`;\n\tconst { rows: tableExistsRows } = await pool.query(tableExistsQuery, [tableName]);\n\tif (!tableExistsRows[0]?.exists) {\n\t\tthrow new HTTPException(404, {\n\t\t\tmessage: `Table \"${tableName}\" does not exist`,\n\t\t});\n\t}\n\n\t// Get column information\n\tconst columnsQuery = `\n\t\tSELECT \n\t\t\tcolumn_name,\n\t\t\tdata_type,\n\t\t\tudt_name,\n\t\t\tis_nullable,\n\t\t\tcolumn_default,\n\t\t\tcharacter_maximum_length,\n\t\t\tnumeric_precision,\n\t\t\tnumeric_scale\n\t\tFROM information_schema.columns\n\t\tWHERE table_schema = 'public' AND table_name = $1\n\t\tORDER BY ordinal_position\n\t`;\n\tconst { rows: columns } = await pool.query<ColumnInfo>(columnsQuery, [tableName]);\n\n\t// Get constraints (primary keys, foreign keys, unique)\n\tconst constraintsQuery = `\n\t\tSELECT \n\t\t\ttc.constraint_name,\n\t\t\ttc.constraint_type,\n\t\t\tkcu.column_name,\n\t\t\tccu.table_name AS foreign_table_name,\n\t\t\tccu.column_name AS foreign_column_name\n\t\tFROM information_schema.table_constraints tc\n\t\tJOIN information_schema.key_column_usage kcu\n\t\t\tON tc.constraint_name = kcu.constraint_name\n\t\t\tAND tc.table_schema = kcu.table_schema\n\t\tLEFT JOIN information_schema.constraint_column_usage ccu\n\t\t\tON tc.constraint_name = ccu.constraint_name\n\t\t\tAND tc.table_schema = ccu.table_schema\n\t\t\tAND tc.constraint_type = 'FOREIGN KEY'\n\t\tWHERE tc.table_schema = 'public' AND tc.table_name = $1\n\t\tORDER BY tc.constraint_type, tc.constraint_name\n\t`;\n\tconst { rows: constraints } = await pool.query<ConstraintInfo>(constraintsQuery, [\n\t\ttableName,\n\t]);\n\n\t// Get indexes (excluding primary key indexes which are auto-created)\n\tconst indexesQuery = `\n\t\tSELECT indexname, indexdef\n\t\tFROM pg_indexes\n\t\tWHERE schemaname = 'public' AND tablename = $1\n\t\tAND indexname NOT IN (\n\t\t\tSELECT constraint_name \n\t\t\tFROM information_schema.table_constraints \n\t\t\tWHERE table_schema = 'public' AND table_name = $1 AND constraint_type = 'PRIMARY KEY'\n\t\t)\n\t`;\n\tconst { rows: indexes } = await pool.query<IndexInfo>(indexesQuery, [tableName]);\n\n\t// Build the CREATE TABLE statement\n\tconst schemaLines: string[] = [];\n\tschemaLines.push(`create table public.${tableName} (`);\n\n\t// Add columns\n\tconst columnDefs: string[] = [];\n\tfor (const col of columns) {\n\t\tlet colDef = ` ${col.column_name} ${formatDataType(col)}`;\n\n\t\tif (col.is_nullable === \"NO\") {\n\t\t\tcolDef += \" not null\";\n\t\t}\n\n\t\tif (col.column_default !== null) {\n\t\t\tcolDef += ` default ${col.column_default}`;\n\t\t}\n\n\t\tcolumnDefs.push(colDef);\n\t}\n\n\t// Group constraints by name to handle composite keys\n\tconst constraintMap = new Map<string, ConstraintInfo[]>();\n\tfor (const constraint of constraints) {\n\t\tconst existing = constraintMap.get(constraint.constraint_name) || [];\n\t\texisting.push(constraint);\n\t\tconstraintMap.set(constraint.constraint_name, existing);\n\t}\n\n\t// Add constraints\n\tconst constraintDefs: string[] = [];\n\tfor (const [constraintName, constraintColumns] of constraintMap) {\n\t\tconst firstConstraint = constraintColumns[0];\n\t\tconst columnNames = constraintColumns.map((c) => c.column_name).join(\", \");\n\n\t\tif (firstConstraint.constraint_type === \"PRIMARY KEY\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} primary key (${columnNames})`);\n\t\t} else if (firstConstraint.constraint_type === \"FOREIGN KEY\") {\n\t\t\tconst foreignTable = firstConstraint.foreign_table_name;\n\t\t\tconst foreignColumn = firstConstraint.foreign_column_name;\n\t\t\tconstraintDefs.push(\n\t\t\t\t` constraint ${constraintName} foreign key (${columnNames}) references ${foreignTable} (${foreignColumn})`,\n\t\t\t);\n\t\t} else if (firstConstraint.constraint_type === \"UNIQUE\") {\n\t\t\tconstraintDefs.push(` constraint ${constraintName} unique (${columnNames})`);\n\t\t}\n\t}\n\n\t// Combine column and constraint definitions\n\tconst allDefs = [...columnDefs, ...constraintDefs];\n\tschemaLines.push(allDefs.join(\",\\n\"));\n\n\tschemaLines.push(\") tablespace pg_default;\");\n\n\t// Add indexes as separate statements\n\tfor (const index of indexes) {\n\t\t// Skip unique indexes that are already covered by unique constraints\n\t\tconst isUniqueConstraint = Array.from(constraintMap.values()).some(\n\t\t\t(c) => c[0].constraint_type === \"UNIQUE\" && c[0].constraint_name === index.indexname,\n\t\t);\n\t\tif (!isUniqueConstraint) {\n\t\t\tschemaLines.push(\"\");\n\t\t\tschemaLines.push(`${index.indexdef};`);\n\t\t}\n\t}\n\n\treturn schemaLines.join(\"\\n\");\n}\n\nfunction formatDataType(col: ColumnInfo): string {\n\tconst { data_type, udt_name, character_maximum_length, numeric_precision, numeric_scale } =\n\t\tcol;\n\n\t// Handle user-defined types (enums)\n\tif (data_type === \"USER-DEFINED\") {\n\t\treturn udt_name;\n\t}\n\n\t// Handle array types\n\tif (data_type === \"ARRAY\") {\n\t\treturn `${udt_name.replace(/^_/, \"\")}[]`;\n\t}\n\n\t// Handle character types with length\n\tif (\n\t\t(data_type === \"character varying\" || data_type === \"varchar\") &&\n\t\tcharacter_maximum_length\n\t) {\n\t\treturn `varchar(${character_maximum_length})`;\n\t}\n\n\tif (data_type === \"character\" && character_maximum_length) {\n\t\treturn `char(${character_maximum_length})`;\n\t}\n\n\t// Handle numeric with precision and scale\n\tif (data_type === \"numeric\" && numeric_precision !== null) {\n\t\tif (numeric_scale !== null && numeric_scale > 0) {\n\t\t\treturn `numeric(${numeric_precision}, ${numeric_scale})`;\n\t\t}\n\t\treturn `numeric(${numeric_precision})`;\n\t}\n\n\t// Handle timestamp types\n\tif (data_type === \"timestamp with time zone\") {\n\t\treturn \"timestamp with time zone\";\n\t}\n\n\tif (data_type === \"timestamp without time zone\") {\n\t\treturn \"timestamp\";\n\t}\n\n\t// Map common data types\n\tconst typeMap: Record<string, string> = {\n\t\t\"character varying\": \"varchar\",\n\t\tcharacter: \"char\",\n\t\t\"double precision\": \"float8\",\n\t\tinteger: \"integer\",\n\t\tbigint: \"bigint\",\n\t\tsmallint: \"smallint\",\n\t\tboolean: \"boolean\",\n\t\ttext: \"text\",\n\t\tuuid: \"uuid\",\n\t\tjson: \"json\",\n\t\tjsonb: \"jsonb\",\n\t\tdate: \"date\",\n\t\ttime: \"time\",\n\t\tbytea: \"bytea\",\n\t};\n\n\treturn typeMap[data_type] || data_type;\n}\n","import type { CursorData, FilterType, SortDirection, SortType } from \"shared/types\";\n\nexport function buildWhereClause(filters: FilterType[]): {\n\tclause: string;\n\tvalues: unknown[];\n} {\n\tif (filters.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\tconst conditions: string[] = [];\n\tconst values: unknown[] = [];\n\n\tfor (const filter of filters) {\n\t\tconst paramIndex = values.length + 1;\n\t\tconst columnName = `\"${filter.columnName}\"`;\n\n\t\tswitch (filter.operator) {\n\t\t\tcase \"=\":\n\t\t\tcase \"!=\":\n\t\t\tcase \">\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<\":\n\t\t\tcase \"<=\":\n\t\t\t\tconditions.push(`${columnName} ${filter.operator} $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"is\":\n\t\t\t\t// Handle NULL values\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} = $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"is not\":\n\t\t\t\tif (filter.value.toLowerCase() === \"null\") {\n\t\t\t\t\tconditions.push(`${columnName} IS NOT NULL`);\n\t\t\t\t} else {\n\t\t\t\t\tconditions.push(`${columnName} != $${paramIndex}`);\n\t\t\t\t\tvalues.push(filter.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"like\":\n\t\t\t\tconditions.push(`${columnName}::text LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not like\":\n\t\t\t\tconditions.push(`${columnName}::text NOT LIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"ilike\":\n\t\t\t\tconditions.push(`${columnName}::text ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tcase \"not ilike\":\n\t\t\t\tconditions.push(`${columnName}::text NOT ILIKE $${paramIndex}`);\n\t\t\t\tvalues.push(filter.value);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Unknown operator, skip\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (conditions.length === 0) {\n\t\treturn { clause: \"\", values: [] };\n\t}\n\n\treturn { clause: `WHERE ${conditions.join(\" AND \")}`, values };\n}\n\nexport function buildSortClause(sorts: SortType[] | string, order: SortDirection): string {\n\t// Handle array of Sort objects (new format for referenced tables)\n\tif (Array.isArray(sorts)) {\n\t\tif (sorts.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst sortParts = sorts.map(\n\t\t\t(sort) => `\"${sort.columnName}\" ${sort.direction.toUpperCase()}`,\n\t\t);\n\t\treturn `ORDER BY ${sortParts.join(\", \")}`;\n\t}\n\n\t// Handle legacy format (string column name + order)\n\tif (sorts && typeof sorts === \"string\") {\n\t\treturn `ORDER BY \"${sorts}\" ${order?.toUpperCase() || \"ASC\"}`;\n\t}\n\n\treturn \"\";\n}\n\nexport function buildCursorWhereClause(\n\tcursorData: CursorData,\n\tdirection: SortDirection,\n\tsortDirection: SortDirection,\n\tstartParamIndex: number,\n): { clause: string; values: unknown[] } {\n\tconst { values, sortColumns } = cursorData;\n\tconst conditions: string[] = [];\n\tconst queryValues: unknown[] = [];\n\n\t// Determine comparison operator based on direction and sort order\n\t// Forward + ASC = >, Forward + DESC = <\n\t// Backward + ASC = <, Backward + DESC = >\n\tconst isAscending = sortDirection === \"asc\";\n\tconst isForward = direction === \"asc\";\n\tconst useGreaterThan = isAscending === isForward;\n\n\t// Build row comparison for multi-column cursor\n\t// Uses tuple comparison: (col1, col2, ...) > (val1, val2, ...)\n\tif (sortColumns.length > 0) {\n\t\tconst columnList = sortColumns.map((col) => `\"${col}\"`).join(\", \");\n\t\tconst placeholders = sortColumns.map((_, i) => `$${startParamIndex + i}`).join(\", \");\n\t\tconst operator = useGreaterThan ? \">\" : \"<\";\n\n\t\tconditions.push(`(${columnList}) ${operator} (${placeholders})`);\n\t\tfor (const col of sortColumns) {\n\t\t\tqueryValues.push(values[col]);\n\t\t}\n\t}\n\n\treturn {\n\t\tclause: conditions.length > 0 ? `(${conditions.join(\" AND \")})` : \"\",\n\t\tvalues: queryValues,\n\t};\n}\n","import type {\n\tCursorData,\n\tDatabaseSchemaType,\n\tFilterType,\n\tSortDirection,\n\tSortType,\n\tTableDataResultSchemaType,\n} from \"shared/types\";\nimport { getDbPool } from \"@/db-manager.js\";\nimport {\n\tbuildCursorWhereClause,\n\tbuildSortClause,\n\tbuildWhereClause,\n} from \"@/utils/build-clauses.js\";\n\n// Encode cursor data to base64 string\nconst encodeCursor = (data: CursorData): string => {\n\treturn Buffer.from(JSON.stringify(data)).toString(\"base64url\");\n};\n\n// Decode base64 cursor string to cursor data\nconst decodeCursor = (cursor: string): CursorData | null => {\n\ttry {\n\t\treturn JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n// Get primary key column(s) for a table\nconst getPrimaryKeyColumns = async (\n\tpool: ReturnType<typeof getDbPool>,\n\ttableName: string,\n): Promise<string[]> => {\n\t// Quote the table name to preserve case sensitivity in PostgreSQL\n\tconst quotedTableName = `\"${tableName}\"`;\n\tconst result = await pool.query(\n\t\t`SELECT a.attname as column_name\n\t\t FROM pg_index i\n\t\t JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n\t\t WHERE i.indrelid = $1::regclass AND i.indisprimary\n\t\t ORDER BY array_position(i.indkey, a.attnum)`,\n\t\t[quotedTableName],\n\t);\n\treturn result.rows.map((row) => row.column_name);\n};\n\nexport interface GetTableDataParams {\n\ttableName: string;\n\tcursor?: string;\n\tlimit?: number;\n\tdirection?: SortDirection;\n\tsort?: string | SortType[];\n\torder?: SortDirection;\n\tfilters?: FilterType[];\n\tdb: DatabaseSchemaType[\"db\"];\n}\n\nexport const getTableData = async ({\n\ttableName,\n\tcursor = \"\",\n\tlimit = 50,\n\tdirection = \"asc\",\n\tsort = [],\n\torder = \"asc\",\n\tfilters = [],\n\tdb,\n}: GetTableDataParams): Promise<TableDataResultSchemaType> => {\n\tconst pool = getDbPool(db);\n\n\t// Get primary key columns for stable cursor pagination\n\tconst primaryKeyColumns = await getPrimaryKeyColumns(pool, tableName);\n\n\t// Determine sort columns - use provided sort or fall back to primary key\n\tlet sortColumns: string[] = [];\n\tlet effectiveSortDirection: SortDirection = order;\n\n\tif (Array.isArray(sort) && sort.length > 0) {\n\t\tsortColumns = sort.map((s) => s.columnName);\n\t\teffectiveSortDirection = sort[0].direction;\n\t} else if (typeof sort === \"string\" && sort) {\n\t\tsortColumns = [sort];\n\t}\n\t// Always include primary key columns for stable pagination\n\tconst cursorColumns = [\n\t\t...sortColumns,\n\t\t...primaryKeyColumns.filter((pk) => !sortColumns.includes(pk)),\n\t];\n\n\t// If no sort columns and no primary key, fall back to ctid (PostgreSQL internal row id)\n\tif (cursorColumns.length === 0) {\n\t\tcursorColumns.push(\"ctid\");\n\t}\n\t// Build filter WHERE clause\n\tconst { clause: filterWhereClause, values: filterValues } = buildWhereClause(filters);\n\t// Build cursor WHERE clause if cursor is provided\n\tlet cursorWhereClause = \"\";\n\tlet cursorValues: unknown[] = [];\n\n\tif (cursor) {\n\t\tconst cursorData = decodeCursor(cursor);\n\t\tif (cursorData) {\n\t\t\tconst cursorResult = buildCursorWhereClause(\n\t\t\t\tcursorData,\n\t\t\t\tdirection,\n\t\t\t\teffectiveSortDirection,\n\t\t\t\tfilterValues.length + 1,\n\t\t\t);\n\t\t\tcursorWhereClause = cursorResult.clause;\n\t\t\tcursorValues = cursorResult.values;\n\t\t}\n\t}\n\t// Combine WHERE clauses\n\tlet combinedWhereClause = \"\";\n\tif (filterWhereClause && cursorWhereClause) {\n\t\t// Remove \"WHERE \" prefix from filterWhereClause and combine\n\t\tconst filterCondition = filterWhereClause.replace(/^WHERE\\s+/i, \"\");\n\t\tcombinedWhereClause = `WHERE ${filterCondition} AND ${cursorWhereClause}`;\n\t} else if (filterWhereClause) {\n\t\tcombinedWhereClause = filterWhereClause;\n\t} else if (cursorWhereClause) {\n\t\tcombinedWhereClause = `WHERE ${cursorWhereClause}`;\n\t}\n\n\t// Build sort clause\n\tconst sortClause = buildSortClause(Array.isArray(sort) ? sort : sort, order);\n\n\t// For backward pagination, reverse the sort order\n\tlet effectiveSortClause = sortClause;\n\tif (direction === \"desc\") {\n\t\tif (sortClause) {\n\t\t\teffectiveSortClause = sortClause\n\t\t\t\t.replace(/\\bASC\\b/gi, \"TEMP_DESC\")\n\t\t\t\t.replace(/\\bDESC\\b/gi, \"ASC\")\n\t\t\t\t.replace(/TEMP_DESC/g, \"DESC\");\n\t\t} else {\n\t\t\t// Default sort by cursor columns in reverse\n\t\t\tconst reverseSortParts = cursorColumns.map(\n\t\t\t\t(col) => `\"${col}\" ${effectiveSortDirection === \"asc\" ? \"DESC\" : \"ASC\"}`,\n\t\t\t);\n\t\t\teffectiveSortClause = `ORDER BY ${reverseSortParts.join(\", \")}`;\n\t\t}\n\t} else if (!sortClause && cursorColumns.length > 0) {\n\t\t// Default sort by cursor columns\n\t\tconst defaultSortParts = cursorColumns.map(\n\t\t\t(col) => `\"${col}\" ${effectiveSortDirection.toUpperCase()}`,\n\t\t);\n\t\teffectiveSortClause = `ORDER BY ${defaultSortParts.join(\", \")}`;\n\t}\n\n\t// Get total count (with filters only, not cursor)\n\tconst countRes = await pool.query(\n\t\t`SELECT COUNT(*) as total FROM \"${tableName}\" ${filterWhereClause}`,\n\t\tfilterValues,\n\t);\n\tconst totalRows = Number(countRes.rows[0].total);\n\t// Fetch one extra row to determine if there are more results\n\tconst limitParamIndex = filterValues.length + cursorValues.length + 1;\n\tconst dataRes = await pool.query(\n\t\t`SELECT * FROM \"${tableName}\" ${combinedWhereClause} ${effectiveSortClause} LIMIT $${limitParamIndex}`,\n\t\t[...filterValues, ...cursorValues, limit + 1],\n\t);\n\t// Check if table has columns\n\tconst hasColumns = dataRes.fields && dataRes.fields.length > 0;\n\t// Filter out empty objects\n\tlet rows = hasColumns\n\t\t? dataRes.rows.filter((row) => Object.keys(row).length > 0)\n\t\t: dataRes.rows;\n\t// Determine if there are more results\n\tconst hasMore = rows.length > limit;\n\tif (hasMore) {\n\t\trows = rows.slice(0, limit);\n\t}\n\t// For backward pagination, reverse the results to maintain correct order\n\tif (direction === \"desc\") {\n\t\trows = rows.reverse();\n\t}\n\t// Build cursors for next/previous pages\n\tlet nextCursor: string | null = null;\n\tlet prevCursor: string | null = null;\n\tif (rows.length > 0) {\n\t\tconst firstRow = rows[0];\n\t\tconst lastRow = rows[rows.length - 1];\n\t\t// Create cursor from row values\n\t\tconst createCursorFromRow = (row: Record<string, unknown>): CursorData => ({\n\t\t\tvalues: Object.fromEntries(cursorColumns.map((col) => [col, row[col]])),\n\t\t\tsortColumns: cursorColumns,\n\t\t});\n\t\t// For forward pagination\n\t\tif (direction === \"asc\") {\n\t\t\t// Next cursor: if there are more results, encode the last row\n\t\t\tif (hasMore) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if we used a cursor to get here, encode the first row\n\t\t\tif (cursor) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t} else {\n\t\t\t// For backward pagination\n\t\t\t// Next cursor: if we used a cursor, encode the last row (to go forward again)\n\t\t\tif (cursor) {\n\t\t\t\tnextCursor = encodeCursor(createCursorFromRow(lastRow));\n\t\t\t}\n\t\t\t// Previous cursor: if there are more results going backward, encode the first row\n\t\t\tif (hasMore) {\n\t\t\t\tprevCursor = encodeCursor(createCursorFromRow(firstRow));\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tdata: rows,\n\t\tmeta: {\n\t\t\tlimit,\n\t\t\ttotal: totalRows,\n\t\t\thasNextPage: direction === \"asc\" ? hasMore : !!cursor,\n\t\t\thasPreviousPage: direction === \"asc\" ? !!cursor : hasMore,\n\t\t\tnextCursor,\n\t\t\tprevCursor,\n\t\t},\n\t};\n};\n","import type { CellValue, FormatType } from \"shared/types\";\nimport { utils, write } from \"xlsx\";\n\ninterface ExportFileOptions {\n\tcols: string[];\n\trows: Record<string, CellValue>[];\n\tformat: FormatType;\n\ttableName: string;\n}\n\n/**\n * Converts table data to the specified export format (CSV, XLSX, or JSON)\n *\n * @param options - The export options\n * @param options.cols - Array of column names\n * @param options.rows - Array of row data objects\n * @param options.format - The export format ('csv', 'xlsx', or 'json')\n * @param options.tableName - The name of the table being exported\n * @returns The file content as a Uint8Array\n */\nexport function getExportFile({ cols, rows, format, tableName }: ExportFileOptions): BodyInit {\n\tswitch (format) {\n\t\tcase \"json\": {\n\t\t\tconst jsonContent = JSON.stringify(rows ?? [], null, 2);\n\t\t\treturn new Uint8Array(Buffer.from(jsonContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"csv\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst csvContent = utils.sheet_to_csv(worksheet);\n\t\t\treturn new Uint8Array(Buffer.from(csvContent, \"utf-8\"));\n\t\t}\n\n\t\tcase \"xlsx\": {\n\t\t\tconst data: CellValue[][] = [\n\t\t\t\tcols,\n\t\t\t\t...(rows?.map((row) => cols?.map((col) => row[col])) ?? []),\n\t\t\t];\n\t\t\tconst worksheet = utils.aoa_to_sheet(data);\n\t\t\tconst workbook = utils.book_new();\n\t\t\tutils.book_append_sheet(workbook, worksheet, tableName.slice(0, 31));\n\t\t\tconst buffer = write(workbook, {\n\t\t\t\tbookType: \"xlsx\",\n\t\t\t\ttype: \"buffer\",\n\t\t\t}) as Buffer;\n\t\t\treturn new Uint8Array(buffer);\n\t\t}\n\t}\n}\n","import { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport {\n\taddColumnSchema,\n\talterColumnSchema,\n\ttype ColumnInfoSchemaType,\n\tcreateTableSchema,\n\ttype DeleteTableResult,\n\tdatabaseSchema,\n\tdeleteColumnParamSchema,\n\tdeleteColumnQuerySchema,\n\tdeleteTableQuerySchema,\n\texportTableSchema,\n\trenameColumnSchema,\n\ttype TableDataResultSchemaType,\n\ttype TableInfoSchemaType,\n\ttype TableSchemaResult,\n\ttableDataQuerySchema,\n\ttableNameSchema,\n} from \"shared/types\";\nimport type { ApiHandler, RouteEnv } from \"@/app.types.js\";\nimport { addColumn as pgAddColumn } from \"@/dao/add-column.dao.js\";\nimport { alterColumn as pgAlterColumn } from \"@/dao/alter-column.dao.js\";\nimport { createTable as pgCreateTable } from \"@/dao/create-table.dao.js\";\nimport { deleteColumn as pgDeleteColumn } from \"@/dao/delete-column.dao.js\";\nimport { deleteTable as pgDeleteTable } from \"@/dao/delete-table.dao.js\";\nimport { exportTableData as pgExportTableData } from \"@/dao/export-table.dao.js\";\nimport { addColumn as mysqlAddColumn } from \"@/dao/mysql/add-column.mysql.dao.js\";\nimport { alterColumn as mysqlAlterColumn } from \"@/dao/mysql/alter-column.mysql.dao.js\";\nimport { createTable as mysqlCreateTable } from \"@/dao/mysql/create-table.mysql.dao.js\";\nimport { deleteColumn as mysqlDeleteColumn } from \"@/dao/mysql/delete-column.mysql.dao.js\";\nimport { deleteTable as mysqlDeleteTable } from \"@/dao/mysql/delete-table.mysql.dao.js\";\nimport { exportTableData as mysqlExportTableData } from \"@/dao/mysql/export-table.mysql.dao.js\";\nimport { renameColumn as mysqlRenameColumn } from \"@/dao/mysql/rename-column.mysql.dao.js\";\nimport { getTableColumns as mysqlGetTableColumns } from \"@/dao/mysql/table-columns.mysql.dao.js\";\nimport { getTablesList as mysqlGetTablesList } from \"@/dao/mysql/table-list.mysql.dao.js\";\nimport { getTableSchema as mysqlGetTableSchema } from \"@/dao/mysql/table-schema.mysql.dao.js\";\nimport { getTableData as mysqlGetTableData } from \"@/dao/mysql/tables-data.mysql.dao.js\";\nimport { renameColumn as pgRenameColumn } from \"@/dao/rename-column.dao.js\";\nimport { getTableColumns as pgGetTableColumns } from \"@/dao/table-columns.dao.js\";\nimport { getTablesList as pgGetTablesList } from \"@/dao/table-list.dao.js\";\nimport { getTableSchema as pgGetTableSchema } from \"@/dao/table-schema.dao.js\";\nimport { getTableData as pgGetTableData } from \"@/dao/tables-data.dao.js\";\nimport { getExportFile } from \"@/utils/get-export-file.js\";\n\nexport const tablesRoutes = new Hono<RouteEnv>()\n\t/**\n\t * Base path for the endpoints, /:dbType/tables/...\n\t */\n\t.basePath(\"/tables\")\n\n\t/**\n\t * GET /tables\n\t * Returns list of all tables in the currently connected database\n\t */\n\t.get(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tasync (c): ApiHandler<TableInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst tablesList =\n\t\t\t\tdbType === \"mysql\" ? await mysqlGetTablesList(db) : await pgGetTablesList(db);\n\t\t\treturn c.json({ data: tablesList }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * POST /tables\n\t * Creates a new table in the currently connected database\n\t */\n\t.post(\n\t\t\"/\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"json\", createTableSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlCreateTable({ tableData: body, db });\n\t\t\t} else {\n\t\t\t\tawait pgCreateTable({ tableData: body, db });\n\t\t\t}\n\t\t\treturn c.json({ data: `Table ${body.tableName} created successfully` }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName\n\t * Deletes a table from the database\n\t */\n\t.delete(\n\t\t\"/:tableName\",\n\t\tzValidator(\"query\", deleteTableQuerySchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<DeleteTableResult> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst result =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlDeleteTable({ tableName, db, cascade })\n\t\t\t\t\t: await pgDeleteTable({ tableName, db, cascade });\n\t\t\treturn c.json({ data: result }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * DELETE /tables/:tableName/columns/:columnName\n\t * Deletes a column from a table\n\t */\n\t.delete(\n\t\t\"/:tableName/columns/:columnName\",\n\t\tzValidator(\"query\", deleteColumnQuerySchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db, cascade } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst { deletedCount } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlDeleteColumn({ tableName, columnName, cascade, db })\n\t\t\t\t\t: await pgDeleteColumn({ tableName, columnName, cascade, db });\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" deleted successfully from table \"${tableName}\" with ${deletedCount} rows deleted`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * POST /tables/:tableName/columns\n\t * Adds a column to a table\n\t */\n\t.post(\n\t\t\"/:tableName/columns\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"json\", addColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlAddColumn({ tableName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgAddColumn({ tableName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${body.columnName}\" added successfully to table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /tables/:tableName/columns/:columnName/rename\n\t * Renames a column in a table\n\t */\n\t.patch(\n\t\t\"/:tableName/columns/:columnName/rename\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tzValidator(\"json\", renameColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgRenameColumn({ tableName, columnName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" renamed to \"${body.newColumnName}\" in table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * PATCH /tables/:tableName/columns/:columnName\n\t * Alters a column in a table\n\t */\n\t.patch(\n\t\t\"/:tableName/columns/:columnName\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", deleteColumnParamSchema),\n\t\tzValidator(\"json\", alterColumnSchema),\n\t\tasync (c): ApiHandler<string> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName, columnName } = c.req.valid(\"param\");\n\t\t\tconst body = c.req.valid(\"json\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tif (dbType === \"mysql\") {\n\t\t\t\tawait mysqlAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t} else {\n\t\t\t\tawait pgAlterColumn({ tableName, columnName, db, ...body });\n\t\t\t}\n\n\t\t\treturn c.json(\n\t\t\t\t{\n\t\t\t\t\tdata: `Column \"${columnName}\" updated successfully in table \"${tableName}\"`,\n\t\t\t\t},\n\t\t\t\t200,\n\t\t\t);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/columns\n\t * Returns list of all columns in a table\n\t */\n\t.get(\n\t\t\"/:tableName/columns\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<ColumnInfoSchemaType[]> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst columns =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlGetTableColumns({ tableName, db })\n\t\t\t\t\t: await pgGetTableColumns({ tableName, db });\n\t\t\treturn c.json({ data: columns }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/schema\n\t * Returns the CREATE TABLE schema for a table\n\t */\n\t.get(\n\t\t\"/:tableName/schema\",\n\t\tzValidator(\"query\", databaseSchema),\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tasync (c): ApiHandler<TableSchemaResult> => {\n\t\t\tconst { db } = c.req.valid(\"query\");\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst schema =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlGetTableSchema({ tableName, db })\n\t\t\t\t\t: await pgGetTableSchema({ tableName, db });\n\t\t\treturn c.json({ data: { schema } }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/data\n\t * Get cursor-paginated data for a table\n\t */\n\t.get(\n\t\t\"/:tableName/data\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", tableDataQuerySchema),\n\t\tasync (c): ApiHandler<TableDataResultSchemaType> => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { cursor, limit, direction, sort, order, filters, db } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\t\t\tconst tableData =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlGetTableData({\n\t\t\t\t\t\t\ttableName,\n\t\t\t\t\t\t\tcursor,\n\t\t\t\t\t\t\tlimit,\n\t\t\t\t\t\t\tdirection,\n\t\t\t\t\t\t\tsort,\n\t\t\t\t\t\t\torder,\n\t\t\t\t\t\t\tfilters,\n\t\t\t\t\t\t\tdb,\n\t\t\t\t\t\t})\n\t\t\t\t\t: await pgGetTableData({\n\t\t\t\t\t\t\ttableName,\n\t\t\t\t\t\t\tcursor,\n\t\t\t\t\t\t\tlimit,\n\t\t\t\t\t\t\tdirection,\n\t\t\t\t\t\t\tsort,\n\t\t\t\t\t\t\torder,\n\t\t\t\t\t\t\tfilters,\n\t\t\t\t\t\t\tdb,\n\t\t\t\t\t\t});\n\t\t\treturn c.json({ data: tableData }, 200);\n\t\t},\n\t)\n\n\t/**\n\t * GET /tables/:tableName/export\n\t * Export table data to CSV or XLSX format\n\t */\n\t.get(\n\t\t\"/:tableName/export\",\n\t\tzValidator(\"param\", tableNameSchema),\n\t\tzValidator(\"query\", exportTableSchema),\n\t\tasync (c) => {\n\t\t\tconst { tableName } = c.req.valid(\"param\");\n\t\t\tconst { db, format } = c.req.valid(\"query\");\n\t\t\tconst dbType = c.get(\"dbType\");\n\n\t\t\tconst { cols, rows } =\n\t\t\t\tdbType === \"mysql\"\n\t\t\t\t\t? await mysqlExportTableData({ tableName, db })\n\t\t\t\t\t: await pgExportTableData({ tableName, db });\n\t\t\tconst fileContent = getExportFile({ cols, rows, format, tableName });\n\t\t\tlet contentType: string | undefined;\n\n\t\t\tswitch (format) {\n\t\t\t\tcase \"csv\":\n\t\t\t\t\tcontentType = \"text/csv\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"xlsx\":\n\t\t\t\t\tcontentType = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"json\":\n\t\t\t\t\tcontentType = \"application/json\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn new Response(fileContent, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": contentType ?? \"\",\n\t\t\t\t\t\"Content-Disposition\": `attachment; filename=\"${tableName}_export.${format}\"`,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t);\n\nexport type TablesRoutes = typeof tablesRoutes.routes;\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { zValidator } from \"@hono/zod-validator\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { logger } from \"hono/logger\";\nimport { prettyJSON } from \"hono/pretty-json\";\nimport { type DatabaseTypeSchema, databaseTypeParamSchema } from \"shared/types\";\nimport type { AppType } from \"@/app.types.js\";\nimport { handleError, validationHook } from \"@/middlewares/error-handler.js\";\nimport { chatRoutes } from \"@/routes/chat.routes.js\";\nimport { databasesRoutes } from \"@/routes/databases.routes.js\";\nimport { queryRoutes } from \"@/routes/query.routes.js\";\nimport { recordsRoutes } from \"@/routes/records.routes.js\";\nimport { tablesRoutes } from \"@/routes/tables.routes.js\";\n\n/**\n * Get the path to the core distribution directory.\n */\nconst getCoreDistPath = () => {\n\tif (process.env.NODE_ENV === \"development\") {\n\t\treturn path.resolve(process.cwd(), \"../core/dist\");\n\t}\n\n\tconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\treturn path.resolve(__dirname, \"./core-dist\");\n};\n\nexport const createServer = () => {\n\tconst app = new Hono<AppType>({ strict: false })\n\t\t/**\n\t\t * Enable CORS\n\t\t */\n\t\t.use(\"/*\", cors())\n\n\t\t/**\n\t\t * Pretty print the JSON response\n\t\t */\n\t\t.use(prettyJSON({ space: 2 }))\n\n\t\t/**\n\t\t * Enable logger in development mode\n\t\t */\n\t\t.use(process.env.NODE_ENV === \"development\" ? logger() : (_, next) => next())\n\n\t\t/**\n\t\t * Serve the favicon.ico file\n\t\t */\n\t\t.use(\n\t\t\t\"/favicon.ico\",\n\t\t\tserveStatic({\n\t\t\t\tpath: path.resolve(getCoreDistPath(), \"favicon.ico\"),\n\t\t\t}),\n\t\t)\n\n\t\t/**\n\t\t * Handle CORS requests\n\t\t */\n\t\t.use(\"*\", async (c, next) => {\n\t\t\tc.header(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\tc.header(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n\t\t\tc.header(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\t\t\tawait next();\n\t\t})\n\n\t\t/**\n\t\t * Handle errors\n\t\t */\n\t\t.onError(handleError)\n\n\t\t/**\n\t\t * Database routes - available at root level (no dbType required)\n\t\t */\n\t\t.route(\"/\", databasesRoutes)\n\n\t\t/**\n\t\t * Serve static assets (before dbType validation to avoid conflicts)\n\t\t */\n\t\t.use(\"/assets/*\", serveStatic({ root: getCoreDistPath() }))\n\t\t.use(\"/image.png\", serveStatic({ root: getCoreDistPath() }))\n\n\t\t/**\n\t\t * Routes that require dbType validation - under /:dbType/...\n\t\t */\n\t\t.use(\"/:dbType/*\", zValidator(\"param\", databaseTypeParamSchema, validationHook))\n\t\t.use(\"/:dbType/*\", async (c, next) => {\n\t\t\tconst dbType = c.req.param(\"dbType\") as DatabaseTypeSchema;\n\t\t\tc.set(\"dbType\", dbType);\n\t\t\tawait next();\n\t\t})\n\t\t.route(\"/:dbType\", tablesRoutes)\n\t\t.route(\"/:dbType\", recordsRoutes)\n\t\t.route(\"/:dbType\", queryRoutes)\n\t\t.route(\"/:dbType\", chatRoutes)\n\n\t\t/**\n\t\t * Serve all other static files as fallback (for SPA)\n\t\t */\n\t\t.use(\"/*\", serveStatic({ root: getCoreDistPath() }));\n\n\treturn { app };\n};\n\nexport type { AppType };\n\n// Export the app type for hc client\nexport type AppRoutes = ReturnType<typeof createServer>[\"app\"];\n","import { intro, outro } from \"@clack/prompts\";\nimport { serve } from \"@hono/node-server\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { args } from \"@/cmd/args.js\";\nimport { getDatabaseUrl } from \"@/cmd/get-db-url.js\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\nimport { showHelp } from \"@/cmd/show-help.js\";\nimport { showStatus } from \"@/cmd/show-status.js\";\nimport { showVersion } from \"@/cmd/show-version.js\";\n\nexport const main = async () => {\n\tconst { env, port, databaseUrl, varName, status, help, version } = args();\n\n\t// Handle help flag\n\tif (help) {\n\t\tshowHelp();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle version flag\n\tif (version) {\n\t\tshowVersion();\n\t\tprocess.exit(0);\n\t}\n\n\t// Handle status flag\n\tif (status) {\n\t\tawait showStatus(env, databaseUrl, varName);\n\t\tprocess.exit(0);\n\t}\n\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst PORT = port ? parseInt(port, 10) : DEFAULTS.PORT;\n\tconst VAR_NAME = varName || DEFAULTS.VAR_NAME;\n\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\tconst DATABASE_URL = databaseUrl ? databaseUrl : await getDatabaseUrl(ENV, VAR_NAME);\n\n\t// Set DATABASE_URL in process.env before importing createServer\n\t// This ensures the db pool is initialized with the correct connection string\n\tprocess.env.DATABASE_URL = DATABASE_URL;\n\n\t// Import createServer dynamically after setting DATABASE_URL\n\tconst { createServer } = await import(\"./utils/create-server.js\");\n\tconst { app } = createServer();\n\tserve({\n\t\tfetch: app.fetch,\n\t\tport: PORT,\n\t});\n\n\toutro(color.green(`Server running at ${color.cyan(`http://localhost:${PORT}`)}`));\n};\n\nmain().catch((err) => {\n\tconsole.error(color.red(`❌ Unexpected error: ${err.message}`));\n\tprocess.exit(1);\n});\n","import { program } from \"commander\";\nimport type { Args } from \"shared/types\";\n\n/**\n * Get the arguments from the command line\n */\nexport const args = () => {\n\tprogram\n\t\t.name(\"db-studio\")\n\t\t.option(\"-e, --env <path>\", \"Path to custom .env file\")\n\t\t.option(\"-p, --port <port>\", \"Port to run the server on\")\n\t\t.option(\"-d, --database-url <url>\", \"Database URL to use\")\n\t\t.option(\n\t\t\t\"-n, --var-name <name>\",\n\t\t\t\"Custom environment variable name (default: DATABASE_URL)\",\n\t\t)\n\t\t.option(\"-s, --status\", \"Show status of the server\")\n\t\t.option(\"-h, --help\", \"Show help\")\n\t\t.option(\"-v, --version\", \"Show version\")\n\t\t.parse(process.argv);\n\n\treturn program.opts<Args>();\n};\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport { cancel, isCancel, note, select, spinner, text } from \"@clack/prompts\";\nimport { type DotenvParseOutput, parse as parseDotenv } from \"dotenv\";\nimport color from \"picocolors\";\n\n/**\n * Get the database URL from .env file, then process.env\n */\nexport const getDatabaseUrl = async (env?: DotenvParseOutput | null, varName?: string) => {\n\tconst envVarName = varName || \"DATABASE_URL\";\n\n\tif (env?.[envVarName]) {\n\t\treturn env[envVarName];\n\t}\n\n\t// Fall back to process.env (e.g. from shell or package.json script)\n\tif (process.env[envVarName]) {\n\t\treturn process.env[envVarName];\n\t}\n\n\tconst s = spinner();\n\ts.start(\"Looking for database connection...\");\n\n\tif (!env) {\n\t\tnote(color.red(`No .env file found and ${envVarName} not set in process.env`));\n\t} else {\n\t\tnote(color.red(`${envVarName} not found in .env or process.env`));\n\t}\n\n\tconst choice = await select({\n\t\tmessage: `How do you want to provide ${envVarName}?`,\n\t\toptions: [\n\t\t\t{ value: \"manual\", label: \"Enter connection string manually\" },\n\t\t\t{ value: \"other-env\", label: \"Use different .env file\" },\n\t\t\t// todo: add multiple db connections support\n\t\t\t{ value: \"cancel\", label: \"Cancel / Exit\" },\n\t\t],\n\t\tinitialValue: \"manual\",\n\t});\n\tif (isCancel(choice) || choice === \"cancel\") {\n\t\tcancel(\"No database connection provided. Exiting...\");\n\t\tprocess.exit(0);\n\t}\n\n\tif (choice === \"other-env\") {\n\t\ts.start(\"Waiting for path...\");\n\t\tconst customPath = await text({\n\t\t\tmessage: \"Enter path to .env file\",\n\t\t\tplaceholder: \"~/projects/myapp/.env.local or ./special.env\",\n\t\t\tvalidate(value?: string) {\n\t\t\t\tif (!value?.trim()) return \"Path is required\";\n\t\t\t},\n\t\t});\n\n\t\tif (isCancel(customPath)) {\n\t\t\tcancel(\"Cancelled.\");\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\ts.stop(\"Trying custom .env...\");\n\n\t\tconst customEnvPath = resolve(customPath);\n\t\ttry {\n\t\t\tconst content = await readFile(customEnvPath, \"utf-8\");\n\t\t\tconst parsed = parseDotenv(content);\n\t\t\tif (parsed[envVarName]) {\n\t\t\t\treturn parsed[envVarName];\n\t\t\t}\n\t\t\tthrow new Error(`${envVarName} still missing in custom file`);\n\t\t} catch (e: unknown) {\n\t\t\tconst error = e as Error;\n\t\t\tcancel(`Cannot read or parse file: ${color.dim(error.message)}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// 3. Manual input\n\ts.stop(\"Manual input...\");\n\n\tconst dbUrl = await text({\n\t\tmessage: `Paste your ${envVarName}`,\n\t\tplaceholder: \"postgresql://user:password@localhost:5432/mydb\",\n\t\tvalidate(value?: string) {\n\t\t\tif (!value?.trim()) return \"Connection string is required!\";\n\t\t\ttry {\n\t\t\t\tnew URL(value); // very basic check\n\t\t\t\treturn undefined;\n\t\t\t} catch {\n\t\t\t\treturn \"Must be a valid URL format\";\n\t\t\t}\n\t\t},\n\t});\n\n\tif (isCancel(dbUrl)) {\n\t\tcancel(\"Cancelled.\");\n\t\tprocess.exit(0);\n\t}\n\n\treturn dbUrl.trim();\n};\n","import { access, readFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport { parse as parseDotenv } from \"dotenv\";\n\n/**\n * Find .env path: try cwd, then walk up parent directories until root.\n */\nconst findEnvPath = async (startDir: string): Promise<string | null> => {\n\tlet dir = resolve(startDir);\n\tfor (;;) {\n\t\tconst envPath = resolve(dir, \".env\");\n\t\ttry {\n\t\t\tawait access(envPath);\n\t\t\treturn envPath;\n\t\t} catch {\n\t\t\t// ENOENT or other: try parent\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n};\n\n/**\n * Load the environment variables from the file.\n * When no path is given: tries current directory, then parent directories until a .env is found.\n * When --env path is given: uses that path only (no walk).\n */\nexport const loadEnv = async (env?: string) => {\n\tlet envPath: string | null;\n\n\tif (env) {\n\t\tenvPath = resolve(env);\n\t} else {\n\t\tenvPath = await findEnvPath(process.cwd());\n\t}\n\n\tif (!envPath) return null;\n\n\ttry {\n\t\tconst content = await readFile(envPath, \"utf-8\");\n\t\treturn parseDotenv(content);\n\t} catch (err) {\n\t\tif (err instanceof Error && err.message.includes(\"ENOENT\")) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow err;\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { META } from \"shared/constants/meta.js\";\n\n/**\n * Display help information\n */\nexport const showHelp = () => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconsole.log(color.bold(\"\\nUsage:\"));\n\tconsole.log(\" db-studio [options]\\n\");\n\n\tconsole.log(color.bold(\"Supported Databases:\"));\n\tconsole.log(\" MySQL, PostgreSQL\\n\");\n\n\tconsole.log(color.bold(\"Options:\"));\n\tconsole.log(\" -e, --env <path> Path to custom .env file\");\n\tconsole.log(\" -p, --port <port> Port to run the server on (default: 3333)\");\n\tconsole.log(\" -d, --database-url <url> Database URL to use\");\n\tconsole.log(\n\t\t\" -n, --var-name <name> Custom environment variable name (default: DATABASE_URL)\",\n\t);\n\tconsole.log(\" -s, --status Show status of the database connection\");\n\tconsole.log(\" -h, --help Show this help message\");\n\tconsole.log(\" -v, --version Show version number\\n\");\n\n\tconsole.log(color.bold(\"Examples:\"));\n\tconsole.log(\" db-studio\");\n\tconsole.log(\" db-studio -e .env.local\");\n\tconsole.log(\" db-studio -p 4000\");\n\tconsole.log(\" db-studio -d postgresql://user:pass@localhost:5432/mydb\");\n\tconsole.log(\" db-studio -n MY_DATABASE_URL\");\n\tconsole.log(\" db-studio -e .env.production -n PROD_DB_URL\");\n\tconsole.log(\" db-studio --status\\n\");\n\n\toutro(color.green(`For more information, visit: ${META.SITE_DOCS_LINK}`));\n};\n","import { intro, note, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport { DEFAULTS } from \"shared/constants\";\nimport { loadEnv } from \"@/cmd/load-env.js\";\n\n/**\n * Show connection status\n */\nexport const showStatus = async (env?: string, databaseUrl?: string, varName?: string) => {\n\tintro(color.inverse(\" db-studio \"));\n\n\tconst envVarName = varName || DEFAULTS.VAR_NAME;\n\tlet foundUrl: string | null = null;\n\n\t// Check if DATABASE_URL is provided via CLI\n\tif (databaseUrl) {\n\t\tfoundUrl = databaseUrl;\n\t} else {\n\t\t// Try .env file, then process.env\n\t\tconst ENV = env ? await loadEnv(env) : await loadEnv();\n\t\tif (ENV?.[envVarName]) {\n\t\t\tfoundUrl = ENV[envVarName];\n\t\t} else if (process.env[envVarName]) {\n\t\t\tfoundUrl = process.env[envVarName] ?? null;\n\t\t}\n\t}\n\n\tif (foundUrl) {\n\t\toutro(color.green(`✓ Database connection configured (using ${envVarName})`));\n\t} else {\n\t\tnote(color.red(`✗ ${envVarName} not found`), \"Status\");\n\t\tconsole.log(color.yellow(\"\\n To configure database connection:\"));\n\t\tconsole.log(color.dim(\" • Supported databases: MySQL, PostgreSQL\"));\n\t\tconsole.log(color.dim(` • Add ${envVarName} to your .env file or set it in process.env`));\n\t\tconsole.log(color.dim(\" • Use -d flag: db-studio -d <url>\"));\n\t\tconsole.log(color.dim(\" • Use -e flag: db-studio -e <path-to-env>\"));\n\t\tconsole.log(color.dim(\" • Use -n flag: db-studio -n <var-name>\\n\"));\n\n\t\toutro(color.yellow(\"⚠ No database connection configured\"));\n\t}\n};\n","import { intro, outro } from \"@clack/prompts\";\nimport color from \"picocolors\";\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\n/**\n * Display version information\n */\nexport const showVersion = () => {\n\tintro(color.inverse(\" db-studio \"));\n\toutro(color.green(`🚀 db-studio v${packageJson.version}`));\n};\n","{\n \"name\": \"db-studio\",\n \"type\": \"module\",\n \"version\": \"1.5.1\",\n \"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.\",\n \"keywords\": [\n \"database client\",\n \"database gui\",\n \"database browser\",\n \"sql client\",\n \"sql editor\",\n \"query tool\",\n \"table editor\",\n \"data editor\",\n \"postgres\",\n \"postgresql\",\n \"postgresql client\",\n \"postgresql gui\",\n \"pgadmin alternative\",\n \"mysql\",\n \"mysql client\",\n \"ai sql\",\n \"er diagram\",\n \"database management\",\n \"database studio\"\n ],\n \"author\": \"Hüsam 🥑 <devhsmq@gmail.com>\",\n \"homepage\": \"https://dbstudio.sh\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/husamql3/db-studio.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/husamql3/db-studio/issues\"\n },\n \"license\": \"MIT\",\n \"bin\": {\n \"db-studio\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"NODE_ENV=development tsx watch src/index.ts\",\n \"build\": \"tsup --minify --sourcemap\",\n \"prepack\": \"cd ../core && bun run build && cd ../server && bun run build\",\n \"start\": \"node dist/index.js\",\n \"check\": \"biome check --write --unsafe\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.0.1\",\n \"@hono/node-server\": \"^1.19.7\",\n \"@hono/zod-validator\": \"^0.7.6\",\n \"commander\": \"^14.0.3\",\n \"dotenv\": \"^17.3.1\",\n \"hono\": \"^4.10.4\",\n \"mysql2\": \"^3.18.2\",\n \"pg\": \"^8.13.1\",\n \"picocolors\": \"^1.1.1\",\n \"xlsx\": \"^0.18.5\",\n \"zod\": \"^4.2.1\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.2.6\",\n \"@types/node\": \"^20.11.17\",\n \"@types/pg\": \"^8.16.0\",\n \"@vitest/coverage-v8\": \"^4.0.17\",\n \"shared\": \"workspace:*\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.7.1\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"^4.0.17\"\n }\n}"],"mappings":"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","names":["init_chat","__esmMin","init_column_types_mysql","__esmMin","init_column_types_pgsql","__esmMin","DEFAULTS","init_defaults","__esmMin","init_links","__esmMin","META","init_meta","__esmMin","init_proxy_limits","__esmMin","init_constants","__esmMin","init_chat","init_column_types_mysql","init_column_types_pgsql","init_defaults","init_links","init_meta","init_proxy_limits","z","databaseSchema","DATABASE_TYPES","databaseTypeSchema","currentDatabaseSchema","databaseTypeParamSchema","tableNameSchema","init_database_types","__esmMin","z","addColumnSchema","addColumnParamsSchema","init_add_column_types","__esmMin","init_database_types","databaseSchema","tableNameSchema","z","addRecordSchema","init_add_record_types","__esmMin","z","deleteColumnQuerySchema","deleteColumnParamSchema","deleteColumnParamsSchema","deleteColumnSuccessResponseSchema","init_delete_column_types","__esmMin","init_database_types","databaseSchema","val","z","alterColumnSchema","alterColumnParamsSchema","init_alter_column_types","__esmMin","init_database_types","init_delete_column_types","databaseSchema","deleteColumnParamSchema","init_api_response_types","__esmMin","z","bulkInsertRecordsSchema","init_bulk_insert_records_type","__esmMin","z","chatSchema","init_chat_types","__esmMin","init_database_types","databaseSchema","init_cmd_args_types","__esmMin","z","dataTypes","dataTypesSchema","DataTypes","standardizedDataTypes","standardizedDataTypeSchema","columnInfoSchema","init_column_info_types","__esmMin","mapPostgresToDataType","pgType","normalized","DataTypes","standardizeDataTypeLabel","StandardizedDataType","mapMysqlToDataType","mysqlDataType","columnType","fullType","standardizeMysqlDataTypeLabel","init_column_type","__esmMin","init_column_info_types","z","FOREIGN_KEY_ACTIONS","foreignKeyActionSchema","fieldDataSchema","foreignKeyDataSchema","createTableSchema","init_create_table_types","__esmMin","z","databaseInfoSchema","databaseListSchema","connectionInfoSchema","init_database_list_types","__esmMin","init_database_types","databaseTypeSchema","init_database_schema_type","__esmMin","z","deleteRecordSchema","init_delete_record_types","__esmMin","z","deleteTableQuerySchema","init_delete_table_types","__esmMin","init_database_types","databaseSchema","val","z","executeQuerySchema","init_execute_query_types","__esmMin","z","FORMAT_TYPES","exportTableSchema","init_export_table_types","__esmMin","init_database_types","databaseSchema","init_rate_limit_response_type","__esmMin","z","renameColumnSchema","renameColumnParamsSchema","init_rename_column_types","__esmMin","init_database_types","init_delete_column_types","databaseSchema","deleteColumnParamSchema","z","filterSchema","sortDirections","sortSchema","tableDataMetaSchema","tableDataResultSchema","tableDataQuerySchema","init_table_data_types","__esmMin","init_database_types","databaseSchema","val","parsed","z","tableInfoSchema","init_table_info_type","__esmMin","z","tableSchemaResultSchema","init_table_schema_types","__esmMin","updateRecordsSchema","init_update_recors_types","__esmMin","init_types","__esmMin","init_add_column_types","init_add_record_types","init_alter_column_types","init_api_response_types","init_bulk_insert_records_type","init_chat_types","init_cmd_args_types","init_column_type","init_column_info_types","init_create_table_types","init_database_types","init_database_list_types","init_database_schema_type","init_delete_column_types","init_delete_record_types","init_delete_table_types","init_execute_query_types","init_export_table_types","init_rate_limit_response_type","init_rename_column_types","init_table_data_types","init_table_info_type","init_table_schema_types","init_update_recors_types","HTTPException","DatabaseError","ZodError","handleError","e","c","issue","mysqlError","validationHook","init_error_handler","__esmMin","result","Pool","dbInstance","getPool","db","init_db","__esmMin","err","error","_target","prop","createMysqlPool","Pool","DatabaseManager","databaseManager","getDbPool","getMysqlPool","getDbType","init_db_manager","__esmMin","url","protocol","databaseUrl","error","database","connectionString","poolConfig","pool","err","dbName","pgClosePromises","mysqlClosePromises","HTTPException","getTableColumns","tableName","db","pool","getDbPool","query","rows","r","parsedEnumValues","mapPostgresToDataType","standardizeDataTypeLabel","init_table_columns_dao","__esmMin","init_types","init_db_manager","getTableNames","db","pool","getDbPool","query","rows","getTableDescription","tableName","client","getSampleData","convertColumnInfo","col","column","extractRelationships","tables","relationships","table","toTable","toColumn","getDatabaseSchema","options","includeSampleData","includeDescriptions","tablePromises","columns","description","sampleData","getTableColumns","row","key","value","error","getDetailedSchema","init_table_details_schema","__esmMin","init_db","init_db_manager","init_table_columns_dao","generateSystemPrompt","schema","formatSchemaForPrompt","output","table","col","pkIndicator","fkIndicator","nullable","rel","init_system_prompt_generator","__esmMin","zValidator","Hono","chatRoutes","init_chat_routes","__esmMin","init_constants","init_types","init_table_details_schema","init_system_prompt_generator","chatSchema","c","messages","conversationId","db","schema","getDetailedSchema","systemPrompt","generateSystemPrompt","payload","proxyResponse","DEFAULTS","errorData","readable","writable","parseDatabaseUrl","databaseUrl","url","init_parse_database_url","__esmMin","HTTPException","getDatabasesList","pool","getDbPool","query","rows","getCurrentDatabase","getDatabaseConnectionInfo","result","connectionInfoSchema","urlDefaults","parseDatabaseUrl","init_database_list_dao","__esmMin","init_types","init_db_manager","init_parse_database_url","HTTPException","getDatabasesList","pool","getMysqlPool","rows","getCurrentDatabase","getDatabaseConnectionInfo","infoRows","connRows","info","activeConnections","urlDefaults","parseDatabaseUrl","init_database_list_mysql_dao","__esmMin","init_db_manager","init_parse_database_url","Hono","databasesRoutes","init_databases_routes","__esmMin","init_database_list_dao","init_database_list_mysql_dao","init_db_manager","c","dbType","getDbType","databases","getDatabasesList","current","getCurrentDatabase","info","getDatabaseConnectionInfo","HTTPException","executeQuery","init_query_mysql_dao","__esmMin","init_db_manager","query","db","pool","getMysqlPool","cleanedQuery","startTime","result","fields","duration","rows","f","dmlResult","HTTPException","executeQuery","init_query_dao","__esmMin","init_db_manager","query","db","pool","getDbPool","cleanedQuery","startTime","result","duration","field","zValidator","Hono","queryRoutes","init_query_routes","__esmMin","init_types","init_query_mysql_dao","init_query_dao","databaseSchema","executeQuerySchema","c","query","db","data","executeQuery","HTTPException","addRecord","db","params","tableName","data","pool","getDbPool","columns","values","placeholders","_","index","columnNames","col","query","result","init_add_record_dao","__esmMin","init_db_manager","HTTPException","bulkInsertRecords","init_bulk_insert_records_dao","__esmMin","init_db_manager","tableName","records","db","client","getDbPool","columns","columnNames","col","successCount","failureCount","errors","i","record","values","placeholders","_","index","insertSQL","error","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pool","constraintsByTable","constraint","key","pkValues","pk","_tableColumn","constraints","placeholders","_","i","relatedQuery","relatedResult","deleteRecords","pkColumn","query","result","error","forceDeleteRecords","totalRelatedDeleted","deletedTables","deleteRelatedRecursively","targetTable","targetColumn","values","nestedFks","nestedFk","nestedPlaceholders","selectQuery","nestedValues","deletePlaceholders","deleteQuery","deleteResult","init_delete_records_dao","__esmMin","init_db_manager","HTTPException","parseMysqlEnumValues","columnType","match","v","getTableColumns","tableName","db","pool","getMysqlPool","query","rows","r","dataType","enumValues","mapMysqlToDataType","standardizeMysqlDataTypeLabel","init_table_columns_mysql_dao","__esmMin","init_types","init_db_manager","HTTPException","addRecord","db","params","tableName","data","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","columns","values","value","index","columnName","placeholders","columnNames","query","result","init_add_record_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","bulkInsertRecords","init_bulk_insert_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","tableName","records","db","connection","getMysqlPool","columns","columnNames","col","tableColumns","getTableColumns","booleanColumns","i","record","values","value","placeholders","insertSQL","error","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecords","primaryKeys","fkConstraints","relatedRecords","pkValues","pk","constraintsByTable","constraint","key","_tableColumn","constraints","placeholders","relatedRows","deleteRecords","pkColumn","connection","result","error","MYSQL_FK_VIOLATION","forceDeleteRecords","totalRelatedDeleted","deletedTables","visited","deleteRelatedRecursively","targetTable","targetColumn","values","visitedSet","nestedFks","nestedFk","nestedPlaceholders","selectRows","nestedValues","deletePlaceholders","deleteResult","mainPlaceholders","init_delete_records_mysql_dao","__esmMin","init_db_manager","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getMysqlPool","tableColumns","getTableColumns","booleanColumns","col","updatesByRow","update","pkValue","connection","totalUpdated","rowUpdates","setClauses","u","values","query","result","error","init_update_records_mysql_dao","__esmMin","init_db_manager","init_table_columns_mysql_dao","HTTPException","updateRecords","params","db","tableName","updates","primaryKey","pool","getDbPool","updatesByRow","update","pkValue","totalUpdated","rowUpdates","setClauses","u","index","values","query","result","error","init_update_records_dao","__esmMin","init_db_manager","zValidator","Hono","recordsRoutes","init_records_routes","__esmMin","init_types","init_add_record_dao","init_bulk_insert_records_dao","init_delete_records_dao","init_add_record_mysql_dao","init_bulk_insert_records_mysql_dao","init_delete_records_mysql_dao","init_update_records_mysql_dao","init_update_records_dao","databaseSchema","addRecordSchema","c","db","tableName","data","dbType","insertedCount","addRecord","updateRecordsSchema","primaryKey","updates","updatedCount","updateRecords","deleteRecordSchema","primaryKeys","deletedCount","fkViolation","relatedRecords","deleteRecords","forceDeleteRecords","bulkInsertRecordsSchema","records","result","bulkInsertRecords","HTTPException","addColumn","params","tableName","columnName","columnType","defaultValue","isPrimaryKey","isNullable","isUnique","isIdentity","isArray","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","columnDefinition","init_add_column_dao","__esmMin","init_db_manager","HTTPException","alterColumn","params","tableName","columnName","columnType","isNullable","defaultValue","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","client","error","init_alter_column_dao","__esmMin","init_db_manager","createTable","tableData","db","tableName","fields","foreignKeys","pool","getDbPool","columnDefinitions","field","columnDef","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_dao","__esmMin","init_db_manager","HTTPException","deleteColumn","params","tableName","columnName","cascade","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","columnRows","dropColumnSQL","rowCount","init_delete_column_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","getDbPool","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","pool","constraint","relatedQuery","relatedResult","getTableRowCount","result","deleteTable","params","cascade","tableExistsQuery","tableRows","rowCount","dropTableSQL","error","init_delete_table_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getDbPool","rows","init_export_table_dao","__esmMin","init_db_manager","formatMysqlDefaultValue","defaultValue","columnType","trimmed","mapColumnTypeToMysql","isArray","normalized","buildMysqlColumnDefinition","field","options","mappedType","columnDef","init_mysql_column_utils","__esmMin","HTTPException","addColumn","params","tableName","columnName","columnType","defaultValue","isPrimaryKey","isNullable","isUnique","isIdentity","isArray","db","pool","getMysqlPool","tableRows","columnRows","columnDefinition","buildMysqlColumnDefinition","init_add_column_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","alterColumn","params","tableName","columnName","columnType","isNullable","defaultValue","db","pool","getMysqlPool","tableRows","columnRows","columnRow","columnDefinition","buildMysqlColumnDefinition","init_alter_column_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","createTable","tableData","db","tableName","fields","foreignKeys","pool","getMysqlPool","columnDefinitions","field","buildMysqlColumnDefinition","primaryKeyFields","f","constraintDefs","pkColumns","foreignKeyConstraints","fk","allDefinitions","createTableSQL","init_create_table_mysql_dao","__esmMin","init_db_manager","init_mysql_column_utils","HTTPException","deleteColumn","params","tableName","columnName","db","pool","getMysqlPool","tableRows","columnRows","result","init_delete_column_mysql_dao","__esmMin","init_db_manager","HTTPException","getForeignKeyReferences","tableName","db","pool","getMysqlPool","rows","row","getRelatedRecordsForTable","fkConstraints","relatedRecords","constraint","relatedRows","getTableRowCount","deleteTable","params","cascade","tableRows","rowCount","connection","error","mysqlError","MYSQL_FK_DEPENDENCY","MYSQL_FK_ROW_REFERENCED","init_delete_table_mysql_dao","__esmMin","init_db_manager","HTTPException","exportTableData","tableName","db","pool","getMysqlPool","rows","init_export_table_mysql_dao","__esmMin","init_db_manager","HTTPException","renameColumn","params","tableName","columnName","newColumnName","db","pool","getMysqlPool","tableRows","currentColumnRows","nextColumnRows","init_rename_column_mysql_dao","__esmMin","init_db_manager","getTablesList","db","pool","getMysqlPool","tablesQuery","tables","table","countRows","countRow","init_table_list_mysql_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getMysqlPool","tableRows","rows","row","createTableSql","init_table_schema_mysql_dao","__esmMin","init_db_manager","buildWhereClauseMysql","filters","conditions","values","filter","columnName","buildSortClauseMysql","sorts","order","sort","buildCursorWhereClauseMysql","cursorData","direction","sortDirection","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","operator","init_build_clauses_mysql","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_mysql_dao","__esmMin","init_db_manager","init_build_clauses_mysql","data","cursor","pool","tableName","rows","row","limit","direction","sort","order","filters","db","getMysqlPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClauseMysql","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClauseMysql","combinedWhereClause","sortClause","buildSortClauseMysql","effectiveSortClause","col","countRows","totalRows","fetchLimit","dataRows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","HTTPException","renameColumn","params","tableName","columnName","newColumnName","db","pool","getDbPool","tableExistsQuery","tableRows","columnExistsQuery","currentColumnRows","nextColumnRows","init_rename_column_dao","__esmMin","init_db_manager","HTTPException","getTablesList","db","pool","getDbPool","tablesQuery","tables","table","countQuery","rows","init_table_list_dao","__esmMin","init_db_manager","HTTPException","getTableSchema","tableName","db","pool","getDbPool","tableExistsQuery","tableExistsRows","columnsQuery","columns","constraintsQuery","constraints","indexesQuery","indexes","schemaLines","columnDefs","col","colDef","formatDataType","constraintMap","constraint","existing","constraintDefs","constraintName","constraintColumns","firstConstraint","columnNames","c","foreignTable","foreignColumn","allDefs","index","data_type","udt_name","character_maximum_length","numeric_precision","numeric_scale","init_table_schema_dao","__esmMin","init_db_manager","buildWhereClause","filters","conditions","values","filter","paramIndex","columnName","buildSortClause","sorts","order","sort","buildCursorWhereClause","cursorData","direction","sortDirection","startParamIndex","sortColumns","queryValues","useGreaterThan","columnList","col","placeholders","_","i","operator","init_build_clauses","__esmMin","encodeCursor","decodeCursor","getPrimaryKeyColumns","getTableData","init_tables_data_dao","__esmMin","init_db_manager","init_build_clauses","data","cursor","pool","tableName","quotedTableName","row","limit","direction","sort","order","filters","db","getDbPool","primaryKeyColumns","sortColumns","effectiveSortDirection","s","cursorColumns","pk","filterWhereClause","filterValues","buildWhereClause","cursorWhereClause","cursorValues","cursorData","cursorResult","buildCursorWhereClause","combinedWhereClause","sortClause","buildSortClause","effectiveSortClause","col","countRes","totalRows","limitParamIndex","dataRes","rows","hasMore","nextCursor","prevCursor","firstRow","lastRow","createCursorFromRow","utils","write","getExportFile","cols","rows","format","tableName","jsonContent","data","row","col","worksheet","csvContent","workbook","buffer","init_get_export_file","__esmMin","zValidator","Hono","tablesRoutes","init_tables_routes","__esmMin","init_types","init_add_column_dao","init_alter_column_dao","init_create_table_dao","init_delete_column_dao","init_delete_table_dao","init_export_table_dao","init_add_column_mysql_dao","init_alter_column_mysql_dao","init_create_table_mysql_dao","init_delete_column_mysql_dao","init_delete_table_mysql_dao","init_export_table_mysql_dao","init_rename_column_mysql_dao","init_table_columns_mysql_dao","init_table_list_mysql_dao","init_table_schema_mysql_dao","init_tables_data_mysql_dao","init_rename_column_dao","init_table_columns_dao","init_table_list_dao","init_table_schema_dao","init_tables_data_dao","init_get_export_file","databaseSchema","c","db","tablesList","getTablesList","createTableSchema","body","createTable","deleteTableQuerySchema","tableNameSchema","cascade","tableName","result","deleteTable","deleteColumnQuerySchema","deleteColumnParamSchema","columnName","dbType","deletedCount","deleteColumn","addColumnSchema","addColumn","renameColumnSchema","renameColumn","alterColumnSchema","alterColumn","columns","getTableColumns","schema","getTableSchema","tableDataQuerySchema","cursor","limit","direction","sort","order","filters","tableData","getTableData","exportTableSchema","format","cols","rows","exportTableData","fileContent","getExportFile","contentType","create_server_exports","__export","createServer","path","fileURLToPath","serveStatic","zValidator","Hono","cors","logger","prettyJSON","getCoreDistPath","init_create_server","__esmMin","init_types","init_error_handler","init_chat_routes","init_databases_routes","init_query_routes","init_records_routes","init_tables_routes","__dirname","_","next","c","handleError","databasesRoutes","databaseTypeParamSchema","validationHook","dbType","tablesRoutes","recordsRoutes","queryRoutes","chatRoutes","init_constants","intro","outro","serve","color","program","args","readFile","resolve","cancel","isCancel","note","select","spinner","text","parseDotenv","color","getDatabaseUrl","env","varName","envVarName","s","choice","customPath","value","customEnvPath","content","parsed","e","error","dbUrl","access","readFile","dirname","resolve","parseDotenv","findEnvPath","startDir","dir","envPath","parent","loadEnv","env","content","err","init_meta","intro","outro","color","showHelp","META","init_constants","intro","note","outro","color","showStatus","env","databaseUrl","varName","intro","color","envVarName","DEFAULTS","foundUrl","ENV","loadEnv","outro","note","intro","outro","color","package_default","showVersion","intro","color","outro","package_default","main","env","port","databaseUrl","varName","status","help","version","args","showHelp","showVersion","showStatus","intro","color","PORT","DEFAULTS","VAR_NAME","ENV","loadEnv","DATABASE_URL","getDatabaseUrl","createServer","app","serve","outro","err"]}
|