db-studio 1.22.1 → 1.24.0
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/dist/index.js +83 -83
- package/dist/index.js.map +1 -1
- package/dist/web-dist/assets/{_pathlessLayout-Dq6e_NF8.js → _pathlessLayout-CB8Z8IH1.js} +2 -2
- package/dist/web-dist/assets/{_pathlessLayout-BwDB7UH8.js → _pathlessLayout-CBZWPtVx.js} +1 -1
- package/dist/web-dist/assets/{_queryId-B0DdcAYp.js → _queryId-2wchukJ_.js} +1 -1
- package/dist/web-dist/assets/{_table-CEn3NlzI.js → _table--BjwnIM-.js} +1 -1
- package/dist/web-dist/assets/{_table-CeyFxEOk.js → _table-BI6bCR2Y.js} +1 -1
- package/dist/web-dist/assets/{_table-8PsqQd2I.js → _table-DOiK9HT-.js} +1 -1
- package/dist/web-dist/assets/{abap-D7a1LaMr.js → abap-Bq2SF2ze.js} +1 -1
- package/dist/web-dist/assets/{apex-DUCizuOA.js → apex-CvF3BxEV.js} +1 -1
- package/dist/web-dist/assets/{azcli-08P0e1MB.js → azcli-B4auVtoa.js} +1 -1
- package/dist/web-dist/assets/{badge-Vam-1V2U.js → badge-BDq0-MGZ.js} +1 -1
- package/dist/web-dist/assets/{bat-D5u4dSiM.js → bat-Dgzfdvgu.js} +1 -1
- package/dist/web-dist/assets/{bicep-BEKH2mi6.js → bicep-BCqDeEGY.js} +1 -1
- package/dist/web-dist/assets/{browser-CFtnfZcn.js → browser-Bz0aS3wt.js} +1 -1
- package/dist/web-dist/assets/{bundle-mjs-Ba_GShnc.js → bundle-mjs-Czg11uv-.js} +1 -1
- package/dist/web-dist/assets/{cameligo-zyLkuFrC.js → cameligo-DYa2RnKC.js} +1 -1
- package/dist/web-dist/assets/{chat-sidebar-DgaJDLmC.js → chat-sidebar-XCnj-kCg.js} +47 -47
- package/dist/web-dist/assets/{clojure-HAASvMw5.js → clojure-BbDsvL5e.js} +1 -1
- package/dist/web-dist/assets/{code-editor-CnNQKM4a.js → code-editor-CeKukbpw.js} +1 -1
- package/dist/web-dist/assets/{coffee-H0zBiaDN.js → coffee-CsaUF2V_.js} +1 -1
- package/dist/web-dist/assets/{connect-DvvXMsnR.js → connect-CjcuNXdF.js} +1 -1
- package/dist/web-dist/assets/{constants-CyYxDPW-.js → constants-BmHYxRwL.js} +9 -9
- package/dist/web-dist/assets/{cpp-BZfon7-f.js → cpp-BUVD_5yb.js} +1 -1
- package/dist/web-dist/assets/{csharp-39w9Tlew.js → csharp-zs4B3O4X.js} +1 -1
- package/dist/web-dist/assets/{csp-BvxksuL7.js → csp-BK9lGLNX.js} +1 -1
- package/dist/web-dist/assets/{css-CJVemR09.js → css-b1JV3oRC.js} +1 -1
- package/dist/web-dist/assets/{cssMode-DO0wgAFc.js → cssMode-CQCx-Amk.js} +1 -1
- package/dist/web-dist/assets/{cypher-Bvz6qhjG.js → cypher-BqBU8Z2b.js} +1 -1
- package/dist/web-dist/assets/{dart-Bik0gG49.js → dart-DSDIxxqa.js} +1 -1
- package/dist/web-dist/assets/{database.store-DwsAyPWD.js → database.store-B5nYwx6g.js} +10 -10
- package/dist/web-dist/assets/{dist-DMyf6Dko.js → dist-BzdAqvqB.js} +1 -1
- package/dist/web-dist/assets/{dist-CsoBsImu.js → dist-CbondfsI.js} +1 -1
- package/dist/web-dist/assets/{dockerfile-CmiPMp9-.js → dockerfile-Dgyg8Vn1.js} +1 -1
- package/dist/web-dist/assets/{ecl-_UvSEdJJ.js → ecl-BqCo88uM.js} +1 -1
- package/dist/web-dist/assets/{editor.api-ZRrI_I0I.js → editor.api-DwxoFYQ2.js} +1 -1
- package/dist/web-dist/assets/{elixir-B0Z5zPx8.js → elixir-CTUGPZ6C.js} +1 -1
- package/dist/web-dist/assets/{esm-DvPyREUh.js → esm-DFZkY2_t.js} +1 -1
- package/dist/web-dist/assets/{flow9-3F4_wOOf.js → flow9-D4BWoch3.js} +1 -1
- package/dist/web-dist/assets/{format-cell-value-D-naTnK8.js → format-cell-value-Bl9a_el7.js} +1 -1
- package/dist/web-dist/assets/{freemarker2-DW3uoX2z.js → freemarker2-CDPCStHA.js} +1 -1
- package/dist/web-dist/assets/{fsharp-BwHGoEdM.js → fsharp-D3hSCsYp.js} +1 -1
- package/dist/web-dist/assets/{go-BEkNilfT.js → go-BQ5Amm1L.js} +1 -1
- package/dist/web-dist/assets/{graphql-CLhWbOdF.js → graphql-iD1Jte7G.js} +1 -1
- package/dist/web-dist/assets/{handlebars-CSWXmB1f.js → handlebars-DGCxQ8J4.js} +1 -1
- package/dist/web-dist/assets/{hcl-rlt52D7g.js → hcl-D47OjiCw.js} +1 -1
- package/dist/web-dist/assets/{highlighted-body-OFNGDK62-Doh9xMZT.js → highlighted-body-OFNGDK62-DwmD8iTj.js} +1 -1
- package/dist/web-dist/assets/{html-DDuMQc1q.js → html-s4rwfaEL.js} +1 -1
- package/dist/web-dist/assets/{htmlMode-CZLd9AHF.js → htmlMode-CLgwngSs.js} +1 -1
- package/dist/web-dist/assets/{icons-BnNQtg24.js → icons-Cp2j-kCt.js} +1 -1
- package/dist/web-dist/assets/{index-ck6tTAHc.js → index-bHd_PHGE.js} +8 -8
- package/dist/web-dist/assets/{indexes-Dd93lTvB.js → indexes-CC7CSOZI.js} +1 -1
- package/dist/web-dist/assets/{ini-B_HJ11CK.js → ini-DNs4UNBm.js} +1 -1
- package/dist/web-dist/assets/{java-sJiisr_y.js → java-C844kcMX.js} +1 -1
- package/dist/web-dist/assets/{javascript-DEDHUUwN.js → javascript-CM6qxDQg.js} +1 -1
- package/dist/web-dist/assets/{json-editor-yk4dK6or.js → json-editor-DhzLauWb.js} +1 -1
- package/dist/web-dist/assets/{jsonMode-BWSSz50U.js → jsonMode-ktYHQ7k4.js} +1 -1
- package/dist/web-dist/assets/{julia-CKhCzNm4.js → julia-DBbgm8bE.js} +1 -1
- package/dist/web-dist/assets/{keys-D6vrgtRa.js → keys-B79aFFUM.js} +1 -1
- package/dist/web-dist/assets/{kotlin-DoToTuww.js → kotlin-CczUn3Bo.js} +1 -1
- package/dist/web-dist/assets/{label-DxIJiZ44.js → label-BxAgnFDj.js} +1 -1
- package/dist/web-dist/assets/{less-BWpVNsBn.js → less-BDndQXE2.js} +1 -1
- package/dist/web-dist/assets/{lexon-DCHU-p6q.js → lexon-DrJKrLHU.js} +1 -1
- package/dist/web-dist/assets/{liquid-f2Iv2fB9.js → liquid-BOxI8WO7.js} +1 -1
- package/dist/web-dist/assets/{logs-DQk3nMcE.js → logs-CKGCAlGi.js} +1 -1
- package/dist/web-dist/assets/{lspLanguageFeatures-C-GLKDeb.js → lspLanguageFeatures-B-pTo3Bn.js} +1 -1
- package/dist/web-dist/assets/{lua-DNCGIfAF.js → lua-B-DZsKtS.js} +1 -1
- package/dist/web-dist/assets/{m3-BnZMimxx.js → m3-Owy8TjS4.js} +1 -1
- package/dist/web-dist/assets/{markdown-Clbw2Wwn.js → markdown-D79UG6z3.js} +1 -1
- package/dist/web-dist/assets/{mdx-DgWB8wIX.js → mdx-DGvwS7WO.js} +1 -1
- package/dist/web-dist/assets/{mermaid-GHXKKRXX-DkUW61ZT.js → mermaid-GHXKKRXX-BedrloC7.js} +1 -1
- package/dist/web-dist/assets/{middleware-BhQeo1dQ.js → middleware-CgadqUs_.js} +1 -1
- package/dist/web-dist/assets/{mips-D_cnnY5G.js → mips--YcTYhla.js} +1 -1
- package/dist/web-dist/assets/{module-w1fnPEU7.js → module-DMKyVt4Z.js} +1 -1
- package/dist/web-dist/assets/{monaco-theme-BKlvSnyu.js → monaco-theme-DDFn4QWa.js} +4 -4
- package/dist/web-dist/assets/{msdax-B2cS1W51.js → msdax-BT5TAMyz.js} +1 -1
- package/dist/web-dist/assets/{mysql-DxrfSPeX.js → mysql-DiqG_FKN.js} +1 -1
- package/dist/web-dist/assets/{objective-c--BCIKkyu.js → objective-c-C_BfMpoA.js} +1 -1
- package/dist/web-dist/assets/{pascal-Dw621VHn.js → pascal-BJsCnNJo.js} +1 -1
- package/dist/web-dist/assets/{pascaligo-DismPj_H.js → pascaligo-IucQKKBl.js} +1 -1
- package/dist/web-dist/assets/{perl-CP4p3tPz.js → perl-D1p264f9.js} +1 -1
- package/dist/web-dist/assets/{personal-preferences.store-D1vwYECY.js → personal-preferences.store-BiMq0Y52.js} +1 -1
- package/dist/web-dist/assets/{pgsql-Dug71UC1.js → pgsql-BVu_MjK3.js} +1 -1
- package/dist/web-dist/assets/{php-C5xzvzTl.js → php-DIWn0kxW.js} +1 -1
- package/dist/web-dist/assets/{pla-BRidbwAJ.js → pla-BriG1dlB.js} +1 -1
- package/dist/web-dist/assets/{postiats-BtskjtmJ.js → postiats-Cb0eCw4F.js} +1 -1
- package/dist/web-dist/assets/{powerquery-BRNFimOG.js → powerquery-D-S-D3uG.js} +1 -1
- package/dist/web-dist/assets/{powershell-DtC8hmfI.js → powershell-Br0yPko5.js} +1 -1
- package/dist/web-dist/assets/{preload-helper-D4DSFROY.js → preload-helper-iAe7doxP.js} +1 -1
- package/dist/web-dist/assets/{protobuf-F_x1Cjx3.js → protobuf-DXgwoXmw.js} +1 -1
- package/dist/web-dist/assets/{pug-D4dgjeKq.js → pug-CkrU_Its.js} +1 -1
- package/dist/web-dist/assets/{python-DPX6MnDe.js → python-DtkdMPl6.js} +1 -1
- package/dist/web-dist/assets/{qsharp-CcXqZf4s.js → qsharp-BFgaE9um.js} +1 -1
- package/dist/web-dist/assets/queries.store-BjfGDMSV.js +1 -0
- package/dist/web-dist/assets/{query-runner-BKek4lAm.js → query-runner-DcgFi94b.js} +3 -3
- package/dist/web-dist/assets/{r-BiIJXs3I.js → r-Cy-L7tzv.js} +1 -1
- package/dist/web-dist/assets/{radix-ui-qEOOL1_K.js → radix-ui-DsfBT21F.js} +1 -1
- package/dist/web-dist/assets/{razor-oLIBzSas.js → razor-NF3TzW48.js} +1 -1
- package/dist/web-dist/assets/{react-DgIpWRm8.js → react-CXUHf7G9.js} +1 -1
- package/dist/web-dist/assets/{react-dom-BZ0gDQU5.js → react-dom-Dc3YY6Lb.js} +1 -1
- package/dist/web-dist/assets/{redis-DJrZMmOR.js → redis-Dz00h2PU.js} +1 -1
- package/dist/web-dist/assets/{redis-value-Dhm0spIW.js → redis-value-ZB2FU0Y3.js} +1 -1
- package/dist/web-dist/assets/{redshift-yzDIBhLh.js → redshift-DqNXfDmg.js} +1 -1
- package/dist/web-dist/assets/{restructuredtext-CF7t2BQG.js → restructuredtext-B5fKLW7g.js} +1 -1
- package/dist/web-dist/assets/{rolldown-runtime-BEBKJ2Xb.js → rolldown-runtime-BpaiXjxi.js} +1 -1
- package/dist/web-dist/assets/{ruby-Buzq-_Hg.js → ruby-CCPPZ85l.js} +1 -1
- package/dist/web-dist/assets/{runner-Di4uLR8Z.js → runner-DWDNo8PW.js} +1 -1
- package/dist/web-dist/assets/{rust-Dhjx0oUU.js → rust-BshObZ-f.js} +1 -1
- package/dist/web-dist/assets/{sb-CS7EOb-z.js → sb-qkcFW9ML.js} +1 -1
- package/dist/web-dist/assets/{scala-BXrWIpsI.js → scala-BqGFtNCK.js} +1 -1
- package/dist/web-dist/assets/schema-B06aGalT.js +1 -0
- package/dist/web-dist/assets/{schema-CC7fIVGB.js → schema-DLKXOflr.js} +1 -1
- package/dist/web-dist/assets/{scheme-1v2Ab8rC.js → scheme-CSDCifY0.js} +1 -1
- package/dist/web-dist/assets/{scss-BuvMyI80.js → scss-DDU3Surn.js} +1 -1
- package/dist/web-dist/assets/{select-CRpiKcof.js → select-XrU76gkU.js} +1 -1
- package/dist/web-dist/assets/{separator-UVHn5WOz.js → separator-jMywB-2c.js} +1 -1
- package/dist/web-dist/assets/{sheet-sidebar-C1Wgdn-M.js → sheet-sidebar-CatxqUMS.js} +1 -1
- package/dist/web-dist/assets/{shell-BlLMYxqc.js → shell-B9GKK-mC.js} +1 -1
- package/dist/web-dist/assets/{solidity-CApe2Ev-.js → solidity-T4nLiSrl.js} +1 -1
- package/dist/web-dist/assets/{sophia-CyZa8od3.js → sophia-CxHxp787.js} +1 -1
- package/dist/web-dist/assets/{sparql-CwoK2n9Y.js → sparql-Cc68XDZz.js} +1 -1
- package/dist/web-dist/assets/{spinner-CwZXU6BY.js → spinner-C5eJUcQ8.js} +1 -1
- package/dist/web-dist/assets/{sql-P2kzvpIo.js → sql-DuSKWG0U.js} +1 -1
- package/dist/web-dist/assets/{st-cP-ZBIfp.js → st-CvDv-80q.js} +1 -1
- package/dist/web-dist/assets/{swift-BAgj8_oO.js → swift-CS9QIYkd.js} +1 -1
- package/dist/web-dist/assets/{systemverilog-bKvq7GjD.js → systemverilog-BnPj7u1A.js} +1 -1
- package/dist/web-dist/assets/{table-Dq85hQaM.js → table-Ddncv8yc.js} +1 -1
- package/dist/web-dist/assets/{tables-DGOK-1JF.js → tables-BCWRd0qR.js} +4 -4
- package/dist/web-dist/assets/{tanstack-Bkos0wYR.js → tanstack-BPG3IW5e.js} +1 -1
- package/dist/web-dist/assets/{tcl-CZYhj3uE.js → tcl-B6jg-5Cb.js} +1 -1
- package/dist/web-dist/assets/{tooltip-BGS6CdKU.js → tooltip-5N-vnBUx.js} +1 -1
- package/dist/web-dist/assets/{tsMode-CWkS0PFZ.js → tsMode-CQfgMr7J.js} +1 -1
- package/dist/web-dist/assets/{twig-BYkhheLh.js → twig-ldZgB-wD.js} +1 -1
- package/dist/web-dist/assets/{typescript-BVovNcHi.js → typescript-CANwj-Sa.js} +1 -1
- package/dist/web-dist/assets/{typespec-wOndea04.js → typespec-DjERUFVV.js} +1 -1
- package/dist/web-dist/assets/{use-database-engine-BPO0PzHc.js → use-database-engine-BUPMYqQP.js} +1 -1
- package/dist/web-dist/assets/{use-theme-DQtr7wmG.js → use-theme-DBziCVvW.js} +1 -1
- package/dist/web-dist/assets/{utils-CwFw8YqE.js → utils-BDZEB_LK.js} +1 -1
- package/dist/web-dist/assets/{vb-DI947VUc.js → vb-BZwS3C6o.js} +1 -1
- package/dist/web-dist/assets/{visualizer-CWs82Oat.js → visualizer-R12YQrWQ.js} +1 -1
- package/dist/web-dist/assets/{vscode-DfeEYiA3.js → vscode-B0k_qsbq.js} +1 -1
- package/dist/web-dist/assets/{wgsl-CxEBKz2H.js → wgsl-DNuFR9Dj.js} +1 -1
- package/dist/web-dist/assets/{workers-DtzEtdkU.js → workers-B2aTtOoy.js} +1 -1
- package/dist/web-dist/assets/{xml-B8wczl4_.js → xml-CmdBBiXu.js} +1 -1
- package/dist/web-dist/assets/{yaml-DbwQqCV9.js → yaml-DeyJxOQB.js} +1 -1
- package/dist/web-dist/index.html +30 -30
- package/package.json +1 -1
- package/dist/web-dist/assets/queries.store-DPfK-_0h.js +0 -1
- package/dist/web-dist/assets/schema-Dg-DmfQp.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var pl=Object.defineProperty;var N=(r,e)=>()=>(r&&(e=r(r=0)),e);var Dt=(r,e)=>{for(var t in e)pl(r,t,{get:e[t],enumerable:!0})};var y=N(()=>{"use strict";(function(){try{var r=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};r.SENTRY_RELEASE={id:"db-studio@1.22.1"}}catch{}})()});var As=N(()=>{"use strict";y()});var Ds=N(()=>{"use strict";y()});var _s=N(()=>{"use strict";y()});var Is,Os,at,xs=N(()=>{"use strict";y();Is=globalThis.process?.env,Os=Is?.NODE_ENV,at={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:Os==="development",PROXY_URL:Is?.DB_STUDIO_PROXY_URL??(Os==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var Ls=N(()=>{"use strict";y()});var Ps,Tr=N(()=>{"use strict";y();Ps={AUTHOR:"H\xFCsam \u{1F951} <husam@ql3.dev>",AUTHOR_NAME:"H\xFCsam",AUTHOR_AVATAR:"/avocado.png",AUTHOR_USERNAME:"husamql3",AUTHOR_GITHUB_LINK:"https://github.com/husamql3",SITE_DESCRIPTION:"The modern pgAdmin alternative that works with every database.",SITE_KEYWORDS:["pgadmin alternative","database client","database gui","database browser","sql editor","postgresql client","mysql client","table editor","ai sql","er diagram"],SITE_TITLE:"db-studio",SITE_NAME:"dbstudio.sh",SITE_URL:"https://dbstudio.sh",SITE_X_LINK:"https://x.com/dbstudio_sh",SITE_GITHUB_LINK:"https://github.com/husamql3/db-studio",SITE_GITHUB_NEW_ISSUE_LINK:"https://github.com/husamql3/db-studio/issues/new/choose",SITE_DOCS_LINK:"https://dbstudio.sh/docs",SITE_CHANGELOG_LINK:"https://dbstudio.sh/changelog",SITE_ROADMAP_LINK:"https://dbstudio.sh/roadmap",SITE_IMAGE:"https://dbstudio.sh/og-image.png",SITE_IMAGE_WIDTH:"1200",SITE_IMAGE_HEIGHT:"630",SITE_IMAGE_ALT:"dbstudio.sh \u2013 Modern database management studio",SITE_COLOR:"#1447e6"}});var $s=N(()=>{"use strict";y()});var Jt=N(()=>{"use strict";y();As();Ds();_s();xs();Ls();Tr();$s()});import{z as bt}from"zod";var F,U,Ot,dt,El,wl,ce,Ee=N(()=>{"use strict";y();F=bt.object({db:bt.string("Database name is required")}),U=F.extend({schemaName:bt.string().optional()}),Ot=["pg","mysql","mssql","mongodb","sqlite","redis","duckdb","oracle","clickhouse"],dt=bt.enum(Ot,{message:"Invalid database type"}),El=F.extend({dbType:dt}),wl=bt.object({dbType:dt}),ce=bt.object({tableName:bt.string("Table name is required")})});import{z as je}from"zod";var qe,Sl,Cl,qs=N(()=>{"use strict";y();Ee();qe=je.object({columnName:je.string("Column name is required"),columnType:je.string("Column type is required"),defaultValue:je.string().optional(),isPrimaryKey:je.boolean().default(!1),isNullable:je.boolean().default(!1),isUnique:je.boolean().default(!1),isIdentity:je.boolean().default(!1),isArray:je.boolean().default(!1)}),Sl=ce,Cl=je.object({db:F.shape.db,tableName:ce.shape.tableName,schemaName:U.shape.schemaName,columnName:qe.shape.columnName,columnType:qe.shape.columnType,defaultValue:qe.shape.defaultValue,isPrimaryKey:qe.shape.isPrimaryKey,isNullable:qe.shape.isNullable,isUnique:qe.shape.isUnique,isIdentity:qe.shape.isIdentity,isArray:qe.shape.isArray})});import{z as Xt}from"zod";var Sr,Bs=N(()=>{"use strict";y();Sr=Xt.object({tableName:Xt.string("Table name is required"),data:Xt.record(Xt.string("Column name is required"),Xt.any())})});import{z as Rl}from"zod";var Fs,Cr,Ks,Rr,Nr=N(()=>{"use strict";y();Fs=["gemini","openai","anthropic","grok","openrouter"],Cr=Rl.enum(Fs),Ks=[{id:"gemini",label:"Google Gemini",models:[{id:"gemini-3-flash-preview",label:"Gemini 3 Flash"},{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro"}]},{id:"openai",label:"OpenAI",models:[{id:"gpt-5.2",label:"GPT-5.2"},{id:"gpt-5-mini",label:"GPT-5 mini"}]},{id:"anthropic",label:"Anthropic",models:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}]},{id:"grok",label:"xAI Grok",models:[{id:"grok-4.6",label:"Grok 4.6"},{id:"grok-4.5",label:"Grok 4.5"}]},{id:"openrouter",label:"OpenRouter",models:[{id:"openai/gpt-5.2",label:"GPT-5.2 via OpenRouter"},{id:"anthropic/claude-sonnet-4.6",label:"Claude Sonnet 4.6 via OpenRouter"}]}],Rr=r=>Ks.find(e=>e.id===r)?.models[0]?.id??"gemini-3-flash-preview"});import{z as Be}from"zod";var Ar,we,Nl,Al,Cn=N(()=>{"use strict";y();Ee();Ar=U.extend({cascade:Be.string().optional().transform(r=>r==="true")}),we=Be.object({tableName:Be.string("Table name is required"),columnName:Be.string("Column name is required")}),Nl=Be.object({db:F.shape.db,tableName:we.shape.tableName,schemaName:U.shape.schemaName,columnName:we.shape.columnName,cascade:Be.boolean().optional()}),Al=Be.object({message:Be.string("Message is required"),tableName:Be.string("Table name is required"),columnName:Be.string("Column name is required"),deletedCount:Be.number("Deleted count is required").default(0)})});import{z as Zt}from"zod";var It,Dl,_l,Hs=N(()=>{"use strict";y();Ee();Cn();It=Zt.object({columnType:Zt.string("Column type is required"),isNullable:Zt.boolean(),defaultValue:Zt.string().nullable().optional()}),Dl=we,_l=Zt.object({db:F.shape.db,tableName:we.shape.tableName,schemaName:U.shape.schemaName,columnName:we.shape.columnName,columnType:It.shape.columnType,isNullable:It.shape.isNullable,defaultValue:It.shape.defaultValue})});var js=N(()=>{"use strict";y()});import{z as xt}from"zod";var Dr,Ws=N(()=>{"use strict";y();Dr=xt.object({tableName:xt.string().min(1,"Table name is required"),records:xt.array(xt.record(xt.string(),xt.any())).min(1,"At least one record is required")})});import{z as de}from"zod";var Ol,Il,_r,Ys=N(()=>{"use strict";y();Nr();Ee();Ol=de.object({type:de.string(),content:de.string().optional()}).passthrough(),Il=de.object({provider:Cr.optional().default("gemini"),model:de.string().min(1).optional(),messages:de.array(de.object({id:de.string(),role:de.enum(["user","assistant","system","tool","reasoning"]),content:de.union([de.string(),de.null(),de.array(de.unknown())]).optional(),parts:de.array(Ol).optional()}).passthrough()),data:de.object({conversationId:de.string().optional(),db:F.shape.db,includeSchema:de.boolean().optional().default(!0)})}),_r=Il.transform(r=>({...r,model:r.model??Rr(r.provider)}))});var Vs=N(()=>{"use strict";y()});import{z as Ie}from"zod";var xl,zs,L,Ll,Gs,Pl,Or=N(()=>{"use strict";y();xl=["text","boolean","number","enum","json","date","array"],zs=Ie.enum(xl),L={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},Ll=["int","bigint","smallint","numeric","float","double","money","tinyint","mediumint","bit","boolean","text","varchar","char","tinytext","mediumtext","longtext","json","jsonb","xml","uuid","date","time","timestamp","timestamptz","interval","datetime","year","bytea","inet","cidr","macaddr","macaddr8","point","line","polygon","binary","varbinary","blob","tinyblob","mediumblob","longblob","array","enum","set"],Gs=Ie.enum(Ll),Pl=Ie.object({columnName:Ie.string(),dataType:zs,dataTypeLabel:Gs,isNullable:Ie.boolean(),columnDefault:Ie.string().nullable(),isPrimaryKey:Ie.boolean(),isForeignKey:Ie.boolean(),referencedTable:Ie.string().nullable(),referencedSchema:Ie.string().optional(),referencedColumn:Ie.string().nullable(),enumValues:Ie.array(Ie.string()).nullable()})});function Rn(r){let e=r?.toLowerCase().trim()||"";return e.includes("[]")||e==="date"||e==="time"||e==="time without time zone"||e.startsWith("time(")||e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")||e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?L.date:e==="integer"||e==="int"||e==="int4"||e==="bigint"||e==="int8"||e==="smallint"||e==="int2"||e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")||e==="real"||e==="float4"||e==="double precision"||e==="float8"||e==="float"||e==="serial"||e==="serial4"||e==="bigserial"||e==="serial8"||e==="money"?L.number:e==="boolean"||e==="bool"?L.boolean:e==="json"||e==="jsonb"?L.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?L.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")||e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"||e==="uuid"||e==="interval"||e.startsWith("interval")||e==="bytea"||e==="point"||e==="line"||e==="polygon"||e==="inet"||e==="cidr"||e==="macaddr"||e==="macaddr8"?L.text:L.text}function Ir(r){if(!r)return T.text;let e=r.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?T.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?T.bigint:e==="smallint"||e==="int2"?T.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?T.numeric:e==="real"||e==="float4"?T.float:e==="double precision"||e==="float8"||e==="float"?T.double:e==="money"?T.money:e==="boolean"||e==="bool"?T.boolean:e==="text"?T.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?T.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?T.char:e==="json"?T.json:e==="jsonb"?T.jsonb:e==="xml"?T.xml:e==="uuid"?T.uuid:e==="date"?T.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?T.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?T.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?T.timestamptz:e==="interval"||e.startsWith("interval")?T.interval:e==="bytea"?T.bytea:e==="inet"?T.inet:e==="cidr"?T.cidr:e==="macaddr"?T.macaddr:e==="macaddr8"?T.macaddr8:e==="point"?T.point:e==="line"?T.line:e==="polygon"?T.polygon:e.startsWith("array")||e.includes("[]")?T.text:e.startsWith("user-defined")||e==="enum"?T.enum:T.text}function Nn(r,e){let t=r?.toLowerCase().trim()||"",n=e?.toLowerCase().trim()||"";return t==="tinyint"&&n==="tinyint(1)"?L.boolean:t==="tinyint"||t==="smallint"||t==="mediumint"||t==="int"||t==="integer"||t==="bigint"||t==="decimal"||t==="numeric"||t==="float"||t==="double"||t==="real"||t==="bit"?L.number:t==="boolean"||t==="bool"?L.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?L.date:t==="json"?L.json:t==="enum"||t==="set"?L.enum:L.text}function xr(r,e){if(!r)return T.text;let t=r.toLowerCase().trim(),n=e?.toLowerCase().trim()||"";return t==="tinyint"&&n==="tinyint(1)"?T.boolean:t==="tinyint"?T.tinyint:t==="smallint"?T.smallint:t==="mediumint"?T.mediumint:t==="int"||t==="integer"?T.int:t==="bigint"?T.bigint:t==="decimal"||t==="numeric"?T.numeric:t==="float"||t==="real"?T.float:t==="double"?T.double:t==="bit"?T.bit:t==="boolean"||t==="bool"?T.boolean:t==="char"?T.char:t==="varchar"?T.varchar:t==="tinytext"?T.tinytext:t==="text"?T.text:t==="mediumtext"?T.mediumtext:t==="longtext"?T.longtext:t==="binary"?T.binary:t==="varbinary"?T.varbinary:t==="tinyblob"?T.tinyblob:t==="blob"?T.blob:t==="mediumblob"?T.mediumblob:t==="longblob"?T.longblob:t==="json"?T.json:t==="date"?T.date:t==="time"?T.time:t==="datetime"?T.datetime:t==="timestamp"?T.timestamp:t==="year"?T.year:t==="enum"?T.enum:t==="set"?T.set:T.text}function An(r){let e=r?.toLowerCase().trim()||"";return e==="tinyint"||e==="smallint"||e==="int"||e==="bigint"||e==="decimal"||e==="numeric"||e==="float"||e==="real"||e==="money"||e==="smallmoney"?L.number:e==="bit"?L.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?L.date:e==="json"?L.json:L.text}function Lr(r){if(!r)return T.text;let e=r.toLowerCase().trim();return e==="tinyint"?T.tinyint:e==="smallint"?T.smallint:e==="int"?T.int:e==="bigint"?T.bigint:e==="decimal"||e==="numeric"?T.numeric:e==="float"||e==="real"?T.float:e==="money"||e==="smallmoney"?T.money:e==="bit"?T.boolean:e==="char"?T.char:e==="varchar"?T.varchar:e==="text"?T.text:e==="nchar"?T.char:e==="nvarchar"?T.varchar:e==="ntext"?T.text:e==="binary"?T.binary:e==="varbinary"?T.varbinary:e==="image"?T.blob:e==="uniqueidentifier"?T.uuid:e==="date"?T.date:e==="time"?T.time:e==="datetime"||e==="datetime2"||e==="smalldatetime"?T.datetime:e==="datetimeoffset"?T.timestamptz:e==="json"?T.json:e==="xml"?T.xml:T.text}function Dn(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?L.boolean:e==="json"?L.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?L.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?L.number:L.text}function Pr(r){let e=r?.toLowerCase().trim()||"";return e==="integer"||e==="int"?T.int:e==="bigint"||e.startsWith("bigint(")?T.bigint:e==="smallint"||e.startsWith("smallint(")?T.smallint:e==="tinyint"||e.startsWith("tinyint(")?T.tinyint:e==="mediumint"||e.startsWith("mediumint(")?T.mediumint:e.includes("int")?T.int:e==="real"||e==="float"||e.startsWith("float(")?T.float:e==="double"||e==="double precision"||e.startsWith("double(")?T.double:e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?T.numeric:e==="boolean"||e==="bool"?T.boolean:e==="text"||e==="clob"?T.text:e==="varchar"||e.startsWith("varchar(")?T.varchar:e==="char"||e.startsWith("char(")?T.char:e==="json"?T.json:e==="date"?T.date:e==="time"?T.time:e==="datetime"?T.datetime:e==="timestamp"?T.timestamp:e==="blob"?T.blob:T.text}function _n(r){let e=r?.toLowerCase().trim()||"";return e.endsWith("]")||e.startsWith("struct")||e.startsWith("map")||e.startsWith("union")||e==="json"?L.json:e==="boolean"||e==="bool"?L.boolean:e.startsWith("enum")?L.enum:e==="interval"?L.text:e==="date"||e.startsWith("time")||e==="datetime"?L.date:e.includes("int")||e==="float"||e==="real"||e==="double"||e.startsWith("decimal")||e.startsWith("numeric")||e==="bignum"?L.number:L.text}function $r(r){let e=r?.toLowerCase().trim()||"";return e.endsWith("]")?T.array:e.startsWith("struct")||e.startsWith("map")||e.startsWith("union")||e==="json"?T.json:e.startsWith("enum")?T.enum:e==="interval"?T.interval:e==="tinyint"||e==="utinyint"?T.tinyint:e==="smallint"||e==="usmallint"?T.smallint:e==="integer"||e==="int"?T.int:e.includes("int")||e==="bignum"?T.bigint:e.startsWith("decimal")||e.startsWith("numeric")?T.numeric:e==="float"||e==="real"?T.float:e==="double"?T.double:e==="boolean"||e==="bool"?T.boolean:e==="varchar"||e.startsWith("varchar(")?T.varchar:e==="uuid"?T.uuid:e==="date"?T.date:e==="timestamp with time zone"||e==="timestamptz"?T.timestamptz:e.startsWith("timestamp")||e==="datetime"?T.timestamp:e.startsWith("time")?T.time:e==="blob"||e==="bytea"?T.blob:e==="bit"||e==="bitstring"?T.bit:T.text}function On(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"?L.boolean:e==="json"?L.json:e==="date"||e.startsWith("timestamp")?L.date:e.startsWith("number")||e.startsWith("float")||e==="integer"||e==="binary_float"||e==="binary_double"?L.number:L.text}function Mr(r){let e=r?.toLowerCase().trim()||"";if(e==="boolean")return T.boolean;if(e==="json")return T.json;if(e==="xmltype")return T.xml;if(e==="integer")return T.int;let t=e.match(/^number\((\d+)(?:,0)?\)$/);if(t){let n=Number(t[1]);if(n<=4)return T.smallint;if(n<=10)return T.int;if(n<=19)return T.bigint}return e.startsWith("number")?T.numeric:e==="binary_float"?T.float:e==="binary_double"||e.startsWith("float")?T.double:e.startsWith("varchar")||e.startsWith("nvarchar")?T.varchar:e.startsWith("char")||e.startsWith("nchar")?T.char:e.startsWith("timestamp")&&e.endsWith("time zone")?T.timestamptz:e==="date"||e.startsWith("timestamp")?T.timestamp:e.startsWith("interval")?T.interval:e==="blob"||e==="long raw"?T.blob:e.startsWith("raw")?T.varbinary:T.text}function Lt(r){let e=r.trim();for(;;){let t=e.match(/^(?:Nullable|LowCardinality)\((.*)\)$/);if(!t?.[1])return e;e=t[1].trim()}}function In(r){let e=Lt(r);return e.startsWith("Array(")?L.array:e.startsWith("Enum8(")||e.startsWith("Enum16(")?L.enum:e==="Bool"?L.boolean:/^(Date|Date32|DateTime|DateTime64|Time|Time64)\b/.test(e)?L.date:/^(U?Int\d+|Float\d+|BFloat16|Decimal\d*)\b/.test(e)?L.number:/^(JSON|Object|Map|Tuple|Variant|Dynamic|Nested)\b/.test(e)?L.json:L.text}function kr(r){let e=Lt(r);return e.startsWith("Array(")?T.array:e.startsWith("Enum8(")||e.startsWith("Enum16(")?T.enum:e==="Bool"?T.boolean:/^U?Int8$/.test(e)?T.tinyint:/^U?Int16$/.test(e)?T.smallint:/^U?Int32$/.test(e)?T.int:/^U?Int(64|128|256)$/.test(e)?T.bigint:e==="Float32"||e==="BFloat16"?T.float:e==="Float64"?T.double:e.startsWith("Decimal")?T.numeric:e.startsWith("FixedString(")?T.char:e==="UUID"?T.uuid:e==="IPv4"||e==="IPv6"?T.inet:e==="Date"||e==="Date32"?T.date:e.startsWith("DateTime64")?T.timestamp:e.startsWith("DateTime")?T.datetime:e.startsWith("Time")?T.time:/^(JSON|Object|Map|Tuple|Variant|Dynamic|Nested)\b/.test(e)?T.json:T.text}var T,Qs=N(()=>{"use strict";y();Or();T={int:"int",bigint:"bigint",smallint:"smallint",numeric:"numeric",float:"float",double:"double",money:"money",tinyint:"tinyint",mediumint:"mediumint",bit:"bit",boolean:"boolean",text:"text",varchar:"varchar",char:"char",tinytext:"tinytext",mediumtext:"mediumtext",longtext:"longtext",json:"json",jsonb:"jsonb",xml:"xml",uuid:"uuid",date:"date",time:"time",timestamp:"timestamp",timestamptz:"timestamptz",interval:"interval",datetime:"datetime",year:"year",bytea:"bytea",inet:"inet",cidr:"cidr",macaddr:"macaddr",macaddr8:"macaddr8",point:"point",line:"line",polygon:"polygon",binary:"binary",varbinary:"varbinary",blob:"blob",tinyblob:"tinyblob",mediumblob:"mediumblob",longblob:"longblob",array:"array",enum:"enum",set:"set"}});import{z as Se}from"zod";var Js,en,Xs,$l,vr,Ur,Zs=N(()=>{"use strict";y();Ee();Js=["red","orange","amber","green","teal","blue","violet","pink"],en=Se.enum(Js),Xs=Se.object({id:Se.string(),name:Se.string(),color:en.nullable(),lastUsedAt:Se.number(),dbType:dt,maskedUrl:Se.string()}),$l=Se.object({connections:Se.array(Xs),active:Se.object({id:Se.string().nullable(),dbType:dt,connectionId:Se.string()}).nullable()}),vr=Se.object({url:Se.string().trim().min(1,"Paste a connection URL")}),Ur=Se.object({name:Se.string().trim().min(1,"Name is required").max(100).optional(),color:en.nullable().optional()})});import{z as pe}from"zod";var eo,qr,to,no,Br,ro=N(()=>{"use strict";y();eo=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],qr=pe.enum(eo),to=pe.object({columnName:pe.string("Column name is required"),columnType:pe.string("Column type is required"),defaultValue:pe.string().optional(),isPrimaryKey:pe.boolean().default(!1),isNullable:pe.boolean().default(!1),isUnique:pe.boolean().default(!1),isIdentity:pe.boolean().default(!1),isArray:pe.boolean().default(!1)}),no=pe.object({columnName:pe.string("Column name is required"),referencedTable:pe.string("Referenced table is required"),referencedColumn:pe.string("Referenced column is required"),onUpdate:qr.default("NO ACTION"),onDelete:qr.default("NO ACTION")}),Br=pe.object({tableName:pe.string("Table name is required"),fields:pe.array(to).min(1,"At least one field is required"),foreignKeys:pe.array(no).optional()})});var j,We,ao=N(()=>{"use strict";y();Ee();j={pg:{label:"PostgreSQL",protocols:["postgres","postgresql","cockroachdb"],defaultPort:5432,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!0,rowMutation:!0,indexes:{methods:["btree","hash","gin","gist","spgist","brin"],createNote:"Building an index blocks writes to this table until it finishes."},serverLogs:!0},mysql:{label:"MySQL",protocols:["mysql","mysql2","mariadb","tidb"],defaultPort:3306,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null},serverLogs:!0},mssql:{label:"SQL Server",protocols:["mssql","sqlserver"],defaultPort:1433,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:"Building an index blocks writes to this table until it finishes."},serverLogs:!0},mongodb:{label:"MongoDB",protocols:["mongodb","mongodb+srv"],defaultPort:27017,dataModel:"document",editorLanguage:"json",liveMode:!1,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null},serverLogs:!0},sqlite:{label:"SQLite / libSQL / D1",protocols:["sqlite","libsql","d1"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null},serverLogs:!1},redis:{label:"Redis",protocols:["redis","rediss"],defaultPort:6379,dataModel:"key-value",editorLanguage:"plaintext",liveMode:!1,schemaSelector:!1,rowMutation:!0,indexes:!1,serverLogs:!0},duckdb:{label:"DuckDB",protocols:["duckdb"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:"DuckDB cannot alter or rename a table that has an index, or alter or drop a column an index covers."},serverLogs:!1},oracle:{label:"Oracle",protocols:["oracle"],defaultPort:1521,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:"Building an index blocks writes to this table until it finishes."},serverLogs:!0},clickhouse:{label:"ClickHouse",protocols:["clickhouse","clickhouses"],defaultPort:8123,dataModel:"relational",editorLanguage:"pgsql",liveMode:!1,schemaSelector:!1,indexes:!1,rowMutation:!1,rowMutationReason:"Use a SQL query to update or delete ClickHouse rows; sorting keys are not unique.",serverLogs:!0}},We=r=>Ot.find(e=>j[e].protocols.includes(r))});import{z as Ce}from"zod";var so,Ml,kl,oo=N(()=>{"use strict";y();Ee();so=Ce.object({name:Ce.string("Name is required"),size:Ce.string("Size is required"),owner:Ce.string("Owner is required"),encoding:Ce.string("Encoding is required")}),Ml=Ce.object({databases:Ce.array(so),dbType:dt}),kl=Ce.object({version:Ce.string("Version is required"),database:Ce.string("Database is required"),user:Ce.string("User is required"),host:Ce.string("Host is required").nullable(),port:Ce.number("Port is required").nullable(),active_connections:Ce.coerce.number("Active connections is required"),max_connections:Ce.coerce.number("Max connections is required")})});var io=N(()=>{"use strict";y()});import{z as Pt}from"zod";var xn,co=N(()=>{"use strict";y();xn=Pt.object({tableName:Pt.string("Table name is required"),primaryKeys:Pt.array(Pt.object({columnName:Pt.string("Column name is required"),value:Pt.any()})).min(1,"At least one primary key is required")})});import{z as vl}from"zod";var Fr,lo=N(()=>{"use strict";y();Ee();Fr=U.extend({cascade:vl.string().optional().transform(r=>r==="true")})});import{z as uo}from"zod";var Kr,mo=N(()=>{"use strict";y();Kr=uo.object({query:uo.string("Query is required")})});import{z as Ul}from"zod";var po,Hr,fo=N(()=>{"use strict";y();Ee();po=["csv","xlsx","json"],Hr=U.extend({format:Ul.enum(po,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as le}from"zod";var yo,ql,Ln,Bl,Pn,Fl,ho=N(()=>{"use strict";y();Ee();yo=["primary","unique-constraint","index"],ql=le.object({indexName:le.string(),columns:le.array(le.string()),isUnique:le.boolean(),isSparse:le.boolean().optional(),expireAfterSeconds:le.number().nonnegative().optional(),method:le.string().nullable(),kind:le.enum(yo),definition:le.string().nullable()}),Ln=le.object({indexName:le.string().min(1),columns:le.array(le.string().min(1)).min(1),isUnique:le.boolean(),method:le.string().optional()}),Bl=Ln.extend({db:F.shape.db,tableName:ce.shape.tableName,schemaName:U.shape.schemaName}),Pn=le.object({tableName:le.string("Table name is required"),indexName:le.string("Index name is required")}),Fl=Pn.extend({db:F.shape.db,schemaName:U.shape.schemaName})});import{z as E}from"zod";var $n,q,jr,Wr,Kl,Yr,$t,Hl,jl,Wl,Yl,Vl,zl,Gl,go,Ql,Vr,Jl,Xl,Zl,eu,tu,nu,ru,zr,au,su,ou,iu,cu,lu,uu,mu,du,pu,fu,yu,hu,gu,bu,Gr,Qr,Tu,bo=N(()=>{"use strict";y();$n=E.enum(["string","hash","list","set","zset","stream","unknown"]),q=E.object({base64:E.string().max(16*1024*1024).refine(r=>/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/.test(r),"Invalid unpadded base64url value"),utf8:E.string().optional()}),jr=E.object({db:E.string(),cursor:E.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:E.coerce.number().int().min(1).max(200).default(50),search:E.string().max(512).optional(),exactPattern:E.stringbool().default(!1),type:$n.exclude(["unknown"]).optional()}),Wr=E.object({key:q,type:$n,ttlMs:E.number().int(),memoryBytes:E.number().int().nonnegative().nullable()}),Kl=E.object({keys:E.array(Wr),nextCursor:E.string().nullable(),hasMore:E.boolean()}),Yr=E.object({db:E.string(),cursor:E.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:E.coerce.number().int().min(1).max(500).default(100),full:E.stringbool().default(!1),direction:E.enum(["forward","backward"]).default("forward")}),$t=E.object({key:E.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),Hl=E.object({kind:E.literal("string"),value:q,truncated:E.boolean()}),jl=E.object({kind:E.literal("hash"),entries:E.array(E.object({field:q,value:q}))}),Wl=E.object({kind:E.literal("list"),entries:E.array(E.object({index:E.number().int(),value:q}))}),Yl=E.object({kind:E.literal("set"),members:E.array(q)}),Vl=E.object({kind:E.literal("zset"),entries:E.array(E.object({member:q,score:E.union([E.number(),E.literal("inf"),E.literal("-inf")])}))}),zl=E.object({kind:E.literal("stream"),entries:E.array(E.object({id:E.string(),fields:E.array(E.object({field:q,value:q}))}))}),Gl=E.object({kind:E.literal("unknown")}),go=E.discriminatedUnion("kind",[Hl,jl,Wl,Yl,Vl,zl,Gl]),Ql=Wr.extend({length:E.number().int().nonnegative().nullable(),revision:E.string(),value:go,nextCursor:E.string().nullable(),hasMore:E.boolean()}),Vr=E.object({db:E.string(),offset:E.coerce.number().int().nonnegative().default(0),limit:E.coerce.number().int().min(1).max(1024*1024).default(1024*1024),expectedRevision:E.string().optional()}),Jl=E.object({chunk:q,length:E.number().int().nonnegative(),nextOffset:E.number().int().nonnegative().nullable(),hasMore:E.boolean()}),Xl=E.object({kind:E.literal("string"),value:q}),Zl=E.object({kind:E.literal("hash"),entries:E.array(E.object({field:q,value:q})).min(1)}),eu=E.object({kind:E.literal("list"),entries:E.array(q).min(1)}),tu=E.object({kind:E.literal("set"),members:E.array(q).min(1)}),nu=E.object({kind:E.literal("zset"),entries:E.array(E.object({member:q,score:E.number()})).min(1)}),ru=E.object({kind:E.literal("stream"),id:E.string().default("*"),fields:E.array(E.object({field:q,value:q})).min(1)}),zr=E.object({key:q,type:$n.exclude(["unknown"]),value:E.discriminatedUnion("kind",[Xl,Zl,eu,tu,nu,ru]),ttlMs:E.number().int().positive().nullable().default(null)}),au=E.object({key:q,revision:E.string().nullable(),deleted:E.boolean()}),su=E.object({action:E.literal("rename"),newKey:q}),ou=E.object({action:E.literal("setTtl"),ttlMs:E.number().int().positive().nullable()}),iu=E.object({action:E.literal("setString"),value:q}),cu=E.object({action:E.literal("upsertHash"),field:q,value:q}),lu=E.object({action:E.literal("deleteHash"),field:q}),uu=E.object({action:E.literal("pushList"),side:E.enum(["left","right"]),value:q}),mu=E.object({action:E.literal("setList"),index:E.number().int(),value:q}),du=E.object({action:E.literal("deleteList"),index:E.number().int()}),pu=E.object({action:E.literal("addSet"),member:q}),fu=E.object({action:E.literal("removeSet"),member:q}),yu=E.object({action:E.literal("upsertZset"),member:q,score:E.number()}),hu=E.object({action:E.literal("removeZset"),member:q}),gu=E.object({action:E.literal("appendStream"),id:E.string().default("*"),fields:E.array(E.object({field:q,value:q})).min(1)}),bu=E.object({action:E.literal("deleteStream"),id:E.string()}),Gr=E.object({expectedRevision:E.string(),force:E.boolean().default(!1),operation:E.discriminatedUnion("action",[su,ou,iu,cu,lu,uu,mu,du,pu,fu,yu,hu,gu,bu])}),Qr=E.object({db:E.string(),expectedRevision:E.string(),force:E.stringbool().default(!1)}),Tu=E.object({deleted:E.boolean()})});var To=N(()=>{"use strict";y()});import{z as Jr}from"zod";var Mn,Eu,wu,Eo=N(()=>{"use strict";y();Ee();Cn();Mn=Jr.object({newColumnName:Jr.string("New column name is required")}),Eu=we,wu=Jr.object({db:F.shape.db,tableName:we.shape.tableName,schemaName:U.shape.schemaName,columnName:we.shape.columnName,newColumnName:Mn.shape.newColumnName})});import{z as kn}from"zod";var tn,Su,Cu,wo=N(()=>{"use strict";y();Ee();tn=kn.object({newTableName:kn.string("New table name is required").trim().min(1,"New table name is required"),schemaName:kn.string().trim().min(1).optional()}),Su=ce,Cu=kn.object({db:F.shape.db,tableName:ce.shape.tableName,newTableName:tn.shape.newTableName,schemaName:tn.shape.schemaName})});import{z as $e}from"zod";var So,Co,Ru,Ro=N(()=>{"use strict";y();So=["fatal","error","warning","info","debug"],Co=$e.enum(So),Ru=$e.object({ts:$e.string(),level:Co,rawLevel:$e.string(),source:$e.string().optional(),code:$e.string().optional(),message:$e.string(),durationMs:$e.number().optional(),statement:$e.string().optional(),detail:$e.record($e.string(),$e.string())})});import{z}from"zod";var Nu,nn,Au,No,Du,Xr,Ao=N(()=>{"use strict";y();Ee();Nu=z.object({columnName:z.string(),operator:z.string(),value:z.string()}),nn=["asc","desc"],Au=z.object({columnName:z.string(),direction:z.enum(nn)}),No=z.object({limit:z.number(),total:z.number(),totalEstimated:z.boolean().optional(),hasNextPage:z.boolean(),hasPreviousPage:z.boolean(),nextCursor:z.string().nullable(),prevCursor:z.string().nullable()}),Du=z.object({data:z.array(z.record(z.string(),z.unknown())),meta:No}),Xr=z.object({db:F.shape.db,schemaName:U.shape.schemaName,cursor:z.string().optional(),limit:z.string().optional().default("50").transform(Number),direction:z.enum(nn).optional().default(nn[0]),sort:z.string().optional().transform(r=>{if(!r)return"";try{let e=JSON.parse(r);return Array.isArray(e)?e:r}catch{return r}}),order:z.enum(nn).optional(),filters:z.string().optional().transform(r=>{if(!r)return[];try{return JSON.parse(r)}catch{return[]}})})});import{z as rn}from"zod";var _u,Do=N(()=>{"use strict";y();_u=rn.object({tableName:rn.string("Table name is required"),schemaName:rn.string().optional(),rowCount:rn.coerce.number("Row count is required"),rowCountEstimated:rn.boolean().optional()})});import{z as _o}from"zod";var Ou,Oo=N(()=>{"use strict";y();Ou=_o.object({schema:_o.string()})});import{z as Me}from"zod";var Zr,Io=N(()=>{"use strict";y();Zr=Me.object({tableName:Me.string("Table name is required"),primaryKey:Me.string("Primary key is required").default("id"),primaryKeys:Me.array(Me.string().min(1)).min(1).optional(),updates:Me.array(Me.object({rowData:Me.record(Me.string("Column name is required"),Me.any()),columnName:Me.string("Column name is required"),value:Me.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var xo={};Dt(xo,{AI_PROVIDERS:()=>Fs,AI_PROVIDER_OPTIONS:()=>Ks,CONNECTION_COLORS:()=>Js,DATABASE_ENGINES:()=>j,DATABASE_TYPES:()=>Ot,DataTypes:()=>L,FOREIGN_KEY_ACTIONS:()=>eo,FORMAT_TYPES:()=>po,INDEX_KINDS:()=>yo,SERVER_LOG_LEVELS:()=>So,StandardizedDataType:()=>T,addColumnParamSchema:()=>Sl,addColumnParamsSchema:()=>Cl,addColumnSchema:()=>qe,addRecordSchema:()=>Sr,aiProviderSchema:()=>Cr,alterColumnParamSchema:()=>Dl,alterColumnParamsSchema:()=>_l,alterColumnSchema:()=>It,bulkInsertRecordsSchema:()=>Dr,chatSchema:()=>_r,columnInfoSchema:()=>Pl,connectUrlSchema:()=>vr,connectionColorSchema:()=>en,connectionInfoSchema:()=>kl,connectionSummarySchema:()=>Xs,connectionsStateSchema:()=>$l,createIndexParamsSchema:()=>Bl,createIndexSchema:()=>Ln,createKeySchema:()=>zr,createTableSchema:()=>Br,currentDatabaseSchema:()=>El,dataTypesSchema:()=>zs,databaseInfoSchema:()=>so,databaseListSchema:()=>Ml,databaseSchema:()=>F,databaseTypeParamSchema:()=>wl,databaseTypeSchema:()=>dt,dbTypeFromProtocol:()=>We,deleteColumnParamSchema:()=>we,deleteColumnParamsSchema:()=>Nl,deleteColumnQuerySchema:()=>Ar,deleteColumnSuccessResponseSchema:()=>Al,deleteKeyQuerySchema:()=>Qr,deleteKeyResultSchema:()=>Tu,deleteRecordSchema:()=>xn,deleteTableQuerySchema:()=>Fr,dropIndexParamSchema:()=>Pn,dropIndexParamsSchema:()=>Fl,encodedRedisValueSchema:()=>q,executeQuerySchema:()=>Kr,exportTableSchema:()=>Hr,fieldDataSchema:()=>to,filterSchema:()=>Nu,foreignKeyActionSchema:()=>qr,foreignKeyDataSchema:()=>no,getDefaultAiModel:()=>Rr,indexInfoSchema:()=>ql,keyActionSchema:()=>Gr,keyDetailsQuerySchema:()=>Yr,keyDetailsResultSchema:()=>Ql,keyParamSchema:()=>$t,keyRawQuerySchema:()=>Vr,keyRawResultSchema:()=>Jl,keyScanQuerySchema:()=>jr,keyScanResultSchema:()=>Kl,keyWriteResultSchema:()=>au,mapClickhouseToDataType:()=>In,mapDuckdbToDataType:()=>_n,mapMssqlToDataType:()=>An,mapMysqlToDataType:()=>Nn,mapOracleToDataType:()=>On,mapPostgresToDataType:()=>Rn,mapSqliteToDataType:()=>Dn,redisKeySummarySchema:()=>Wr,redisKeyTypeSchema:()=>$n,redisKeyValueSchema:()=>go,renameColumnParamSchema:()=>Eu,renameColumnParamsSchema:()=>wu,renameColumnSchema:()=>Mn,renameTableParamSchema:()=>Su,renameTableParamsSchema:()=>Cu,renameTableSchema:()=>tn,serverLogEntrySchema:()=>Ru,serverLogLevelSchema:()=>Co,sortDirections:()=>nn,sortSchema:()=>Au,standardizeClickhouseDataTypeLabel:()=>kr,standardizeDataTypeLabel:()=>Ir,standardizeDuckdbDataTypeLabel:()=>$r,standardizeMssqlDataTypeLabel:()=>Lr,standardizeMysqlDataTypeLabel:()=>xr,standardizeOracleDataTypeLabel:()=>Mr,standardizeSqliteDataTypeLabel:()=>Pr,standardizedDataTypeSchema:()=>Gs,tableDataMetaSchema:()=>No,tableDataQuerySchema:()=>Xr,tableDataResultSchema:()=>Du,tableInfoSchema:()=>_u,tableNameSchema:()=>ce,tableQuerySchema:()=>U,tableSchemaResultSchema:()=>Ou,unwrapClickhouseType:()=>Lt,updateConnectionSchema:()=>Ur,updateRecordsSchema:()=>Zr});var G=N(()=>{"use strict";y();qs();Bs();Nr();Hs();js();Ws();Ys();Vs();Qs();Or();Zs();ro();Ee();ao();oo();io();Cn();co();lo();mo();fo();ho();bo();To();Eo();wo();Ro();Ao();Do();Oo();Io()});var Iu,xu,Lu,vn,ea=N(()=>{"use strict";y();G();Iu=Object.values(j).flatMap(({protocols:r})=>r).map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),xu=new RegExp(`\\b(?:${Iu}):\\/\\/\\S+`,"gi"),Lu=/\b(authToken=)[^&\s]+/gi,vn=r=>r.replace(xu,e=>`the configured database${e.match(/[),.]+$/)?.[0]??""}`).replace(Lu,"$1[redacted]")});var d,te=N(()=>{"use strict";y();d=class extends Error{constructor(t,{message:n,cause:a}={}){super(n,{cause:a});this.status=t}}});import{AsyncLocalStorage as Mu}from"async_hooks";import{randomUUID as Po}from"crypto";var ku,vu,ta,$o,Mo,st,Uu,qu,Bu,ko,na,ne,W,Ye=N(()=>{"use strict";y();te();ku=Po(),vu=/^[A-Za-z0-9_-]{8,64}$/,ta=new Mu,$o=r=>r&&vu.test(r)?r:Po(),Mo=(r,e)=>ta.run(r,e),st=()=>ta.getStore()?.requestId,Uu=r=>{let e=r instanceof d?"HTTPException":r instanceof Error?r.name:"Error";return/^[A-Za-z][A-Za-z0-9]{0,49}$/.test(e)?e:"Error"},qu=/^[A-Z0-9_-]{2,32}$/,Bu=[[/^timeout exceeded when trying to connect$/,"POOL_ACQUIRE_TIMEOUT"],[/^(timeout expired|Connection terminated due to connection timeout)$/,"CONNECT_TIMEOUT"],[/^Connection terminated/,"CONNECTION_TERMINATED"],[/^Client has encountered a connection error/,"CONNECTION_BROKEN"]],ko=r=>{if(!(r instanceof Error))return;let{code:e,errno:t,number:n,cause:a}=r;return typeof n=="number"&&Number.isSafeInteger(n)?String(n):typeof e=="string"&&qu.test(e)?e:typeof e=="number"&&Number.isSafeInteger(e)?String(e):typeof t=="number"&&Number.isSafeInteger(t)?String(t):r.name==="ReplyError"?r.message.match(/^[A-Z]{3,32}(?= |$)/)?.[0]:Bu.find(([s])=>s.test(r.message))?.[1]??ko(a)},na=r=>r instanceof d&&r.cause?r.cause:r,ne=r=>{let e=na(r);return{error_type:Uu(e),error_code:ko(e)}},W=(r,e,t={})=>{let n=ta.getStore();process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:r,event:e,instance_id:ku,request_id:n?.requestId,operation:n?.operation,db_type:n?.dbType,...t})}
|
|
3
|
-
`)}});function
|
|
2
|
+
var Nl=Object.defineProperty;var N=(r,e)=>()=>(r&&(e=r(r=0)),e);var Ot=(r,e)=>{for(var t in e)Nl(r,t,{get:e[t],enumerable:!0})};var h=N(()=>{"use strict";(function(){try{var r=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};r.SENTRY_RELEASE={id:"db-studio@1.24.0"}}catch{}})()});var Ps=N(()=>{"use strict";h()});var $s=N(()=>{"use strict";h()});var Ms=N(()=>{"use strict";h()});var vs,ks,st,Us=N(()=>{"use strict";h();vs=globalThis.process?.env,ks=vs?.NODE_ENV,st={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:ks==="development",PROXY_URL:vs?.DB_STUDIO_PROXY_URL??(ks==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var qs=N(()=>{"use strict";h()});var Bs,Nr=N(()=>{"use strict";h();Bs={AUTHOR:"H\xFCsam \u{1F951} <husam@ql3.dev>",AUTHOR_NAME:"H\xFCsam",AUTHOR_AVATAR:"/avocado.png",AUTHOR_USERNAME:"husamql3",AUTHOR_GITHUB_LINK:"https://github.com/husamql3",SITE_DESCRIPTION:"The modern pgAdmin alternative that works with every database.",SITE_KEYWORDS:["pgadmin alternative","database client","database gui","database browser","sql editor","postgresql client","mysql client","table editor","ai sql","er diagram"],SITE_TITLE:"db-studio",SITE_NAME:"dbstudio.sh",SITE_URL:"https://dbstudio.sh",SITE_X_LINK:"https://x.com/dbstudio_sh",SITE_GITHUB_LINK:"https://github.com/husamql3/db-studio",SITE_GITHUB_NEW_ISSUE_LINK:"https://github.com/husamql3/db-studio/issues/new/choose",SITE_DOCS_LINK:"https://dbstudio.sh/docs",SITE_CHANGELOG_LINK:"https://dbstudio.sh/changelog",SITE_ROADMAP_LINK:"https://dbstudio.sh/roadmap",SITE_IMAGE:"https://dbstudio.sh/og-image.png",SITE_IMAGE_WIDTH:"1200",SITE_IMAGE_HEIGHT:"630",SITE_IMAGE_ALT:"dbstudio.sh \u2013 Modern database management studio",SITE_COLOR:"#1447e6"}});var Fs=N(()=>{"use strict";h()});var en=N(()=>{"use strict";h();Ps();$s();Ms();Us();qs();Nr();Fs()});import{z as gt}from"zod";var F,U,xt,mt,Ll,Pl,ce,Te=N(()=>{"use strict";h();F=gt.object({db:gt.string("Database name is required")}),U=F.extend({schemaName:gt.string().optional()}),xt=["pg","mysql","mssql","mongodb","sqlite","redis","duckdb","oracle","clickhouse"],mt=gt.enum(xt,{message:"Invalid database type"}),Ll=F.extend({dbType:mt}),Pl=gt.object({dbType:mt}),ce=gt.object({tableName:gt.string("Table name is required")})});import{z as We}from"zod";var Fe,$l,Ml,Ys=N(()=>{"use strict";h();Te();Fe=We.object({columnName:We.string("Column name is required"),columnType:We.string("Column type is required"),defaultValue:We.string().optional(),isPrimaryKey:We.boolean().default(!1),isNullable:We.boolean().default(!1),isUnique:We.boolean().default(!1),isIdentity:We.boolean().default(!1),isArray:We.boolean().default(!1)}),$l=ce,Ml=We.object({db:F.shape.db,tableName:ce.shape.tableName,schemaName:U.shape.schemaName,columnName:Fe.shape.columnName,columnType:Fe.shape.columnType,defaultValue:Fe.shape.defaultValue,isPrimaryKey:Fe.shape.isPrimaryKey,isNullable:Fe.shape.isNullable,isUnique:Fe.shape.isUnique,isIdentity:Fe.shape.isIdentity,isArray:Fe.shape.isArray})});import{z as tn}from"zod";var _r,Vs=N(()=>{"use strict";h();_r=tn.object({tableName:tn.string("Table name is required"),data:tn.record(tn.string("Column name is required"),tn.any())})});import{z as kl}from"zod";var zs,Or,Gs,Ir,xr=N(()=>{"use strict";h();zs=["gemini","openai","anthropic","grok","openrouter"],Or=kl.enum(zs),Gs=[{id:"gemini",label:"Google Gemini",models:[{id:"gemini-3-flash-preview",label:"Gemini 3 Flash"},{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro"}]},{id:"openai",label:"OpenAI",models:[{id:"gpt-5.2",label:"GPT-5.2"},{id:"gpt-5-mini",label:"GPT-5 mini"}]},{id:"anthropic",label:"Anthropic",models:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}]},{id:"grok",label:"xAI Grok",models:[{id:"grok-4.6",label:"Grok 4.6"},{id:"grok-4.5",label:"Grok 4.5"}]},{id:"openrouter",label:"OpenRouter",models:[{id:"openai/gpt-5.2",label:"GPT-5.2 via OpenRouter"},{id:"anthropic/claude-sonnet-4.6",label:"Claude Sonnet 4.6 via OpenRouter"}]}],Ir=r=>Gs.find(e=>e.id===r)?.models[0]?.id??"gemini-3-flash-preview"});import{z as Ke}from"zod";var Lr,Ee,vl,Ul,Dn=N(()=>{"use strict";h();Te();Lr=U.extend({cascade:Ke.string().optional().transform(r=>r==="true")}),Ee=Ke.object({tableName:Ke.string("Table name is required"),columnName:Ke.string("Column name is required")}),vl=Ke.object({db:F.shape.db,tableName:Ee.shape.tableName,schemaName:U.shape.schemaName,columnName:Ee.shape.columnName,cascade:Ke.boolean().optional()}),Ul=Ke.object({message:Ke.string("Message is required"),tableName:Ke.string("Table name is required"),columnName:Ke.string("Column name is required"),deletedCount:Ke.number("Deleted count is required").default(0)})});import{z as nn}from"zod";var Lt,ql,Bl,Qs=N(()=>{"use strict";h();Te();Dn();Lt=nn.object({columnType:nn.string("Column type is required"),isNullable:nn.boolean(),defaultValue:nn.string().nullable().optional()}),ql=Ee,Bl=nn.object({db:F.shape.db,tableName:Ee.shape.tableName,schemaName:U.shape.schemaName,columnName:Ee.shape.columnName,columnType:Lt.shape.columnType,isNullable:Lt.shape.isNullable,defaultValue:Lt.shape.defaultValue})});var Js=N(()=>{"use strict";h()});import{z as Pt}from"zod";var Pr,Xs=N(()=>{"use strict";h();Pr=Pt.object({tableName:Pt.string().min(1,"Table name is required"),records:Pt.array(Pt.record(Pt.string(),Pt.any())).min(1,"At least one record is required")})});import{z as de}from"zod";var Fl,Kl,$r,Zs=N(()=>{"use strict";h();xr();Te();Fl=de.object({type:de.string(),content:de.string().optional()}).passthrough(),Kl=de.object({provider:Or.optional().default("gemini"),model:de.string().min(1).optional(),messages:de.array(de.object({id:de.string(),role:de.enum(["user","assistant","system","tool","reasoning"]),content:de.union([de.string(),de.null(),de.array(de.unknown())]).optional(),parts:de.array(Fl).optional()}).passthrough()),data:de.object({conversationId:de.string().optional(),db:F.shape.db,includeSchema:de.boolean().optional().default(!0)})}),$r=Kl.transform(r=>({...r,model:r.model??Ir(r.provider)}))});var eo=N(()=>{"use strict";h()});import{z as Le}from"zod";var Hl,to,L,jl,no,Wl,Mr=N(()=>{"use strict";h();Hl=["text","boolean","number","enum","json","date","array"],to=Le.enum(Hl),L={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},jl=["int","bigint","smallint","numeric","float","double","money","tinyint","mediumint","bit","boolean","text","varchar","char","tinytext","mediumtext","longtext","json","jsonb","xml","uuid","date","time","timestamp","timestamptz","interval","datetime","year","bytea","inet","cidr","macaddr","macaddr8","point","line","polygon","binary","varbinary","blob","tinyblob","mediumblob","longblob","array","enum","set"],no=Le.enum(jl),Wl=Le.object({columnName:Le.string(),dataType:to,dataTypeLabel:no,isNullable:Le.boolean(),columnDefault:Le.string().nullable(),isPrimaryKey:Le.boolean(),isForeignKey:Le.boolean(),referencedTable:Le.string().nullable(),referencedSchema:Le.string().optional(),referencedColumn:Le.string().nullable(),enumValues:Le.array(Le.string()).nullable()})});function _n(r){let e=r?.toLowerCase().trim()||"";return e.includes("[]")||e==="date"||e==="time"||e==="time without time zone"||e.startsWith("time(")||e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")||e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?L.date:e==="integer"||e==="int"||e==="int4"||e==="bigint"||e==="int8"||e==="smallint"||e==="int2"||e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")||e==="real"||e==="float4"||e==="double precision"||e==="float8"||e==="float"||e==="serial"||e==="serial4"||e==="bigserial"||e==="serial8"||e==="money"?L.number:e==="boolean"||e==="bool"?L.boolean:e==="json"||e==="jsonb"?L.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?L.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")||e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"||e==="uuid"||e==="interval"||e.startsWith("interval")||e==="bytea"||e==="point"||e==="line"||e==="polygon"||e==="inet"||e==="cidr"||e==="macaddr"||e==="macaddr8"?L.text:L.text}function kr(r){if(!r)return T.text;let e=r.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?T.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?T.bigint:e==="smallint"||e==="int2"?T.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?T.numeric:e==="real"||e==="float4"?T.float:e==="double precision"||e==="float8"||e==="float"?T.double:e==="money"?T.money:e==="boolean"||e==="bool"?T.boolean:e==="text"?T.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?T.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?T.char:e==="json"?T.json:e==="jsonb"?T.jsonb:e==="xml"?T.xml:e==="uuid"?T.uuid:e==="date"?T.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?T.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?T.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?T.timestamptz:e==="interval"||e.startsWith("interval")?T.interval:e==="bytea"?T.bytea:e==="inet"?T.inet:e==="cidr"?T.cidr:e==="macaddr"?T.macaddr:e==="macaddr8"?T.macaddr8:e==="point"?T.point:e==="line"?T.line:e==="polygon"?T.polygon:e.startsWith("array")||e.includes("[]")?T.text:e.startsWith("user-defined")||e==="enum"?T.enum:T.text}function On(r,e){let t=r?.toLowerCase().trim()||"",n=e?.toLowerCase().trim()||"";return t==="tinyint"&&n==="tinyint(1)"?L.boolean:t==="tinyint"||t==="smallint"||t==="mediumint"||t==="int"||t==="integer"||t==="bigint"||t==="decimal"||t==="numeric"||t==="float"||t==="double"||t==="real"||t==="bit"?L.number:t==="boolean"||t==="bool"?L.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?L.date:t==="json"?L.json:t==="enum"||t==="set"?L.enum:L.text}function vr(r,e){if(!r)return T.text;let t=r.toLowerCase().trim(),n=e?.toLowerCase().trim()||"";return t==="tinyint"&&n==="tinyint(1)"?T.boolean:t==="tinyint"?T.tinyint:t==="smallint"?T.smallint:t==="mediumint"?T.mediumint:t==="int"||t==="integer"?T.int:t==="bigint"?T.bigint:t==="decimal"||t==="numeric"?T.numeric:t==="float"||t==="real"?T.float:t==="double"?T.double:t==="bit"?T.bit:t==="boolean"||t==="bool"?T.boolean:t==="char"?T.char:t==="varchar"?T.varchar:t==="tinytext"?T.tinytext:t==="text"?T.text:t==="mediumtext"?T.mediumtext:t==="longtext"?T.longtext:t==="binary"?T.binary:t==="varbinary"?T.varbinary:t==="tinyblob"?T.tinyblob:t==="blob"?T.blob:t==="mediumblob"?T.mediumblob:t==="longblob"?T.longblob:t==="json"?T.json:t==="date"?T.date:t==="time"?T.time:t==="datetime"?T.datetime:t==="timestamp"?T.timestamp:t==="year"?T.year:t==="enum"?T.enum:t==="set"?T.set:T.text}function In(r){let e=r?.toLowerCase().trim()||"";return e==="tinyint"||e==="smallint"||e==="int"||e==="bigint"||e==="decimal"||e==="numeric"||e==="float"||e==="real"||e==="money"||e==="smallmoney"?L.number:e==="bit"?L.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?L.date:e==="json"?L.json:L.text}function Ur(r){if(!r)return T.text;let e=r.toLowerCase().trim();return e==="tinyint"?T.tinyint:e==="smallint"?T.smallint:e==="int"?T.int:e==="bigint"?T.bigint:e==="decimal"||e==="numeric"?T.numeric:e==="float"||e==="real"?T.float:e==="money"||e==="smallmoney"?T.money:e==="bit"?T.boolean:e==="char"?T.char:e==="varchar"?T.varchar:e==="text"?T.text:e==="nchar"?T.char:e==="nvarchar"?T.varchar:e==="ntext"?T.text:e==="binary"?T.binary:e==="varbinary"?T.varbinary:e==="image"?T.blob:e==="uniqueidentifier"?T.uuid:e==="date"?T.date:e==="time"?T.time:e==="datetime"||e==="datetime2"||e==="smalldatetime"?T.datetime:e==="datetimeoffset"?T.timestamptz:e==="json"?T.json:e==="xml"?T.xml:T.text}function xn(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?L.boolean:e==="json"?L.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?L.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?L.number:L.text}function qr(r){let e=r?.toLowerCase().trim()||"";return e==="integer"||e==="int"?T.int:e==="bigint"||e.startsWith("bigint(")?T.bigint:e==="smallint"||e.startsWith("smallint(")?T.smallint:e==="tinyint"||e.startsWith("tinyint(")?T.tinyint:e==="mediumint"||e.startsWith("mediumint(")?T.mediumint:e.includes("int")?T.int:e==="real"||e==="float"||e.startsWith("float(")?T.float:e==="double"||e==="double precision"||e.startsWith("double(")?T.double:e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?T.numeric:e==="boolean"||e==="bool"?T.boolean:e==="text"||e==="clob"?T.text:e==="varchar"||e.startsWith("varchar(")?T.varchar:e==="char"||e.startsWith("char(")?T.char:e==="json"?T.json:e==="date"?T.date:e==="time"?T.time:e==="datetime"?T.datetime:e==="timestamp"?T.timestamp:e==="blob"?T.blob:T.text}function Ln(r){let e=r?.toLowerCase().trim()||"";return e.endsWith("]")||e.startsWith("struct")||e.startsWith("map")||e.startsWith("union")||e==="json"?L.json:e==="boolean"||e==="bool"?L.boolean:e.startsWith("enum")?L.enum:e==="interval"?L.text:e==="date"||e.startsWith("time")||e==="datetime"?L.date:e.includes("int")||e==="float"||e==="real"||e==="double"||e.startsWith("decimal")||e.startsWith("numeric")||e==="bignum"?L.number:L.text}function Br(r){let e=r?.toLowerCase().trim()||"";return e.endsWith("]")?T.array:e.startsWith("struct")||e.startsWith("map")||e.startsWith("union")||e==="json"?T.json:e.startsWith("enum")?T.enum:e==="interval"?T.interval:e==="tinyint"||e==="utinyint"?T.tinyint:e==="smallint"||e==="usmallint"?T.smallint:e==="integer"||e==="int"?T.int:e.includes("int")||e==="bignum"?T.bigint:e.startsWith("decimal")||e.startsWith("numeric")?T.numeric:e==="float"||e==="real"?T.float:e==="double"?T.double:e==="boolean"||e==="bool"?T.boolean:e==="varchar"||e.startsWith("varchar(")?T.varchar:e==="uuid"?T.uuid:e==="date"?T.date:e==="timestamp with time zone"||e==="timestamptz"?T.timestamptz:e.startsWith("timestamp")||e==="datetime"?T.timestamp:e.startsWith("time")?T.time:e==="blob"||e==="bytea"?T.blob:e==="bit"||e==="bitstring"?T.bit:T.text}function Pn(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"?L.boolean:e==="json"?L.json:e==="date"||e.startsWith("timestamp")?L.date:e.startsWith("number")||e.startsWith("float")||e==="integer"||e==="binary_float"||e==="binary_double"?L.number:L.text}function Fr(r){let e=r?.toLowerCase().trim()||"";if(e==="boolean")return T.boolean;if(e==="json")return T.json;if(e==="xmltype")return T.xml;if(e==="integer")return T.int;let t=e.match(/^number\((\d+)(?:,0)?\)$/);if(t){let n=Number(t[1]);if(n<=4)return T.smallint;if(n<=10)return T.int;if(n<=19)return T.bigint}return e.startsWith("number")?T.numeric:e==="binary_float"?T.float:e==="binary_double"||e.startsWith("float")?T.double:e.startsWith("varchar")||e.startsWith("nvarchar")?T.varchar:e.startsWith("char")||e.startsWith("nchar")?T.char:e.startsWith("timestamp")&&e.endsWith("time zone")?T.timestamptz:e==="date"||e.startsWith("timestamp")?T.timestamp:e.startsWith("interval")?T.interval:e==="blob"||e==="long raw"?T.blob:e.startsWith("raw")?T.varbinary:T.text}function $t(r){let e=r.trim();for(;;){let t=e.match(/^(?:Nullable|LowCardinality)\((.*)\)$/);if(!t?.[1])return e;e=t[1].trim()}}function $n(r){let e=$t(r);return e.startsWith("Array(")?L.array:e.startsWith("Enum8(")||e.startsWith("Enum16(")?L.enum:e==="Bool"?L.boolean:/^(Date|Date32|DateTime|DateTime64|Time|Time64)\b/.test(e)?L.date:/^(U?Int\d+|Float\d+|BFloat16|Decimal\d*)\b/.test(e)?L.number:/^(JSON|Object|Map|Tuple|Variant|Dynamic|Nested)\b/.test(e)?L.json:L.text}function Kr(r){let e=$t(r);return e.startsWith("Array(")?T.array:e.startsWith("Enum8(")||e.startsWith("Enum16(")?T.enum:e==="Bool"?T.boolean:/^U?Int8$/.test(e)?T.tinyint:/^U?Int16$/.test(e)?T.smallint:/^U?Int32$/.test(e)?T.int:/^U?Int(64|128|256)$/.test(e)?T.bigint:e==="Float32"||e==="BFloat16"?T.float:e==="Float64"?T.double:e.startsWith("Decimal")?T.numeric:e.startsWith("FixedString(")?T.char:e==="UUID"?T.uuid:e==="IPv4"||e==="IPv6"?T.inet:e==="Date"||e==="Date32"?T.date:e.startsWith("DateTime64")?T.timestamp:e.startsWith("DateTime")?T.datetime:e.startsWith("Time")?T.time:/^(JSON|Object|Map|Tuple|Variant|Dynamic|Nested)\b/.test(e)?T.json:T.text}var T,ro=N(()=>{"use strict";h();Mr();T={int:"int",bigint:"bigint",smallint:"smallint",numeric:"numeric",float:"float",double:"double",money:"money",tinyint:"tinyint",mediumint:"mediumint",bit:"bit",boolean:"boolean",text:"text",varchar:"varchar",char:"char",tinytext:"tinytext",mediumtext:"mediumtext",longtext:"longtext",json:"json",jsonb:"jsonb",xml:"xml",uuid:"uuid",date:"date",time:"time",timestamp:"timestamp",timestamptz:"timestamptz",interval:"interval",datetime:"datetime",year:"year",bytea:"bytea",inet:"inet",cidr:"cidr",macaddr:"macaddr",macaddr8:"macaddr8",point:"point",line:"line",polygon:"polygon",binary:"binary",varbinary:"varbinary",blob:"blob",tinyblob:"tinyblob",mediumblob:"mediumblob",longblob:"longblob",array:"array",enum:"enum",set:"set"}});import{z as we}from"zod";var ao,rn,so,Yl,Hr,jr,oo=N(()=>{"use strict";h();Te();ao=["red","orange","amber","green","teal","blue","violet","pink"],rn=we.enum(ao),so=we.object({id:we.string(),name:we.string(),color:rn.nullable(),lastUsedAt:we.number(),dbType:mt,maskedUrl:we.string()}),Yl=we.object({connections:we.array(so),active:we.object({id:we.string().nullable(),dbType:mt,connectionId:we.string()}).nullable()}),Hr=we.object({url:we.string().trim().min(1,"Paste a connection URL")}),jr=we.object({name:we.string().trim().min(1,"Name is required").max(100).optional(),color:rn.nullable().optional()})});import{z as pe}from"zod";var io,Wr,co,lo,Yr,uo=N(()=>{"use strict";h();io=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],Wr=pe.enum(io),co=pe.object({columnName:pe.string("Column name is required"),columnType:pe.string("Column type is required"),defaultValue:pe.string().optional(),isPrimaryKey:pe.boolean().default(!1),isNullable:pe.boolean().default(!1),isUnique:pe.boolean().default(!1),isIdentity:pe.boolean().default(!1),isArray:pe.boolean().default(!1)}),lo=pe.object({columnName:pe.string("Column name is required"),referencedTable:pe.string("Referenced table is required"),referencedColumn:pe.string("Referenced column is required"),onUpdate:Wr.default("NO ACTION"),onDelete:Wr.default("NO ACTION")}),Yr=pe.object({tableName:pe.string("Table name is required"),fields:pe.array(co).min(1,"At least one field is required"),foreignKeys:pe.array(lo).optional()})});var W,Ye,mo=N(()=>{"use strict";h();Te();W={pg:{label:"PostgreSQL",protocols:["postgres","postgresql","cockroachdb"],defaultPort:5432,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!0,rowMutation:!0,indexes:{methods:["btree","hash","gin","gist","spgist","brin"],createNote:"Building an index blocks writes to this table until it finishes."},serverLogs:!0},mysql:{label:"MySQL",protocols:["mysql","mysql2","mariadb","tidb"],defaultPort:3306,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null},serverLogs:!0},mssql:{label:"SQL Server",protocols:["mssql","sqlserver"],defaultPort:1433,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:"Building an index blocks writes to this table until it finishes."},serverLogs:!0},mongodb:{label:"MongoDB",protocols:["mongodb","mongodb+srv"],defaultPort:27017,dataModel:"document",editorLanguage:"json",liveMode:!1,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null},serverLogs:!0},sqlite:{label:"SQLite / libSQL / D1",protocols:["sqlite","libsql","d1"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null},serverLogs:!1},redis:{label:"Redis",protocols:["redis","rediss"],defaultPort:6379,dataModel:"key-value",editorLanguage:"plaintext",liveMode:!1,schemaSelector:!1,rowMutation:!0,indexes:!1,serverLogs:!0},duckdb:{label:"DuckDB",protocols:["duckdb"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:"DuckDB cannot alter or rename a table that has an index, or alter or drop a column an index covers."},serverLogs:!1},oracle:{label:"Oracle",protocols:["oracle"],defaultPort:1521,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:"Building an index blocks writes to this table until it finishes."},serverLogs:!0},clickhouse:{label:"ClickHouse",protocols:["clickhouse","clickhouses"],defaultPort:8123,dataModel:"relational",editorLanguage:"pgsql",liveMode:!1,schemaSelector:!1,indexes:!1,rowMutation:!1,rowMutationReason:"Use a SQL query to update or delete ClickHouse rows; sorting keys are not unique.",serverLogs:!0}},Ye=r=>xt.find(e=>W[e].protocols.includes(r))});import{z as Se}from"zod";var po,Vl,zl,fo=N(()=>{"use strict";h();Te();po=Se.object({name:Se.string("Name is required"),size:Se.string("Size is required"),owner:Se.string("Owner is required"),encoding:Se.string("Encoding is required")}),Vl=Se.object({databases:Se.array(po),dbType:mt}),zl=Se.object({version:Se.string("Version is required"),database:Se.string("Database is required"),user:Se.string("User is required"),host:Se.string("Host is required").nullable(),port:Se.number("Port is required").nullable(),active_connections:Se.coerce.number("Active connections is required"),max_connections:Se.coerce.number("Max connections is required")})});var ho=N(()=>{"use strict";h()});import{z as Mt}from"zod";var Mn,yo=N(()=>{"use strict";h();Mn=Mt.object({tableName:Mt.string("Table name is required"),primaryKeys:Mt.array(Mt.object({columnName:Mt.string("Column name is required"),value:Mt.any()})).min(1,"At least one primary key is required")})});import{z as Gl}from"zod";var Vr,go=N(()=>{"use strict";h();Te();Vr=U.extend({cascade:Gl.string().optional().transform(r=>r==="true")})});import{z as bo}from"zod";var zr,To=N(()=>{"use strict";h();zr=bo.object({query:bo.string("Query is required")})});import{z as Ql}from"zod";var Eo,Gr,wo=N(()=>{"use strict";h();Te();Eo=["csv","xlsx","json"],Gr=U.extend({format:Ql.enum(Eo,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as le}from"zod";var So,Jl,kn,Xl,vn,Zl,Co=N(()=>{"use strict";h();Te();So=["primary","unique-constraint","index"],Jl=le.object({indexName:le.string(),columns:le.array(le.string()),isUnique:le.boolean(),isSparse:le.boolean().optional(),expireAfterSeconds:le.number().nonnegative().optional(),method:le.string().nullable(),kind:le.enum(So),definition:le.string().nullable()}),kn=le.object({indexName:le.string().min(1),columns:le.array(le.string().min(1)).min(1),isUnique:le.boolean(),method:le.string().optional()}),Xl=kn.extend({db:F.shape.db,tableName:ce.shape.tableName,schemaName:U.shape.schemaName}),vn=le.object({tableName:le.string("Table name is required"),indexName:le.string("Index name is required")}),Zl=vn.extend({db:F.shape.db,schemaName:U.shape.schemaName})});import{z as E}from"zod";var Un,q,Qr,Jr,eu,Xr,kt,tu,nu,ru,au,su,ou,iu,Ro,cu,Zr,lu,uu,mu,du,pu,fu,hu,ea,yu,gu,bu,Tu,Eu,wu,Su,Cu,Ru,Nu,Au,Du,_u,Ou,Iu,ta,na,xu,No=N(()=>{"use strict";h();Un=E.enum(["string","hash","list","set","zset","stream","unknown"]),q=E.object({base64:E.string().max(16*1024*1024).refine(r=>/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/.test(r),"Invalid unpadded base64url value"),utf8:E.string().optional()}),Qr=E.object({db:E.string(),cursor:E.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:E.coerce.number().int().min(1).max(200).default(50),search:E.string().max(512).optional(),exactPattern:E.stringbool().default(!1),type:Un.exclude(["unknown"]).optional()}),Jr=E.object({key:q,type:Un,ttlMs:E.number().int(),memoryBytes:E.number().int().nonnegative().nullable()}),eu=E.object({keys:E.array(Jr),nextCursor:E.string().nullable(),hasMore:E.boolean()}),Xr=E.object({db:E.string(),cursor:E.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:E.coerce.number().int().min(1).max(500).default(100),full:E.stringbool().default(!1),direction:E.enum(["forward","backward"]).default("forward")}),kt=E.object({key:E.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),tu=E.object({kind:E.literal("string"),value:q,truncated:E.boolean()}),nu=E.object({kind:E.literal("hash"),entries:E.array(E.object({field:q,value:q}))}),ru=E.object({kind:E.literal("list"),entries:E.array(E.object({index:E.number().int(),value:q}))}),au=E.object({kind:E.literal("set"),members:E.array(q)}),su=E.object({kind:E.literal("zset"),entries:E.array(E.object({member:q,score:E.union([E.number(),E.literal("inf"),E.literal("-inf")])}))}),ou=E.object({kind:E.literal("stream"),entries:E.array(E.object({id:E.string(),fields:E.array(E.object({field:q,value:q}))}))}),iu=E.object({kind:E.literal("unknown")}),Ro=E.discriminatedUnion("kind",[tu,nu,ru,au,su,ou,iu]),cu=Jr.extend({length:E.number().int().nonnegative().nullable(),revision:E.string(),value:Ro,nextCursor:E.string().nullable(),hasMore:E.boolean()}),Zr=E.object({db:E.string(),offset:E.coerce.number().int().nonnegative().default(0),limit:E.coerce.number().int().min(1).max(1024*1024).default(1024*1024),expectedRevision:E.string().optional()}),lu=E.object({chunk:q,length:E.number().int().nonnegative(),nextOffset:E.number().int().nonnegative().nullable(),hasMore:E.boolean()}),uu=E.object({kind:E.literal("string"),value:q}),mu=E.object({kind:E.literal("hash"),entries:E.array(E.object({field:q,value:q})).min(1)}),du=E.object({kind:E.literal("list"),entries:E.array(q).min(1)}),pu=E.object({kind:E.literal("set"),members:E.array(q).min(1)}),fu=E.object({kind:E.literal("zset"),entries:E.array(E.object({member:q,score:E.number()})).min(1)}),hu=E.object({kind:E.literal("stream"),id:E.string().default("*"),fields:E.array(E.object({field:q,value:q})).min(1)}),ea=E.object({key:q,type:Un.exclude(["unknown"]),value:E.discriminatedUnion("kind",[uu,mu,du,pu,fu,hu]),ttlMs:E.number().int().positive().nullable().default(null)}),yu=E.object({key:q,revision:E.string().nullable(),deleted:E.boolean()}),gu=E.object({action:E.literal("rename"),newKey:q}),bu=E.object({action:E.literal("setTtl"),ttlMs:E.number().int().positive().nullable()}),Tu=E.object({action:E.literal("setString"),value:q}),Eu=E.object({action:E.literal("upsertHash"),field:q,value:q}),wu=E.object({action:E.literal("deleteHash"),field:q}),Su=E.object({action:E.literal("pushList"),side:E.enum(["left","right"]),value:q}),Cu=E.object({action:E.literal("setList"),index:E.number().int(),value:q}),Ru=E.object({action:E.literal("deleteList"),index:E.number().int()}),Nu=E.object({action:E.literal("addSet"),member:q}),Au=E.object({action:E.literal("removeSet"),member:q}),Du=E.object({action:E.literal("upsertZset"),member:q,score:E.number()}),_u=E.object({action:E.literal("removeZset"),member:q}),Ou=E.object({action:E.literal("appendStream"),id:E.string().default("*"),fields:E.array(E.object({field:q,value:q})).min(1)}),Iu=E.object({action:E.literal("deleteStream"),id:E.string()}),ta=E.object({expectedRevision:E.string(),force:E.boolean().default(!1),operation:E.discriminatedUnion("action",[gu,bu,Tu,Eu,wu,Su,Cu,Ru,Nu,Au,Du,_u,Ou,Iu])}),na=E.object({db:E.string(),expectedRevision:E.string(),force:E.stringbool().default(!1)}),xu=E.object({deleted:E.boolean()})});var Ao=N(()=>{"use strict";h()});import{z as ra}from"zod";var qn,Lu,Pu,Do=N(()=>{"use strict";h();Te();Dn();qn=ra.object({newColumnName:ra.string("New column name is required")}),Lu=Ee,Pu=ra.object({db:F.shape.db,tableName:Ee.shape.tableName,schemaName:U.shape.schemaName,columnName:Ee.shape.columnName,newColumnName:qn.shape.newColumnName})});import{z as Bn}from"zod";var an,$u,Mu,_o=N(()=>{"use strict";h();Te();an=Bn.object({newTableName:Bn.string("New table name is required").trim().min(1,"New table name is required"),schemaName:Bn.string().trim().min(1).optional()}),$u=ce,Mu=Bn.object({db:F.shape.db,tableName:ce.shape.tableName,newTableName:an.shape.newTableName,schemaName:an.shape.schemaName})});import{z as ke}from"zod";var Oo,Io,ku,xo=N(()=>{"use strict";h();Oo=["fatal","error","warning","info","debug"],Io=ke.enum(Oo),ku=ke.object({ts:ke.string(),level:Io,rawLevel:ke.string(),source:ke.string().optional(),code:ke.string().optional(),message:ke.string(),durationMs:ke.number().optional(),statement:ke.string().optional(),detail:ke.record(ke.string(),ke.string())})});import{z as K}from"zod";var Lo,sn,Po,$o,vu,aa,Mo=N(()=>{"use strict";h();Te();Lo=K.object({columnName:K.string(),operator:K.string(),value:K.string()}),sn=["asc","desc"],Po=K.object({columnName:K.string(),direction:K.enum(sn)}),$o=K.object({limit:K.number(),total:K.number(),totalEstimated:K.boolean().optional(),hasNextPage:K.boolean(),hasPreviousPage:K.boolean(),nextCursor:K.string().nullable(),prevCursor:K.string().nullable()}),vu=K.object({data:K.array(K.record(K.string(),K.unknown())),meta:$o}),aa=K.object({db:F.shape.db,schemaName:U.shape.schemaName,cursor:K.string().optional(),limit:K.string().optional().default("50").transform(Number),direction:K.enum(sn).optional().default(sn[0]),sort:K.string().optional().transform(r=>{if(!r)return"";try{let e=JSON.parse(r);return Array.isArray(e)?e:r}catch{return r}}).pipe(K.union([K.string(),K.array(Po)])),order:K.enum(sn).optional(),filters:K.string().optional().transform(r=>{if(!r)return[];try{return JSON.parse(r)}catch{return[]}}).pipe(K.array(Lo))})});import{z as on}from"zod";var Uu,ko=N(()=>{"use strict";h();Uu=on.object({tableName:on.string("Table name is required"),schemaName:on.string().optional(),rowCount:on.coerce.number("Row count is required"),rowCountEstimated:on.boolean().optional()})});import{z as vo}from"zod";var qu,Uo=N(()=>{"use strict";h();qu=vo.object({schema:vo.string()})});import{z as ve}from"zod";var sa,qo=N(()=>{"use strict";h();sa=ve.object({tableName:ve.string("Table name is required"),primaryKey:ve.string("Primary key is required").default("id"),primaryKeys:ve.array(ve.string().min(1)).min(1).optional(),updates:ve.array(ve.object({rowData:ve.record(ve.string("Column name is required"),ve.any()),columnName:ve.string("Column name is required"),value:ve.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var Bo={};Ot(Bo,{AI_PROVIDERS:()=>zs,AI_PROVIDER_OPTIONS:()=>Gs,CONNECTION_COLORS:()=>ao,DATABASE_ENGINES:()=>W,DATABASE_TYPES:()=>xt,DataTypes:()=>L,FOREIGN_KEY_ACTIONS:()=>io,FORMAT_TYPES:()=>Eo,INDEX_KINDS:()=>So,SERVER_LOG_LEVELS:()=>Oo,StandardizedDataType:()=>T,addColumnParamSchema:()=>$l,addColumnParamsSchema:()=>Ml,addColumnSchema:()=>Fe,addRecordSchema:()=>_r,aiProviderSchema:()=>Or,alterColumnParamSchema:()=>ql,alterColumnParamsSchema:()=>Bl,alterColumnSchema:()=>Lt,bulkInsertRecordsSchema:()=>Pr,chatSchema:()=>$r,columnInfoSchema:()=>Wl,connectUrlSchema:()=>Hr,connectionColorSchema:()=>rn,connectionInfoSchema:()=>zl,connectionSummarySchema:()=>so,connectionsStateSchema:()=>Yl,createIndexParamsSchema:()=>Xl,createIndexSchema:()=>kn,createKeySchema:()=>ea,createTableSchema:()=>Yr,currentDatabaseSchema:()=>Ll,dataTypesSchema:()=>to,databaseInfoSchema:()=>po,databaseListSchema:()=>Vl,databaseSchema:()=>F,databaseTypeParamSchema:()=>Pl,databaseTypeSchema:()=>mt,dbTypeFromProtocol:()=>Ye,deleteColumnParamSchema:()=>Ee,deleteColumnParamsSchema:()=>vl,deleteColumnQuerySchema:()=>Lr,deleteColumnSuccessResponseSchema:()=>Ul,deleteKeyQuerySchema:()=>na,deleteKeyResultSchema:()=>xu,deleteRecordSchema:()=>Mn,deleteTableQuerySchema:()=>Vr,dropIndexParamSchema:()=>vn,dropIndexParamsSchema:()=>Zl,encodedRedisValueSchema:()=>q,executeQuerySchema:()=>zr,exportTableSchema:()=>Gr,fieldDataSchema:()=>co,filterSchema:()=>Lo,foreignKeyActionSchema:()=>Wr,foreignKeyDataSchema:()=>lo,getDefaultAiModel:()=>Ir,indexInfoSchema:()=>Jl,keyActionSchema:()=>ta,keyDetailsQuerySchema:()=>Xr,keyDetailsResultSchema:()=>cu,keyParamSchema:()=>kt,keyRawQuerySchema:()=>Zr,keyRawResultSchema:()=>lu,keyScanQuerySchema:()=>Qr,keyScanResultSchema:()=>eu,keyWriteResultSchema:()=>yu,mapClickhouseToDataType:()=>$n,mapDuckdbToDataType:()=>Ln,mapMssqlToDataType:()=>In,mapMysqlToDataType:()=>On,mapOracleToDataType:()=>Pn,mapPostgresToDataType:()=>_n,mapSqliteToDataType:()=>xn,redisKeySummarySchema:()=>Jr,redisKeyTypeSchema:()=>Un,redisKeyValueSchema:()=>Ro,renameColumnParamSchema:()=>Lu,renameColumnParamsSchema:()=>Pu,renameColumnSchema:()=>qn,renameTableParamSchema:()=>$u,renameTableParamsSchema:()=>Mu,renameTableSchema:()=>an,serverLogEntrySchema:()=>ku,serverLogLevelSchema:()=>Io,sortDirections:()=>sn,sortSchema:()=>Po,standardizeClickhouseDataTypeLabel:()=>Kr,standardizeDataTypeLabel:()=>kr,standardizeDuckdbDataTypeLabel:()=>Br,standardizeMssqlDataTypeLabel:()=>Ur,standardizeMysqlDataTypeLabel:()=>vr,standardizeOracleDataTypeLabel:()=>Fr,standardizeSqliteDataTypeLabel:()=>qr,standardizedDataTypeSchema:()=>no,tableDataMetaSchema:()=>$o,tableDataQuerySchema:()=>aa,tableDataResultSchema:()=>vu,tableInfoSchema:()=>Uu,tableNameSchema:()=>ce,tableQuerySchema:()=>U,tableSchemaResultSchema:()=>qu,unwrapClickhouseType:()=>$t,updateConnectionSchema:()=>jr,updateRecordsSchema:()=>sa});var z=N(()=>{"use strict";h();Ys();Vs();xr();Qs();Js();Xs();Zs();eo();ro();Mr();oo();uo();Te();mo();fo();ho();Dn();yo();go();To();wo();Co();No();Ao();Do();_o();xo();Mo();ko();Uo();qo()});var Bu,Fu,Ku,Fn,oa=N(()=>{"use strict";h();z();Bu=Object.values(W).flatMap(({protocols:r})=>r).map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),Fu=new RegExp(`\\b(?:${Bu}):\\/\\/\\S+`,"gi"),Ku=/\b(authToken=)[^&\s]+/gi,Fn=r=>r.replace(Fu,e=>`the configured database${e.match(/[),.]+$/)?.[0]??""}`).replace(Ku,"$1[redacted]")});var d,te=N(()=>{"use strict";h();d=class extends Error{constructor(t,{message:n,cause:a}={}){super(n,{cause:a});this.status=t}}});import{AsyncLocalStorage as Wu}from"async_hooks";import{randomUUID as Ko}from"crypto";var Yu,Vu,Kn,Ho,jo,ot,ia,zu,Gu,Qu,Wo,ca,fe,Q,Ve=N(()=>{"use strict";h();te();Yu=Ko(),Vu=/^[A-Za-z0-9_-]{8,64}$/,Kn=new Wu,Ho=r=>r&&Vu.test(r)?r:Ko(),jo=(r,e)=>Kn.run(r,e),ot=()=>Kn.getStore()?.requestId,ia=()=>Kn.getStore()?.connectionId,zu=r=>{let e=r instanceof d?"HTTPException":r instanceof Error?r.name:"Error";return/^[A-Za-z][A-Za-z0-9]{0,49}$/.test(e)?e:"Error"},Gu=/^[A-Z0-9_-]{2,32}$/,Qu=[[/^timeout exceeded when trying to connect$/,"POOL_ACQUIRE_TIMEOUT"],[/^(timeout expired|Connection terminated due to connection timeout)$/,"CONNECT_TIMEOUT"],[/^Connection terminated/,"CONNECTION_TERMINATED"],[/^Client has encountered a connection error/,"CONNECTION_BROKEN"]],Wo=r=>{if(!(r instanceof Error))return;let{code:e,errno:t,number:n,cause:a}=r;return typeof n=="number"&&Number.isSafeInteger(n)?String(n):typeof e=="string"&&Gu.test(e)?e:typeof e=="number"&&Number.isSafeInteger(e)?String(e):typeof t=="number"&&Number.isSafeInteger(t)?String(t):r.name==="ReplyError"?r.message.match(/^[A-Z]{3,32}(?= |$)/)?.[0]:Qu.find(([s])=>s.test(r.message))?.[1]??Wo(a)},ca=r=>r instanceof d&&r.cause?r.cause:r,fe=r=>{let e=ca(r);return{error_type:zu(e),error_code:Wo(e)}},Q=(r,e,t={})=>{let n=Kn.getStore();process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:r,event:e,instance_id:Yu,request_id:n?.requestId,operation:n?.operation,db_type:n?.dbType,...t})}
|
|
3
|
+
`)}});function Oe(r){try{let e=new URL(r);return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||Ju(e)}}catch(e){return Q("error","database_url_unparseable",fe(e)),{host:"localhost",port:5432}}}var Hn,Ju,Yo,ze=N(()=>{"use strict";h();z();Ve();Hn={cockroachdb:{driverScheme:"postgresql",defaultPort:26257},mariadb:{driverScheme:"mysql",defaultPort:3306},tidb:{driverScheme:"mysql",defaultPort:4e3}},Ju=r=>{let e=r.protocol.replace(":",""),t=Ye(e);return Hn[e]?.defaultPort??(t&&W[t].defaultPort)??5432},Yo=r=>{let e=new URL(r),t=Hn[e.protocol.replace(":","")];return t?(e.port||=String(t.defaultPort),e.protocol=t.driverScheme,e.toString()):r}});var bt,la=N(()=>{bt={name:"db-studio",type:"module",version:"1.24.0",description:"Modern database client for PostgreSQL with spreadsheet-like grid, AI-powered SQL assistance, ER diagrams, fast data browsing and editing. CLI tool, upcoming desktop & web versions.",keywords:["database client","database gui","database browser","sql client","sql editor","query tool","table editor","data editor","postgres","postgresql","postgresql client","postgresql gui","pgadmin alternative","mysql","mysql client","ai sql","er diagram","database management","database studio"],author:"H\xFCsam \u{1F951} <husam@ql3.dev>",homepage:"https://dbstudio.sh",repository:{type:"git",url:"git+https://github.com/husamql3/db-studio.git"},bugs:{url:"https://github.com/husamql3/db-studio/issues"},license:"Apache-2.0",bin:{"db-studio":"./dist/index.js"},files:["dist"],scripts:{dev:"portless run","dev:app":"NODE_ENV=development tsx watch src/index.ts",build:"tsup --minify",prepack:"cd ../web && bun run build && cd ../server && bun run build",start:`sh -c 'APP_PORT=\${PORT:-3333}; portless proxy start >/dev/null && portless alias db-studio "$APP_PORT" --force >/dev/null && HOST=127.0.0.1 PORT="$APP_PORT" DB_STUDIO_SERVER_URL=https://db-studio.localhost node dist/index.js'`,format:"biome check --write --unsafe",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage",e2e:"tsx e2e/contract.ts","e2e:perf":"tsx e2e/perf.ts","e2e:grid":"tsx e2e/grid.ts","e2e:schema-routing":"tsx e2e/schema-routing.ts","e2e:visualizer":"tsx e2e/visualizer.ts"},portless:{name:"api.db-studio",script:"dev:app"},dependencies:{"@clack/prompts":"^1.0.1","@clickhouse/client":"^1.24.0","@duckdb/node-api":"^1.5.6-r.1","@elysiajs/cors":"^1.4.2","@elysiajs/node":"^1.4.5","@libsql/client":"^0.18.0","@sentry/node":"^10.73.0",commander:"^15.0.0",dotenv:"^18.0.0",elysia:"^1.4.30",ioredis:"^6.0.0",mongodb:"^7.1.1",mssql:"^12.2.0",mysql2:"^3.18.2",open:"^11.0.0",oracledb:"^7.0.1",pg:"^8.20.0",picocolors:"^1.1.1","posthog-node":"^5.20.0",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@db-studio/shared":"workspace:*","@sentry/esbuild-plugin":"^5.4.0","@types/mssql":"^12.3.0","@types/node":"^26.0.0","@types/oracledb":"^7.0.3","@types/pg":"^8.16.0","@vitest/coverage-v8":"^5.0.0","playwright-core":"1.61.0",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^7.0.2",vitest:"^5.0.0"}}});var ti={};Ot(ti,{captureInstallationActive:()=>fa,captureServerError:()=>ha,captureServerEvent:()=>zn,databaseTypeForRequest:()=>un,durationBucket:()=>da,flushServerObservability:()=>fm,getTelemetryConfig:()=>Yn,initServerObservability:()=>ei,operationForRequest:()=>ln,outcomeForStatus:()=>pa,resetTelemetryId:()=>ma,setTelemetryEnabled:()=>Vn,startServerSpan:()=>ya});import{randomUUID as Jo}from"crypto";import{existsSync as rm,mkdirSync as am,readFileSync as sm,writeFileSync as om}from"fs";import{homedir as ua,platform as im}from"os";import jn from"path";import*as Pe from"@sentry/node";import{PostHog as cm}from"posthog-node";var lm,Xo,Wn,um,mm,dt,Tt,dm,pm,Et,cn,Yn,Vn,ma,da,pa,Zo,ln,un,ei,fm,zn,fa,hm,ha,ya,mn=N(()=>{"use strict";h();z();Ve();la();lm=()=>process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development",Xo=()=>{let r=process.env.DB_STUDIO_DATA_DIR??process.env.XDG_STATE_HOME??(process.platform==="win32"?process.env.LOCALAPPDATA:jn.join(ua(),".local","state"));return jn.join(r||jn.join(ua(),".db-studio"),"db-studio","telemetry.json")},Wn=r=>{try{let e=Xo();am(jn.dirname(e),{recursive:!0}),om(e,JSON.stringify(r),{encoding:"utf8",mode:384})}catch{}},um=()=>({installationId:Jo(),enabled:!0}),mm=()=>{let r=Xo();try{if(rm(r)){let t=JSON.parse(sm(r,"utf8"));if(typeof t.installationId=="string"&&typeof t.enabled=="boolean")return{installationId:t.installationId,enabled:t.enabled,lastActiveAt:typeof t.lastActiveAt=="string"?t.lastActiveAt:void 0}}}catch{}let e=um();return Wn(e),e},dm="https://a1e890d1105f1f27fcb1dbead71c30dd@o4509725125181440.ingest.de.sentry.io/4512040493383760",pm="phc_nxaQk54MWAehmL72J4gjVbrQCpbSTedMyHn3PvFxAhkd",Et=()=>dt??=mm(),cn=()=>!lm()&&process.env.DB_STUDIO_TELEMETRY!=="0"&&Et().enabled,Yn=()=>({enabled:cn(),installationId:Et().installationId,appVersion:bt.version}),Vn=r=>{dt={...Et(),enabled:r},Wn(dt),r?(Tt?.enable(),ei()):(Tt?.disable(),Pe.close(500))},ma=()=>(dt={...Et(),installationId:Jo(),lastActiveAt:void 0},Wn(dt),dt.installationId),da=r=>r<100?"under_100ms":r<1e3?"100ms_1s":r<5e3?"1s_5s":"over_5s",pa=r=>r>=500?"server_error":r>=400?"client_error":"success",Zo=new RegExp(`^/api/(${xt.join("|")})(?=/|$)`),ln=(r,e)=>{let t=e.replace(Zo,"/api"),a=[[/^\/api\/databases(?:\/|$)/,"databases"],[/^\/api\/tables(?:\/|$)/,"tables"],[/^\/api\/records(?:\/|$)/,"records"],[/^\/api\/query(?:\/|$)/,"query"],[/^\/api\/keys(?:\/|$)/,"keys"],[/^\/api\/chat(?:\/|$)/,"chat"]].find(([s])=>s.test(t))?.[1]??"other";return`${r.toLowerCase()}_${a}`},un=r=>r.match(Zo)?.[1],ei=()=>{if(!cn())return;let r=process.env.DB_STUDIO_SENTRY_DSN??dm;r&&(!Pe.isInitialized()||Pe.getClient()?.getOptions().enabled===!1)&&Pe.init({dsn:r,environment:process.env.NODE_ENV??"production",release:`db-studio@${bt.version}`,tracesSampleRate:.1,sendDefaultPii:!1,defaultIntegrations:!1,beforeSend(t){return delete t.request,t.user={id:Et().installationId},delete t.breadcrumbs,delete t.server_name,t},beforeSendSpan(t){return{...t,data:Object.fromEntries(Object.entries(t.data??{}).filter(([n])=>n.startsWith("db_studio.")))}}});let e=process.env.DB_STUDIO_POSTHOG_KEY??pm;e&&!Tt&&(Tt=new cm(e,{host:process.env.DB_STUDIO_POSTHOG_HOST??"https://eu.i.posthog.com",flushAt:20,flushInterval:1e4,requestTimeout:2e3}))},fm=()=>Promise.allSettled([Tt?.shutdown(2e3),Pe.close(2e3)]),zn=r=>{!cn()||!Tt||Tt.capture({distinctId:Et().installationId,event:r.event,properties:{...r.properties,source:"server",app_version:bt.version,$geoip_disable:!1}})},fa=()=>{if(!cn())return;let r=Et(),e=r.lastActiveAt?Date.parse(r.lastActiveAt):0;Date.now()-e<864e5||(dt={...r,lastActiveAt:new Date().toISOString()},Wn(dt),zn({event:"installation_active",properties:{runtime:`node-${process.versions.node.split(".")[0]}`,os:im()}}))},hm=(r,e,t)=>{let n=new Error(t);if(n.name=e,r instanceof Error&&r.stack){let a=ua(),s=r.stack.split(`
|
|
4
4
|
`).slice(1).filter(o=>/^\s*at\s/.test(o)).map(o=>o.replaceAll(a,"~"));n.stack=[`${e}: ${t}`,...s].join(`
|
|
5
|
-
`)}return n},
|
|
6
|
-
`,{mode:384}),await
|
|
5
|
+
`)}return n},ha=(r,{operation:e,status:t,dbType:n})=>{if(!cn()||t<500)return;let{error_type:a,error_code:s}=fe(r),o=ot(),i=`${e} failed with ${t}${s?` ${s}`:""}`;Pe.captureException(hm(ca(r),a,i),{tags:{operation:e,source:"server",release:bt.version,status:String(t),...n?{db_type:n}:{},error_type:a,...s?{error_code:s}:{},...o?{request_id:o}:{}},fingerprint:[e,String(t),a,s??"unknown"]})},ya=(r,e,t)=>Pe.startSpan({name:r,op:"http.server",attributes:{"db_studio.operation":r,...e?{"db_studio.db_type":e}:{}}},t)});var ni={};Ot(ni,{checkDatabaseConnection:()=>ba,getDatabaseConnectionDetails:()=>gm});var ym,ga,gm,ba,Ta=N(()=>{"use strict";h();z();ze();ym=2e3,ga=async r=>{let e;try{return await Promise.race([r,new Promise((t,n)=>{e=setTimeout(()=>n(new Error("Database startup check timed out")),ym)})])}finally{e&&clearTimeout(e)}},gm=r=>{let e=Ye(r.split("://")[0]?.toLowerCase()??"");if(!e)return null;let{label:t,defaultPort:n}=W[e];if(r.startsWith("sqlite://"))return{type:e,name:t,destination:"local file"};if(r.startsWith("d1://"))return{type:e,name:t,destination:"Cloudflare D1"};if(n===null)return{type:e,name:t,destination:new URL(r).host};let{host:a,port:s}=Oe(r);return{type:e,name:t,destination:`${a}:${s}`}},ba=async r=>{switch(r.getDbType()){case"pg":await ga(r.getPgPool().then(e=>e.query("SELECT 1")));return;case"mysql":await(await r.getMysqlPool()).query("SELECT 1");return;case"mssql":await(await r.getMssqlPool()).request().query("SELECT 1");return;case"mongodb":{await(await r.getMongoClient()).db(r.getMongoDbName()).command({ping:1});return}case"sqlite":await ga(r.getSqliteClient().then(e=>e.execute("SELECT 1")));return;case"redis":await(await r.getRedisClient()).ping();return;case"duckdb":await r.withDuckdbConnection(e=>e.run("SELECT 1"));return;case"oracle":{let e=await(await r.getOraclePool()).getConnection();await e.execute("SELECT 1 FROM dual").finally(()=>e.close());return}case"clickhouse":await ga(r.getClickhouseClient().then(e=>e.query({query:"SELECT 1"})))}}});import{randomUUID as bm}from"crypto";import{chmod as Tm,mkdir as Em,readFile as wm,rename as Sm,writeFile as Cm}from"fs/promises";import{homedir as Rm}from"os";import{basename as Nm,join as si,resolve as Am}from"path";import{z as pt}from"zod";var Dm,_m,oi,Gn,ri,ii,Om,Im,Ut,ci,xm,ai,Ea,Lm,wa,Sa,Ca,Ra,li,ui,mi,di,Na=N(()=>{"use strict";h();z();te();Dm=pt.object({id:pt.string(),name:pt.string(),url:pt.string(),color:rn.nullable(),lastUsedAt:pt.number()}),_m=pt.object({version:pt.literal(1),connections:pt.array(Dm)}),oi=()=>process.env.DB_STUDIO_CONFIG_DIR??si(Rm(),".dbstudio"),Gn=()=>si(oi(),"connections.json"),ri="\u2022\u2022\u2022\u2022",ii=/^(sqlite|duckdb):\/\/(.*)$/,Om=new Set(["authtoken","password","token"]),Im=r=>{try{return decodeURIComponent(r.replaceAll("+"," ")).toLowerCase()}catch{return r.toLowerCase()}},Ut=r=>r.replace(/^([a-z][a-z0-9+.-]*:\/\/[^:/@?#]*:)[^/?#]*@/i,`$1${ri}@`).replace(/([?&])([^=&#]*)=[^&#]*/g,(e,t,n)=>Om.has(Im(n))?`${t}${n}=${ri}`:e),ci=(r,e=process.cwd())=>{let t=r.trim(),n=t.match(ii);if(!n)return t;let[,a,s=""]=n;return s===":memory:"||s.startsWith("/")?t:`${a}://${Am(e,s)}`},xm=r=>{let e=r.match(ii);if(e)return Nm(e[2]??"")||r;try{let t=new URL(r),n=decodeURIComponent(t.pathname.replace(/^\/+|\/+$/g,""));return n?`${t.hostname}/${n}`:t.hostname}catch{return Ut(r)}},ai=r=>Ut(r),Ea=async()=>{let r;try{r=await wm(Gn(),"utf8")}catch(t){if(t.code==="ENOENT")return[];throw t}let e=_m.safeParse(JSON.parse(r));if(!e.success)throw new Error(`${Gn()} is not a valid connections file`);return e.data.connections},Lm=async r=>{let e=oi();await Em(e,{recursive:!0,mode:448}),await Tm(e,448);let t=`${Gn()}.${process.pid}.tmp`;await Cm(t,`${JSON.stringify({version:1,connections:r},null," ")}
|
|
6
|
+
`,{mode:384}),await Sm(t,Gn())},wa=Promise.resolve(),Sa=r=>{let e=wa.then(async()=>{let[t,n]=r(await Ea());return await Lm(t),n});return wa=e.catch(()=>{}),e},Ca=()=>new d(404,{message:"Saved connection not found"}),Ra=()=>wa.then(Ea,Ea),li=async r=>{let e=(await Ra()).find(t=>t.id===r);if(!e)throw Ca();return e},ui=r=>Sa(e=>{let t=e.find(a=>ai(a.url)===ai(r)),n=t?{...t,url:r,lastUsedAt:Date.now()}:{id:bm(),name:xm(r),url:r,color:null,lastUsedAt:Date.now()};return[t?e.map(a=>a.id===n.id?n:a):[...e,n],n]}),mi=(r,{name:e,color:t})=>Sa(n=>{let a=n.find(o=>o.id===r);if(!a)throw Ca();let s={...a,name:e??a.name,color:t===void 0?a.color:t};return[n.map(o=>o.id===r?s:o),s]}),di=r=>Sa(e=>{if(!e.some(t=>t.id===r))throw Ca();return[e.filter(t=>t.id!==r),void 0]})});import{statSync as Pm}from"fs";var Aa,$m,pi,Da=N(()=>{"use strict";h();Aa=r=>r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/(1024*1024)).toFixed(1)} MB`,$m=r=>{if(!r)return"in-memory";try{return Aa(Pm(r).size)}catch{return"N/A"}},pi=r=>({execute:e=>r.execute(e),batch:(e,t)=>r.batch(e,t),rebuildTable:async e=>{await r.migrate(e)},info:async()=>{let[e,t]=await Promise.all([r.execute("PRAGMA database_list"),r.execute("SELECT sqlite_version()")]),n=e.rows.find(a=>a.name==="main")?.file;return{name:"main",size:r.protocol==="file"?$m(typeof n=="string"?n:""):"N/A",version:`SQLite ${t.rows[0]?.[0]}`}},close:()=>r.close()})});var yi,Mm,km,vm,fi,hi,gi,bi=N(()=>{"use strict";h();te();Da();yi=r=>{let{host:e,pathname:t,searchParams:n}=new URL(r),a=decodeURIComponent(t.slice(1)),s=n.get("authToken")||process.env.CLOUDFLARE_API_TOKEN;if(!e)throw new Error("The Cloudflare D1 URL has no account id: put it where the host goes");if(!a)throw new Error("The Cloudflare D1 URL has no database id: put it where the path goes");if(!s)throw new Error("The Cloudflare D1 URL has no authToken parameter and CLOUDFLARE_API_TOKEN is not set");return{accountId:e,databaseId:a,token:s}},Mm=BigInt(Number.MIN_SAFE_INTEGER),km=BigInt(Number.MAX_SAFE_INTEGER),vm=r=>typeof r!="bigint"?r:r>=Mm&&r<=km?Number(r):r.toString(),fi=r=>typeof r=="string"?{sql:r,params:[]}:{sql:r.sql,params:r.args.map(vm)},hi=({results:r,meta:e})=>({columns:r.columns,rows:r.rows.map(t=>t.map(n=>Array.isArray(n)?Uint8Array.from(n).buffer:n)),rowsAffected:e.changes}),gi=({accountId:r,databaseId:e,token:t})=>{let n=`https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(r)}/d1/database/${encodeURIComponent(e)}`,a=async(o,i)=>{let c=await fetch(`${n}${o}`,{method:i===void 0?"GET":"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:i===void 0?void 0:JSON.stringify(i),signal:AbortSignal.timeout(3e4)}),l=await c.text(),u;try{u=JSON.parse(l)}catch{u=void 0}let m=u?.errors?.[0]?.message;if(c.status===401||c.status===403)throw new Error(`${m??"Cloudflare D1 refused the API token"} (HTTP status ${c.status})`);if(!u?.success||u.result===null)throw new Error(m??`Cloudflare D1 request failed with HTTP status ${c.status}`);return u.result},s=async o=>o.length?(await a("/raw",{batch:o.map(fi)})).map(hi):[];return{execute:async o=>hi((await a("/raw",fi(o)))[0]),batch:s,rebuildTable:async(o,i)=>{if(i.length){let c=i.map(u=>`"${u}"`).join(", "),l=i.length===1?"references":"reference";throw new d(400,{message:`Cloudflare D1 always enforces foreign keys, so changing a column of a table that ${c} ${l} would delete or block their rows`})}await s(o)},info:async()=>{let{name:o,file_size:i}=await a("");return{name:o,size:Aa(i),version:"Cloudflare D1"}},close:()=>{}}}});var Um,dn,Ge,je,Qe,qt,wt=N(()=>{"use strict";h();Um={pg:()=>import("pg"),mysql:()=>import("mysql2/promise"),mssql:()=>import("mssql").then(r=>r.default),mongodb:()=>import("mongodb"),sqlite:()=>import("@libsql/client"),redis:()=>import("ioredis"),duckdb:()=>import("@duckdb/node-api"),oracle:()=>import("oracledb").then(r=>r.default),clickhouse:()=>import("@clickhouse/client")},dn={},Ge=async r=>{let e=dn[r]??await Um[r]();return dn[r]=e,e},je=r=>{let e=dn[r];if(!e)throw new Error(`The ${r} driver is used before a connection opened`);return e},Qe=r=>dn.pg!==void 0&&r instanceof dn.pg.DatabaseError,qt=r=>Qe(r)&&r.code?.startsWith("23")===!0});var Wa={};Ot(Wa,{DatabaseManager:()=>Ft,closeAllDbPools:()=>Km,coerceObjectId:()=>yn,getClickhouseClient:()=>$a,getConnectionUrl:()=>Ma,getDbPool:()=>xa,getDbType:()=>St,getIsolatedRedisClient:()=>Ha,getMongoClient:()=>qa,getMongoDb:()=>Fa,getMongoDbName:()=>Ba,getMssqlPool:()=>Pa,getMysqlPool:()=>La,getOpenConnection:()=>fn,getOraclePool:()=>Ua,getRedisClient:()=>Ka,getRedisDefaultDb:()=>ja,getSqliteClient:()=>ka,isValidObjectId:()=>hn,latestConnectionId:()=>Oa,openConnection:()=>_a,requestConnectionId:()=>Ia,withDuckdbConnection:()=>va});import{resolve as qm}from"path";import{pathToFileURL as Bm}from"url";var Bt,Ft,pn,Qn,Fm,_a,fn,Oa,Ia,Ce,xa,La,Pa,$a,St,Ma,Km,ka,va,Ua,qa,Ba,Fa,Ka,Ha,ja,hn,yn,Je=N(()=>{"use strict";h();z();bi();wt();te();Ve();Da();ze();Bt=r=>{try{return decodeURIComponent(r.replace(/%(?![0-9a-fA-F]{2})/g,"%25"))}catch{return r}},Ft=class{pgPools=new Map;mysqlPools=new Map;mssqlPools=new Map;mongoClient=null;sqliteClient=null;duckdb=null;duckdbQueue=Promise.resolve();oraclePool=null;redisClients=new Map;redisClusterChecked=!1;clickhouseClients=new Map;baseConfig;constructor(e=null){this.baseConfig=e?this.parseConfig(e):null}detectDbType(e){let t=e.protocol.replace(":",""),n=Ye(t);if(n)return n;let a=Object.values(W).map(({label:s,protocols:o})=>`${s} (${o.join(", ")})`).join(", ");throw new Error(`Unsupported database type: ${t}. Supported types: ${a}.`)}parseConfig(e){let t=Ye(e.split("://")[0]);if(t&&W[t].defaultPort===null)return{url:e,host:"localhost",port:0,user:"",password:"",dbType:t};let n,a;try{n=Yo(e),a=new URL(n)}catch{throw new Error("The connection URL is not a valid URL")}let s=this.detectDbType(a);return{url:n,host:a.hostname,port:Number.parseInt(a.port,10)||(W[s].defaultPort??0),user:Bt(a.username),password:Bt(a.password),dbType:s}}config(){if(!this.baseConfig)throw new d(409,{message:"No database is connected"});return this.baseConfig}getDbType(){return this.config().dbType}getConnectionUrl(){return this.config().url}buildConnectionString(e){let t=this.config();if(W[t.dbType].defaultPort===null)return t.url;try{let n=new URL(t.url);return e&&(n.pathname=`/${encodeURIComponent(e)}`),n.toString()}catch(n){throw new Error(`Failed to build connection string for database "${e}": ${n instanceof Error?n.message:String(n)}`)}}getSqliteClient(){let{url:e,dbType:t}=this.config();if(t!=="sqlite")throw new Error("The connection is not a sqlite://, libsql:// or d1:// connection");return this.sqliteClient??=this.openSqliteClient(e).catch(n=>{throw this.sqliteClient=null,n}),this.sqliteClient}async openSqliteClient(e){if(e.startsWith("d1://"))return gi(yi(e));let t=e.startsWith("sqlite://")?e.slice(9):null,n=t===null?e:t===":memory:"?t:Bm(qm(t)).href,{createClient:a}=await Ge("sqlite"),s=a({url:n,intMode:"bigint"});return s.protocol==="file"&&(await s.execute("PRAGMA journal_mode = WAL"),await s.execute("PRAGMA foreign_keys = ON")),pi(s)}async closeSqliteClient(){let e=this.sqliteClient;this.sqliteClient=null,e&&(await e.catch(()=>null))?.close()}withDuckdbConnection(e){let t=this.duckdbQueue.then(async()=>e((await this.openDuckdb()).connection));return this.duckdbQueue=t.catch(()=>{}),t}openDuckdb(){let e=this.config();if(e.dbType!=="duckdb")throw new Error("The connection is not a duckdb:// connection");if(!this.duckdb){let t=e.url.replace(/^duckdb:\/\//,"");this.duckdb=(async()=>{try{let{DuckDBInstance:n}=await Ge("duckdb"),a=await n.create(t,{checkpoint_threshold:"0b"});return{instance:a,connection:await a.connect()}}catch(n){this.duckdb=null;let a=n instanceof Error?n.message:String(n);throw a.includes("Could not set lock on file")?new Error(`The DuckDB file "${t}" is locked by another process. Close the other program using it and try again. (${a})`):n}})()}return this.duckdb}async closeDuckdb(){let e=this.duckdb;this.duckdb=null;let t=await e?.catch(()=>null);t?.connection.closeSync(),t?.instance.closeSync()}getOraclePool(){let{url:e,host:t,port:n,user:a,password:s,dbType:o}=this.config();if(o!=="oracle")throw new Error("The connection is not an oracle:// connection");let i=decodeURIComponent(new URL(e).pathname.slice(1));return this.oraclePool??=Ge("oracle").then(c=>c.createPool({user:a,password:s,connectString:`${t}:${n}/${i}`,poolMin:0,poolMax:10,connectTimeout:5,sessionCallback:(l,u,m)=>{l.execute("ALTER SESSION SET TIME_ZONE = '+00:00'").then(()=>l.execute(`ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS.FF9' NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS.FF9TZH:TZM' NLS_NUMERIC_CHARACTERS = '.,'`)).then(()=>m(),m)}})).catch(c=>{throw this.oraclePool=null,c}),this.oraclePool}async closeOraclePool(){let e=this.oraclePool;this.oraclePool=null,await(await e?.catch(()=>null))?.close(0)}async getPgPool(e){let t=this.buildConnectionString(e),{Pool:n}=await Ge("pg");if(!this.pgPools.has(t)){let a={connectionString:t,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:1e4},s=new n({...a,onConnect:o=>o.query(`SELECT set_config(
|
|
7
7
|
'search_path',
|
|
8
8
|
COALESCE(
|
|
9
9
|
'public, ' || string_agg(quote_ident(nspname), ', ' ORDER BY nspname),
|
|
@@ -14,7 +14,7 @@ var pl=Object.defineProperty;var N=(r,e)=>()=>(r&&(e=r(r=0)),e);var Dt=(r,e)=>{f
|
|
|
14
14
|
FROM pg_namespace
|
|
15
15
|
WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'public', 'crdb_internal', 'pg_extension')
|
|
16
16
|
AND nspname NOT LIKE 'pg_toast%'
|
|
17
|
-
AND nspname NOT LIKE 'pg_temp%';`).then(()=>{},i=>{W("warn","db_search_path_widen_failed",{db_type:"pg",...ne(i)})})});s.on("error",o=>{W("error","db_pool_error",{db_type:"pg",...ne(o)})}),this.pgPools.set(t,s)}return this.pgPools.get(t)}async getMysqlPool(e){let t=this.config(),n=this.buildConnectionString(e),{createPool:a}=await ze("mysql");if(!this.mysqlPools.has(n)){let s=new URL(n),o=Ut(s.pathname.slice(1)),i=a({host:t.host,port:t.port,user:t.user,password:t.password,database:o||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(n,i)}return this.mysqlPools.get(n)}async getMssqlPool(e){let t=this.config(),n=this.buildConnectionString(e),a=await ze("mssql");if(!this.mssqlPools.has(n)){let s=new URL(n),o=Ut(s.pathname.slice(1)),i={server:t.host,port:t.port,user:t.user,password:t.password,database:o||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},c=await new a.ConnectionPool(i).connect();c.on("error",l=>{W("error","db_pool_error",{db_type:"mssql",...ne(l)})}),this.mssqlPools.set(n,c)}return this.mssqlPools.get(n)}async getClickhouseClient(e){let t=this.config(),n=new URL(this.buildConnectionString(e)),a=Ut(n.pathname.slice(1))||"default",{ClickHouseLogLevel:s,createClient:o}=await ze("clickhouse"),i=this.clickhouseClients.get(a);if(i)return i;let c=n.protocol==="clickhouses:",l=o({url:`${c?"https":"http"}://${n.hostname}:${n.port||(c?8443:8123)}`,username:t.user||"default",password:t.password,database:a,request_timeout:3e4,clickhouse_settings:{output_format_json_quote_64bit_integers:1,output_format_json_quote_decimals:1,wait_end_of_query:1},log:{level:s.OFF}});return this.clickhouseClients.set(a,l),l}getPool(e){return this.getPgPool(e)}async closePgPool(e){let t=this.pgPools.get(e);t&&(await t.end(),this.pgPools.delete(e),W("info","db_pool_closed",{db_type:"pg"}))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e),W("info","db_pool_closed",{db_type:"mysql"}))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e),W("info","db_pool_closed",{db_type:"mssql"}))}async closePool(e){if(this.baseConfig?.dbType==="sqlite"&&e===this.baseConfig.url){await this.closeSqliteClient();return}if(this.baseConfig?.dbType==="duckdb"&&e===this.baseConfig.url){await this.closeDuckdb();return}if(this.baseConfig?.dbType==="oracle"){await this.closeOraclePool();return}await this.closePgPool(e),await this.closeMysqlPool(e),await this.closeMssqlPool(e)}async closePoolByDatabase(e){if(this.baseConfig?.dbType==="sqlite"){await this.closeSqliteClient();return}if(this.baseConfig?.dbType==="duckdb"){await this.closeDuckdb();return}if(this.baseConfig?.dbType==="oracle"){await this.closeOraclePool();return}let t=this.buildConnectionString(e);await this.closePool(t)}async getMongoClient(){if(!this.mongoClient){let{url:e}=this.config(),{MongoClient:t}=await ze("mongodb"),n=new t(e);try{await n.connect(),this.mongoClient=n}catch(a){try{await n.close()}catch{}throw a}}return this.mongoClient}getMongoDbName(){return Ut(new URL(this.config().url).pathname.replace(/^\/+|\/+$/g,""))||"admin"}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){let t=this.config();if(t.dbType!=="redis")throw new Error("The connection is not a redis:// connection");let n=e??this.getRedisDefaultDb(),a=this.redisClients.get(n);if(a)return a;let s=new URL(t.url),o={host:t.host,port:t.port,db:n,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};t.user&&(o.username=t.user),t.password&&(o.password=t.password),s.protocol==="rediss:"&&(o.tls={});let{Redis:i}=await ze("redis"),c=new i(o);try{if(await c.connect(),!this.redisClusterChecked){let l=await c.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(l))throw await c.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let u=l.match(/^redis_version:([^\r\n]+)/m)?.[1],[m=0,p=0]=u?.split(".").map(Number)??[];if(m<6||m===6&&p<2)throw await c.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${u??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(l){throw await c.quit().catch(()=>{}),l}return this.redisClients.set(n,c),c}async getIsolatedRedisClient(e){let t=(await this.getRedisClient(e)).duplicate();return await t.connect(),t}getRedisDefaultDb(){if(!this.baseConfig)return 0;try{let t=new URL(this.baseConfig.url).pathname.replace(/^\//,"");if(!t)return 0;let n=Number.parseInt(t,10);return Number.isFinite(n)?n:0}catch{return 0}}async closeAll(){let e=Array.from(this.pgPools.values()).map(async s=>{await s.end(),W("info","db_pool_closed",{db_type:"pg"})}),t=Array.from(this.mysqlPools.values()).map(async s=>{await s.end(),W("info","db_pool_closed",{db_type:"mysql"})}),n=Array.from(this.mssqlPools.values()).map(async s=>{await s.close(),W("info","db_pool_closed",{db_type:"mssql"})});await Promise.all([...e,...t,...n]),this.pgPools.clear(),this.mysqlPools.clear(),this.mssqlPools.clear(),this.mongoClient&&(await this.mongoClient.close(),this.mongoClient=null),await this.closeSqliteClient(),await this.closeDuckdb(),await this.closeOraclePool();let a=Array.from(this.redisClients.values()).map(async s=>{await s.quit().catch(()=>{}),W("info","db_pool_closed",{db_type:"redis"})});await Promise.all(a),this.redisClients.clear(),this.redisClusterChecked=!1,await Promise.all(Array.from(this.clickhouseClients.values()).map(s=>s.close())),this.clickhouseClients.clear()}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys()),...Array.from(this.mssqlPools.keys())]}},fe=new qt,Sa=async r=>{let e=fe;fe=r,await e.closeAll()},Ca=r=>fe.getPgPool(r),Ra=r=>fe.getMysqlPool(r),Na=async r=>fe.getMssqlPool(r),Aa=r=>fe.getClickhouseClient(r),ot=()=>fe.getDbType(),Da=()=>fe.getConnectionUrl(),xm=async()=>fe.closeAll(),_a=()=>fe.getSqliteClient(),Oa=r=>fe.withDuckdbConnection(r),Ia=()=>fe.getOraclePool(),xa=()=>fe.getMongoClient(),La=()=>fe.getMongoDbName(),Pa=r=>fe.getMongoDb(r),$a=r=>fe.getRedisClient(r),Ma=r=>fe.getIsolatedRedisClient(r),ka=()=>fe.getRedisDefaultDb(),un=r=>typeof r=="string"&&Ke("mongodb").ObjectId.isValid(r),mn=r=>{let{ObjectId:e}=Ke("mongodb");return typeof r=="string"&&e.isValid(r)?new e(r):r}});var pi={};Dt(pi,{connect:()=>Yn,connectSaved:()=>Ba,getConnectionId:()=>qa,getConnectionsState:()=>dn,summarize:()=>Fa});import{randomUUID as Lm}from"crypto";import{access as Pm}from"fs/promises";var Ua,Wn,ui,$m,mi,qa,Mm,Yn,Ba,di,dn,Fa,Vn=N(()=>{"use strict";y();G();pa();ea();Ta();it();te();Ye();Ua=null,Wn=null,ui=Promise.resolve(),$m=/^(?:sqlite|duckdb):\/\/(.+)$/,mi=r=>vn(r instanceof Error?r.message:String(r)),qa=()=>Wn,Mm=async r=>{if(r===Ua)return;let e;try{e=new qt(r)}catch(n){throw new d(400,{message:mi(n),cause:n})}try{await da(e)}catch(n){throw await e.closeAll().catch(()=>{}),new d(400,{message:`Could not connect: ${mi(n)}`,cause:n})}let t=Sa(e);Ua=r,Wn=Lm(),await t.catch(n=>{W("warn","connection_close_failed",ne(n))})},Yn=(r,{requireExistingFile:e=!1}={})=>{let t=Zo(r),n=ui.then(async()=>{let a=t.match($m)?.[1];e&&a&&a!==":memory:"&&await Pm(a).catch(()=>{throw new d(400,{message:`No database file at ${a}`})}),await Mm(t);try{return await ti(t)}catch(s){return W("warn","connection_save_failed",ne(s)),null}});return ui=n.catch(()=>{}),n},Ba=async r=>{let e=await ei(r);return Yn(e.url,{requireExistingFile:!0})},di=r=>{let e=We(r.url.split("://")[0]?.toLowerCase()??"");if(!e)return null;let{id:t,name:n,color:a,lastUsedAt:s}=r;return{id:t,name:n,color:a,lastUsedAt:s,dbType:e,maskedUrl:kt(r.url)}},dn=async()=>{let r=await ba(),e=r.map(di).filter(n=>n!==null).sort((n,a)=>a.lastUsedAt-n.lastUsedAt),t=Ua;return{connections:e,active:t&&Wn?{id:r.find(n=>kt(n.url)===kt(t))?.id??null,dbType:ot(),connectionId:Wn}:null}},Fa=r=>{let e=di(r);if(!e)throw new d(500,{message:"Saved connection has an unknown engine"});return e}});function Bt(r){return ge.get(r)}function fi(r,e){if(!km(r))throw new d(400,{message:`Key browsing is not supported for database type: "${e}"`});return r}var Ka,ge,km,Ct=N(()=>{"use strict";y();te();Ka=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new d(400,{message:`Unsupported database type: "${e}". Supported types: ${this.getSupportedTypes().join(", ")}`});return t}has(e){return this.adapters.has(e)}getSupportedTypes(){return[...this.adapters.keys()]}},ge=new Ka;km=r=>"scanKeys"in r&&typeof r.scanKeys=="function"});function ue(r){throw new d(501,{message:`${r} is not implemented for this database type`})}function vm(){throw new d(400,{message:"Server logs are not supported for this database type"})}function Ha(){throw new d(400,{message:"Indexes are not supported for this database type"})}var ct,se,Qe=N(()=>{"use strict";y();St();te();ct=5e4;se=class{assertDeletableKey(e){if(e.length>1)throw new d(400,{message:"Deleting rows from tables with a composite primary key is not supported yet."})}wrapError(e){if(e instanceof d)return e;if(e instanceof Error){let t=e,n=t.code??e.cause?.code;return n==="ECONNREFUSED"||n==="ENOTFOUND"||n==="ETIMEDOUT"||n==="ER_ACCESS_DENIED_ERROR"||n==="ER_BAD_HOST_ERROR"||n==="ECONNRESET"||t.errno===1045||t.errno===2003||t.errno===2002||e.message.includes("ECONNREFUSED")||e.message.includes("connection refused")||e.message.includes("timeout expired")||e.message.includes("Connection terminated")||e.message.includes("MongoNetworkError")||e.message.includes("MongoServerSelectionError")||e.message.includes("Login failed")||/HTTP status (401|403)\b/.test(e.message)||e.message.startsWith("NOAUTH")||e.message.startsWith("WRONGPASS")||e.message.startsWith("LOADING")||e.message.startsWith("BUSY")||e.message.startsWith("READONLY")||e.message.startsWith("CLUSTERDOWN")||e.message.includes("Redis cluster mode is not supported")||e.message.includes("Could not set lock on file")||/^(ORA-(01017|03113|03114|03135|12170|12505|12514|12541|28000)|NJS-5(00|01|03|10|11|18|21)):/.test(e.message)||e.message.includes("Authentication failed: password is incorrect")||e.message==="Timeout error."||Ge(e)&&e.code?.startsWith("08")?new d(503,{message:e.message,cause:e}):Ge(e)&&e.code==="42501"?new d(403,{message:e.message,cause:e}):new d(500,{message:e.message,cause:e})}return new d(500,{message:"Internal server error",cause:e})}resolveKeyColumns(e){return e.primaryKeys?.length?e.primaryKeys:[e.primaryKey]}assertWholeKey(e,t){let n=e.filter(a=>!t.includes(a));if(n.length>0)throw new d(400,{message:`Updates must match on every primary key column; missing: ${n.join(", ")}`})}groupUpdatesByKey(e,t){let n=new Map;for(let a of e.updates){let s=t.map(c=>{let l=a.rowData[c];if(l==null)throw new d(400,{message:`Primary key "${c}" not found in row data.`});return l}),o=JSON.stringify(s.map(c=>String(c))),i=n.get(o)??{keyValues:s,rowUpdates:[]};i.rowUpdates.push({columnName:a.columnName,value:a.value}),n.set(o,i)}return[...n.values()]}orderTerms(e=[],t,n){let a=typeof e=="string"?e?[{columnName:e,direction:t}]:[]:e,s=a[0]?.direction??t;return[...a.map(o=>({column:o.columnName,direction:o.direction})),...n.filter(o=>!a.some(i=>i.columnName===o)).map(o=>({column:o,direction:s}))]}describeKey(e,t){return e.map((n,a)=>`${n} = ${t[a]}`).join(", ")}assertDifferentTableName(e,t){if(e===t)throw new d(400,{message:`New table name must be different from "${e}"`})}encodeCursor(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}decodeCursor(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}normalizeRow(e){let t={};for(let[n,a]of Object.entries(e))t[n]=a;return t}async getTableData(e){try{let{db:t,limit:n=50,direction:a="asc"}=e,s=this.buildTableDataQuery(e),[o,i]=await Promise.all([this.runQuery(t,s.countSql,s.countValues),this.runQuery(t,s.sql,s.values)]),c=Number(o[0]?.total??0),l=i.length>n,u=l?i.slice(0,n):i,m=this.normalizeRows(u);a==="desc"&&(m=m.reverse());let{nextCursor:p,prevCursor:f}=this.buildCursors(e,m,l);return{data:m,meta:{limit:n,total:c,hasNextPage:a==="asc"?l:!!e.cursor,hasPreviousPage:a==="asc"?!!e.cursor:l,nextCursor:p,prevCursor:f}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let n=`SELECT * FROM ${this.quoteIdentifier(e)}`,a=await this.runQuery(t,n,[]);if(!a||a.length===0)throw new d(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(a[0]),rows:a}}catch(n){throw this.wrapError(n)}}getDatabasesList(){return ue("getDatabasesList")}getCurrentDatabase(){return ue("getCurrentDatabase")}getDatabaseConnectionInfo(){return ue("getDatabaseConnectionInfo")}getTablesList(e){return ue("getTablesList")}createTable(e){return ue("createTable")}deleteTable(e){return ue("deleteTable")}renameTable(e){return ue("renameTable")}getTableSchema(e){return ue("getTableSchema")}getTableColumns(e){return ue("getTableColumns")}addColumn(e){return ue("addColumn")}deleteColumn(e){return ue("deleteColumn")}alterColumn(e){return ue("alterColumn")}renameColumn(e){return ue("renameColumn")}getTableIndexes(e){return Ha()}createIndex(e){return Ha()}dropIndex(e){return Ha()}getServerLogs(e){return vm()}addRecord(e){return ue("addRecord")}updateRecords(e){return ue("updateRecords")}deleteRecords(e){return ue("deleteRecords")}forceDeleteRecords(e){return ue("forceDeleteRecords")}bulkInsertRecords(e){return ue("bulkInsertRecords")}executeQuery(e){return ue("executeQuery")}}});var Q,H,K,J,ja,Wa,zn,Gn,re,Re,Qn,Rt,Ft,ke,Je=N(()=>{"use strict";y();it();Q=r=>Ca(r),H=r=>Ra(r),K=r=>Na(r),J=()=>_a(),ja=r=>Oa(r),Wa=()=>Ia(),zn=()=>xa(),Gn=()=>La(),re=r=>Pa(r),Re=r=>$a(r),Qn=r=>Ma(r),Rt=()=>ka(),Ft=r=>Aa(r),ke=()=>Da()});var Le,ae,_e,he,lt=N(()=>{"use strict";y();Le="/* db-studio:server-logs */",ae=r=>({available:!1,reason:r}),_e=r=>r.sort((e,t)=>e.ts.localeCompare(t.ts)).slice(-500),he=r=>Object.fromEntries(Object.entries(r).filter(([,e])=>e!=null&&e!=="").map(([e,t])=>[e,typeof t=="string"?t:JSON.stringify(t)]))});function yi(r){let e=[],t=[],n=a=>(t.push(a),`{p${t.length-1}:String}`);for(let{columnName:a,operator:s,value:o}of r){let i=Ya(a);switch(s){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${i} ${s} ${n(o)}`);break;case"is":e.push(o.toLowerCase()==="null"?`${i} IS NULL`:`${i} = ${n(o)}`);break;case"is not":e.push(o.toLowerCase()==="null"?`${i} IS NOT NULL`:`${i} != ${n(o)}`);break;case"like":e.push(`toString(${i}) LIKE ${n(o)}`);break;case"not like":e.push(`toString(${i}) NOT LIKE ${n(o)}`);break;case"ilike":e.push(`toString(${i}) ILIKE ${n(o)}`);break;case"not ilike":e.push(`toString(${i}) NOT ILIKE ${n(o)}`);break}}return{clause:e.length?`WHERE ${e.join(" AND ")}`:"",values:t}}function hi(r,e,t){let n=Array.isArray(r)?r:r?[{columnName:r,direction:e}]:[],a=(n[0]?.direction??e).toUpperCase(),s=[...n.map(o=>`${Ya(o.columnName)} ${o.direction.toUpperCase()}`),...t.map(o=>`${o} ${a}`)];return s.length?`ORDER BY ${s.join(", ")}`:""}function Um(r,e,t){let a={smallserial:"UInt16",serial2:"UInt16",serial:"UInt32",serial4:"UInt32",bigserial:"UInt64",serial8:"UInt64",tinyint:"Int8",smallint:"Int16",int2:"Int16",int:"Int32",int4:"Int32",integer:"Int32",bigint:"Int64",int8:"Int64",numeric:"Decimal(38, 10)",decimal:"Decimal(38, 10)",money:"Decimal(19, 4)",real:"Float32",float4:"Float32",float:"Float64",float8:"Float64","double precision":"Float64",boolean:"Bool",bool:"Bool",text:"String",varchar:"String","character varying":"String",char:"String",character:"String",bpchar:"String",citext:"String",uuid:"UUID",json:t?"JSON":"String",jsonb:t?"JSON":"String",xml:"String",date:"Date32",time:"String","time without time zone":"String",timestamp:"DateTime64(6)","timestamp without time zone":"DateTime64(6)",timestamptz:"DateTime64(6, 'UTC')","timestamp with time zone":"DateTime64(6, 'UTC')",interval:"String",bytea:"String",inet:"String",cidr:"String",macaddr:"String",macaddr8:"String"}[r.toLowerCase().trim()]??r.trim();return e?`Array(${a})`:a}function Jn(r,e){let t=Ya(r.columnName);if(r.isIdentity||/serial/i.test(r.columnType))return`${t} UInt64 DEFAULT generateSnowflakeID()`;let n=Um(r.columnType,r.isArray??!1,e),a=r.isNullable&&!r.isPrimaryKey&&!r.isArray,s=`${t} ${a?`Nullable(${n})`:n}`,o=r.defaultValue?.trim();return o&&(s+=` DEFAULT ${qm[o.toLowerCase()]??o}`),s}var oe,Ya,qm,gi=N(()=>{"use strict";y();oe=r=>`\`${r.replaceAll("\\","\\\\").replaceAll("`","\\`")}\``,Ya=oe;qm={"now()":"now()",current_timestamp:"now()","current_timestamp()":"now()",current_date:"today()","gen_random_uuid()":"generateUUIDv4()","uuid_generate_v4()":"generateUUIDv4()"}});import{ClickHouseError as bi}from"@clickhouse/client";var Bm,Ti,Fm,Km,Xn,Ei=N(()=>{"use strict";y();G();Qe();Je();lt();te();Ve();gi();Bm={mutations_sync:"2"},Ti=r=>/^(LowCardinality\()?Nullable\(/.test(r),Fm=(r,e)=>{if(r==null)return null;let t=Lt(e);if(r===""&&t!=="String"&&!t.startsWith("FixedString"))return null;if(r instanceof Date)return r.toISOString();if(t==="Bool"&&typeof r=="string")return["true","t","1","yes","on"].includes(r.trim().toLowerCase());if(typeof r=="string"&&(t.startsWith("JSON")||t.startsWith("Array(")||t.startsWith("Map(")))try{return JSON.parse(r)}catch{throw new d(400,{message:`Invalid ${t} value: ${r}`})}return typeof r=="object"&&t==="String"?JSON.stringify(r):r},Km={Fatal:"fatal",Critical:"fatal",Error:"error",Warning:"warning"},Xn=class extends se{serverVersion=null;async runQuery(e,t,n){let a=Object.fromEntries(n.map((s,o)=>[`p${o}`,s]));return await this.select(e,t,a)}quoteIdentifier(e){return oe(e)}mapToUniversalType(e){return In(e)}mapFromUniversalType(e){return{text:"String",number:"Int64",boolean:"Bool",json:"String",date:"DateTime",array:"Array(String)",enum:"String"}[e]??"String"}buildTableDataQuery(e){return this.buildPageQuery(e,[])}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,n){let{cursor:a,limit:s=50}=e,o=a?this.decodeOffsetCursor(a):0;return{nextCursor:n?this.makeCursor(o+s):null,prevCursor:o>0?this.makeCursor(Math.max(0,o-s)):null}}async getTableData(e){try{let{db:t,tableName:n,limit:a=50,cursor:s}=e,o=await this.getTable(t,n),i=o.sorting_key?[`(${o.sorting_key})`]:[];o.engine.endsWith("MergeTree")&&i.push("_part","_part_offset");let c=this.buildPageQuery(e,i),[l,u]=await Promise.all([this.runQuery(t,c.countSql,c.countValues),this.runQuery(t,c.sql,c.values)]),m=u.length>a,p=this.normalizeRows(m?u.slice(0,a):u),f=s?this.decodeOffsetCursor(s):0;return{data:p,meta:{limit:a,total:Number(l[0]?.total??0),hasNextPage:m,hasPreviousPage:f>0,...this.buildCursors(e,p,m)}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{return(await this.select(void 0,`SELECT d.name AS name, formatReadableSize(p.bytes) AS size
|
|
17
|
+
AND nspname NOT LIKE 'pg_temp%';`).then(()=>{},i=>{Q("warn","db_search_path_widen_failed",{db_type:"pg",...fe(i)})})});s.on("error",o=>{Q("error","db_pool_error",{db_type:"pg",...fe(o)})}),this.pgPools.set(t,s)}return this.pgPools.get(t)}async getMysqlPool(e){let t=this.config(),n=this.buildConnectionString(e),{createPool:a}=await Ge("mysql");if(!this.mysqlPools.has(n)){let s=new URL(n),o=Bt(s.pathname.slice(1)),i=a({host:t.host,port:t.port,user:t.user,password:t.password,database:o||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(n,i)}return this.mysqlPools.get(n)}async getMssqlPool(e){let t=this.config(),n=this.buildConnectionString(e),a=await Ge("mssql");if(!this.mssqlPools.has(n)){let s=new URL(n),o=Bt(s.pathname.slice(1)),i={server:t.host,port:t.port,user:t.user,password:t.password,database:o||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},c=await new a.ConnectionPool(i).connect();c.on("error",l=>{Q("error","db_pool_error",{db_type:"mssql",...fe(l)})}),this.mssqlPools.set(n,c)}return this.mssqlPools.get(n)}async getClickhouseClient(e){let t=this.config(),n=new URL(this.buildConnectionString(e)),a=Bt(n.pathname.slice(1))||"default",{ClickHouseLogLevel:s,createClient:o}=await Ge("clickhouse"),i=this.clickhouseClients.get(a);if(i)return i;let c=n.protocol==="clickhouses:",l=o({url:`${c?"https":"http"}://${n.hostname}:${n.port||(c?8443:8123)}`,username:t.user||"default",password:t.password,database:a,request_timeout:3e4,clickhouse_settings:{output_format_json_quote_64bit_integers:1,output_format_json_quote_decimals:1,wait_end_of_query:1},log:{level:s.OFF}});return this.clickhouseClients.set(a,l),l}getPool(e){return this.getPgPool(e)}async closePgPool(e){let t=this.pgPools.get(e);t&&(await t.end(),this.pgPools.delete(e),Q("info","db_pool_closed",{db_type:"pg"}))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e),Q("info","db_pool_closed",{db_type:"mysql"}))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e),Q("info","db_pool_closed",{db_type:"mssql"}))}async closePool(e){if(this.baseConfig?.dbType==="sqlite"&&e===this.baseConfig.url){await this.closeSqliteClient();return}if(this.baseConfig?.dbType==="duckdb"&&e===this.baseConfig.url){await this.closeDuckdb();return}if(this.baseConfig?.dbType==="oracle"){await this.closeOraclePool();return}await this.closePgPool(e),await this.closeMysqlPool(e),await this.closeMssqlPool(e)}async closePoolByDatabase(e){if(this.baseConfig?.dbType==="sqlite"){await this.closeSqliteClient();return}if(this.baseConfig?.dbType==="duckdb"){await this.closeDuckdb();return}if(this.baseConfig?.dbType==="oracle"){await this.closeOraclePool();return}let t=this.buildConnectionString(e);await this.closePool(t)}async getMongoClient(){if(!this.mongoClient){let{url:e}=this.config(),{MongoClient:t}=await Ge("mongodb"),n=new t(e);try{await n.connect(),this.mongoClient=n}catch(a){try{await n.close()}catch{}throw a}}return this.mongoClient}getMongoDbName(){return Bt(new URL(this.config().url).pathname.replace(/^\/+|\/+$/g,""))||"admin"}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){let t=this.config();if(t.dbType!=="redis")throw new Error("The connection is not a redis:// connection");let n=e??this.getRedisDefaultDb(),a=this.redisClients.get(n);if(a)return a;let s=new URL(t.url),o={host:t.host,port:t.port,db:n,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};t.user&&(o.username=t.user),t.password&&(o.password=t.password),s.protocol==="rediss:"&&(o.tls={});let{Redis:i}=await Ge("redis"),c=new i(o);try{if(await c.connect(),!this.redisClusterChecked){let l=await c.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(l))throw await c.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let u=l.match(/^redis_version:([^\r\n]+)/m)?.[1],[m=0,p=0]=u?.split(".").map(Number)??[];if(m<6||m===6&&p<2)throw await c.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${u??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(l){throw await c.quit().catch(()=>{}),l}return this.redisClients.set(n,c),c}async getIsolatedRedisClient(e){let t=(await this.getRedisClient(e)).duplicate();return await t.connect(),t}getRedisDefaultDb(){if(!this.baseConfig)return 0;try{let t=new URL(this.baseConfig.url).pathname.replace(/^\//,"");if(!t)return 0;let n=Number.parseInt(t,10);return Number.isFinite(n)?n:0}catch{return 0}}async closeAll(){let e=Array.from(this.pgPools.values()).map(async s=>{await s.end(),Q("info","db_pool_closed",{db_type:"pg"})}),t=Array.from(this.mysqlPools.values()).map(async s=>{await s.end(),Q("info","db_pool_closed",{db_type:"mysql"})}),n=Array.from(this.mssqlPools.values()).map(async s=>{await s.close(),Q("info","db_pool_closed",{db_type:"mssql"})});await Promise.all([...e,...t,...n]),this.pgPools.clear(),this.mysqlPools.clear(),this.mssqlPools.clear(),this.mongoClient&&(await this.mongoClient.close(),this.mongoClient=null),await this.closeSqliteClient(),await this.closeDuckdb(),await this.closeOraclePool();let a=Array.from(this.redisClients.values()).map(async s=>{await s.quit().catch(()=>{}),Q("info","db_pool_closed",{db_type:"redis"})});await Promise.all(a),this.redisClients.clear(),this.redisClusterChecked=!1,await Promise.all(Array.from(this.clickhouseClients.values()).map(s=>s.close())),this.clickhouseClients.clear()}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys()),...Array.from(this.mssqlPools.keys())]}},pn=new Map,Qn=null,Fm=new Ft,_a=(r,e)=>{pn.set(r,e),Qn=r},fn=r=>pn.get(r),Oa=()=>Qn,Ia=()=>{let r=ia();return r&&pn.has(r)?r:Qn},Ce=()=>pn.get(ia()??Qn??"")??Fm,xa=r=>Ce().getPgPool(r),La=r=>Ce().getMysqlPool(r),Pa=async r=>Ce().getMssqlPool(r),$a=r=>Ce().getClickhouseClient(r),St=()=>Ce().getDbType(),Ma=()=>Ce().getConnectionUrl(),Km=async()=>{await Promise.all([...pn.values()].map(r=>r.closeAll()))},ka=()=>Ce().getSqliteClient(),va=r=>Ce().withDuckdbConnection(r),Ua=()=>Ce().getOraclePool(),qa=()=>Ce().getMongoClient(),Ba=()=>Ce().getMongoDbName(),Fa=r=>Ce().getMongoDb(r),Ka=r=>Ce().getRedisClient(r),Ha=r=>Ce().getIsolatedRedisClient(r),ja=()=>Ce().getRedisDefaultDb(),hn=r=>typeof r=="string"&&je("mongodb").ObjectId.isValid(r),yn=r=>{let{ObjectId:e}=je("mongodb");return typeof r=="string"&&e.isValid(r)?new e(r):r}});var Si={};Ot(Si,{connect:()=>Jn,connectSaved:()=>Va,getConnectionsState:()=>gn,summarize:()=>za});import{randomUUID as Hm}from"crypto";import{access as jm}from"fs/promises";var Ti,Ya,Wm,Ei,Ym,Jn,Va,wi,gn,za,Ga=N(()=>{"use strict";h();z();Ta();oa();Na();Je();te();Ve();Ti=Promise.resolve(),Ya=new Map,Wm=/^(?:sqlite|duckdb):\/\/(.+)$/,Ei=r=>Fn(r instanceof Error?r.message:String(r)),Ym=async r=>{let e=[...Ya].find(([,a])=>a===r)?.[0];if(e)return e;let t;try{t=new Ft(r)}catch(a){throw new d(400,{message:Ei(a),cause:a})}try{await ba(t)}catch(a){throw await t.closeAll().catch(()=>{}),new d(400,{message:`Could not connect: ${Ei(a)}`,cause:a})}let n=Hm();return _a(n,t),Ya.set(n,r),n},Jn=(r,{requireExistingFile:e=!1}={})=>{let t=ci(r),n=Ti.then(async()=>{let a=t.match(Wm)?.[1];e&&a&&a!==":memory:"&&await jm(a).catch(()=>{throw new d(400,{message:`No database file at ${a}`})});let s=await Ym(t);return await ui(t).catch(o=>{Q("warn","connection_save_failed",fe(o))}),s});return Ti=n.catch(()=>{}),n},Va=async r=>{let e=await li(r);return Jn(e.url,{requireExistingFile:!0})},wi=r=>{let e=Ye(r.url.split("://")[0]?.toLowerCase()??"");if(!e)return null;let{id:t,name:n,color:a,lastUsedAt:s}=r;return{id:t,name:n,color:a,lastUsedAt:s,dbType:e,maskedUrl:Ut(r.url)}},gn=async(r=Ia())=>{let e=await Ra(),t=e.map(wi).filter(s=>s!==null).sort((s,o)=>o.lastUsedAt-s.lastUsedAt),n=r&&Ya.get(r),a=r&&fn(r);return!r||!n||!a?{connections:t,active:null}:{connections:t,active:{id:e.find(s=>Ut(s.url)===Ut(n))?.id??null,dbType:a.getDbType(),connectionId:r}}},za=r=>{let e=wi(r);if(!e)throw new d(500,{message:"Saved connection has an unknown engine"});return e}});function Kt(r){return ye.get(r)}function Ci(r,e){if(!Vm(r))throw new d(400,{message:`Key browsing is not supported for database type: "${e}"`});return r}var Qa,ye,Vm,Ct=N(()=>{"use strict";h();te();Qa=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new d(400,{message:`Unsupported database type: "${e}". Supported types: ${this.getSupportedTypes().join(", ")}`});return t}has(e){return this.adapters.has(e)}getSupportedTypes(){return[...this.adapters.keys()]}},ye=new Qa;Vm=r=>"scanKeys"in r&&typeof r.scanKeys=="function"});function ue(r){throw new d(501,{message:`${r} is not implemented for this database type`})}function zm(){throw new d(400,{message:"Server logs are not supported for this database type"})}function Ja(){throw new d(400,{message:"Indexes are not supported for this database type"})}var it,ae,Xe=N(()=>{"use strict";h();wt();te();it=5e4;ae=class{assertDeletableKey(e){if(e.length>1)throw new d(400,{message:"Deleting rows from tables with a composite primary key is not supported yet."})}wrapError(e){if(e instanceof d)return e;if(e instanceof Error){let t=e,n=t.code??e.cause?.code,a=e.number;return Qe(e)&&e.code==="42501"||e.name==="RequestError"&&(a===229||a===230)?new d(403,{message:e.message,cause:e}):n==="ECONNREFUSED"||n==="ENOTFOUND"||n==="ETIMEDOUT"||n==="ER_ACCESS_DENIED_ERROR"||n==="ER_BAD_HOST_ERROR"||n==="ECONNRESET"||t.errno===1045||t.errno===2003||t.errno===2002||e.message.includes("ECONNREFUSED")||e.message.includes("connection refused")||e.message.includes("timeout expired")||e.message.includes("Connection terminated")||e.message.includes("MongoNetworkError")||e.message.includes("MongoServerSelectionError")||e.message.includes("Login failed")||/HTTP status (401|403)\b/.test(e.message)||e.message.startsWith("NOAUTH")||e.message.startsWith("WRONGPASS")||e.message.startsWith("LOADING")||e.message.startsWith("BUSY")||e.message.startsWith("READONLY")||e.message.startsWith("CLUSTERDOWN")||e.message.includes("Redis cluster mode is not supported")||e.message.includes("Could not set lock on file")||/^(ORA-(01017|03113|03114|03135|12170|12505|12514|12541|28000)|NJS-5(00|01|03|10|11|18|21)):/.test(e.message)||e.message.includes("Authentication failed: password is incorrect")||e.message==="Timeout error."||Qe(e)&&e.code?.startsWith("08")?new d(503,{message:e.message,cause:e}):new d(500,{message:e.message,cause:e})}return new d(500,{message:"Internal server error",cause:e})}resolveKeyColumns(e){return e.primaryKeys?.length?e.primaryKeys:[e.primaryKey]}assertWholeKey(e,t){let n=e.filter(a=>!t.includes(a));if(n.length>0)throw new d(400,{message:`Updates must match on every primary key column; missing: ${n.join(", ")}`})}groupUpdatesByKey(e,t){let n=new Map;for(let a of e.updates){let s=t.map(c=>{let l=a.rowData[c];if(l==null)throw new d(400,{message:`Primary key "${c}" not found in row data.`});return l}),o=JSON.stringify(s.map(c=>String(c))),i=n.get(o)??{keyValues:s,rowUpdates:[]};i.rowUpdates.push({columnName:a.columnName,value:a.value}),n.set(o,i)}return[...n.values()]}orderTerms(e=[],t,n){let a=typeof e=="string"?e?[{columnName:e,direction:t}]:[]:e,s=a[0]?.direction??t;return[...a.map(o=>({column:o.columnName,direction:o.direction})),...n.filter(o=>!a.some(i=>i.columnName===o)).map(o=>({column:o,direction:s}))]}describeKey(e,t){return e.map((n,a)=>`${n} = ${t[a]}`).join(", ")}assertDifferentTableName(e,t){if(e===t)throw new d(400,{message:`New table name must be different from "${e}"`})}encodeCursor(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}decodeCursor(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}normalizeRow(e){let t={};for(let[n,a]of Object.entries(e))t[n]=a;return t}async getTableData(e){try{let{db:t,limit:n=50,direction:a="asc"}=e,s=this.buildTableDataQuery(e),[o,i]=await Promise.all([this.runQuery(t,s.countSql,s.countValues),this.runQuery(t,s.sql,s.values)]),c=Number(o[0]?.total??0),l=i.length>n,u=l?i.slice(0,n):i,m=this.normalizeRows(u);a==="desc"&&(m=m.reverse());let{nextCursor:p,prevCursor:f}=this.buildCursors(e,m,l);return{data:m,meta:{limit:n,total:c,hasNextPage:a==="asc"?l:!!e.cursor,hasPreviousPage:a==="asc"?!!e.cursor:l,nextCursor:p,prevCursor:f}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let n=`SELECT * FROM ${this.quoteIdentifier(e)}`,a=await this.runQuery(t,n,[]);if(!a||a.length===0)throw new d(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(a[0]),rows:a}}catch(n){throw this.wrapError(n)}}getDatabasesList(){return ue("getDatabasesList")}getCurrentDatabase(){return ue("getCurrentDatabase")}getDatabaseConnectionInfo(){return ue("getDatabaseConnectionInfo")}getTablesList(e){return ue("getTablesList")}createTable(e){return ue("createTable")}deleteTable(e){return ue("deleteTable")}renameTable(e){return ue("renameTable")}getTableSchema(e){return ue("getTableSchema")}getTableColumns(e){return ue("getTableColumns")}addColumn(e){return ue("addColumn")}deleteColumn(e){return ue("deleteColumn")}alterColumn(e){return ue("alterColumn")}renameColumn(e){return ue("renameColumn")}getTableIndexes(e){return Ja()}createIndex(e){return Ja()}dropIndex(e){return Ja()}getServerLogs(e){return zm()}addRecord(e){return ue("addRecord")}updateRecords(e){return ue("updateRecords")}deleteRecords(e){return ue("deleteRecords")}forceDeleteRecords(e){return ue("forceDeleteRecords")}bulkInsertRecords(e){return ue("bulkInsertRecords")}executeQuery(e){return ue("executeQuery")}}});var G,j,H,J,Xa,Za,Xn,Zn,ne,Re,er,Rt,Nt,Ue,Ze=N(()=>{"use strict";h();Je();G=r=>xa(r),j=r=>La(r),H=r=>Pa(r),J=()=>ka(),Xa=r=>va(r),Za=()=>Ua(),Xn=()=>qa(),Zn=()=>Ba(),ne=r=>Fa(r),Re=r=>Ka(r),er=r=>Ha(r),Rt=()=>ja(),Nt=r=>$a(r),Ue=()=>Ma()});var $e,re,Ie,he,ct=N(()=>{"use strict";h();$e="/* db-studio:server-logs */",re=r=>({available:!1,reason:r}),Ie=r=>r.sort((e,t)=>e.ts.localeCompare(t.ts)).slice(-500),he=r=>Object.fromEntries(Object.entries(r).filter(([,e])=>e!=null&&e!=="").map(([e,t])=>[e,typeof t=="string"?t:JSON.stringify(t)]))});function Ri(r){let e=[],t=[],n=a=>(t.push(a),`{p${t.length-1}:String}`);for(let{columnName:a,operator:s,value:o}of r){let i=es(a);switch(s){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${i} ${s} ${n(o)}`);break;case"is":e.push(o.toLowerCase()==="null"?`${i} IS NULL`:`${i} = ${n(o)}`);break;case"is not":e.push(o.toLowerCase()==="null"?`${i} IS NOT NULL`:`${i} != ${n(o)}`);break;case"like":e.push(`toString(${i}) LIKE ${n(o)}`);break;case"not like":e.push(`toString(${i}) NOT LIKE ${n(o)}`);break;case"ilike":e.push(`toString(${i}) ILIKE ${n(o)}`);break;case"not ilike":e.push(`toString(${i}) NOT ILIKE ${n(o)}`);break}}return{clause:e.length?`WHERE ${e.join(" AND ")}`:"",values:t}}function Ni(r,e,t){let n=Array.isArray(r)?r:r?[{columnName:r,direction:e}]:[],a=(n[0]?.direction??e).toUpperCase(),s=[...n.map(o=>`${es(o.columnName)} ${o.direction.toUpperCase()}`),...t.map(o=>`${o} ${a}`)];return s.length?`ORDER BY ${s.join(", ")}`:""}function Gm(r,e,t){let a={smallserial:"UInt16",serial2:"UInt16",serial:"UInt32",serial4:"UInt32",bigserial:"UInt64",serial8:"UInt64",tinyint:"Int8",smallint:"Int16",int2:"Int16",int:"Int32",int4:"Int32",integer:"Int32",bigint:"Int64",int8:"Int64",numeric:"Decimal(38, 10)",decimal:"Decimal(38, 10)",money:"Decimal(19, 4)",real:"Float32",float4:"Float32",float:"Float64",float8:"Float64","double precision":"Float64",boolean:"Bool",bool:"Bool",text:"String",varchar:"String","character varying":"String",char:"String",character:"String",bpchar:"String",citext:"String",uuid:"UUID",json:t?"JSON":"String",jsonb:t?"JSON":"String",xml:"String",date:"Date32",time:"String","time without time zone":"String",timestamp:"DateTime64(6)","timestamp without time zone":"DateTime64(6)",timestamptz:"DateTime64(6, 'UTC')","timestamp with time zone":"DateTime64(6, 'UTC')",interval:"String",bytea:"String",inet:"String",cidr:"String",macaddr:"String",macaddr8:"String"}[r.toLowerCase().trim()]??r.trim();return e?`Array(${a})`:a}function tr(r,e){let t=es(r.columnName);if(r.isIdentity||/serial/i.test(r.columnType))return`${t} UInt64 DEFAULT generateSnowflakeID()`;let n=Gm(r.columnType,r.isArray??!1,e),a=r.isNullable&&!r.isPrimaryKey&&!r.isArray,s=`${t} ${a?`Nullable(${n})`:n}`,o=r.defaultValue?.trim();return o&&(s+=` DEFAULT ${Qm[o.toLowerCase()]??o}`),s}var se,es,Qm,Ai=N(()=>{"use strict";h();se=r=>`\`${r.replaceAll("\\","\\\\").replaceAll("`","\\`")}\``,es=se;Qm={"now()":"now()",current_timestamp:"now()","current_timestamp()":"now()",current_date:"today()","gen_random_uuid()":"generateUUIDv4()","uuid_generate_v4()":"generateUUIDv4()"}});import{ClickHouseError as Di}from"@clickhouse/client";var Jm,_i,Xm,Zm,nr,Oi=N(()=>{"use strict";h();z();Xe();Ze();ct();te();ze();Ai();Jm={mutations_sync:"2"},_i=r=>/^(LowCardinality\()?Nullable\(/.test(r),Xm=(r,e)=>{if(r==null)return null;let t=$t(e);if(r===""&&t!=="String"&&!t.startsWith("FixedString"))return null;if(r instanceof Date)return r.toISOString();if(t==="Bool"&&typeof r=="string")return["true","t","1","yes","on"].includes(r.trim().toLowerCase());if(typeof r=="string"&&(t.startsWith("JSON")||t.startsWith("Array(")||t.startsWith("Map(")))try{return JSON.parse(r)}catch{throw new d(400,{message:`Invalid ${t} value: ${r}`})}return typeof r=="object"&&t==="String"?JSON.stringify(r):r},Zm={Fatal:"fatal",Critical:"fatal",Error:"error",Warning:"warning"},nr=class extends ae{serverVersion=new WeakMap;async runQuery(e,t,n){let a=Object.fromEntries(n.map((s,o)=>[`p${o}`,s]));return await this.select(e,t,a)}quoteIdentifier(e){return se(e)}mapToUniversalType(e){return $n(e)}mapFromUniversalType(e){return{text:"String",number:"Int64",boolean:"Bool",json:"String",date:"DateTime",array:"Array(String)",enum:"String"}[e]??"String"}buildTableDataQuery(e){return this.buildPageQuery(e,[])}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,n){let{cursor:a,limit:s=50}=e,o=a?this.decodeOffsetCursor(a):0;return{nextCursor:n?this.makeCursor(o+s):null,prevCursor:o>0?this.makeCursor(Math.max(0,o-s)):null}}async getTableData(e){try{let{db:t,tableName:n,limit:a=50,cursor:s}=e,o=await this.getTable(t,n),i=o.sorting_key?[`(${o.sorting_key})`]:[];o.engine.endsWith("MergeTree")&&i.push("_part","_part_offset");let c=this.buildPageQuery(e,i),[l,u]=await Promise.all([this.runQuery(t,c.countSql,c.countValues),this.runQuery(t,c.sql,c.values)]),m=u.length>a,p=this.normalizeRows(m?u.slice(0,a):u),f=s?this.decodeOffsetCursor(s):0;return{data:p,meta:{limit:a,total:Number(l[0]?.total??0),hasNextPage:m,hasPreviousPage:f>0,...this.buildCursors(e,p,m)}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{return(await this.select(void 0,`SELECT d.name AS name, formatReadableSize(p.bytes) AS size
|
|
18
18
|
FROM system.databases AS d
|
|
19
19
|
LEFT JOIN (
|
|
20
20
|
SELECT database, sum(bytes_on_disk) AS bytes FROM system.parts WHERE active GROUP BY database
|
|
@@ -25,10 +25,10 @@ var pl=Object.defineProperty;var N=(r,e)=>()=>(r&&(e=r(r=0)),e);var Dt=(r,e)=>{f
|
|
|
25
25
|
currentUser() AS user,
|
|
26
26
|
currentDatabase() AS database,
|
|
27
27
|
(SELECT sum(value) FROM system.metrics WHERE metric IN ('TCPConnection', 'HTTPConnection', 'MySQLConnection', 'PostgreSQLConnection')) AS active_connections,
|
|
28
|
-
(SELECT value FROM system.server_settings WHERE name = 'max_connections') AS max_connections`);if(!e)throw new d(500,{message:"No connection information returned"});let{host:t,port:n}=
|
|
28
|
+
(SELECT value FROM system.server_settings WHERE name = 'max_connections') AS max_connections`);if(!e)throw new d(500,{message:"No connection information returned"});let{host:t,port:n}=Oe(Ue());return{host:t,port:n,user:e.user,database:e.database,version:`ClickHouse ${e.version}`,active_connections:Number(e.active_connections),max_connections:Number(e.max_connections)}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{return(await this.select(e,`SELECT name AS tableName, total_rows AS rowCount
|
|
29
29
|
FROM system.tables
|
|
30
30
|
WHERE database = currentDatabase() AND NOT is_temporary AND NOT startsWith(name, '.inner')
|
|
31
|
-
ORDER BY name`)).map(n=>({tableName:n.tableName,rowCount:Number(n.rowCount??0)}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e;if(s?.length)throw new d(400,{message:"ClickHouse does not support foreign keys"});let o=a.find(i=>i.isUnique&&!i.isPrimaryKey);if(o)throw new d(400,{message:`ClickHouse does not enforce UNIQUE constraints; clear "Unique" on "${o.columnName}"`});try{let i=await this.isAtLeast(t,25,3);if(a.some(u=>u.isIdentity||/serial/i.test(u.columnType))&&!await this.isAtLeast(t,24,6))throw new d(400,{message:"Auto-generated ids need ClickHouse 24.6 or newer (generateSnowflakeID)"});let c=a.map(u=>
|
|
31
|
+
ORDER BY name`)).map(n=>({tableName:n.tableName,rowCount:Number(n.rowCount??0)}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e;if(s?.length)throw new d(400,{message:"ClickHouse does not support foreign keys"});let o=a.find(i=>i.isUnique&&!i.isPrimaryKey);if(o)throw new d(400,{message:`ClickHouse does not enforce UNIQUE constraints; clear "Unique" on "${o.columnName}"`});try{let i=await this.isAtLeast(t,25,3);if(a.some(u=>u.isIdentity||/serial/i.test(u.columnType))&&!await this.isAtLeast(t,24,6))throw new d(400,{message:"Auto-generated ids need ClickHouse 24.6 or newer (generateSnowflakeID)"});let c=a.map(u=>tr(u,i)),l=a.filter(u=>u.isPrimaryKey).map(u=>se(u.columnName));await this.command(t,`CREATE TABLE ${se(n)} (${c.join(", ")}) ENGINE = MergeTree ORDER BY ${l.length?`(${l.join(", ")})`:"tuple()"}`)}catch(i){throw this.wrapError(i)}}async deleteTable({tableName:e,db:t}){try{await this.getTable(t,e);let[n]=await this.select(t,`SELECT count() AS total FROM ${se(e)}`);return await this.command(t,`DROP TABLE ${se(e)}`),{deletedCount:Number(n?.total??0),fkViolation:!1,relatedRecords:[]}}catch(n){throw this.wrapError(n)}}async renameTable({tableName:e,newTableName:t,db:n}){this.assertDifferentTableName(e,t);try{if(await this.getTable(n,e),await this.findTable(n,t))throw new d(409,{message:`Table "${t}" already exists`});await this.command(n,`RENAME TABLE ${se(e)} TO ${se(t)}`)}catch(a){throw this.wrapError(a)}}async getTableSchema({tableName:e,db:t}){try{await this.getTable(t,e);let[n]=await this.select(t,`SHOW CREATE TABLE ${se(e)}`);return n?.statement??""}catch(n){throw this.wrapError(n)}}async getTableColumns({tableName:e,db:t}){try{return await this.getTable(t,e),(await this.getColumns(t,e)).map(a=>({columnName:a.name,dataType:$n(a.type),dataTypeLabel:Kr(a.type),isNullable:_i(a.type),columnDefault:a.default_expression||null,isPrimaryKey:a.is_in_sorting_key===1,isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:/^Enum(8|16)\(/.test($t(a.type))?[...a.type.matchAll(/'((?:[^'\\]|\\.)*)'\s*=/g)].map(s=>s[1]??""):null}))}catch(n){throw this.wrapError(n)}}async addColumn(e){let{tableName:t,columnName:n,db:a}=e;if(e.isUnique)throw new d(400,{message:"ClickHouse does not enforce UNIQUE constraints"});try{if(await this.getTable(a,t),(await this.getColumns(a,t)).some(i=>i.name===n))throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let o=tr({...e,isPrimaryKey:!1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${se(t)} ADD COLUMN ${o}`)}catch(s){throw this.wrapError(s)}}async deleteColumn({tableName:e,columnName:t,db:n}){try{if((await this.getColumn(n,e,t)).is_in_sorting_key)throw new d(400,{message:`"${t}" is part of the sorting key and cannot be dropped`});return await this.command(n,`ALTER TABLE ${se(e)} DROP COLUMN ${se(t)}`),{deletedCount:1}}catch(a){throw this.wrapError(a)}}async alterColumn(e){let{tableName:t,columnName:n,db:a}=e;try{let s=await this.getColumn(a,t,n),o=tr({...e,columnName:n,isPrimaryKey:s.is_in_sorting_key===1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${se(t)} MODIFY COLUMN ${o}`)}catch(s){throw this.wrapError(s)}}async renameColumn({tableName:e,columnName:t,newColumnName:n,db:a}){try{if(await this.getColumn(a,e,t),(await this.getColumns(a,e)).some(o=>o.name===n))throw new d(409,{message:`Column "${n}" already exists in table "${e}"`});await this.command(a,`ALTER TABLE ${se(e)} RENAME COLUMN ${se(t)} TO ${se(n)}`)}catch(s){throw this.wrapError(s)}}async addRecord({db:e,params:t}){if(!Object.keys(t.data).length)throw new d(400,{message:"No data provided for insert"});return await this.insertRows(e,t.tableName,[t.data]),{insertedCount:1}}async bulkInsertRecords({tableName:e,records:t,db:n}){if(!t?.length)throw new d(400,{message:"At least one record is required"});return await this.insertRows(n,e,t),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}async updateRecords(e){throw new d(400,{message:W.clickhouse.rowMutationReason})}async deleteRecords(e){throw new d(400,{message:W.clickhouse.rowMutationReason})}async forceDeleteRecords(e){throw new d(400,{message:W.clickhouse.rowMutationReason})}async executeQuery({query:e,db:t}){let n=e.trim().replace(/;+\s*$/,"");if(!n)throw new d(400,{message:"Query is required"});let a=performance.now();try{let s=await Nt(t),o=n.replace(/^(\s*(--[^\n]*\n|\/\*[\s\S]*?\*\/))*/,"").match(/^\s*(\w+)/)?.[1]?.toUpperCase();if(o&&["SELECT","WITH","SHOW","DESC","DESCRIBE","EXPLAIN","EXISTS"].includes(o)){let l=await s.query({query:n,format:"JSON"}),{meta:u=[],data:m}=await l.json();return{columns:u.map(p=>p.name),rows:m,rowCount:m.length,duration:performance.now()-a,message:m.length===0?"OK":void 0}}let{summary:i}=await s.command({query:n,clickhouse_settings:Jm}),c=Number(i?.written_rows??0);return{columns:[],rows:[],rowCount:c,duration:performance.now()-a,message:`OK (${c} rows affected)`}}catch(s){throw this.wrapError(s)}}async getServerLogs({db:e}){let t=await Nt(e),n=async a=>{try{return await(await t.query({query:`${$e} ${a}`,format:"JSONEachRow",clickhouse_settings:{log_queries:0}})).json()}catch(s){if(s instanceof Di&&s.type==="UNKNOWN_TABLE")return null;throw s}};try{let a=await n(`SELECT toUnixTimestamp64Milli(event_time_microseconds) AS ms, type, query_duration_ms,
|
|
32
32
|
query, exception, exception_code, user, query_id, read_rows,
|
|
33
33
|
formatReadableSize(memory_usage) AS memory
|
|
34
34
|
FROM system.query_log
|
|
@@ -39,39 +39,39 @@ var pl=Object.defineProperty;var N=(r,e)=>()=>(r&&(e=r(r=0)),e);var Dt=(r,e)=>{f
|
|
|
39
39
|
WHERE event_date >= yesterday()
|
|
40
40
|
AND level IN ('Fatal', 'Critical', 'Error', 'Warning')
|
|
41
41
|
AND logger_name NOT IN ('executeQuery', 'TCPHandler', 'HTTPHandler')
|
|
42
|
-
ORDER BY event_time_microseconds DESC LIMIT ${500}`);if(!a&&!s)return
|
|
42
|
+
ORDER BY event_time_microseconds DESC LIMIT ${500}`);if(!a&&!s)return re("query_log and text_log are both off in the server config.");let o=[...(a??[]).reverse().map(i=>{let c=i.type!=="QueryFinish";return{ts:new Date(Number(i.ms)).toISOString(),level:c?"error":"info",rawLevel:i.type,code:c?String(i.exception_code):void 0,message:c?i.exception:i.query,durationMs:Number(i.query_duration_ms),statement:c?i.query:void 0,detail:he({user:i.user,query_id:i.query_id,read_rows:i.read_rows,memory:i.memory})}}),...(s??[]).reverse().map(i=>({ts:new Date(Number(i.ms)).toISOString(),level:Zm[i.level]??"info",rawLevel:i.level,source:i.logger_name,message:i.message,detail:he({query_id:i.query_id})}))];return{available:!0,source:s?"system.query_log + system.text_log":"system.query_log",entries:Ie(o)}}catch(a){if(a instanceof Di&&a.type==="ACCESS_DENIED")return re("Reading the server log needs: GRANT SELECT ON system.query_log TO <user>; and the same on system.text_log.");throw this.wrapError(a)}}async select(e,t,n={}){return(await(await Nt(e)).query({query:t,query_params:n,format:"JSONEachRow"})).json()}async command(e,t,n={},a={}){await(await Nt(e)).command({query:t,query_params:n,clickhouse_settings:a})}buildPageQuery(e,t){let{tableName:n,filters:a=[],sort:s=[],order:o="asc",limit:i=50,cursor:c}=e,{clause:l,values:u}=Ri(a),m=Ni(s,o,t),p=c?this.decodeOffsetCursor(c):0,f=u.length;return{sql:`SELECT * FROM ${se(n)} ${l} ${m} LIMIT {p${f+1}:UInt64} OFFSET {p${f}:UInt64}`,values:[...u,p,i+1],countSql:`SELECT count() AS total FROM ${se(n)} ${l}`,countValues:u}}async findTable(e,t){let[n]=await this.select(e,"SELECT engine, sorting_key FROM system.tables WHERE database = currentDatabase() AND name = {table:String}",{table:t});return n}async getTable(e,t){let n=await this.findTable(e,t);if(!n)throw new d(404,{message:`Table "${t}" does not exist`});return n}getColumns(e,t){return this.select(e,`SELECT name, type, default_expression, is_in_sorting_key
|
|
43
43
|
FROM system.columns
|
|
44
44
|
WHERE database = currentDatabase() AND table = {table:String}
|
|
45
|
-
ORDER BY position`,{table:t})}async getColumn(e,t,n){await this.getTable(e,t);let a=(await this.getColumns(e,t)).find(s=>s.name===n);if(!a)throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});return a}async insertRows(e,t,n){try{await this.getTable(e,t);let a=new Map((await this.getColumns(e,t)).map(o=>[o.name,o.type])),s=n.map(o=>Object.fromEntries(Object.entries(o).flatMap(([i,c])=>{let l=a.get(i);if(!l)throw new d(400,{message:`Column "${i}" does not exist in table "${t}"`});let u=Fm(c,l);return u===null&&!Ti(l)?[]:[[i,u]]})));await(await Ft(e)).insert({table:oe(t),values:s,format:"JSONEachRow",clickhouse_settings:{date_time_input_format:"best_effort"}})}catch(a){throw this.wrapError(a)}}async isAtLeast(e,t,n){if(!this.serverVersion){let[o]=await this.select(e,"SELECT version() AS version");this.serverVersion=(o?.version??"0.0").split(".").map(Number)}let[a=0,s=0]=this.serverVersion;return a>t||a===t&&s>=n}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){return Number(this.decodeCursor(e)?.values._offset??0)}}});function wi(r){let e=[],t=[];for(let n of r){let a=x(n.columnName),s=n.value.toLowerCase()==="null";switch(n.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${n.operator} ?`),t.push(n.value);break;case"is":s?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(n.value));break;case"is not":s?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(n.value));break;case"like":case"not like":case"ilike":case"not ilike":e.push(`CAST(${a} AS VARCHAR) ${n.operator.toUpperCase()} ?`),t.push(n.value);break}}return{conditions:e,values:t}}function Ri(r,e,t){let n=[],a=[],s=[],o=[];for(let i of r){let c=x(i.column),l=e[i.column]??null,{descending:u,nullsLast:m}=Si(i,t),p=l===null?m?null:`${c} IS NOT NULL`:`${c} ${u?"<":">"} ?${m?` OR ${c} IS NULL`:""}`;p&&(n.push(`(${[...s,`(${p})`].join(" AND ")})`),a.push(...o,...l===null?[]:[l])),l===null?s.push(`${c} IS NULL`):(s.push(`${c} = ?`),o.push(l))}return{clause:n.length?`(${n.join(" OR ")})`:"FALSE",values:a}}function Zn(r,e){let t=r.toLowerCase().trim(),a={serial:"INTEGER",serial4:"INTEGER",bigserial:"BIGINT",serial8:"BIGINT",smallserial:"SMALLINT",serial2:"SMALLINT",int:"INTEGER",int4:"INTEGER",integer:"INTEGER",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",numeric:"DECIMAL(18, 3)",decimal:"DECIMAL(18, 3)",real:"FLOAT",float4:"FLOAT",float:"DOUBLE","double precision":"DOUBLE",float8:"DOUBLE",money:"DECIMAL(19, 4)",boolean:"BOOLEAN",bool:"BOOLEAN",text:"VARCHAR",varchar:"VARCHAR","character varying":"VARCHAR",char:"VARCHAR",character:"VARCHAR",bpchar:"VARCHAR",uuid:"UUID",json:"JSON",jsonb:"JSON",xml:"VARCHAR",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"TIMESTAMP","timestamp without time zone":"TIMESTAMP","timestamp with time zone":"TIMESTAMPTZ",timestamptz:"TIMESTAMPTZ",interval:"INTERVAL",bytea:"BLOB",inet:"VARCHAR",cidr:"VARCHAR",macaddr:"VARCHAR",macaddr8:"VARCHAR",point:"VARCHAR",line:"VARCHAR",polygon:"VARCHAR"}[t]??r.toUpperCase();return e?`${a}[]`:a}var x,Va,Si,Ci,Hm,za,Ni=N(()=>{"use strict";y();x=r=>`"${r.replaceAll('"','""')}"`,Va=r=>r.length?`WHERE ${r.join(" AND ")}`:"";Si=(r,e)=>({descending:r.direction==="desc"!==e,nullsLast:!e}),Ci=(r,e=!1)=>`ORDER BY ${r.map(t=>{let{descending:n,nullsLast:a}=Si(t,e);return`${x(t.column)} ${n?"DESC":"ASC"} NULLS ${a?"LAST":"FIRST"}`}).join(", ")}`;Hm=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),za=r=>Hm.has(r.toLowerCase().trim())});import{statSync as jm}from"fs";var Ht,Wm,Ai,Qa,be,Ga,pn,er,Ym,Vm,zm,Gm,tr,Di=N(()=>{"use strict";y();G();Qe();Je();St();te();Ni();Ht="database_name = current_database() AND schema_name = current_schema()",Wm=r=>{let{DuckDBTypeId:e}=Ke("duckdb");return r===e.BIGINT||r===e.UBIGINT||r===e.HUGEINT||r===e.UHUGEINT},Ai=r=>{let e=r.columnTypes(),t=r.columnNames().filter((a,s)=>Wm(e[s].typeId)),n=r.getRowObjectsJson();for(let a of n)for(let s of t){let o=a[s];typeof o=="string"&&Number.isSafeInteger(Number(o))&&(a[s]=Number(o))}return n},Qa=r=>r==null?null:typeof r=="string"||typeof r=="number"||typeof r=="boolean"||typeof r=="bigint"?r:r instanceof Date?r.toISOString():JSON.stringify(r),be=async(r,e,t=[])=>Ai(await r.runAndReadAll(e,t.map(Qa))),Ga=async(r,e,t=[])=>(await r.runAndReadAll(e,t.map(Qa))).rowsChanged,pn=async(r,e)=>{await r.run("BEGIN TRANSACTION");try{let t=await e();return await r.run("COMMIT"),t}catch(t){throw await r.run("ROLLBACK").catch(()=>{}),t}},er=r=>r.map(()=>"?").join(", "),Ym=r=>r.columns.map((e,t)=>`c.${x(e)} = p.${x(r.referencedColumns[t])}`).join(" AND "),Vm=r=>r.flatMap(e=>[...(e.column_default??"").matchAll(/nextval\('([^']+)'\)/g)].map(t=>t[1])),zm=[["Dependency Error","DuckDB cannot alter or rename a table that another table's foreign key references or that has an index. Drop the referencing table or the index first."],["has a CHECK constraint","DuckDB cannot change the type of a column that has a CHECK constraint."],["an index depends on it","DuckDB cannot alter or drop a column covered by an index, primary key or unique constraint."]],Gm=new Set(["CASCADE","SET NULL","SET DEFAULT"]),tr=class extends se{async runQuery(e,t,n){return ja(a=>be(a,t,n))}quoteIdentifier(e){return x(e)}mapToUniversalType(e){return _n(e)}mapFromUniversalType(e){return{text:"VARCHAR",number:"DOUBLE",boolean:"BOOLEAN",json:"JSON",date:"TIMESTAMP",array:"VARCHAR[]",enum:"VARCHAR"}[e]??"VARCHAR"}buildTableDataQuery(e){throw new Error("DuckDbAdapter.getTableData builds its own query")}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){throw new Error("DuckDbAdapter.getTableData builds its own cursors")}wrapError(e){if(e instanceof Error){let t=zm.find(([n])=>e.message.includes(n));if(t)return new d(400,{message:`${t[1]} (${e.message})`,cause:e})}return super.wrapError(e)}withConnection(e){return ja(e).catch(t=>{throw this.wrapError(t)})}async getTableData(e){let{tableName:t,limit:n=50,direction:a="asc",sort:s=[],order:o="asc",cursor:i,filters:c=[]}=e;return this.withConnection(async l=>{await this.requireColumns(l,t);let u=await this.primaryKey(l,t),m=this.orderTerms(s,o,u.length?u:["rowid"]),p=a==="desc",f=wi(c),b=i?this.decodeCursor(i):null,h=b?Ri(m,b.values,p):null,g=Ci(m,p),S=u.length?"*":"*, rowid",w=Va(h?[...f.conditions,h.clause]:f.conditions),[D]=await be(l,`SELECT COUNT(*) AS total FROM ${x(t)} ${Va(f.conditions)}`,f.values),A=await be(l,`SELECT ${S} FROM ${x(t)} ${w} ${g} LIMIT ?`,[...f.values,...h?.values??[],n+1]),R=A.length>n,C=A.slice(0,n);p&&C.reverse();let _=M=>this.encodeCursor({values:Object.fromEntries(m.map(X=>[X.column,M[X.column]])),sortColumns:m.map(X=>X.column)}),O=C[0],$=C.at(-1),P=p?!!i:R,v=p?R:!!i;return{data:C.map(M=>{if(u.length)return this.normalizeRow(M);let{rowid:X,...k}=M;return this.normalizeRow(k)}),meta:{limit:n,total:Number(D?.total??0),hasNextPage:P,hasPreviousPage:v,nextCursor:P&&$?_($):null,prevCursor:v&&O?_(O):null}}})}async getDatabasesList(){return this.withConnection(async e=>(await be(e,"SELECT database_name, path FROM duckdb_databases() WHERE database_name = current_database()")).map(n=>({name:n.database_name,size:this.getFileSize(n.path),owner:"",encoding:"UTF-8"})))}async getCurrentDatabase(){return this.withConnection(async e=>{let[t]=await be(e,"SELECT current_database() AS db");return{db:t.db}})}async getDatabaseConnectionInfo(){return this.withConnection(async e=>{let[t]=await be(e,"SELECT current_database() AS db, version() AS version");return{host:null,port:null,user:"",database:t.db,version:`DuckDB ${t.version}`,active_connections:1,max_connections:1}})}async getTablesList(e){return this.withConnection(async t=>{let n=await be(t,`SELECT table_name FROM duckdb_tables() WHERE ${Ht} AND NOT temporary ORDER BY table_name`),a=[];for(let{table_name:s}of n){let[o]=await be(t,`SELECT COUNT(*) AS count FROM ${x(s)}`);a.push({tableName:s,rowCount:Number(o?.count??0)})}return a})}async createTable({tableData:e}){let{tableName:t,fields:n,foreignKeys:a=[]}=e;for(let l of a){let u=[l.onUpdate,l.onDelete].find(m=>Gm.has(m));if(u)throw new d(400,{message:`DuckDB foreign keys do not support ${u} (on "${l.columnName}"). Use NO ACTION or RESTRICT.`})}let s=[],o=n.filter(l=>l.isPrimaryKey).map(l=>l.columnName),i=n.map(l=>{let u=`${x(l.columnName)} ${Zn(l.columnType,l.isArray)}`;if(o.length===1&&l.isPrimaryKey&&(u+=" PRIMARY KEY"),l.isUnique&&!l.isPrimaryKey&&(u+=" UNIQUE"),!l.isNullable&&!l.isPrimaryKey&&(u+=" NOT NULL"),l.isIdentity||za(l.columnType)){let m=`${t}_${l.columnName}_seq`;s.push(m),u+=` DEFAULT nextval('${m.replaceAll("'","''")}')`}else l.defaultValue?.trim()&&(u+=` DEFAULT ${l.defaultValue.trim()}`);return u});o.length>1&&i.push(`PRIMARY KEY (${o.map(x).join(", ")})`);let c=a.map(l=>`FOREIGN KEY (${x(l.columnName)}) REFERENCES ${x(l.referencedTable)} (${x(l.referencedColumn)}) ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`);await this.withConnection(l=>pn(l,async()=>{for(let u of s)await l.run(`CREATE SEQUENCE ${x(u)}`);await l.run(`CREATE TABLE ${x(t)} (${[...i,...c].join(", ")})`)}))}async deleteTable({tableName:e,cascade:t}){return this.withConnection(async n=>{let a=await this.requireColumns(n,e),s=(await this.foreignKeys(n,"referenced_table",e)).filter(i=>i.table!==e);if(s.length){if(t)throw new d(400,{message:`DuckDB cannot drop "${e}" while ${[...new Set(s.map(i=>`"${i.table}"`))].join(", ")} reference it, and it cannot remove those foreign keys. Delete the referencing tables first.`});return{deletedCount:0,fkViolation:!0,relatedRecords:await this.sampleReferencingRows(n,s)}}let[o]=await be(n,`SELECT COUNT(*) AS count FROM ${x(e)}`);await n.run(`DROP TABLE ${x(e)}`);for(let i of Vm(a))await n.run(`DROP SEQUENCE IF EXISTS ${x(i)}`).catch(()=>{});return{deletedCount:Number(o?.count??0),fkViolation:!1,relatedRecords:[]}})}async renameTable({tableName:e,newTableName:t}){this.assertDifferentTableName(e,t),await this.withConnection(async n=>{if(await this.requireColumns(n,e),(await this.columns(n,t)).length)throw new d(409,{message:`Table "${t}" already exists`});await n.run(`ALTER TABLE ${x(e)} RENAME TO ${x(t)}`)})}async getTableSchema({tableName:e}){return this.withConnection(async t=>{let[n]=await be(t,`SELECT sql FROM duckdb_tables() WHERE ${Ht} AND table_name = ?`,[e]);if(!n)throw new d(404,{message:`Table "${e}" does not exist`});return n.sql})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let n=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),s=new Map((await this.foreignKeys(t,"table_name",e)).flatMap(o=>o.columns.map((i,c)=>[i,{table:o.referencedTable,column:o.referencedColumns[c]}])));return n.map(o=>{let i=s.get(o.column_name),c=a.has(o.column_name);return{columnName:o.column_name,dataType:_n(o.data_type),dataTypeLabel:$r(o.data_type),isNullable:o.is_nullable&&!c,columnDefault:o.column_default,isPrimaryKey:c,isForeignKey:!!i,referencedTable:i?.table??null,referencedColumn:i?.column??null,enumValues:o.data_type.startsWith("ENUM(")?[...o.data_type.matchAll(/'((?:[^']|'')*)'/g)].map(l=>l[1].replaceAll("''","'")):null}})})}async addColumn(e){let{tableName:t,columnName:n,columnType:a,defaultValue:s,isNullable:o,isUnique:i,isPrimaryKey:c}=e;if(i||c)throw new d(400,{message:`DuckDB cannot add a ${c?"PRIMARY KEY":"UNIQUE"} column to an existing table. Add the column without it, or recreate the table.`});let l=e.isIdentity||za(a)?`${t}_${n}_seq`:null,u=`${x(n)} ${Zn(a,e.isArray)}`;l?u+=` DEFAULT nextval('${l.replaceAll("'","''")}')`:s?.trim()&&(u+=` DEFAULT ${s.trim()}`),await this.withConnection(async m=>{if((await this.requireColumns(m,t)).some(f=>f.column_name===n))throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});await pn(m,async()=>{l&&await m.run(`CREATE SEQUENCE ${x(l)}`),await m.run(`ALTER TABLE ${x(t)} ADD COLUMN ${u}`),o||await m.run(`ALTER TABLE ${x(t)} ALTER COLUMN ${x(n)} SET NOT NULL`).catch(f=>{throw String(f).includes("NOT NULL constraint failed")?new d(400,{message:`Column "${n}" needs a default value to be NOT NULL, because "${t}" already has rows.`}):f})})})}async deleteColumn({tableName:e,columnName:t}){return await this.withConnection(async n=>{await this.requireColumn(n,e,t),await n.run(`ALTER TABLE ${x(e)} DROP COLUMN ${x(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o}=e,i=`ALTER TABLE ${x(t)} ALTER COLUMN ${x(n)}`;await this.withConnection(async c=>{await this.requireColumn(c,t,n),await pn(c,async()=>{await c.run(`${i} TYPE ${Zn(a,!1)}`),await c.run(`${i} ${s?"DROP":"SET"} NOT NULL`),await c.run(o?.trim()?`${i} SET DEFAULT ${o.trim()}`:`${i} DROP DEFAULT`)})})}async renameColumn({tableName:e,columnName:t,newColumnName:n}){await this.withConnection(async a=>{if((await this.requireColumn(a,e,t)).some(o=>o.column_name===n))throw new d(409,{message:`Column "${n}" already exists in table "${e}"`});await a.run(`ALTER TABLE ${x(e)} RENAME COLUMN ${x(t)} TO ${x(n)}`)})}async getTableIndexes({tableName:e}){return this.withConnection(t=>this.listIndexes(t,e))}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o}=e;await this.withConnection(async i=>{let c=await this.requireColumns(i,t),l=a.find(u=>!c.some(m=>m.column_name===u));if(l!==void 0)throw new d(400,{message:`Column "${l}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});try{await i.run(`CREATE ${s?"UNIQUE ":""}INDEX ${x(n)} ON ${x(t)} (${a.map(x).join(", ")})`)}catch(u){throw u instanceof Error&&/already exists|Data contains duplicates/.test(u.message)?new d(409,{message:u.message,cause:u}):u}})}async dropIndex({tableName:e,indexName:t}){await this.withConnection(async n=>{if(!(await this.listIndexes(n,e)).some(s=>s.indexName===t))throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});await n.run(`DROP INDEX ${x(t)}`)})}async addRecord({params:e}){let{tableName:t,data:n}=e,a=Object.keys(n);if(!a.length)throw new d(400,{message:"No data provided for insert"});return{insertedCount:await this.withConnection(o=>Ga(o,`INSERT INTO ${x(t)} (${a.map(x).join(", ")}) VALUES (${er(a)})`,Object.values(n)))}}async updateRecords({params:e}){let{tableName:t}=e,n=this.resolveKeyColumns(e),a=this.groupUpdatesByKey(e,n);return{updatedCount:await this.withConnection(o=>pn(o,async()=>{this.assertWholeKey(await this.primaryKey(o,t),n);let i=0;for(let{keyValues:c,rowUpdates:l}of a){let u=await Ga(o,`UPDATE ${x(t)} SET ${l.map(m=>`${x(m.columnName)} = ?`).join(", ")} WHERE ${n.map(m=>`${x(m)} = ?`).join(" AND ")}`,[...l.map(m=>m.value),...c]);if(u===0)throw new d(404,{message:`Record with ${this.describeKey(n,c)} not found in table "${t}"`});i+=u}return i}))}}async deleteRecords({tableName:e,primaryKeys:t}){let n=t[0]?.columnName;if(!n)throw new d(400,{message:"Primary key column name is required"});let a=t.map(s=>s.value);return this.withConnection(async s=>{this.assertDeletableKey(await this.primaryKey(s,e));try{return{deletedCount:await Ga(s,`DELETE FROM ${x(e)} WHERE ${x(n)} IN (${er(a)})`,a),fkViolation:!1,relatedRecords:[]}}catch(o){if(!(o instanceof Error)||!o.message.includes("Violates foreign key constraint"))throw o;let i=[];for(let c of await this.foreignKeys(s,"referenced_table",e)){let l=await be(s,`SELECT c.* FROM ${x(c.table)} c JOIN ${x(e)} p ON ${Ym(c)} WHERE p.${x(n)} IN (${er(a)}) LIMIT 100`,a);l.length&&i.push({tableName:c.table,columnName:c.columns.join(", "),constraintName:c.constraintName,records:l})}return{deletedCount:0,fkViolation:!0,relatedRecords:i}}})}async forceDeleteRecords(e){let t=await this.deleteRecords(e);if(t.fkViolation)throw new d(400,{message:"DuckDB cannot atomically delete a row and its dependent rows. Delete the dependent rows explicitly, then retry. Nothing was deleted."});return{deletedCount:t.deletedCount}}async bulkInsertRecords({tableName:e,records:t}){if(!t?.length)throw new d(400,{message:"At least one record is required"});let n=Object.keys(t[0]),a=await this.withConnection(s=>pn(s,async()=>{let o=await s.prepare(`INSERT INTO ${x(e)} (${n.map(x).join(", ")}) VALUES (${er(n)})`);for(let i of t)o.bind(n.map(c=>Qa(i[c]))),await o.run();return t.length}));return{success:!0,message:`Bulk insert completed: ${a} records inserted`,successCount:a,failureCount:0}}async executeQuery({query:e}){if(!e?.trim())throw new d(400,{message:"Query is required"});return this.withConnection(async t=>{let{ResultReturnType:n,StatementType:a}=Ke("duckdb"),s=performance.now(),o=await t.extractStatements(e);if(o.count!==1)throw new d(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let i=await o.prepare(0);try{if(i.statementType===a.TRANSACTION)throw new d(400,{message:"Transactions cannot span query-runner requests. BEGIN, COMMIT, and ROLLBACK are not supported."});let c=await i.runAndReadAll(),l=performance.now()-s;if(c.returnType===n.CHANGED_ROWS)return{columns:[],rows:[],rowCount:c.rowsChanged,duration:l,message:`OK (${c.rowsChanged} rows affected)`};if(c.returnType===n.NOTHING)return{columns:[],rows:[],rowCount:0,duration:l,message:"OK"};let u=Ai(c);return{columns:c.columnNames(),rows:u,rowCount:u.length,duration:l,message:u.length===0?"OK":void 0}}finally{i.destroySync()}})}getFileSize(e){if(!e)return"in-memory";try{let t=jm(e).size;return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}catch{return"N/A"}}columns(e,t){return be(e,`SELECT column_name, data_type, is_nullable, column_default FROM duckdb_columns() WHERE ${Ht} AND table_name = ? ORDER BY column_index`,[t])}async requireColumns(e,t){let n=await this.columns(e,t);if(!n.length)throw new d(404,{message:`Table "${t}" does not exist`});return n}async requireColumn(e,t,n){let a=await this.requireColumns(e,t);if(!a.some(s=>s.column_name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});return a}async listIndexes(e,t){return await this.requireColumns(e,t),(await be(e,`SELECT index_name, is_unique, expressions::VARCHAR[] AS keys, sql FROM duckdb_indexes() WHERE ${Ht} AND table_name = ? ORDER BY index_name`,[t])).map(a=>({indexName:a.index_name,columns:a.keys.map(s=>s.startsWith('"')?s.slice(1,-1).replaceAll('""','"'):s.startsWith("(")?s.slice(1,-1):s),isUnique:a.is_unique,method:null,kind:"index",definition:a.keys.some(s=>s.startsWith("("))?a.sql:null}))}async primaryKey(e,t){let[n]=await be(e,`SELECT constraint_column_names AS columns FROM duckdb_constraints() WHERE ${Ht} AND table_name = ? AND constraint_type = 'PRIMARY KEY'`,[t]);return n?.columns??[]}async foreignKeys(e,t,n){return be(e,`SELECT constraint_name AS "constraintName", table_name AS "table", constraint_column_names AS "columns", referenced_table AS "referencedTable", referenced_column_names AS "referencedColumns" FROM duckdb_constraints() WHERE ${Ht} AND constraint_type = 'FOREIGN KEY' AND ${t} = ?`,[n])}async sampleReferencingRows(e,t){let n=[];for(let a of t){let s=await be(e,`SELECT * FROM ${x(a.table)} WHERE ${a.columns.map(o=>`${x(o)} IS NOT NULL`).join(" AND ")} LIMIT 100`);s.length&&n.push({tableName:a.table,columnName:a.columns.join(", "),constraintName:a.constraintName,records:s})}return n}}});var Qm,_i,Oi=N(()=>{"use strict";y();Qm=new Set(["admin","config","local"]),_i=(r,e)=>{let t=r.filter(n=>!Qm.has(n.name)||n.name===e);return!e||t.some(n=>n.name===e)?t:[...t,{name:e,sizeOnDisk:0}]}});function Ii(r){if(!r||r.length===0)return{};let e=[];for(let t of r){let n=t.columnName,a=Jm(t.value),s=t.operator.toLowerCase();if(n)switch(s){case"=":e.push({[n]:a});break;case"!=":e.push({[n]:{$ne:a}});break;case">":e.push({[n]:{$gt:a}});break;case">=":e.push({[n]:{$gte:a}});break;case"<":e.push({[n]:{$lt:a}});break;case"<=":e.push({[n]:{$lte:a}});break;case"is":e.push({[n]:a});break;case"is not":e.push({[n]:{$ne:a}});break;case"like":e.push({[n]:{$regex:nr(String(a)),$options:""}});break;case"not like":e.push({[n]:{$not:{$regex:nr(String(a)),$options:""}}});break;case"ilike":e.push({[n]:{$regex:nr(String(a)),$options:"i"}});break;case"not ilike":e.push({[n]:{$not:{$regex:nr(String(a)),$options:"i"}}});break;default:e.push({[n]:a});break}}return e.length?{$and:e}:{}}function Ja(r,e){return r?Array.isArray(r)?r.length===0?{_id:1}:Object.fromEntries(r.map(t=>[t.columnName,t.direction==="desc"?-1:1])):typeof r=="string"&&r.length>0?{[r]:e==="desc"?-1:1}:{_id:1}:{_id:1}}function Xa(r){return Buffer.from(JSON.stringify({offset:r})).toString("base64url")}function xi(r){if(!r)return 0;try{let e=JSON.parse(Buffer.from(r,"base64url").toString("utf-8"));return typeof e.offset=="number"?e.offset:0}catch{return 0}}var nr,Jm,Li=N(()=>{"use strict";y();it();nr=r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Jm=r=>{let e=r.trim();if(e==="null")return null;if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return!Number.isNaN(t)&&e!==""?t:un(e)?mn(e):e}});var rr,jt,Xm,Zm,ed,td,nd,Pi,fn,rd,Mi,ad,sd,od,Wt,id,cd,ld,$i,ud,ar,ki=N(()=>{"use strict";y();Qe();Je();lt();it();te();Ye();Oi();Ve();Li();rr=r=>r instanceof Date?r.toISOString():typeof r=="bigint"?r.toString():r&&typeof r=="object"?"_bsontype"in r&&r._bsontype==="ObjectId"?r.toHexString():Array.isArray(r)?r.map(e=>rr(e)):Object.fromEntries(Object.entries(r).map(([e,t])=>[e,rr(t)])):r,jt=r=>rr(r),Xm=["sparse","expireAfterSeconds","partialFilterExpression","collation"],Zm=r=>{let e=r.name??"",t=e==="_id_",n=Object.values(r.key),a=r.weights,s=a?Object.keys(r.key).flatMap(c=>c==="_fts"?Object.keys(a):c==="_ftsx"?[]:[c]):Object.keys(r.key),o={};a&&(o.weights=a);for(let c of Xm){let l=r[c];l!=null&&l!==!1&&(o[c]=rr(l))}let i=n.every(c=>c===1)&&Object.keys(o).length===0;return{indexName:e,columns:s,isUnique:t||r.unique===!0,isSparse:r.sparse,expireAfterSeconds:r.expireAfterSeconds,method:n.find(c=>typeof c=="string")??null,kind:t?"primary":"index",definition:i?null:JSON.stringify({key:r.key,...o})}},ed=new Set([85,86,11e3]),td=r=>r instanceof Date?"date":r&&typeof r=="object"?Array.isArray(r)?"array":"_bsontype"in r?"text":"json":typeof r=="boolean"?"boolean":typeof r=="number"||typeof r=="bigint"?"number":"text",nd=r=>{switch(r){case"number":return"numeric";case"boolean":return"boolean";case"json":return"json";case"date":return"date";case"array":return"array";case"enum":return"enum";default:return"text"}},Pi=r=>typeof r=="string"&&un(r),fn=r=>mn(r),rd=r=>{if(!Number.isFinite(r))return"n/a";let e=["B","KB","MB","GB","TB"],t=r,n=0;for(;t>=1024&&n<e.length-1;)t/=1024,n++;return`${t.toFixed(1)} ${e[n]}`},Mi=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),ad=r=>{let e=r.trim();if(Mi.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},sd=r=>{if(r==null)return"null";if(r instanceof Date)return"date";if(typeof r=="boolean")return"bool";if(typeof r=="number")return Number.isInteger(r)?"int":"double";if(typeof r=="bigint")return"long";if(Array.isArray(r))return"array";if(typeof r=="object"){let e=r._bsontype;return e==="ObjectId"?"objectId":e==="Decimal128"?"decimal":e==="Binary"?"binData":e==="Timestamp"?"timestamp":e?e.toLowerCase():"object"}return"string"},od=(r,e)=>{if(r!=null&&r.trim()!=="")try{return JSON.parse(r)}catch{return r}switch(e){case"string":return"";case"int":case"long":case"double":case"decimal":return 0;case"bool":return!1;case"array":return[];case"object":return{};case"date":return new Date;default:return null}},Wt=r=>{if(r._id&&typeof r._id=="string")return{...r,_id:fn(r._id)};if(r._id&&typeof r._id=="object"){let e=r._id;if(Array.isArray(e.$in))return{...r,_id:{...e,$in:e.$in.map(t=>typeof t=="string"?fn(t):t)}};if(Array.isArray(e.$nin))return{...r,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?fn(t):t)}}}return r},id=13,cd=8e3,ld=51803,$i={F:"fatal",E:"error",W:"warning",I:"info"},ud=({t:r,s:e,c:t,id:n,ctx:a,msg:s,attr:o={}})=>{if(n===ld){let{ns:i,command:c,durationMillis:l,...u}=o,m=Object.fromEntries(Object.entries(c??{}).filter(([p])=>!p.startsWith("$")&&p!=="lsid"));return{ts:new Date(r.$date).toISOString(),level:$i[e]??"debug",rawLevel:e,source:t,message:`${i} ${JSON.stringify(m)}`,durationMs:Number(l),detail:he({id:n,ctx:a,...u})}}return{ts:new Date(r.$date).toISOString(),level:$i[e]??"debug",rawLevel:e,source:t,message:s,detail:he({id:n,ctx:a,...o})}},ar=class extends se{runQuery(){throw new d(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new d(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(jt(t)))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"int":case"long":case"double":case"decimal":return"number";case"bool":return"boolean";case"date":return"date";case"array":return"array";case"object":return"json";default:return"text"}}mapFromUniversalType(e){switch(e){case"number":return"double";case"boolean":return"bool";case"date":return"date";case"array":return"array";case"json":return"object";default:return"string"}}wrapError(e){if(e instanceof d)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new d(503,{message:e.message,cause:e})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:n,cursor:a,limit:s,direction:o="asc",sort:i,order:c,filters:l}=e,m=(await re(n)).collection(t),p=Ii(l??[]),f=Ja(i??"",c),b=s&&s>0?s:50,h=xi(a),g=Number.isFinite(h)&&h>=0?h:0,S=o==="desc"?Math.max(g-b,0):g,[w,D]=await Promise.all([m.countDocuments(p),m.find(p).sort(f).skip(S).limit(b).toArray()]),A=D.map(_=>jt(_)),R=S+b,C=Math.max(S-b,0);return{data:A,meta:{limit:b,total:w,hasNextPage:R<w,hasPreviousPage:S>0,nextCursor:R<w?Xa(R):null,prevCursor:S>0?Xa(C):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let o=(await(await re(t)).collection(e).find({}).limit(1e4).toArray()).map(c=>jt(c));return{cols:Array.from(new Set(o.flatMap(c=>Object.keys(c)))),rows:o}}catch(n){throw this.wrapError(n)}}async getDatabasesList(){try{let a=(await(await zn()).db().admin().listDatabases()).databases??[];if(!a[0])throw new d(500,{message:"No databases returned from MongoDB"});return _i(a,Gn()).map(s=>({name:s.name,size:rd(s.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:Gn()}}async getDatabaseConnectionInfo(){try{let t=(await zn()).db().admin(),n=De(ke()),a={};try{a=await t.serverStatus()}catch(s){W("warn","db_server_status_failed",ne(s))}return{host:n.host,port:n.port,user:"n/a",database:Gn(),version:a.version??"unknown",active_connections:a.connections?.current??0,max_connections:(a.connections?.current??0)+(a.connections?.available??0)}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=await re(e),n=await t.listCollections().toArray(),a=[];for(let s of n){let o=await t.collection(s.name).estimatedDocumentCount();a.push({tableName:s.name,rowCount:o})}return a}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){try{let n=e?.tableName??"",a=await re(t);if((await a.listCollections({name:n}).toArray()).length>0)throw new d(400,{message:`Collection "${n}" already exists`});let o=e?.fields??[];if(o.length===0){await a.createCollection(n);return}let i={},c=[];for(let l of o){let u=ad(l.columnType);if(!Mi.has(u))throw new d(400,{message:`Unsupported MongoDB BSON type "${l.columnType}" for field "${l.columnName}"`});l.isArray?i[l.columnName]={bsonType:"array",...u!=="array"?{items:{bsonType:u}}:{}}:i[l.columnName]={bsonType:u},l.isNullable||c.push(l.columnName)}await a.createCollection(n,{validator:{$jsonSchema:{bsonType:"object",required:c,properties:i,additionalProperties:!0}},validationAction:"error"})}catch(n){throw this.wrapError(n)}}async deleteTable({tableName:e,db:t}){try{let a=(await re(t)).collection(e),s=await a.estimatedDocumentCount();return await a.drop(),{deletedCount:s,fkViolation:!1,relatedRecords:[]}}catch(n){throw this.wrapError(n)}}async renameTable(e){try{let{tableName:t,newTableName:n,db:a}=e;this.assertDifferentTableName(t,n);let s=await re(a);if((await s.listCollections({name:t}).toArray()).length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if((await s.listCollections({name:n}).toArray()).length>0)throw new d(409,{message:`Collection "${n}" already exists`});await s.collection(t).rename(n)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){try{let n=await re(t);if((await n.listCollections({name:e}).toArray()).length===0)throw new d(404,{message:`Collection "${e}" does not exist`});let s=n.collection(e),o=await s.find({}).limit(200).toArray(),i=await s.estimatedDocumentCount(),c=new Map,l=new Map;for(let f of o)for(let[b,h]of Object.entries(f)){let g=sd(h);c.has(b)||(c.set(b,new Set),l.set(b,0)),c.get(b)?.add(g),l.set(b,(l.get(b)??0)+1)}let u={},m=[];for(let[f,b]of c.entries()){let h=l.get(f)??0,g=Array.from(b).filter(w=>w!=="null"),S=b.has("null")||h<o.length;h===o.length&&o.length>0&&!S&&m.push(f),u[f]=g.length===1?{bsonType:S?[g[0],"null"]:g[0]}:{bsonType:S?[...g,"null"]:g}}let p={collection:e,estimatedDocumentCount:i,sampledDocuments:o.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(p,null,2)}catch(n){throw this.wrapError(n)}}async getTableColumns({tableName:e,db:t}){try{let s=await(await re(t)).collection(e).find({}).limit(200).toArray(),o=s.length,i=new Map,c=(l,u)=>{let m=td(u);if(!i.has(l))i.set(l,{types:new Set([m]),nullable:!1,presentCount:1});else{let p=i.get(l);p.types.add(m),p.presentCount+=1}};for(let l of s)for(let[u,m]of Object.entries(l)){if(m==null){if(!i.has(u))i.set(u,{types:new Set(["text"]),nullable:!0,presentCount:1});else{let p=i.get(u);p.nullable=!0,p.presentCount+=1}continue}c(u,m)}if(o>0)for(let l of i.values())l.presentCount<o&&(l.nullable=!0);return i.has("_id")||i.set("_id",{types:new Set(["text"]),nullable:!1,presentCount:o}),Array.from(i.entries()).map(([l,u])=>{let m=u.types.values().next().value??"text";return{columnName:l,dataType:m,dataTypeLabel:nd(m),isNullable:u.nullable,columnDefault:null,isPrimaryKey:l==="_id",isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}})}catch(n){throw this.wrapError(n)}}async addColumn(e){try{let{tableName:t,columnName:n,columnType:a,defaultValue:s,isNullable:o,db:i}=e,c=await re(i),l=await c.listCollections({name:t}).toArray();if(l.length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if(await c.collection(t).findOne({[n]:{$exists:!0}}))throw new d(409,{message:`Field "${n}" already exists in collection "${t}"`});let m=od(s,a);await c.collection(t).updateMany({},{$set:{[n]:m}});let f=l[0].options?.validator?.$jsonSchema??{},b={...f.properties??{},[n]:{bsonType:o?[a,"null"]:a}},h=[...f.required??[]];!o&&!h.includes(n)&&h.push(n),await c.command({collMod:t,validator:{$jsonSchema:{...f,bsonType:"object",properties:b,...h.length>0?{required:h}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:n}){try{return{deletedCount:(await(await re(n)).collection(e).updateMany({},{$unset:{[t]:""}})).modifiedCount}}catch(a){throw this.wrapError(a)}}async alterColumn(e){try{let{tableName:t,columnName:n,columnType:a,isNullable:s,db:o}=e,i=await re(o),c=await i.listCollections({name:t}).toArray();if(c.length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if(n==="_id")throw new d(400,{message:'Cannot alter the "_id" field'});let u=c[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},p=[...u.required??[]];m[n]={bsonType:s?[a,"null"]:a};let f=p.indexOf(n);!s&&f===-1?p.push(n):s&&f!==-1&&p.splice(f,1),await i.command({collMod:t,validator:{$jsonSchema:{...u,bsonType:"object",properties:m,...p.length>0?{required:p}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async renameColumn(e){try{let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await re(s);if((await o.listCollections({name:t}).toArray()).length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if(n==="_id")throw new d(400,{message:'Cannot rename the "_id" field'});if(!await o.collection(t).findOne({[n]:{$exists:!0}}))throw new d(404,{message:`Field "${n}" does not exist in collection "${t}"`});if(await o.collection(t).findOne({[a]:{$exists:!0}}))throw new d(409,{message:`Field "${a}" already exists in collection "${t}"`});await o.collection(t).updateMany({[n]:{$exists:!0}},{$rename:{[n]:a}})}catch(t){throw this.wrapError(t)}}async getServerLogs(){try{let e=await zn(),{log:t}=await e.db("admin").command({getLog:"global"}),n=t.flatMap(a=>{try{return[ud(JSON.parse(a))]}catch{return[]}});return{available:!0,source:"getLog: 'global' (the server keeps the newest 1024 entries)",entries:_e(n)}}catch(e){let t=e.code;if(t===id)return ae("Reading the server log needs the getLog action, which the clusterMonitor role grants.");if(t===cd)return ae("This Atlas tier does not allow getLog.");throw this.wrapError(e)}}async listIndexes(e,t){if((await e.listCollections({name:t}).toArray()).length===0)throw new d(404,{message:`Collection "${t}" does not exist`});return(await e.collection(t).listIndexes().toArray()).map(Zm).sort((s,o)=>+(o.kind==="primary")-+(s.kind==="primary")||(s.indexName<o.indexName?-1:s.indexName>o.indexName?1:0))}async getTableIndexes({tableName:e,db:t}){try{return await this.listIndexes(await re(t),e)}catch(n){throw this.wrapError(n)}}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o,db:i}=e;try{if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});let c=a.find(m=>m.split(".").some(p=>p===""||p.startsWith("$")));if(c!==void 0)throw new d(400,{message:`Invalid field path "${c}"`});if(new Set(a).size!==a.length)throw new d(400,{message:"A field can appear only once in an index"});let l=await re(i);if((await this.listIndexes(l,t)).some(m=>m.indexName===n))throw new d(409,{message:`Index "${n}" already exists on collection "${t}"`});await l.collection(t).createIndex(new Map(a.map(m=>[m,1])),{name:n,unique:s})}catch(c){let l=c.code;throw c instanceof Error&&typeof l=="number"&&ed.has(l)?new d(409,{message:c.message,cause:c}):this.wrapError(c)}}async dropIndex({tableName:e,indexName:t,db:n}){try{let a=await re(n),s=(await this.listIndexes(a,e)).find(o=>o.indexName===t);if(!s)throw new d(404,{message:`Index "${t}" does not exist on collection "${e}"`});if(s.kind==="primary")throw new d(400,{message:`Index "${t}" backs the primary key and cannot be dropped`});await a.collection(e).dropIndex(t)}catch(a){throw this.wrapError(a)}}async addRecord({db:e,params:t}){try{let{tableName:n,data:a}=t,o=(await re(e)).collection(n),i=jt(a);if((i._id===""||i._id===null)&&delete i._id,!(await o.insertOne(i)).insertedId)throw new d(500,{message:`Failed to insert record into "${n}"`});return{insertedCount:1}}catch(n){throw this.wrapError(n)}}async updateRecords({db:e,params:t}){try{let{tableName:n}=t,s=(await re(e)).collection(n),o=0,i=this.resolveKeyColumns(t).map(l=>l||"_id"),c=this.groupUpdatesByKey({...t,primaryKeys:i},i);for(let{keyValues:l,rowUpdates:u}of c){if(u.some(b=>b.columnName==="_id"))throw new d(400,{message:'The "_id" field is immutable and cannot be updated.'});let m={};for(let b of u)m[b.columnName]=b.value;let p={};i.forEach((b,h)=>{let g=l[h];p[b]=b==="_id"&&Pi(g)?fn(g):g});let f=await s.updateOne(p,{$set:m});if(f.matchedCount===0)throw new d(404,{message:`Record with ${this.describeKey(i,l)} not found in "${n}"`});o+=f.modifiedCount}return{updatedCount:o}}catch(n){throw this.wrapError(n)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:n,db:a}=e,o=(await re(a)).collection(t),i=n[0]?.columnName??"_id",c=n.map(u=>i==="_id"&&Pi(u.value)?fn(u.value):u.value);return{deletedCount:(await o.deleteMany({[i]:{$in:c}})).deletedCount??0,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:n,db:a}=e;if(!n||n.length===0)throw new d(400,{message:"At least one record is required"});let o=(await re(a)).collection(t),i=n.map(l=>{let u=jt(l);return(u._id===""||u._id===null)&&delete u._id,u}),c=await o.insertMany(i,{ordered:!1});return{success:!0,message:`Successfully inserted ${c.insertedCount} record${c.insertedCount!==1?"s":""}`,successCount:c.insertedCount,failureCount:n.length-c.insertedCount}}catch(t){throw this.wrapError(t)}}async executeQuery({query:e,db:t}){try{if(!e?.trim())throw new d(400,{message:"Query is required"});let n;try{n=JSON.parse(e)}catch{throw new d(400,{message:"Mongo query must be valid JSON"})}if(!n.collection||!n.operation)throw new d(400,{message:"Mongo query must include collection and operation"});let s=(await re(t)).collection(n.collection),o=performance.now(),i=[],c=0,l;switch(n.operation){case"find":{let f=Wt(n.filter??{}),b=s.find(f,n.options??{});b.sort(n.sort??Ja("",void 0)),n.skip&&b.skip(n.skip),n.limit&&b.limit(n.limit),i=await b.toArray(),c=i.length;break}case"aggregate":{i=await s.aggregate(n.pipeline??[],n.options??{}).toArray(),c=i.length;break}case"insertOne":{let f=n.document;if(!f)throw new d(400,{message:"document is required"});c=(await s.insertOne(f)).insertedId?1:0,l="OK";break}case"insertMany":{let f=n.document;if(!Array.isArray(f))throw new d(400,{message:"document array is required"});c=(await s.insertMany(f)).insertedCount??0,l="OK";break}case"updateOne":{let f=Wt(n.filter??{});if(!n.update)throw new d(400,{message:"update is required"});let b=await s.updateOne(f,n.update,n.options??{});c=b.matchedCount??0,l=`OK (${b.modifiedCount??0} modified)`;break}case"updateMany":{let f=Wt(n.filter??{});if(!n.update)throw new d(400,{message:"update is required"});let b=await s.updateMany(f,n.update,n.options??{});c=b.matchedCount??0,l=`OK (${b.modifiedCount??0} modified)`;break}case"deleteOne":{let f=Wt(n.filter??{});c=(await s.deleteOne(f,n.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let f=Wt(n.filter??{});c=(await s.deleteMany(f,n.options??{})).deletedCount??0,l="OK";break}case"count":{let f=Wt(n.filter??{});c=await s.countDocuments(f),i=[{count:c}],l="OK";break}default:throw new d(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-o,m=i.map(f=>jt(f));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:c,duration:u,message:l}}catch(n){throw this.wrapError(n)}}}});function Za(r,e=0){if(r.length===0)return{clause:"",values:[],nextIdx:e};let t=[],n=[],a=e;for(let s of r){let o=`[${s.columnName}]`;switch(s.operator){case"=":case"!=":case">":case">=":case"<":case"<=":t.push(`${o} ${s.operator} @p${a}`),n.push(s.value),a++;break;case"is":s.value.toLowerCase()==="null"?t.push(`${o} IS NULL`):(t.push(`${o} = @p${a}`),n.push(s.value),a++);break;case"is not":s.value.toLowerCase()==="null"?t.push(`${o} IS NOT NULL`):(t.push(`${o} != @p${a}`),n.push(s.value),a++);break;case"like":case"ilike":t.push(`${o} LIKE @p${a}`),n.push(s.value),a++;break;case"not like":case"not ilike":t.push(`${o} NOT LIKE @p${a}`),n.push(s.value),a++;break;default:break}}return t.length===0?{clause:"",values:[],nextIdx:e}:{clause:`WHERE ${t.join(" AND ")}`,values:n,nextIdx:a}}function es(r,e){return Array.isArray(r)?r.length===0?"":`ORDER BY ${r.map(t=>`[${t.columnName}] ${t.direction.toUpperCase()}`).join(", ")}`:r&&typeof r=="string"?`ORDER BY [${r}] ${e?.toUpperCase()||"ASC"}`:""}function vi(r,e,t){let n=es(r,e),a=Array.isArray(r)?r.map(i=>i.columnName):[r],s=(Array.isArray(r)?r[0]?.direction??e:e).toUpperCase(),o=t.filter(i=>!a.includes(i)).map(i=>`[${i}] ${s}`).join(", ");return o?n?`${n}, ${o}`:`ORDER BY ${o}`:n||"ORDER BY (SELECT NULL)"}function ts(r,e){if(e)return"NVARCHAR(MAX)";let t=r.toLowerCase().trim();return{serial:"INT IDENTITY(1,1)",serial4:"INT IDENTITY(1,1)",bigserial:"BIGINT IDENTITY(1,1)",serial8:"BIGINT IDENTITY(1,1)",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",tinyint:"TINYINT",numeric:"NUMERIC",decimal:"DECIMAL",real:"REAL",float4:"REAL",float:"FLOAT","double precision":"FLOAT",float8:"FLOAT",money:"MONEY",boolean:"BIT",bool:"BIT",text:"NVARCHAR(MAX)",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"UNIQUEIDENTIFIER",json:"NVARCHAR(MAX)",jsonb:"NVARCHAR(MAX)",xml:"XML",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME2","timestamp without time zone":"DATETIME2","timestamp with time zone":"DATETIMEOFFSET",timestamptz:"DATETIMEOFFSET",interval:"VARCHAR(255)",bytea:"VARBINARY(MAX)",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)"}[t]||r.toUpperCase()}function ns(r,e){let t=r.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("newid()")?e.toUpperCase().includes("UNIQUEIDENTIFIER")?"NEWID()":null:t.includes("getdate")||t.includes("current_timestamp")?"GETDATE()":r.trim():t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":r.trim()}function Ui(r,e={}){let t=ts(r.columnType,r.isArray??!1),n=`[${r.columnName}] ${t}`;if(r.isIdentity&&!t.includes("IDENTITY")&&(n+=" IDENTITY(1,1)"),!r.isNullable&&!r.isPrimaryKey&&(n+=" NOT NULL"),r.defaultValue?.trim()&&!t.includes("IDENTITY")){let a=ns(r.defaultValue,t);a!==null&&(n+=` DEFAULT ${a}`)}return e.includeUnique&&r.isUnique&&!r.isPrimaryKey&&(n+=" UNIQUE"),e.includePrimaryKey&&r.isPrimaryKey&&(n+=" PRIMARY KEY"),n}var qi=N(()=>{"use strict";y()});var md,dd,pd,fd,yd,hd,gd,bd,Td,He,sr,Bi=N(()=>{"use strict";y();G();Qe();Je();lt();te();Ve();qi();md=547,dd=15003,pd=2812,fd=/^Error: (\d+), Severity: (\d+), State: (\d+)\.?$/,yd=3726,hd=1913,gd=1505,bd=new Set([1919,1978]),Td=3723,He=r=>`[${r.replaceAll("]","]]")}]`,sr=class extends se{async runQuery(e,t,n){let s=(await K(e)).request();return n.forEach((i,c)=>{s.input(`p${c}`,i)}),(await s.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return An(e)}mapFromUniversalType(e){return{text:"NVARCHAR(MAX)",number:"INT",boolean:"BIT",json:"NVARCHAR(MAX)",date:"DATETIME2",array:"NVARCHAR(MAX)",enum:"NVARCHAR(255)"}[e]??"NVARCHAR(MAX)"}buildTableDataQuery(e){let{tableName:t,filters:n=[],sort:a=[],order:s="asc",limit:o=50,cursor:i}=e,{clause:c,values:l,nextIdx:u}=Za(n,0),m=es(a,s)||"ORDER BY (SELECT NULL)",p=i?this.decodeOffsetCursor(i):0,f=`SELECT * FROM [${t}] ${c} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,b=[...l,p,o+1],h=`SELECT COUNT(*) as total FROM [${t}] ${c}`;return{sql:f,values:b,countSql:h,countValues:l}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,n){let{cursor:a,limit:s=50}=e,o=a?this.decodeOffsetCursor(a):0;return{nextCursor:n?this.makeCursor(o+s):null,prevCursor:o>0?this.makeCursor(Math.max(0,o-s)):null}}async getTableData(e){try{let{tableName:t,db:n,limit:a=50,sort:s=[],order:o="asc",cursor:i,filters:c=[]}=e,l=await K(n),u=i?this.decodeOffsetCursor(i):0,{clause:m,values:p,nextIdx:f}=Za(c,0),[b,{total:h,estimated:g}]=await Promise.all([this.getPrimaryKeyColumns(l,t),this.countRows(l,t,m,p)]),S=vi(s,o,b),w=l.request();p.forEach((C,_)=>{w.input(`p${_}`,C)}),w.input(`p${f}`,u),w.input(`p${f+1}`,a+1);let A=(await w.query(`SELECT * FROM [${t}] ${m} ${S} OFFSET @p${f} ROWS FETCH NEXT @p${f+1} ROWS ONLY`)).recordset,R=A.length>a;return R&&(A=A.slice(0,a)),{data:A,meta:{limit:a,total:h,...g&&{totalEstimated:!0},hasNextPage:R,hasPreviousPage:u>0,nextCursor:R?this.makeCursor(u+a):null,prevCursor:u>0?this.makeCursor(Math.max(0,u-a)):null}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=await(await K()).request().query(`
|
|
45
|
+
ORDER BY position`,{table:t})}async getColumn(e,t,n){await this.getTable(e,t);let a=(await this.getColumns(e,t)).find(s=>s.name===n);if(!a)throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});return a}async insertRows(e,t,n){try{await this.getTable(e,t);let a=new Map((await this.getColumns(e,t)).map(o=>[o.name,o.type])),s=n.map(o=>Object.fromEntries(Object.entries(o).flatMap(([i,c])=>{let l=a.get(i);if(!l)throw new d(400,{message:`Column "${i}" does not exist in table "${t}"`});let u=Xm(c,l);return u===null&&!_i(l)?[]:[[i,u]]})));await(await Nt(e)).insert({table:se(t),values:s,format:"JSONEachRow",clickhouse_settings:{date_time_input_format:"best_effort"}})}catch(a){throw this.wrapError(a)}}async isAtLeast(e,t,n){let a=await Nt(e),s=this.serverVersion.get(a);if(!s){let[c]=await this.select(e,"SELECT version() AS version");s=(c?.version??"0.0").split(".").map(Number),this.serverVersion.set(a,s)}let[o=0,i=0]=s;return o>t||o===t&&i>=n}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){return Number(this.decodeCursor(e)?.values._offset??0)}}});function Ii(r){let e=[],t=[];for(let n of r){let a=x(n.columnName),s=n.value.toLowerCase()==="null";switch(n.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${n.operator} ?`),t.push(n.value);break;case"is":s?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(n.value));break;case"is not":s?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(n.value));break;case"like":case"not like":case"ilike":case"not ilike":e.push(`CAST(${a} AS VARCHAR) ${n.operator.toUpperCase()} ?`),t.push(n.value);break}}return{conditions:e,values:t}}function Pi(r,e,t){let n=[],a=[],s=[],o=[];for(let i of r){let c=x(i.column),l=e[i.column]??null,{descending:u,nullsLast:m}=xi(i,t),p=l===null?m?null:`${c} IS NOT NULL`:`${c} ${u?"<":">"} ?${m?` OR ${c} IS NULL`:""}`;p&&(n.push(`(${[...s,`(${p})`].join(" AND ")})`),a.push(...o,...l===null?[]:[l])),l===null?s.push(`${c} IS NULL`):(s.push(`${c} = ?`),o.push(l))}return{clause:n.length?`(${n.join(" OR ")})`:"FALSE",values:a}}function rr(r,e){let t=r.toLowerCase().trim(),a={serial:"INTEGER",serial4:"INTEGER",bigserial:"BIGINT",serial8:"BIGINT",smallserial:"SMALLINT",serial2:"SMALLINT",int:"INTEGER",int4:"INTEGER",integer:"INTEGER",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",numeric:"DECIMAL(18, 3)",decimal:"DECIMAL(18, 3)",real:"FLOAT",float4:"FLOAT",float:"DOUBLE","double precision":"DOUBLE",float8:"DOUBLE",money:"DECIMAL(19, 4)",boolean:"BOOLEAN",bool:"BOOLEAN",text:"VARCHAR",varchar:"VARCHAR","character varying":"VARCHAR",char:"VARCHAR",character:"VARCHAR",bpchar:"VARCHAR",uuid:"UUID",json:"JSON",jsonb:"JSON",xml:"VARCHAR",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"TIMESTAMP","timestamp without time zone":"TIMESTAMP","timestamp with time zone":"TIMESTAMPTZ",timestamptz:"TIMESTAMPTZ",interval:"INTERVAL",bytea:"BLOB",inet:"VARCHAR",cidr:"VARCHAR",macaddr:"VARCHAR",macaddr8:"VARCHAR",point:"VARCHAR",line:"VARCHAR",polygon:"VARCHAR"}[t]??r.toUpperCase();return e?`${a}[]`:a}var x,ts,xi,Li,ed,ns,$i=N(()=>{"use strict";h();x=r=>`"${r.replaceAll('"','""')}"`,ts=r=>r.length?`WHERE ${r.join(" AND ")}`:"";xi=(r,e)=>({descending:r.direction==="desc"!==e,nullsLast:!e}),Li=(r,e=!1)=>`ORDER BY ${r.map(t=>{let{descending:n,nullsLast:a}=xi(t,e);return`${x(t.column)} ${n?"DESC":"ASC"} NULLS ${a?"LAST":"FIRST"}`}).join(", ")}`;ed=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),ns=r=>ed.has(r.toLowerCase().trim())});import{statSync as td}from"fs";var jt,nd,Mi,as,ge,rs,bn,ar,rd,ad,sd,od,sr,ki=N(()=>{"use strict";h();z();Xe();Ze();wt();te();$i();jt="database_name = current_database() AND schema_name = current_schema()",nd=r=>{let{DuckDBTypeId:e}=je("duckdb");return r===e.BIGINT||r===e.UBIGINT||r===e.HUGEINT||r===e.UHUGEINT},Mi=r=>{let e=r.columnTypes(),t=r.columnNames().filter((a,s)=>nd(e[s].typeId)),n=r.getRowObjectsJson();for(let a of n)for(let s of t){let o=a[s];typeof o=="string"&&Number.isSafeInteger(Number(o))&&(a[s]=Number(o))}return n},as=r=>r==null?null:typeof r=="string"||typeof r=="number"||typeof r=="boolean"||typeof r=="bigint"?r:r instanceof Date?r.toISOString():JSON.stringify(r),ge=async(r,e,t=[])=>Mi(await r.runAndReadAll(e,t.map(as))),rs=async(r,e,t=[])=>(await r.runAndReadAll(e,t.map(as))).rowsChanged,bn=async(r,e)=>{await r.run("BEGIN TRANSACTION");try{let t=await e();return await r.run("COMMIT"),t}catch(t){throw await r.run("ROLLBACK").catch(()=>{}),t}},ar=r=>r.map(()=>"?").join(", "),rd=r=>r.columns.map((e,t)=>`c.${x(e)} = p.${x(r.referencedColumns[t])}`).join(" AND "),ad=r=>r.flatMap(e=>[...(e.column_default??"").matchAll(/nextval\('([^']+)'\)/g)].map(t=>t[1])),sd=[["Dependency Error","DuckDB cannot alter or rename a table that another table's foreign key references or that has an index. Drop the referencing table or the index first."],["has a CHECK constraint","DuckDB cannot change the type of a column that has a CHECK constraint."],["an index depends on it","DuckDB cannot alter or drop a column covered by an index, primary key or unique constraint."]],od=new Set(["CASCADE","SET NULL","SET DEFAULT"]),sr=class extends ae{async runQuery(e,t,n){return Xa(a=>ge(a,t,n))}quoteIdentifier(e){return x(e)}mapToUniversalType(e){return Ln(e)}mapFromUniversalType(e){return{text:"VARCHAR",number:"DOUBLE",boolean:"BOOLEAN",json:"JSON",date:"TIMESTAMP",array:"VARCHAR[]",enum:"VARCHAR"}[e]??"VARCHAR"}buildTableDataQuery(e){throw new Error("DuckDbAdapter.getTableData builds its own query")}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){throw new Error("DuckDbAdapter.getTableData builds its own cursors")}wrapError(e){if(e instanceof Error){let t=sd.find(([n])=>e.message.includes(n));if(t)return new d(400,{message:`${t[1]} (${e.message})`,cause:e})}return super.wrapError(e)}withConnection(e){return Xa(e).catch(t=>{throw this.wrapError(t)})}async getTableData(e){let{tableName:t,limit:n=50,direction:a="asc",sort:s=[],order:o="asc",cursor:i,filters:c=[]}=e;return this.withConnection(async l=>{await this.requireColumns(l,t);let u=await this.primaryKey(l,t),m=this.orderTerms(s,o,u.length?u:["rowid"]),p=a==="desc",f=Ii(c),b=i?this.decodeCursor(i):null,y=b?Pi(m,b.values,p):null,g=Li(m,p),S=u.length?"*":"*, rowid",w=ts(y?[...f.conditions,y.clause]:f.conditions),[D]=await ge(l,`SELECT COUNT(*) AS total FROM ${x(t)} ${ts(f.conditions)}`,f.values),A=await ge(l,`SELECT ${S} FROM ${x(t)} ${w} ${g} LIMIT ?`,[...f.values,...y?.values??[],n+1]),R=A.length>n,C=A.slice(0,n);p&&C.reverse();let _=M=>this.encodeCursor({values:Object.fromEntries(m.map(X=>[X.column,M[X.column]])),sortColumns:m.map(X=>X.column)}),O=C[0],$=C.at(-1),P=p?!!i:R,v=p?R:!!i;return{data:C.map(M=>{if(u.length)return this.normalizeRow(M);let{rowid:X,...k}=M;return this.normalizeRow(k)}),meta:{limit:n,total:Number(D?.total??0),hasNextPage:P,hasPreviousPage:v,nextCursor:P&&$?_($):null,prevCursor:v&&O?_(O):null}}})}async getDatabasesList(){return this.withConnection(async e=>(await ge(e,"SELECT database_name, path FROM duckdb_databases() WHERE database_name = current_database()")).map(n=>({name:n.database_name,size:this.getFileSize(n.path),owner:"",encoding:"UTF-8"})))}async getCurrentDatabase(){return this.withConnection(async e=>{let[t]=await ge(e,"SELECT current_database() AS db");return{db:t.db}})}async getDatabaseConnectionInfo(){return this.withConnection(async e=>{let[t]=await ge(e,"SELECT current_database() AS db, version() AS version");return{host:null,port:null,user:"",database:t.db,version:`DuckDB ${t.version}`,active_connections:1,max_connections:1}})}async getTablesList(e){return this.withConnection(async t=>{let n=await ge(t,`SELECT table_name FROM duckdb_tables() WHERE ${jt} AND NOT temporary ORDER BY table_name`),a=[];for(let{table_name:s}of n){let[o]=await ge(t,`SELECT COUNT(*) AS count FROM ${x(s)}`);a.push({tableName:s,rowCount:Number(o?.count??0)})}return a})}async createTable({tableData:e}){let{tableName:t,fields:n,foreignKeys:a=[]}=e;for(let l of a){let u=[l.onUpdate,l.onDelete].find(m=>od.has(m));if(u)throw new d(400,{message:`DuckDB foreign keys do not support ${u} (on "${l.columnName}"). Use NO ACTION or RESTRICT.`})}let s=[],o=n.filter(l=>l.isPrimaryKey).map(l=>l.columnName),i=n.map(l=>{let u=`${x(l.columnName)} ${rr(l.columnType,l.isArray)}`;if(o.length===1&&l.isPrimaryKey&&(u+=" PRIMARY KEY"),l.isUnique&&!l.isPrimaryKey&&(u+=" UNIQUE"),!l.isNullable&&!l.isPrimaryKey&&(u+=" NOT NULL"),l.isIdentity||ns(l.columnType)){let m=`${t}_${l.columnName}_seq`;s.push(m),u+=` DEFAULT nextval('${m.replaceAll("'","''")}')`}else l.defaultValue?.trim()&&(u+=` DEFAULT ${l.defaultValue.trim()}`);return u});o.length>1&&i.push(`PRIMARY KEY (${o.map(x).join(", ")})`);let c=a.map(l=>`FOREIGN KEY (${x(l.columnName)}) REFERENCES ${x(l.referencedTable)} (${x(l.referencedColumn)}) ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`);await this.withConnection(l=>bn(l,async()=>{for(let u of s)await l.run(`CREATE SEQUENCE ${x(u)}`);await l.run(`CREATE TABLE ${x(t)} (${[...i,...c].join(", ")})`)}))}async deleteTable({tableName:e,cascade:t}){return this.withConnection(async n=>{let a=await this.requireColumns(n,e),s=(await this.foreignKeys(n,"referenced_table",e)).filter(i=>i.table!==e);if(s.length){if(t)throw new d(400,{message:`DuckDB cannot drop "${e}" while ${[...new Set(s.map(i=>`"${i.table}"`))].join(", ")} reference it, and it cannot remove those foreign keys. Delete the referencing tables first.`});return{deletedCount:0,fkViolation:!0,relatedRecords:await this.sampleReferencingRows(n,s)}}let[o]=await ge(n,`SELECT COUNT(*) AS count FROM ${x(e)}`);await n.run(`DROP TABLE ${x(e)}`);for(let i of ad(a))await n.run(`DROP SEQUENCE IF EXISTS ${x(i)}`).catch(()=>{});return{deletedCount:Number(o?.count??0),fkViolation:!1,relatedRecords:[]}})}async renameTable({tableName:e,newTableName:t}){this.assertDifferentTableName(e,t),await this.withConnection(async n=>{if(await this.requireColumns(n,e),(await this.columns(n,t)).length)throw new d(409,{message:`Table "${t}" already exists`});await n.run(`ALTER TABLE ${x(e)} RENAME TO ${x(t)}`)})}async getTableSchema({tableName:e}){return this.withConnection(async t=>{let[n]=await ge(t,`SELECT sql FROM duckdb_tables() WHERE ${jt} AND table_name = ?`,[e]);if(!n)throw new d(404,{message:`Table "${e}" does not exist`});return n.sql})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let n=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),s=new Map((await this.foreignKeys(t,"table_name",e)).flatMap(o=>o.columns.map((i,c)=>[i,{table:o.referencedTable,column:o.referencedColumns[c]}])));return n.map(o=>{let i=s.get(o.column_name),c=a.has(o.column_name);return{columnName:o.column_name,dataType:Ln(o.data_type),dataTypeLabel:Br(o.data_type),isNullable:o.is_nullable&&!c,columnDefault:o.column_default,isPrimaryKey:c,isForeignKey:!!i,referencedTable:i?.table??null,referencedColumn:i?.column??null,enumValues:o.data_type.startsWith("ENUM(")?[...o.data_type.matchAll(/'((?:[^']|'')*)'/g)].map(l=>l[1].replaceAll("''","'")):null}})})}async addColumn(e){let{tableName:t,columnName:n,columnType:a,defaultValue:s,isNullable:o,isUnique:i,isPrimaryKey:c}=e;if(i||c)throw new d(400,{message:`DuckDB cannot add a ${c?"PRIMARY KEY":"UNIQUE"} column to an existing table. Add the column without it, or recreate the table.`});let l=e.isIdentity||ns(a)?`${t}_${n}_seq`:null,u=`${x(n)} ${rr(a,e.isArray)}`;l?u+=` DEFAULT nextval('${l.replaceAll("'","''")}')`:s?.trim()&&(u+=` DEFAULT ${s.trim()}`),await this.withConnection(async m=>{if((await this.requireColumns(m,t)).some(f=>f.column_name===n))throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});await bn(m,async()=>{l&&await m.run(`CREATE SEQUENCE ${x(l)}`),await m.run(`ALTER TABLE ${x(t)} ADD COLUMN ${u}`),o||await m.run(`ALTER TABLE ${x(t)} ALTER COLUMN ${x(n)} SET NOT NULL`).catch(f=>{throw String(f).includes("NOT NULL constraint failed")?new d(400,{message:`Column "${n}" needs a default value to be NOT NULL, because "${t}" already has rows.`}):f})})})}async deleteColumn({tableName:e,columnName:t}){return await this.withConnection(async n=>{await this.requireColumn(n,e,t),await n.run(`ALTER TABLE ${x(e)} DROP COLUMN ${x(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o}=e,i=`ALTER TABLE ${x(t)} ALTER COLUMN ${x(n)}`;await this.withConnection(async c=>{await this.requireColumn(c,t,n),await bn(c,async()=>{await c.run(`${i} TYPE ${rr(a,!1)}`),await c.run(`${i} ${s?"DROP":"SET"} NOT NULL`),await c.run(o?.trim()?`${i} SET DEFAULT ${o.trim()}`:`${i} DROP DEFAULT`)})})}async renameColumn({tableName:e,columnName:t,newColumnName:n}){await this.withConnection(async a=>{if((await this.requireColumn(a,e,t)).some(o=>o.column_name===n))throw new d(409,{message:`Column "${n}" already exists in table "${e}"`});await a.run(`ALTER TABLE ${x(e)} RENAME COLUMN ${x(t)} TO ${x(n)}`)})}async getTableIndexes({tableName:e}){return this.withConnection(t=>this.listIndexes(t,e))}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o}=e;await this.withConnection(async i=>{let c=await this.requireColumns(i,t),l=a.find(u=>!c.some(m=>m.column_name===u));if(l!==void 0)throw new d(400,{message:`Column "${l}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});try{await i.run(`CREATE ${s?"UNIQUE ":""}INDEX ${x(n)} ON ${x(t)} (${a.map(x).join(", ")})`)}catch(u){throw u instanceof Error&&/already exists|Data contains duplicates/.test(u.message)?new d(409,{message:u.message,cause:u}):u}})}async dropIndex({tableName:e,indexName:t}){await this.withConnection(async n=>{if(!(await this.listIndexes(n,e)).some(s=>s.indexName===t))throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});await n.run(`DROP INDEX ${x(t)}`)})}async addRecord({params:e}){let{tableName:t,data:n}=e,a=Object.keys(n);if(!a.length)throw new d(400,{message:"No data provided for insert"});return{insertedCount:await this.withConnection(o=>rs(o,`INSERT INTO ${x(t)} (${a.map(x).join(", ")}) VALUES (${ar(a)})`,Object.values(n)))}}async updateRecords({params:e}){let{tableName:t}=e,n=this.resolveKeyColumns(e),a=this.groupUpdatesByKey(e,n);return{updatedCount:await this.withConnection(o=>bn(o,async()=>{this.assertWholeKey(await this.primaryKey(o,t),n);let i=0;for(let{keyValues:c,rowUpdates:l}of a){let u=await rs(o,`UPDATE ${x(t)} SET ${l.map(m=>`${x(m.columnName)} = ?`).join(", ")} WHERE ${n.map(m=>`${x(m)} = ?`).join(" AND ")}`,[...l.map(m=>m.value),...c]);if(u===0)throw new d(404,{message:`Record with ${this.describeKey(n,c)} not found in table "${t}"`});i+=u}return i}))}}async deleteRecords({tableName:e,primaryKeys:t}){let n=t[0]?.columnName;if(!n)throw new d(400,{message:"Primary key column name is required"});let a=t.map(s=>s.value);return this.withConnection(async s=>{this.assertDeletableKey(await this.primaryKey(s,e));try{return{deletedCount:await rs(s,`DELETE FROM ${x(e)} WHERE ${x(n)} IN (${ar(a)})`,a),fkViolation:!1,relatedRecords:[]}}catch(o){if(!(o instanceof Error)||!o.message.includes("Violates foreign key constraint"))throw o;let i=[];for(let c of await this.foreignKeys(s,"referenced_table",e)){let l=await ge(s,`SELECT c.* FROM ${x(c.table)} c JOIN ${x(e)} p ON ${rd(c)} WHERE p.${x(n)} IN (${ar(a)}) LIMIT 100`,a);l.length&&i.push({tableName:c.table,columnName:c.columns.join(", "),constraintName:c.constraintName,records:l})}return{deletedCount:0,fkViolation:!0,relatedRecords:i}}})}async forceDeleteRecords(e){let t=await this.deleteRecords(e);if(t.fkViolation)throw new d(400,{message:"DuckDB cannot atomically delete a row and its dependent rows. Delete the dependent rows explicitly, then retry. Nothing was deleted."});return{deletedCount:t.deletedCount}}async bulkInsertRecords({tableName:e,records:t}){if(!t?.length)throw new d(400,{message:"At least one record is required"});let n=Object.keys(t[0]),a=await this.withConnection(s=>bn(s,async()=>{let o=await s.prepare(`INSERT INTO ${x(e)} (${n.map(x).join(", ")}) VALUES (${ar(n)})`);for(let i of t)o.bind(n.map(c=>as(i[c]))),await o.run();return t.length}));return{success:!0,message:`Bulk insert completed: ${a} records inserted`,successCount:a,failureCount:0}}async executeQuery({query:e}){if(!e?.trim())throw new d(400,{message:"Query is required"});return this.withConnection(async t=>{let{ResultReturnType:n,StatementType:a}=je("duckdb"),s=performance.now(),o=await t.extractStatements(e);if(o.count!==1)throw new d(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let i=await o.prepare(0);try{if(i.statementType===a.TRANSACTION)throw new d(400,{message:"Transactions cannot span query-runner requests. BEGIN, COMMIT, and ROLLBACK are not supported."});let c=await i.runAndReadAll(),l=performance.now()-s;if(c.returnType===n.CHANGED_ROWS)return{columns:[],rows:[],rowCount:c.rowsChanged,duration:l,message:`OK (${c.rowsChanged} rows affected)`};if(c.returnType===n.NOTHING)return{columns:[],rows:[],rowCount:0,duration:l,message:"OK"};let u=Mi(c);return{columns:c.columnNames(),rows:u,rowCount:u.length,duration:l,message:u.length===0?"OK":void 0}}finally{i.destroySync()}})}getFileSize(e){if(!e)return"in-memory";try{let t=td(e).size;return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}catch{return"N/A"}}columns(e,t){return ge(e,`SELECT column_name, data_type, is_nullable, column_default FROM duckdb_columns() WHERE ${jt} AND table_name = ? ORDER BY column_index`,[t])}async requireColumns(e,t){let n=await this.columns(e,t);if(!n.length)throw new d(404,{message:`Table "${t}" does not exist`});return n}async requireColumn(e,t,n){let a=await this.requireColumns(e,t);if(!a.some(s=>s.column_name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});return a}async listIndexes(e,t){return await this.requireColumns(e,t),(await ge(e,`SELECT index_name, is_unique, expressions::VARCHAR[] AS keys, sql FROM duckdb_indexes() WHERE ${jt} AND table_name = ? ORDER BY index_name`,[t])).map(a=>({indexName:a.index_name,columns:a.keys.map(s=>s.startsWith('"')?s.slice(1,-1).replaceAll('""','"'):s.startsWith("(")?s.slice(1,-1):s),isUnique:a.is_unique,method:null,kind:"index",definition:a.keys.some(s=>s.startsWith("("))?a.sql:null}))}async primaryKey(e,t){let[n]=await ge(e,`SELECT constraint_column_names AS columns FROM duckdb_constraints() WHERE ${jt} AND table_name = ? AND constraint_type = 'PRIMARY KEY'`,[t]);return n?.columns??[]}async foreignKeys(e,t,n){return ge(e,`SELECT constraint_name AS "constraintName", table_name AS "table", constraint_column_names AS "columns", referenced_table AS "referencedTable", referenced_column_names AS "referencedColumns" FROM duckdb_constraints() WHERE ${jt} AND constraint_type = 'FOREIGN KEY' AND ${t} = ?`,[n])}async sampleReferencingRows(e,t){let n=[];for(let a of t){let s=await ge(e,`SELECT * FROM ${x(a.table)} WHERE ${a.columns.map(o=>`${x(o)} IS NOT NULL`).join(" AND ")} LIMIT 100`);s.length&&n.push({tableName:a.table,columnName:a.columns.join(", "),constraintName:a.constraintName,records:s})}return n}}});var id,vi,Ui=N(()=>{"use strict";h();id=new Set(["admin","config","local"]),vi=(r,e)=>{let t=r.filter(n=>!id.has(n.name)||n.name===e);return!e||t.some(n=>n.name===e)?t:[...t,{name:e,sizeOnDisk:0}]}});function qi(r){if(!r||r.length===0)return{};let e=[];for(let t of r){let n=t.columnName,a=cd(t.value),s=t.operator.toLowerCase();if(n)switch(s){case"=":e.push({[n]:a});break;case"!=":e.push({[n]:{$ne:a}});break;case">":e.push({[n]:{$gt:a}});break;case">=":e.push({[n]:{$gte:a}});break;case"<":e.push({[n]:{$lt:a}});break;case"<=":e.push({[n]:{$lte:a}});break;case"is":e.push({[n]:a});break;case"is not":e.push({[n]:{$ne:a}});break;case"like":e.push({[n]:{$regex:or(String(a)),$options:""}});break;case"not like":e.push({[n]:{$not:{$regex:or(String(a)),$options:""}}});break;case"ilike":e.push({[n]:{$regex:or(String(a)),$options:"i"}});break;case"not ilike":e.push({[n]:{$not:{$regex:or(String(a)),$options:"i"}}});break;default:e.push({[n]:a});break}}return e.length?{$and:e}:{}}function ss(r,e){return r?Array.isArray(r)?r.length===0?{_id:1}:Object.fromEntries(r.map(t=>[t.columnName,t.direction==="desc"?-1:1])):typeof r=="string"&&r.length>0?{[r]:e==="desc"?-1:1}:{_id:1}:{_id:1}}function os(r){return Buffer.from(JSON.stringify({offset:r})).toString("base64url")}function Bi(r){if(!r)return 0;try{let e=JSON.parse(Buffer.from(r,"base64url").toString("utf-8"));return typeof e.offset=="number"?e.offset:0}catch{return 0}}var or,cd,Fi=N(()=>{"use strict";h();Je();or=r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),cd=r=>{let e=r.trim();if(e==="null")return null;if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return!Number.isNaN(t)&&e!==""?t:hn(e)?yn(e):e}});var ir,Wt,ld,ud,md,dd,pd,Ki,Tn,fd,ji,hd,yd,gd,Yt,bd,Td,Ed,Hi,wd,cr,Wi=N(()=>{"use strict";h();Xe();Ze();ct();Je();te();Ve();Ui();ze();Fi();ir=r=>r instanceof Date?r.toISOString():typeof r=="bigint"?r.toString():r&&typeof r=="object"?"_bsontype"in r&&r._bsontype==="ObjectId"?r.toHexString():Array.isArray(r)?r.map(e=>ir(e)):Object.fromEntries(Object.entries(r).map(([e,t])=>[e,ir(t)])):r,Wt=r=>ir(r),ld=["sparse","expireAfterSeconds","partialFilterExpression","collation"],ud=r=>{let e=r.name??"",t=e==="_id_",n=Object.values(r.key),a=r.weights,s=a?Object.keys(r.key).flatMap(c=>c==="_fts"?Object.keys(a):c==="_ftsx"?[]:[c]):Object.keys(r.key),o={};a&&(o.weights=a);for(let c of ld){let l=r[c];l!=null&&l!==!1&&(o[c]=ir(l))}let i=n.every(c=>c===1)&&Object.keys(o).length===0;return{indexName:e,columns:s,isUnique:t||r.unique===!0,isSparse:r.sparse,expireAfterSeconds:r.expireAfterSeconds,method:n.find(c=>typeof c=="string")??null,kind:t?"primary":"index",definition:i?null:JSON.stringify({key:r.key,...o})}},md=new Set([85,86,11e3]),dd=r=>r instanceof Date?"date":r&&typeof r=="object"?Array.isArray(r)?"array":"_bsontype"in r?"text":"json":typeof r=="boolean"?"boolean":typeof r=="number"||typeof r=="bigint"?"number":"text",pd=r=>{switch(r){case"number":return"numeric";case"boolean":return"boolean";case"json":return"json";case"date":return"date";case"array":return"array";case"enum":return"enum";default:return"text"}},Ki=r=>typeof r=="string"&&hn(r),Tn=r=>yn(r),fd=r=>{if(!Number.isFinite(r))return"n/a";let e=["B","KB","MB","GB","TB"],t=r,n=0;for(;t>=1024&&n<e.length-1;)t/=1024,n++;return`${t.toFixed(1)} ${e[n]}`},ji=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),hd=r=>{let e=r.trim();if(ji.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},yd=r=>{if(r==null)return"null";if(r instanceof Date)return"date";if(typeof r=="boolean")return"bool";if(typeof r=="number")return Number.isInteger(r)?"int":"double";if(typeof r=="bigint")return"long";if(Array.isArray(r))return"array";if(typeof r=="object"){let e=r._bsontype;return e==="ObjectId"?"objectId":e==="Decimal128"?"decimal":e==="Binary"?"binData":e==="Timestamp"?"timestamp":e?e.toLowerCase():"object"}return"string"},gd=(r,e)=>{if(r!=null&&r.trim()!=="")try{return JSON.parse(r)}catch{return r}switch(e){case"string":return"";case"int":case"long":case"double":case"decimal":return 0;case"bool":return!1;case"array":return[];case"object":return{};case"date":return new Date;default:return null}},Yt=r=>{if(r._id&&typeof r._id=="string")return{...r,_id:Tn(r._id)};if(r._id&&typeof r._id=="object"){let e=r._id;if(Array.isArray(e.$in))return{...r,_id:{...e,$in:e.$in.map(t=>typeof t=="string"?Tn(t):t)}};if(Array.isArray(e.$nin))return{...r,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?Tn(t):t)}}}return r},bd=13,Td=8e3,Ed=51803,Hi={F:"fatal",E:"error",W:"warning",I:"info"},wd=({t:r,s:e,c:t,id:n,ctx:a,msg:s,attr:o={}})=>{if(n===Ed){let{ns:i,command:c,durationMillis:l,...u}=o,m=Object.fromEntries(Object.entries(c??{}).filter(([p])=>!p.startsWith("$")&&p!=="lsid"));return{ts:new Date(r.$date).toISOString(),level:Hi[e]??"debug",rawLevel:e,source:t,message:`${i} ${JSON.stringify(m)}`,durationMs:Number(l),detail:he({id:n,ctx:a,...u})}}return{ts:new Date(r.$date).toISOString(),level:Hi[e]??"debug",rawLevel:e,source:t,message:s,detail:he({id:n,ctx:a,...o})}},cr=class extends ae{runQuery(){throw new d(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new d(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(Wt(t)))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"int":case"long":case"double":case"decimal":return"number";case"bool":return"boolean";case"date":return"date";case"array":return"array";case"object":return"json";default:return"text"}}mapFromUniversalType(e){switch(e){case"number":return"double";case"boolean":return"bool";case"date":return"date";case"array":return"array";case"json":return"object";default:return"string"}}wrapError(e){if(e instanceof d)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new d(503,{message:e.message,cause:e})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:n,cursor:a,limit:s,direction:o="asc",sort:i,order:c,filters:l}=e,m=(await ne(n)).collection(t),p=qi(l??[]),f=ss(i??"",c),b=s&&s>0?s:50,y=Bi(a),g=Number.isFinite(y)&&y>=0?y:0,S=o==="desc"?Math.max(g-b,0):g,[w,D]=await Promise.all([m.countDocuments(p),m.find(p).sort(f).skip(S).limit(b).toArray()]),A=D.map(_=>Wt(_)),R=S+b,C=Math.max(S-b,0);return{data:A,meta:{limit:b,total:w,hasNextPage:R<w,hasPreviousPage:S>0,nextCursor:R<w?os(R):null,prevCursor:S>0?os(C):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let o=(await(await ne(t)).collection(e).find({}).limit(1e4).toArray()).map(c=>Wt(c));return{cols:Array.from(new Set(o.flatMap(c=>Object.keys(c)))),rows:o}}catch(n){throw this.wrapError(n)}}async getDatabasesList(){try{let a=(await(await Xn()).db().admin().listDatabases()).databases??[];if(!a[0])throw new d(500,{message:"No databases returned from MongoDB"});return vi(a,Zn()).map(s=>({name:s.name,size:fd(s.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:Zn()}}async getDatabaseConnectionInfo(){try{let t=(await Xn()).db().admin(),n=Oe(Ue()),a={};try{a=await t.serverStatus()}catch(s){Q("warn","db_server_status_failed",fe(s))}return{host:n.host,port:n.port,user:"n/a",database:Zn(),version:a.version??"unknown",active_connections:a.connections?.current??0,max_connections:(a.connections?.current??0)+(a.connections?.available??0)}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=await ne(e),n=await t.listCollections().toArray(),a=[];for(let s of n){let o=await t.collection(s.name).estimatedDocumentCount();a.push({tableName:s.name,rowCount:o})}return a}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){try{let n=e?.tableName??"",a=await ne(t);if((await a.listCollections({name:n}).toArray()).length>0)throw new d(400,{message:`Collection "${n}" already exists`});let o=e?.fields??[];if(o.length===0){await a.createCollection(n);return}let i={},c=[];for(let l of o){let u=hd(l.columnType);if(!ji.has(u))throw new d(400,{message:`Unsupported MongoDB BSON type "${l.columnType}" for field "${l.columnName}"`});l.isArray?i[l.columnName]={bsonType:"array",...u!=="array"?{items:{bsonType:u}}:{}}:i[l.columnName]={bsonType:u},l.isNullable||c.push(l.columnName)}await a.createCollection(n,{validator:{$jsonSchema:{bsonType:"object",required:c,properties:i,additionalProperties:!0}},validationAction:"error"})}catch(n){throw this.wrapError(n)}}async deleteTable({tableName:e,db:t}){try{let a=(await ne(t)).collection(e),s=await a.estimatedDocumentCount();return await a.drop(),{deletedCount:s,fkViolation:!1,relatedRecords:[]}}catch(n){throw this.wrapError(n)}}async renameTable(e){try{let{tableName:t,newTableName:n,db:a}=e;this.assertDifferentTableName(t,n);let s=await ne(a);if((await s.listCollections({name:t}).toArray()).length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if((await s.listCollections({name:n}).toArray()).length>0)throw new d(409,{message:`Collection "${n}" already exists`});await s.collection(t).rename(n)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){try{let n=await ne(t);if((await n.listCollections({name:e}).toArray()).length===0)throw new d(404,{message:`Collection "${e}" does not exist`});let s=n.collection(e),o=await s.find({}).limit(200).toArray(),i=await s.estimatedDocumentCount(),c=new Map,l=new Map;for(let f of o)for(let[b,y]of Object.entries(f)){let g=yd(y);c.has(b)||(c.set(b,new Set),l.set(b,0)),c.get(b)?.add(g),l.set(b,(l.get(b)??0)+1)}let u={},m=[];for(let[f,b]of c.entries()){let y=l.get(f)??0,g=Array.from(b).filter(w=>w!=="null"),S=b.has("null")||y<o.length;y===o.length&&o.length>0&&!S&&m.push(f),u[f]=g.length===1?{bsonType:S?[g[0],"null"]:g[0]}:{bsonType:S?[...g,"null"]:g}}let p={collection:e,estimatedDocumentCount:i,sampledDocuments:o.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(p,null,2)}catch(n){throw this.wrapError(n)}}async getTableColumns({tableName:e,db:t}){try{let s=await(await ne(t)).collection(e).find({}).limit(200).toArray(),o=s.length,i=new Map,c=(l,u)=>{let m=dd(u);if(!i.has(l))i.set(l,{types:new Set([m]),nullable:!1,presentCount:1});else{let p=i.get(l);p.types.add(m),p.presentCount+=1}};for(let l of s)for(let[u,m]of Object.entries(l)){if(m==null){if(!i.has(u))i.set(u,{types:new Set(["text"]),nullable:!0,presentCount:1});else{let p=i.get(u);p.nullable=!0,p.presentCount+=1}continue}c(u,m)}if(o>0)for(let l of i.values())l.presentCount<o&&(l.nullable=!0);return i.has("_id")||i.set("_id",{types:new Set(["text"]),nullable:!1,presentCount:o}),Array.from(i.entries()).map(([l,u])=>{let m=u.types.values().next().value??"text";return{columnName:l,dataType:m,dataTypeLabel:pd(m),isNullable:u.nullable,columnDefault:null,isPrimaryKey:l==="_id",isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}})}catch(n){throw this.wrapError(n)}}async addColumn(e){try{let{tableName:t,columnName:n,columnType:a,defaultValue:s,isNullable:o,db:i}=e,c=await ne(i),l=await c.listCollections({name:t}).toArray();if(l.length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if(await c.collection(t).findOne({[n]:{$exists:!0}}))throw new d(409,{message:`Field "${n}" already exists in collection "${t}"`});let m=gd(s,a);await c.collection(t).updateMany({},{$set:{[n]:m}});let f=l[0].options?.validator?.$jsonSchema??{},b={...f.properties??{},[n]:{bsonType:o?[a,"null"]:a}},y=[...f.required??[]];!o&&!y.includes(n)&&y.push(n),await c.command({collMod:t,validator:{$jsonSchema:{...f,bsonType:"object",properties:b,...y.length>0?{required:y}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:n}){try{return{deletedCount:(await(await ne(n)).collection(e).updateMany({},{$unset:{[t]:""}})).modifiedCount}}catch(a){throw this.wrapError(a)}}async alterColumn(e){try{let{tableName:t,columnName:n,columnType:a,isNullable:s,db:o}=e,i=await ne(o),c=await i.listCollections({name:t}).toArray();if(c.length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if(n==="_id")throw new d(400,{message:'Cannot alter the "_id" field'});let u=c[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},p=[...u.required??[]];m[n]={bsonType:s?[a,"null"]:a};let f=p.indexOf(n);!s&&f===-1?p.push(n):s&&f!==-1&&p.splice(f,1),await i.command({collMod:t,validator:{$jsonSchema:{...u,bsonType:"object",properties:m,...p.length>0?{required:p}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async renameColumn(e){try{let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await ne(s);if((await o.listCollections({name:t}).toArray()).length===0)throw new d(404,{message:`Collection "${t}" does not exist`});if(n==="_id")throw new d(400,{message:'Cannot rename the "_id" field'});if(!await o.collection(t).findOne({[n]:{$exists:!0}}))throw new d(404,{message:`Field "${n}" does not exist in collection "${t}"`});if(await o.collection(t).findOne({[a]:{$exists:!0}}))throw new d(409,{message:`Field "${a}" already exists in collection "${t}"`});await o.collection(t).updateMany({[n]:{$exists:!0}},{$rename:{[n]:a}})}catch(t){throw this.wrapError(t)}}async getServerLogs(){try{let e=await Xn(),{log:t}=await e.db("admin").command({getLog:"global"}),n=t.flatMap(a=>{try{return[wd(JSON.parse(a))]}catch{return[]}});return{available:!0,source:"getLog: 'global' (the server keeps the newest 1024 entries)",entries:Ie(n)}}catch(e){let t=e.code;if(t===bd)return re("Reading the server log needs the getLog action, which the clusterMonitor role grants.");if(t===Td)return re("This Atlas tier does not allow getLog.");throw this.wrapError(e)}}async listIndexes(e,t){if((await e.listCollections({name:t}).toArray()).length===0)throw new d(404,{message:`Collection "${t}" does not exist`});return(await e.collection(t).listIndexes().toArray()).map(ud).sort((s,o)=>+(o.kind==="primary")-+(s.kind==="primary")||(s.indexName<o.indexName?-1:s.indexName>o.indexName?1:0))}async getTableIndexes({tableName:e,db:t}){try{return await this.listIndexes(await ne(t),e)}catch(n){throw this.wrapError(n)}}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o,db:i}=e;try{if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});let c=a.find(m=>m.split(".").some(p=>p===""||p.startsWith("$")));if(c!==void 0)throw new d(400,{message:`Invalid field path "${c}"`});if(new Set(a).size!==a.length)throw new d(400,{message:"A field can appear only once in an index"});let l=await ne(i);if((await this.listIndexes(l,t)).some(m=>m.indexName===n))throw new d(409,{message:`Index "${n}" already exists on collection "${t}"`});await l.collection(t).createIndex(new Map(a.map(m=>[m,1])),{name:n,unique:s})}catch(c){let l=c.code;throw c instanceof Error&&typeof l=="number"&&md.has(l)?new d(409,{message:c.message,cause:c}):this.wrapError(c)}}async dropIndex({tableName:e,indexName:t,db:n}){try{let a=await ne(n),s=(await this.listIndexes(a,e)).find(o=>o.indexName===t);if(!s)throw new d(404,{message:`Index "${t}" does not exist on collection "${e}"`});if(s.kind==="primary")throw new d(400,{message:`Index "${t}" backs the primary key and cannot be dropped`});await a.collection(e).dropIndex(t)}catch(a){throw this.wrapError(a)}}async addRecord({db:e,params:t}){try{let{tableName:n,data:a}=t,o=(await ne(e)).collection(n),i=Wt(a);if((i._id===""||i._id===null)&&delete i._id,!(await o.insertOne(i)).insertedId)throw new d(500,{message:`Failed to insert record into "${n}"`});return{insertedCount:1}}catch(n){throw this.wrapError(n)}}async updateRecords({db:e,params:t}){try{let{tableName:n}=t,s=(await ne(e)).collection(n),o=0,i=this.resolveKeyColumns(t).map(l=>l||"_id"),c=this.groupUpdatesByKey({...t,primaryKeys:i},i);for(let{keyValues:l,rowUpdates:u}of c){if(u.some(b=>b.columnName==="_id"))throw new d(400,{message:'The "_id" field is immutable and cannot be updated.'});let m={};for(let b of u)m[b.columnName]=b.value;let p={};i.forEach((b,y)=>{let g=l[y];p[b]=b==="_id"&&Ki(g)?Tn(g):g});let f=await s.updateOne(p,{$set:m});if(f.matchedCount===0)throw new d(404,{message:`Record with ${this.describeKey(i,l)} not found in "${n}"`});o+=f.modifiedCount}return{updatedCount:o}}catch(n){throw this.wrapError(n)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:n,db:a}=e,o=(await ne(a)).collection(t),i=n[0]?.columnName??"_id",c=n.map(u=>i==="_id"&&Ki(u.value)?Tn(u.value):u.value);return{deletedCount:(await o.deleteMany({[i]:{$in:c}})).deletedCount??0,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:n,db:a}=e;if(!n||n.length===0)throw new d(400,{message:"At least one record is required"});let o=(await ne(a)).collection(t),i=n.map(l=>{let u=Wt(l);return(u._id===""||u._id===null)&&delete u._id,u}),c=await o.insertMany(i,{ordered:!1});return{success:!0,message:`Successfully inserted ${c.insertedCount} record${c.insertedCount!==1?"s":""}`,successCount:c.insertedCount,failureCount:n.length-c.insertedCount}}catch(t){throw this.wrapError(t)}}async executeQuery({query:e,db:t}){try{if(!e?.trim())throw new d(400,{message:"Query is required"});let n;try{n=JSON.parse(e)}catch{throw new d(400,{message:"Mongo query must be valid JSON"})}if(!n.collection||!n.operation)throw new d(400,{message:"Mongo query must include collection and operation"});let s=(await ne(t)).collection(n.collection),o=performance.now(),i=[],c=0,l;switch(n.operation){case"find":{let f=Yt(n.filter??{}),b=s.find(f,n.options??{});b.sort(n.sort??ss("",void 0)),n.skip&&b.skip(n.skip),n.limit&&b.limit(n.limit),i=await b.toArray(),c=i.length;break}case"aggregate":{i=await s.aggregate(n.pipeline??[],n.options??{}).toArray(),c=i.length;break}case"insertOne":{let f=n.document;if(!f)throw new d(400,{message:"document is required"});c=(await s.insertOne(f)).insertedId?1:0,l="OK";break}case"insertMany":{let f=n.document;if(!Array.isArray(f))throw new d(400,{message:"document array is required"});c=(await s.insertMany(f)).insertedCount??0,l="OK";break}case"updateOne":{let f=Yt(n.filter??{});if(!n.update)throw new d(400,{message:"update is required"});let b=await s.updateOne(f,n.update,n.options??{});c=b.matchedCount??0,l=`OK (${b.modifiedCount??0} modified)`;break}case"updateMany":{let f=Yt(n.filter??{});if(!n.update)throw new d(400,{message:"update is required"});let b=await s.updateMany(f,n.update,n.options??{});c=b.matchedCount??0,l=`OK (${b.modifiedCount??0} modified)`;break}case"deleteOne":{let f=Yt(n.filter??{});c=(await s.deleteOne(f,n.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let f=Yt(n.filter??{});c=(await s.deleteMany(f,n.options??{})).deletedCount??0,l="OK";break}case"count":{let f=Yt(n.filter??{});c=await s.countDocuments(f),i=[{count:c}],l="OK";break}default:throw new d(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-o,m=i.map(f=>Wt(f));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:c,duration:u,message:l}}catch(n){throw this.wrapError(n)}}}});function is(r,e=0){if(r.length===0)return{clause:"",values:[],nextIdx:e};let t=[],n=[],a=e;for(let s of r){let o=lr(s.columnName);switch(s.operator){case"=":case"!=":case">":case">=":case"<":case"<=":t.push(`${o} ${s.operator} @p${a}`),n.push(s.value),a++;break;case"is":s.value.toLowerCase()==="null"?t.push(`${o} IS NULL`):(t.push(`${o} = @p${a}`),n.push(s.value),a++);break;case"is not":s.value.toLowerCase()==="null"?t.push(`${o} IS NOT NULL`):(t.push(`${o} != @p${a}`),n.push(s.value),a++);break;case"like":case"ilike":t.push(`${o} LIKE @p${a}`),n.push(s.value),a++;break;case"not like":case"not ilike":t.push(`${o} NOT LIKE @p${a}`),n.push(s.value),a++;break;default:break}}return t.length===0?{clause:"",values:[],nextIdx:e}:{clause:`WHERE ${t.join(" AND ")}`,values:n,nextIdx:a}}function cs(r,e){return Array.isArray(r)?r.length===0?"":`ORDER BY ${r.map(t=>`${lr(t.columnName)} ${t.direction.toUpperCase()}`).join(", ")}`:r&&typeof r=="string"?`ORDER BY ${lr(r)} ${e?.toUpperCase()||"ASC"}`:""}function Yi(r,e,t){let n=cs(r,e),a=Array.isArray(r)?r.map(i=>i.columnName):[r],s=(Array.isArray(r)?r[0]?.direction??e:e).toUpperCase(),o=t.filter(i=>!a.includes(i)).map(i=>`${lr(i)} ${s}`).join(", ");return o?n?`${n}, ${o}`:`ORDER BY ${o}`:n||"ORDER BY (SELECT NULL)"}function ls(r,e){if(e)return"NVARCHAR(MAX)";let t=r.toLowerCase().trim();return{serial:"INT IDENTITY(1,1)",serial4:"INT IDENTITY(1,1)",bigserial:"BIGINT IDENTITY(1,1)",serial8:"BIGINT IDENTITY(1,1)",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",tinyint:"TINYINT",numeric:"NUMERIC",decimal:"DECIMAL",real:"REAL",float4:"REAL",float:"FLOAT","double precision":"FLOAT",float8:"FLOAT",money:"MONEY",boolean:"BIT",bool:"BIT",text:"NVARCHAR(MAX)",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"UNIQUEIDENTIFIER",json:"NVARCHAR(MAX)",jsonb:"NVARCHAR(MAX)",xml:"XML",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME2","timestamp without time zone":"DATETIME2","timestamp with time zone":"DATETIMEOFFSET",timestamptz:"DATETIMEOFFSET",interval:"VARCHAR(255)",bytea:"VARBINARY(MAX)",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)"}[t]||r.toUpperCase()}function us(r,e){let t=r.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("newid()")?e.toUpperCase().includes("UNIQUEIDENTIFIER")?"NEWID()":null:t.includes("getdate")||t.includes("current_timestamp")?"GETDATE()":r.trim():t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":r.trim()}function Vi(r,e={}){let t=ls(r.columnType,r.isArray??!1),n=`[${r.columnName}] ${t}`;if(r.isIdentity&&!t.includes("IDENTITY")&&(n+=" IDENTITY(1,1)"),!r.isNullable&&!r.isPrimaryKey&&(n+=" NOT NULL"),r.defaultValue?.trim()&&!t.includes("IDENTITY")){let a=us(r.defaultValue,t);a!==null&&(n+=` DEFAULT ${a}`)}return e.includeUnique&&r.isUnique&&!r.isPrimaryKey&&(n+=" UNIQUE"),e.includePrimaryKey&&r.isPrimaryKey&&(n+=" PRIMARY KEY"),n}var lr,zi=N(()=>{"use strict";h();lr=r=>`[${r.replaceAll("]","]]")}]`});var Sd,Cd,Rd,Gi,Nd,Ad,Dd,_d,Od,Id,xd,Ne,ur,Qi=N(()=>{"use strict";h();z();Xe();Ze();ct();te();ze();zi();Sd=547,Cd=15003,Rd=27219,Gi=r=>[229,230].includes(r.number??0),Nd=2812,Ad=/^Error: (\d+), Severity: (\d+), State: (\d+)\.?$/,Dd=3726,_d=1913,Od=1505,Id=new Set([1919,1978]),xd=3723,Ne=r=>`[${r.replaceAll("]","]]")}]`,ur=class extends ae{async runQuery(e,t,n){let s=(await H(e)).request();return n.forEach((i,c)=>{s.input(`p${c}`,i)}),(await s.query(t)).recordset}quoteIdentifier(e){return Ne(e)}mapToUniversalType(e){return In(e)}mapFromUniversalType(e){return{text:"NVARCHAR(MAX)",number:"INT",boolean:"BIT",json:"NVARCHAR(MAX)",date:"DATETIME2",array:"NVARCHAR(MAX)",enum:"NVARCHAR(255)"}[e]??"NVARCHAR(MAX)"}buildTableDataQuery(e){let{tableName:t,filters:n=[],sort:a=[],order:s="asc",limit:o=50,cursor:i}=e,{clause:c,values:l,nextIdx:u}=is(n,0),m=cs(a,s)||"ORDER BY (SELECT NULL)",p=i?this.decodeOffsetCursor(i):0,f=`SELECT * FROM ${Ne(t)} ${c} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,b=[...l,p,o+1],y=`SELECT COUNT(*) as total FROM ${Ne(t)} ${c}`;return{sql:f,values:b,countSql:y,countValues:l}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,n){let{cursor:a,limit:s=50}=e,o=a?this.decodeOffsetCursor(a):0;return{nextCursor:n?this.makeCursor(o+s):null,prevCursor:o>0?this.makeCursor(Math.max(0,o-s)):null}}async getTableData(e){try{let{tableName:t,db:n,limit:a=50,sort:s=[],order:o="asc",cursor:i,filters:c=[]}=e,l=await H(n),u=i?this.decodeOffsetCursor(i):0,{clause:m,values:p,nextIdx:f}=is(c,0),[b,{total:y,estimated:g}]=await Promise.all([this.getPrimaryKeyColumns(l,t),this.countRows(l,t,m,p)]),S=Yi(s,o,b),w=l.request();p.forEach((C,_)=>{w.input(`p${_}`,C)}),w.input(`p${f}`,u),w.input(`p${f+1}`,a+1);let A=(await w.query(`SELECT * FROM ${Ne(t)} ${m} ${S} OFFSET @p${f} ROWS FETCH NEXT @p${f+1} ROWS ONLY`)).recordset,R=A.length>a;return R&&(A=A.slice(0,a)),{data:A,meta:{limit:a,total:y,...g&&{totalEstimated:!0},hasNextPage:R,hasPreviousPage:u>0,nextCursor:R?this.makeCursor(u+a):null,prevCursor:u>0?this.makeCursor(Math.max(0,u-a)):null}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=await(await H()).request().query(`
|
|
46
46
|
SELECT
|
|
47
47
|
d.name AS name,
|
|
48
|
-
CAST(ROUND(CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)), 2) AS VARCHAR(20)) + ' MB' AS size,
|
|
49
|
-
SUSER_SNAME(d.owner_sid) AS owner,
|
|
48
|
+
ISNULL(CAST(ROUND(CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)), 2) AS VARCHAR(20)) + ' MB', '') AS size,
|
|
49
|
+
ISNULL(SUSER_SNAME(d.owner_sid), '') AS owner,
|
|
50
50
|
d.collation_name AS encoding
|
|
51
51
|
FROM sys.databases d
|
|
52
|
-
JOIN sys.master_files mf ON d.database_id = mf.database_id
|
|
53
|
-
WHERE (d.database_id > 4 OR d.name = DB_NAME())
|
|
52
|
+
LEFT JOIN sys.master_files mf ON d.database_id = mf.database_id
|
|
53
|
+
WHERE (d.database_id > 4 OR d.name = DB_NAME()) AND HAS_DBACCESS(d.name) = 1
|
|
54
54
|
GROUP BY d.name, d.owner_sid, d.collation_name
|
|
55
55
|
ORDER BY d.name
|
|
56
|
-
`);if(!t.recordset[0])throw new d(500,{message:"No databases returned from server"});return t.recordset}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let t=await(await
|
|
56
|
+
`);if(!t.recordset[0])throw new d(500,{message:"No databases returned from server"});return t.recordset}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let t=await(await H()).request().query("SELECT DB_NAME() AS db");if(!t.recordset[0])throw new d(500,{message:"No current database returned from server"});return t.recordset[0]}async getDatabaseConnectionInfo(){let t=await(await H()).request().query(`
|
|
57
57
|
SELECT
|
|
58
58
|
@@VERSION AS version,
|
|
59
59
|
DB_NAME() AS database_name,
|
|
60
60
|
SUSER_NAME() AS [user],
|
|
61
61
|
@@SERVERNAME AS host,
|
|
62
|
-
(
|
|
62
|
+
CONNECTIONPROPERTY('local_tcp_port') AS port,
|
|
63
63
|
@@MAX_CONNECTIONS AS max_connections,
|
|
64
64
|
(SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1) AS active_connections
|
|
65
|
-
`);if(!t.recordset[0])throw new d(500,{message:"No connection information returned from server"});let n=t.recordset[0],a=
|
|
65
|
+
`);if(!t.recordset[0])throw new d(500,{message:"No connection information returned from server"});let n=t.recordset[0],a=Oe(Ue());return{host:String(n.host||a.host),port:Number(n.port||a.port),user:String(n.user),database:String(n.database_name??""),version:String(n.version),active_connections:Number(n.active_connections??0),max_connections:Number(n.max_connections)}}async getTablesList(e){let t=await H(e),n=await this.rowEstimates(t);return Promise.all([...n].map(async([a,s])=>{if(s>=it)return{tableName:a,rowCount:s,rowCountEstimated:!0};try{let o=await t.request().query(`SELECT COUNT(*) as count FROM ${Ne(a)}`);return{tableName:a,rowCount:Number(o.recordset[0]?.count??0)}}catch(o){if(!Gi(o))throw o;return{tableName:a,rowCount:s,rowCountEstimated:!0}}}))}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e,o=await H(t),i=a.map(m=>{let p=ls(m.columnType,m.isArray??!1),f=`[${m.columnName}] ${p}`;if(!m.isNullable&&!m.isPrimaryKey&&(f+=" NOT NULL"),m.defaultValue&&!p.includes("IDENTITY")){let b=us(m.defaultValue,p);b!==null&&(f+=` DEFAULT ${b}`)}return f}),c=[],l=a.filter(m=>m.isPrimaryKey);l.length>0&&c.push(`PRIMARY KEY (${l.map(m=>`[${m.columnName}]`).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&c.push(`UNIQUE ([${m.columnName}])`);let u=s?.map(m=>`CONSTRAINT [${`FK_${n}_${m.columnName}`}] FOREIGN KEY ([${m.columnName}]) REFERENCES [${m.referencedTable}] ([${m.referencedColumn}]) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await o.request().query(`CREATE TABLE [${n}] (
|
|
66
66
|
${[...i,...c,...u].join(`,
|
|
67
67
|
`)}
|
|
68
|
-
)`)}async deleteTable(e){let{tableName:t,db:n,cascade:a}=e,s=await
|
|
68
|
+
)`)}async deleteTable(e){let{tableName:t,db:n,cascade:a}=e,s=await H(n),o=await s.request().input("tableName",t).query(`
|
|
69
69
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
70
70
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
71
|
-
`);if(Number(o.recordset[0]?.cnt??0)===0)throw new d(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(t,n);if(!a){let c=await this.getRelatedRecordsForTable(t,n);if(c.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:c}}try{if(a){let c=await this.getForeignKeyReferences(t,n);for(let l of c)await s.request().query(`ALTER TABLE [${l.referencingTable}] DROP CONSTRAINT [${l.constraintName}]`)}return await s.request().query(`DROP TABLE [${t}]`),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(c){if(c.number===
|
|
71
|
+
`);if(Number(o.recordset[0]?.cnt??0)===0)throw new d(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(t,n);if(!a){let c=await this.getRelatedRecordsForTable(t,n);if(c.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:c}}try{if(a){let c=await this.getForeignKeyReferences(t,n);for(let l of c)await s.request().query(`ALTER TABLE [${l.referencingTable}] DROP CONSTRAINT [${l.constraintName}]`)}return await s.request().query(`DROP TABLE [${t}]`),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(c){if(c.number===Dd)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,n)};throw c instanceof d?c:new d(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:n,db:a}=e;this.assertDifferentTableName(t,n);let s=await H(a);await this.assertTableExists(s,t);let o=await s.request().input("tableName",n).query(`
|
|
72
72
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
73
73
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
74
|
-
`);if(Number(o.recordset[0]?.cnt??0)>0)throw new d(409,{message:`Table "${n}" already exists`});await s.request().input("oldName",t).input("newName",n).query("EXEC sp_rename @oldName, @newName")}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let n=await
|
|
74
|
+
`);if(Number(o.recordset[0]?.cnt??0)>0)throw new d(409,{message:`Table "${n}" already exists`});await s.request().input("oldName",t).input("newName",n).query("EXEC sp_rename @oldName, @newName")}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let n=await H(t),a=await n.request().input("tableName",e).query(`
|
|
75
75
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
76
76
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
77
77
|
`);if(Number(a.recordset[0]?.cnt??0)===0)throw new d(404,{message:`Table "${e}" does not exist`});let s=await n.request().input("tableName",e).query(`
|
|
@@ -113,7 +113,7 @@ var pl=Object.defineProperty;var N=(r,e)=>()=>(r&&(e=r(r=0)),e);var Dt=(r,e)=>{f
|
|
|
113
113
|
`);if(!s.recordset||s.recordset.length===0)throw new d(500,{message:`Failed to retrieve schema for table "${e}"`});let o=s.recordset.map(i=>{let c=` [${i.COLUMN_NAME}] ${i.DATA_TYPE}`;return i.CHARACTER_MAXIMUM_LENGTH?c+=i.CHARACTER_MAXIMUM_LENGTH===-1?"(MAX)":`(${i.CHARACTER_MAXIMUM_LENGTH})`:i.NUMERIC_PRECISION!==null&&i.NUMERIC_SCALE!==null?c+=`(${i.NUMERIC_PRECISION},${i.NUMERIC_SCALE})`:i.NUMERIC_PRECISION!==null&&(c+=`(${i.NUMERIC_PRECISION})`),c+=i.IS_NULLABLE==="YES"?" NULL":" NOT NULL",i.COLUMN_DEFAULT&&(c+=` DEFAULT ${i.COLUMN_DEFAULT}`),c});return`CREATE TABLE [${e}] (
|
|
114
114
|
${o.join(`,
|
|
115
115
|
`)}
|
|
116
|
-
)`}async getTableColumns({tableName:e,db:t}){let n=await
|
|
116
|
+
)`}async getTableColumns({tableName:e,db:t}){let n=await H(t),a=await n.request().input("tableName",e).query(`
|
|
117
117
|
SELECT
|
|
118
118
|
c.COLUMN_NAME AS columnName,
|
|
119
119
|
c.DATA_TYPE AS dataType,
|
|
@@ -157,22 +157,22 @@ ${o.join(`,
|
|
|
157
157
|
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cc
|
|
158
158
|
ON chk.CONSTRAINT_NAME = cc.CONSTRAINT_NAME AND cc.TABLE_SCHEMA = 'dbo'
|
|
159
159
|
WHERE cc.TABLE_NAME = @tableName AND cc.TABLE_CATALOG = DB_NAME()
|
|
160
|
-
`),o=new Map;for(let i of s.recordset){let c=this.parseCheckConstraintValues(i.checkClause);c&&o.set(i.columnName,c)}return a.recordset.map(i=>{let c=o.get(i.columnName)??null;return{columnName:i.columnName,dataType:c?"enum":
|
|
160
|
+
`),o=new Map;for(let i of s.recordset){let c=this.parseCheckConstraintValues(i.checkClause);c&&o.set(i.columnName,c)}return a.recordset.map(i=>{let c=o.get(i.columnName)??null;return{columnName:i.columnName,dataType:c?"enum":In(i.dataType),dataTypeLabel:c?"enum":Ur(i.dataType),isNullable:!!i.isNullable,columnDefault:i.columnDefault??null,isPrimaryKey:!!i.isPrimaryKey,isForeignKey:!!i.isForeignKey,referencedTable:i.referencedTable??null,referencedColumn:i.referencedColumn??null,enumValues:c}})}async addColumn(e){let{tableName:t,columnName:n,columnType:a,defaultValue:s,isPrimaryKey:o,isNullable:i,isUnique:c,isIdentity:l,db:u}=e,m=await H(u);await this.assertTableExists(m,t);let p=await m.request().input("tableName",t).input("columnName",n).query(`
|
|
161
161
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
162
162
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
163
|
-
`);if(Number(p.recordset[0]?.cnt??0)>0)throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let f=
|
|
163
|
+
`);if(Number(p.recordset[0]?.cnt??0)>0)throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let f=Vi({columnName:n,columnType:a,defaultValue:s,isPrimaryKey:o,isNullable:i,isUnique:c,isIdentity:l},{includePrimaryKey:!0,includeUnique:!0});await m.request().query(`ALTER TABLE [${t}] ADD ${f}`)}async deleteColumn(e){let{tableName:t,columnName:n,db:a}=e,s=await H(a);return await this.assertTableExists(s,t),await this.assertColumnExists(s,t,n),{deletedCount:(await s.request().query(`ALTER TABLE [${t}] DROP COLUMN [${n}]`)).rowsAffected[0]??1}}async alterColumn(e){let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o,db:i}=e,c=await H(i);await this.assertTableExists(c,t),await this.assertColumnExists(c,t,n);let u=(await c.request().input("tableName",t).input("columnName",n).query(`
|
|
164
164
|
SELECT dc.name AS constraint_name
|
|
165
165
|
FROM sys.default_constraints dc
|
|
166
166
|
JOIN sys.columns c
|
|
167
167
|
ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
|
|
168
168
|
WHERE OBJECT_NAME(dc.parent_object_id) = @tableName AND c.name = @columnName
|
|
169
|
-
`)).recordset[0]?.constraint_name;u&&await c.request().query(`ALTER TABLE [${t}] DROP CONSTRAINT [${u}]`);let m=s?"NULL":"NOT NULL";await c.request().query(`ALTER TABLE [${t}] ALTER COLUMN [${n}] ${a} ${m}`),o?.trim()&&await c.request().query(`ALTER TABLE [${t}] ADD DEFAULT ${o.trim()} FOR [${n}]`)}async renameColumn(e){let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await
|
|
169
|
+
`)).recordset[0]?.constraint_name;u&&await c.request().query(`ALTER TABLE [${t}] DROP CONSTRAINT [${u}]`);let m=s?"NULL":"NOT NULL";await c.request().query(`ALTER TABLE [${t}] ALTER COLUMN [${n}] ${a} ${m}`),o?.trim()&&await c.request().query(`ALTER TABLE [${t}] ADD DEFAULT ${o.trim()} FOR [${n}]`)}async renameColumn(e){let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await H(s);await this.assertTableExists(o,t),await this.assertColumnExists(o,t,n);let i=await o.request().input("tableName",t).input("columnName",a).query(`
|
|
170
170
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
171
171
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
172
|
-
`);if(Number(i.recordset[0]?.cnt??0)>0)throw new d(409,{message:`Column "${a}" already exists in table "${t}"`});await o.request().query(`EXEC sp_rename '${t}.${n}', '${a}', 'COLUMN'`)}async getServerLogs({db:e}){let t=await
|
|
172
|
+
`);if(Number(i.recordset[0]?.cnt??0)>0)throw new d(409,{message:`Column "${a}" already exists in table "${t}"`});await o.request().query(`EXEC sp_rename '${t}.${n}', '${a}', 'COLUMN'`)}async getServerLogs({db:e}){let t=await H(e);try{let n=await t.request().query("EXEC sp_readerrorlog 0, 1; SELECT DATEDIFF(MINUTE, GETUTCDATE(), GETDATE()) AS offset"),[a,[{offset:s}]]=n.recordsets,o=[],i=null;for(let c of a){let l=Ad.exec(c.Text);if(l){i={code:l[1],severity:Number(l[2]),process:c.ProcessInfo};continue}let u=i?.process===c.ProcessInfo?i:null;i=null,o.push({ts:new Date(c.LogDate.getTime()-s*6e4).toISOString(),level:u?u.severity>=20?"fatal":u.severity>=11?"error":"warning":"info",rawLevel:u?`Severity ${u.severity}`:"Info",source:c.ProcessInfo,code:u?.code,message:c.Text,detail:{}})}return{available:!0,source:"sp_readerrorlog",entries:Ie(o)}}catch(n){let a=n.number;if(a===Cd||a===Rd)return re("Reading the error log needs the securityadmin server role: ALTER SERVER ROLE securityadmin ADD MEMBER <login>;");if(a===Nd)return re("This server has no error log to read. Azure SQL Database keeps its logs in Azure Monitor.");throw this.wrapError(n)}}async getTableIndexes({tableName:e,db:t}){try{return await this.listIndexes(await H(t),e)}catch(n){throw this.wrapError(n)}}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o,db:i}=e;try{let c=await H(i);await this.assertTableExists(c,t);let l=await c.request().input("tableName",t).query(`
|
|
173
173
|
SELECT COLUMN_NAME AS columnName FROM INFORMATION_SCHEMA.COLUMNS
|
|
174
174
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
175
|
-
`),u=new Set(l.recordset.map(p=>p.columnName)),m=a.find(p=>!u.has(p));if(m!==void 0)throw new d(400,{message:`Column "${m}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});await c.request().query(`CREATE ${s?"UNIQUE ":""}INDEX ${
|
|
175
|
+
`),u=new Set(l.recordset.map(p=>p.columnName)),m=a.find(p=>!u.has(p));if(m!==void 0)throw new d(400,{message:`Column "${m}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});await c.request().query(`CREATE ${s?"UNIQUE ":""}INDEX ${Ne(n)} ON [dbo].${Ne(t)} (${a.map(Ne).join(", ")})`)}catch(c){let l=c.number;throw c instanceof Error&&(l===_d||l===Od)?new d(409,{message:c.message,cause:c}):c instanceof Error&&l!==void 0&&Id.has(l)?new d(400,{message:c.message,cause:c}):this.wrapError(c)}}async dropIndex({tableName:e,indexName:t,db:n}){try{let a=await H(n),s=(await this.listIndexes(a,e)).find(o=>o.indexName===t);if(!s)throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});if(s.kind!=="index")throw new d(400,{message:`Index "${t}" backs a constraint; drop the constraint to remove it`});await a.request().query(`DROP INDEX ${Ne(t)} ON [dbo].${Ne(e)}`)}catch(a){throw a instanceof Error&&a.number===xd?new d(400,{message:a.message,cause:a}):this.wrapError(a)}}async addRecord({db:e,params:t}){let{tableName:n,data:a}=t,s=await H(e),o=await this.getBooleanColumnSet(n,e),i=await s.request().input("tableName",n).query("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(@tableName) AND is_identity = 1"),c=new Set(i.recordset.map(y=>y.name)),l=Object.keys(a).filter(y=>!c.has(y)),u=l.map(y=>{let g=a[y];return o.has(y)&&typeof g=="string"?g==="true"?1:0:g}),m=l.map(y=>`[${y}]`).join(", "),p=l.map((y,g)=>`@param${g}`).join(", "),f=s.request();l.forEach((y,g)=>{f.input(`param${g}`,u[g])});let b=await f.query(`INSERT INTO [${n}] (${m}) VALUES (${p})`);if(b.rowsAffected[0]===0)throw new d(500,{message:`Failed to insert record into "${n}"`});return{insertedCount:b.rowsAffected[0]??0}}async updateRecords({params:e,db:t}){let{tableName:n}=e,a=await H(t),s=await this.getBooleanColumnSet(n,t),o=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,n),o);let i=this.groupUpdatesByKey(e,o),c=a.transaction();await c.begin();try{let l=0;for(let{keyValues:u,rowUpdates:m}of i){let p=c.request(),f=m.map((g,S)=>`[${g.columnName}] = @value${S}`);m.forEach((g,S)=>{let w=g.value;w!==null&&typeof w=="object"&&(w=JSON.stringify(w)),s.has(g.columnName)&&typeof w=="string"&&(w=w==="true"?1:0),p.input(`value${S}`,w)}),u.forEach((g,S)=>{p.input(`pkValue${S}`,g)});let b=o.map((g,S)=>`[${g}] = @pkValue${S}`),y=await p.query(`UPDATE [${n}] SET ${f.join(", ")} WHERE ${b.join(" AND ")}`);if(y.rowsAffected[0]===0)throw new d(404,{message:`Record with ${this.describeKey(o,u)} not found in table "${n}"`});l+=y.rowsAffected[0]??0}return await c.commit(),{updatedCount:l}}catch(l){throw await c.rollback(),l instanceof d?l:new d(500,{message:`Failed to update records in "${n}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:n}){let a=await H(n),s=t[0]?.columnName;if(!s)throw new d(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let o=t.map(c=>c.value),i=a.transaction();await i.begin();try{let c=i.request();o.forEach((m,p)=>{c.input(`pk${p}`,m)});let l=o.map((m,p)=>`@pk${p}`).join(", "),u=await c.query(`DELETE FROM [${e}] WHERE [${s}] IN (${l})`);return await i.commit(),{deletedCount:u.rowsAffected[0]??0,fkViolation:!1,relatedRecords:[]}}catch(c){if(await i.rollback(),c.number===Sd)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,n)};throw c instanceof d?c:new d(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:n}){let a=await H(n),s=t[0]?.columnName;if(!s)throw new d(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let o=t.map(c=>c.value),i=a.transaction();await i.begin();try{let c=await this.getForeignKeyReferences(e,n),l=0,u=new Set,m=new Set,p=async(g,S,w,D)=>{let A=`${g}.${S}`;if(D.has(A))return;D.add(A);let R=await this.getForeignKeyReferences(g,n);for(let $ of R){let P=i.request();w.forEach((k,Y)=>{P.input(`val${Y}`,k)});let v=w.map((k,Y)=>`@val${Y}`).join(", "),X=(await P.query(`SELECT [${$.referencedColumn}] FROM [${g}] WHERE [${S}] IN (${v})`)).recordset.map(k=>k[$.referencedColumn]);X.length>0&&await p($.referencingTable,$.referencingColumn,X,D)}let C=i.request();w.forEach(($,P)=>{C.input(`delVal${P}`,$)});let _=w.map(($,P)=>`@delVal${P}`).join(", "),O=await C.query(`DELETE FROM [${g}] WHERE [${S}] IN (${_})`);l+=O.rowsAffected[0]??0,u.add(g)};for(let g of c)u.has(g.referencingTable)||await p(g.referencingTable,g.referencingColumn,o,m);let f=i.request();o.forEach((g,S)=>{f.input(`mainPk${S}`,g)});let b=o.map((g,S)=>`@mainPk${S}`).join(", "),y=await f.query(`DELETE FROM [${e}] WHERE [${s}] IN (${b})`);return await i.commit(),{deletedCount:(y.rowsAffected[0]??0)+l}}catch(c){throw await i.rollback(),c instanceof d?c:new d(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:n}){if(!t||t.length===0)throw new d(400,{message:"At least one record is required"});let s=(await H(n)).transaction();try{let o=Object.keys(t[0]),i=o.map(l=>`[${l}]`).join(", "),c=await this.getBooleanColumnSet(e,n);await s.begin();for(let l=0;l<t.length;l++){let u=t[l],m=s.request(),p=o.map(b=>{let y=u[b];return c.has(b)&&typeof y=="string"?y==="true"?1:0:y}),f=o.map((b,y)=>`@p${l}_${y}`).join(", ");o.forEach((b,y)=>{m.input(`p${l}_${y}`,p[y])});try{await m.query(`INSERT INTO [${e}] (${i}) VALUES (${f})`)}catch(b){throw new d(500,{message:`Failed to insert record ${l+1}: ${b instanceof Error?b.message:String(b)}`})}}return await s.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(o){throw await s.rollback(),o instanceof d?o:new d(500,{message:`Failed to bulk insert records into "${e}"`})}}async executeQuery({query:e,db:t}){let n=await H(t);if(!e?.trim())throw new d(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),s=performance.now(),o=await n.request().query(a).catch(c=>{throw this.wrapError(c)}),i=performance.now()-s;if(o.recordset){let c=o.recordset;return{columns:o.recordset.columns?Object.keys(o.recordset.columns):Object.keys(c[0]??{}),rows:c,rowCount:c.length,duration:i,message:c.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:o.rowsAffected[0]??0,duration:i,message:`OK \u2014 ${o.rowsAffected[0]??0} row(s) affected`}}async getForeignKeyReferences(e,t){return(await(await H(t)).request().input("tableName",e).query(`
|
|
176
176
|
SELECT
|
|
177
177
|
fk.name AS constraint_name,
|
|
178
178
|
OBJECT_NAME(fk.parent_object_id) AS referencing_table,
|
|
@@ -182,7 +182,7 @@ ${o.join(`,
|
|
|
182
182
|
FROM sys.foreign_keys fk
|
|
183
183
|
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
|
|
184
184
|
WHERE OBJECT_NAME(fk.referenced_object_id) = @tableName
|
|
185
|
-
`)).recordset.map(s=>({constraintName:s.constraint_name,referencingTable:s.referencing_table,referencingColumn:s.referencing_column,referencedTable:s.referenced_table,referencedColumn:s.referenced_column}))}async getRelatedRecordsForTable(e,t){let n=await this.getForeignKeyReferences(e,t);if(n.length===0)return[];let a=await
|
|
185
|
+
`)).recordset.map(s=>({constraintName:s.constraint_name,referencingTable:s.referencing_table,referencingColumn:s.referencing_column,referencedTable:s.referenced_table,referencedColumn:s.referenced_column}))}async getRelatedRecordsForTable(e,t){let n=await this.getForeignKeyReferences(e,t);if(n.length===0)return[];let a=await H(t),s=[];for(let o of n){let i=await a.request().query(`SELECT TOP 100 * FROM [${o.referencingTable}]`);i.recordset.length>0&&s.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:i.recordset})}return s}async getRelatedRecords(e,t,n){let a=await this.getForeignKeyReferences(e,n);if(a.length===0)return[];let s=await H(n),o=t.map(l=>l.value),i=[],c=new Map;for(let l of a){let u=`${l.referencingTable}.${l.referencingColumn}`;c.has(u)||c.set(u,[]),c.get(u)?.push(l)}for(let[,l]of c){let u=l[0];if(!u||!t.find(y=>y.columnName===u.referencedColumn))continue;let p=s.request();o.forEach((y,g)=>{p.input(`pk${g}`,y)});let f=o.map((y,g)=>`@pk${g}`).join(", "),b=await p.query(`SELECT TOP 100 * FROM [${u.referencingTable}] WHERE [${u.referencingColumn}] IN (${f})`);b.recordset.length>0&&i.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:b.recordset})}return i}async rowEstimates(e,t){let n=e.request();t!==void 0&&n.input("tableName",t);let a=await n.query(`
|
|
186
186
|
SELECT t.name AS tableName, SUM(p.rows) AS estimate
|
|
187
187
|
FROM sys.tables t
|
|
188
188
|
JOIN sys.partitions p ON p.object_id = t.object_id AND p.index_id IN (0, 1)
|
|
@@ -190,7 +190,7 @@ ${o.join(`,
|
|
|
190
190
|
${t===void 0?"":"AND t.name = @tableName"}
|
|
191
191
|
GROUP BY t.name
|
|
192
192
|
ORDER BY t.name
|
|
193
|
-
`);return new Map(a.recordset.map(s=>[s.tableName,Number(s.estimate)]))}async countRows(e,t,n,a){if(!n){let i=(await this.rowEstimates(e,t)).get(t)??0;if(i>=
|
|
193
|
+
`);return new Map(a.recordset.map(s=>[s.tableName,Number(s.estimate)]))}async countRows(e,t,n,a){if(!n){let i=(await this.rowEstimates(e,t)).get(t)??0;if(i>=it)return{total:i,estimated:!0}}let s=e.request();a.forEach((i,c)=>{s.input(`p${c}`,i)});let o=await s.query(`SELECT COUNT(*) as total FROM ${Ne(t)} ${n}`);return{total:Number(o.recordset[0]?.total??0),estimated:!1}}async getTableRowCount(e,t){let n=await H(t);try{let a=await n.request().query(`SELECT COUNT(*) as count FROM [${e}]`);return Number(a.recordset[0]?.count??0)}catch(a){if(!Gi(a))throw a;return(await this.rowEstimates(n,e)).get(e)??0}}async getPrimaryKeyColumns(e,t){return(await e.request().input("tableName",t).query(`
|
|
194
194
|
SELECT ku.COLUMN_NAME AS columnName
|
|
195
195
|
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
|
|
196
196
|
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku
|
|
@@ -218,13 +218,13 @@ ${o.join(`,
|
|
|
218
218
|
WHERE i.object_id = OBJECT_ID(QUOTENAME('dbo') + '.' + QUOTENAME(@tableName))
|
|
219
219
|
AND i.type > 0 AND i.is_hypothetical = 0
|
|
220
220
|
ORDER BY i.is_primary_key DESC, i.name, ic.is_included_column, ic.key_ordinal, ic.index_column_id
|
|
221
|
-
`),a=new Map;for(let s of n.recordset){let o=a.get(s.indexName)??{index:{indexName:s.indexName,columns:[],isUnique:s.isUnique,method:s.typeDesc.toLowerCase(),kind:s.isPrimaryKey?"primary":s.isUniqueConstraint?"unique-constraint":"index",definition:null},row:s,keys:[],included:[]};a.set(s.indexName,o),s.columnName!==null&&(s.isIncluded&&!s.typeDesc.endsWith("COLUMNSTORE")?o.included.push(
|
|
221
|
+
`),a=new Map;for(let s of n.recordset){let o=a.get(s.indexName)??{index:{indexName:s.indexName,columns:[],isUnique:s.isUnique,method:s.typeDesc.toLowerCase(),kind:s.isPrimaryKey?"primary":s.isUniqueConstraint?"unique-constraint":"index",definition:null},row:s,keys:[],included:[]};a.set(s.indexName,o),s.columnName!==null&&(s.isIncluded&&!s.typeDesc.endsWith("COLUMNSTORE")?o.included.push(Ne(s.columnName)):(o.index.columns.push(s.columnName),o.keys.push(`${Ne(s.columnName)}${s.isDescending?" DESC":""}`)))}return[...a.values()].map(({index:s,row:o,keys:i,included:c})=>({...s,definition:o.filterDefinition===null?null:`CREATE ${o.isUnique?"UNIQUE ":""}${o.typeDesc} INDEX ${Ne(o.indexName)} ON ${Ne(t)} (${i.join(", ")})${c.length?` INCLUDE (${c.join(", ")})`:""} WHERE ${o.filterDefinition}`}))}async assertTableExists(e,t){let n=await e.request().input("tableName",t).query(`
|
|
222
222
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
223
223
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
224
224
|
`);if(Number(n.recordset[0]?.cnt??0)===0)throw new d(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,n){let a=await e.request().input("tableName",t).input("columnName",n).query(`
|
|
225
225
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
226
226
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
227
|
-
`);if(Number(a.recordset[0]?.cnt??0)===0)throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`})}parseCheckConstraintValues(e){let t=e.match(/'([^']+)'/g);return!t||t.length===0?null:t.map(n=>n.slice(1,-1))}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){let t=this.decodeCursor(e);return Number(t?.values._offset??0)}}});function
|
|
227
|
+
`);if(Number(a.recordset[0]?.cnt??0)===0)throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`})}parseCheckConstraintValues(e){let t=e.match(/'([^']+)'/g);return!t||t.length===0?null:t.map(n=>n.slice(1,-1))}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){let t=this.decodeCursor(e);return Number(t?.values._offset??0)}}});function ms(r){if(r.length===0)return{clause:"",values:[]};let e=[],t=[];for(let n of r){let a=mr(n.columnName);switch(n.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${n.operator} ?`),t.push(n.value);break;case"is":n.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(n.value));break;case"is not":n.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(n.value));break;case"like":case"ilike":e.push(`${a} LIKE ?`),t.push(n.value);break;case"not like":case"not ilike":e.push(`${a} NOT LIKE ?`),t.push(n.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function ds(r,e){return Array.isArray(r)?r.length===0?"":`ORDER BY ${r.map(t=>`${mr(t.columnName)} ${t.direction.toUpperCase()}`).join(", ")}`:r&&typeof r=="string"?`ORDER BY ${mr(r)} ${e?.toUpperCase()||"ASC"}`:""}function ps(r,e,t){let{values:n,sortColumns:a}=r;if(a.length===0)return{clause:"",values:[]};let c=t==="asc"===(e==="asc")?">":"<",l=a.map(mr).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>n[p]);return{clause:`(${l}) ${c} (${u})`,values:m}}function Ld(r,e){if(e)return"JSON";let t=r.toLowerCase().trim();return{serial:"INT AUTO_INCREMENT",serial4:"INT AUTO_INCREMENT",bigserial:"BIGINT AUTO_INCREMENT",serial8:"BIGINT AUTO_INCREMENT",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",numeric:"DECIMAL",decimal:"DECIMAL",real:"FLOAT",float4:"FLOAT",float:"FLOAT","double precision":"DOUBLE",float8:"DOUBLE",money:"DECIMAL(19, 4)",boolean:"TINYINT(1)",bool:"TINYINT(1)",text:"LONGTEXT",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"CHAR(36)",json:"JSON",jsonb:"JSON",xml:"LONGTEXT",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME","timestamp without time zone":"DATETIME","timestamp with time zone":"DATETIME",timestamptz:"DATETIME",interval:"VARCHAR(255)",bytea:"LONGBLOB",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)",point:"POINT",line:"LINESTRING",polygon:"POLYGON"}[t]||r.toUpperCase()}function Pd(r,e){if(!r?.trim())return null;let t=r.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("uuid()")?!e.toUpperCase().includes("CHAR")&&!e.toUpperCase().includes("TEXT")?null:"(UUID())":t.includes("current_timestamp")||t.includes("now()")?"(CURRENT_TIMESTAMP)":t.includes("current_date")?"(CURRENT_DATE)":`(${r.trim()})`:t==="null"?"NULL":t==="true"?"1":t==="false"?"0":r.trim()}function dr(r,e={}){let t=Ld(r.columnType,r.isArray??!1),n=`\`${r.columnName}\` ${t}`;if(!r.isNullable&&!r.isPrimaryKey&&(n+=" NOT NULL"),r.defaultValue&&!t.includes("AUTO_INCREMENT")){let a=Pd(r.defaultValue,t);a!==null&&(n+=` DEFAULT ${a}`)}return(r.isIdentity||e.preserveAutoIncrement)&&!t.includes("AUTO_INCREMENT")&&(n+=" AUTO_INCREMENT"),e.includeUnique&&r.isUnique&&!r.isPrimaryKey&&(n+=" UNIQUE"),e.includePrimaryKey&&r.isPrimaryKey&&(n+=" PRIMARY KEY"),n}var mr,Ji=N(()=>{"use strict";h();mr=r=>`\`${r.replaceAll("`","``")}\``});var Xi,$d,Md,kd,vd,Ud,qd,Bd,Fd,oe,pr,Zi=N(()=>{"use strict";h();z();Xe();Ze();ct();te();ze();Ji();Xi=1451,$d=1217,Md=1061,kd=1062,vd=1553,Ud=new Set([1059,1071,1167,1170,1280,3152]),qd=1142,Bd=1146,Fd={System:"info",Error:"error",Warning:"warning",Note:"info"},oe=r=>`\`${r.replaceAll("`","``")}\``,pr=class extends ae{mariaDb=new WeakMap;async runQuery(e,t,n){let a=await j(e),[s]=await a.execute(t,n);return s}quoteIdentifier(e){return oe(e)}mapToUniversalType(e){return On(e)}mapFromUniversalType(e){return{text:"LONGTEXT",number:"INT",boolean:"TINYINT(1)",json:"JSON",date:"DATETIME",array:"JSON",enum:"TEXT"}[e]??"LONGTEXT"}buildTableDataQuery(e){let{tableName:t,cursor:n="",limit:a=50,direction:s="asc",sort:o=[],order:i="asc",filters:c=[]}=e,l=[],u=i;Array.isArray(o)&&o.length>0?(l=o.map(R=>R.columnName),u=o[0].direction):typeof o=="string"&&o&&(l=[o]);let{clause:m,values:p}=ms(c),f="",b=[];if(n){let R=this.decodeCursor(n);if(R){let C=ps(R,s,u);f=C.clause,b=C.values}}let y="";m&&f?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${f}`:m?y=m:f&&(y=`WHERE ${f}`);let g=ds((Array.isArray(o),o),i),S=g;s==="desc"?g?S=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):l.length>0&&(S=`ORDER BY ${l.map(R=>`${oe(R)} ${u==="asc"?"DESC":"ASC"}`).join(", ")}`):!g&&l.length>0&&(S=`ORDER BY ${l.map(R=>`${oe(R)} ${u.toUpperCase()}`).join(", ")}`);let w=`SELECT * FROM ${oe(t)} ${y} ${S} LIMIT ${a+1}`,D=[...p,...b],A=`SELECT COUNT(*) as total FROM ${oe(t)} ${m}`;return{sql:w,values:D,countSql:A,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,n){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:s=[],cursor:o}=e,i=[];Array.isArray(s)&&s.length>0?i=s.map(f=>f.columnName):typeof s=="string"&&s&&(i=[s]);let c=f=>this.encodeCursor({values:Object.fromEntries(i.map(b=>[b,f[b]])),sortColumns:i}),l=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(n&&(m=c(u)),o&&(p=c(l))):(o&&(m=c(u)),n&&(p=c(l))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,db:n,limit:a=50,direction:s="asc",sort:o=[],order:i="asc",cursor:c,filters:l=[]}=e,u=await j(n),{clause:m,values:p}=ms(l),[f,{total:b,estimated:y}]=await Promise.all([this.getPrimaryKeyColumns(u,t),this.countRows(u,t,m,p)]),g=[],S=i;Array.isArray(o)&&o.length>0?(g=o.map(k=>k.columnName),S=o[0].direction):typeof o=="string"&&o&&(g=[o]);let w=[...g,...f.filter(k=>!g.includes(k))],D="",A=[];if(c){let k=this.decodeCursor(c);if(k){let Y=ps(k,s,S);D=Y.clause,A=Y.values}}let R="";m&&D?R=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${D}`:m?R=m:D&&(R=`WHERE ${D}`);let C=ds((Array.isArray(o),o),i),_=f.filter(k=>!g.includes(k)),O=C;if(s==="desc")if(C){if(O=C.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),_.length){let k=S==="asc"?"DESC":"ASC";O+=`, ${_.map(Y=>`${oe(Y)} ${k}`).join(", ")}`}}else w.length>0&&(O=`ORDER BY ${w.map(k=>`${oe(k)} ${S==="asc"?"DESC":"ASC"}`).join(", ")}`);else!C&&w.length>0?O=`ORDER BY ${w.map(k=>`${oe(k)} ${S.toUpperCase()}`).join(", ")}`:_.length&&(O+=`, ${_.map(k=>`${oe(k)} ${S.toUpperCase()}`).join(", ")}`);let[$]=await u.execute(`SELECT * FROM ${oe(t)} ${R} ${O} LIMIT ${Math.floor(a)+1}`,[...p,...A]),P=$,v=P.length>a;v&&(P=P.slice(0,a)),s==="desc"&&(P=P.reverse());let M=null,X=null;if(P.length>0&&w.length>0){let k=P[0],Y=P[P.length-1],_e=yt=>({values:Object.fromEntries(w.map(ut=>[ut,yt[ut]])),sortColumns:w});s==="asc"?(v&&(M=this.encodeCursor(_e(Y))),c&&(X=this.encodeCursor(_e(k)))):(c&&(M=this.encodeCursor(_e(Y))),v&&(X=this.encodeCursor(_e(k))))}return{data:P,meta:{limit:a,total:b,...y&&{totalEstimated:!0},hasNextPage:s==="asc"?v:!!c,hasPreviousPage:s==="asc"?!!c:v,nextCursor:M,prevCursor:X}}}async getDatabasesList(){try{let e=await j(),[t]=await e.execute(`
|
|
228
228
|
SELECT
|
|
229
229
|
s.SCHEMA_NAME AS name,
|
|
230
230
|
CONCAT(ROUND(COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024, 2), ' MB') AS size,
|
|
@@ -235,7 +235,7 @@ ${o.join(`,
|
|
|
235
235
|
WHERE (s.SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') OR s.SCHEMA_NAME = DATABASE())
|
|
236
236
|
GROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME
|
|
237
237
|
ORDER BY s.SCHEMA_NAME
|
|
238
|
-
`);if(!t[0])throw new d(500,{message:"No databases returned from server"});return t}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=await
|
|
238
|
+
`);if(!t[0])throw new d(500,{message:"No databases returned from server"});return t}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=await j(),[t]=await e.execute("SELECT DATABASE() AS db");if(!t[0])throw new d(500,{message:"No current database returned from server"});return t[0]}async getDatabaseConnectionInfo(){let e=await j(),[t]=await e.execute(`
|
|
239
239
|
SELECT
|
|
240
240
|
VERSION() AS version,
|
|
241
241
|
DATABASE() AS database_name,
|
|
@@ -243,10 +243,10 @@ ${o.join(`,
|
|
|
243
243
|
@@hostname AS host,
|
|
244
244
|
@@port AS port,
|
|
245
245
|
@@max_connections AS max_connections
|
|
246
|
-
`),[n]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new d(500,{message:"No connection information returned from server"});let a=t[0],s=
|
|
246
|
+
`),[n]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new d(500,{message:"No connection information returned from server"});let a=t[0],s=Oe(Ue());return{host:String(a.host||s.host),port:Number(a.port||s.port),user:String(a.user),database:String(a.database_name??""),version:String(a.version),active_connections:Number(n[0]?.cnt??0),max_connections:Number(a.max_connections)}}async getTablesList(e){let t=await j(e),n=await this.rowEstimates(t);return Promise.all([...n].map(async([a,s])=>{if(s>=it)return{tableName:a,rowCount:s,rowCountEstimated:!0};let[o]=await t.execute(`SELECT COUNT(*) as count FROM ${oe(a)}`);return{tableName:a,rowCount:Number(o[0]?.count??0)}}))}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e,o=await j(t),i=a.map(m=>dr(m)),c=[],l=a.filter(m=>m.isPrimaryKey);l.length>0&&c.push(`PRIMARY KEY (${l.map(m=>`\`${m.columnName}\``).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&c.push(`UNIQUE KEY \`uq_${n}_${m.columnName}\` (\`${m.columnName}\`)`);let u=s?.map(m=>`CONSTRAINT \`${`fk_${n}_${m.columnName}_${m.referencedTable}_${m.referencedColumn}`}\` FOREIGN KEY (\`${m.columnName}\`) REFERENCES \`${m.referencedTable}\` (\`${m.referencedColumn}\`) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await o.execute(`CREATE TABLE \`${n}\` (
|
|
247
247
|
${[...i,...c,...u].join(`,
|
|
248
248
|
`)}
|
|
249
|
-
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:n,cascade:a}=e,s=await
|
|
249
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:n,cascade:a}=e,s=await j(n),[o]=await s.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(o[0]?.cnt??0)===0)throw new d(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(s,t);if(!a){let c=await this.getRelatedRecordsForTable(t,n);if(c.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:c}}try{if(a){let c=await s.getConnection();try{await c.execute("SET FOREIGN_KEY_CHECKS = 0"),await c.execute(`DROP TABLE \`${t}\``),await c.execute("SET FOREIGN_KEY_CHECKS = 1")}finally{c.release()}}else await s.execute(`DROP TABLE \`${t}\``);return{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(c){await s.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{});let l=c;if(l.errno===$d||l.errno===Xi)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,n)};throw c instanceof d?c:new d(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:n,db:a}=e;this.assertDifferentTableName(t,n);let s=await j(a);await this.assertTableExists(s,t);let[o]=await s.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[n]);if(Number(o[0]?.cnt??0)>0)throw new d(409,{message:`Table "${n}" already exists`});await s.execute(`RENAME TABLE \`${t.replaceAll("`","``")}\` TO \`${n.replaceAll("`","``")}\``)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let n=await j(t),[a]=await n.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[e]);if(Number(a[0]?.cnt??0)===0)throw new d(404,{message:`Table "${e}" does not exist`});let[s]=await n.execute(`SHOW CREATE TABLE \`${e}\``),o=s[0],i=o?.["Create Table"]??o?.create_table??"";if(!i)throw new d(500,{message:`Failed to retrieve schema for table "${e}"`});return i}async getTableColumns({tableName:e,db:t}){let n=await j(t),a=await this.isMariaDb(n)?`EXISTS (
|
|
250
250
|
SELECT 1 FROM information_schema.CHECK_CONSTRAINTS cc
|
|
251
251
|
WHERE cc.CONSTRAINT_SCHEMA = c.TABLE_SCHEMA
|
|
252
252
|
AND cc.TABLE_NAME = c.TABLE_NAME
|
|
@@ -272,16 +272,16 @@ ${o.join(`,
|
|
|
272
272
|
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
273
273
|
WHERE c.TABLE_SCHEMA = DATABASE()
|
|
274
274
|
AND c.TABLE_NAME = ?
|
|
275
|
-
ORDER BY c.ORDINAL_POSITION`,[e]);if(!s||s.length===0)throw new d(404,{message:`Table "${e}" does not exist`});return s.map(o=>{let i=o.dataType==="enum"||o.dataType==="set",[c,l]=o.isJsonText?["json","json"]:[o.dataType,o.columnType];return{columnName:o.columnName,dataType:
|
|
275
|
+
ORDER BY c.ORDINAL_POSITION`,[e]);if(!s||s.length===0)throw new d(404,{message:`Table "${e}" does not exist`});return s.map(o=>{let i=o.dataType==="enum"||o.dataType==="set",[c,l]=o.isJsonText?["json","json"]:[o.dataType,o.columnType];return{columnName:o.columnName,dataType:On(c,l),dataTypeLabel:vr(c,l),isNullable:!!o.isNullable,columnDefault:o.columnDefault??null,isPrimaryKey:!!o.isPrimaryKey,isForeignKey:!!o.isForeignKey,referencedTable:o.referencedTable??null,...o.referencedSchema&&{referencedSchema:o.referencedSchema},referencedColumn:o.referencedColumn??null,enumValues:i?this.parseMysqlEnumValues(o.columnType):null}})}async addColumn(e){let{tableName:t,columnName:n,columnType:a,defaultValue:s,isPrimaryKey:o,isNullable:i,isUnique:c,isIdentity:l,isArray:u,db:m}=e,p=await j(m);await this.assertTableExists(p,t);let[f]=await p.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,n]);if(Number(f[0]?.cnt??0)>0)throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let b=dr({columnName:n,columnType:a,defaultValue:s,isPrimaryKey:o,isNullable:i,isUnique:c,isIdentity:l,isArray:u},{includePrimaryKey:!0,includeUnique:!0});await p.execute(`ALTER TABLE \`${t}\` ADD COLUMN ${b}`)}async deleteColumn(e){let{tableName:t,columnName:n,db:a}=e,s=await j(a);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,n);let[o]=await s.execute(`ALTER TABLE \`${t}\` DROP COLUMN \`${n}\``);return{deletedCount:o.affectedRows}}async alterColumn(e){let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o,db:i}=e,c=await j(i);await this.assertTableExists(c,t);let[l]=await c.execute("SELECT EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1",[t,n]),u=l[0];if(!u)throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});let m=dr({columnName:n,columnType:a,defaultValue:o,isNullable:s},{preserveAutoIncrement:u.EXTRA?.toLowerCase().includes("auto_increment")});await c.execute(`ALTER TABLE \`${t}\` MODIFY COLUMN ${m}`)}async renameColumn(e){let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await j(s);await this.assertTableExists(o,t),await this.assertColumnExists(o,t,n);let[i]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,a]);if(Number(i[0]?.cnt??0)>0)throw new d(409,{message:`Column "${a}" already exists in table "${t}"`});await o.execute(`ALTER TABLE \`${t}\` RENAME COLUMN \`${n}\` TO \`${a}\``)}async getServerLogs({db:e}){let t=await j(e);try{let[n]=await t.query(`${$e} SELECT UNIX_TIMESTAMP(LOGGED) AS epoch, THREAD_ID, PRIO,
|
|
276
276
|
ERROR_CODE, SUBSYSTEM, DATA
|
|
277
|
-
FROM performance_schema.error_log ORDER BY LOGGED DESC LIMIT ${500}`);return{available:!0,source:"performance_schema.error_log",entries:
|
|
277
|
+
FROM performance_schema.error_log ORDER BY LOGGED DESC LIMIT ${500}`);return{available:!0,source:"performance_schema.error_log",entries:Ie(n.reverse().map(a=>({ts:new Date(Number(a.epoch)*1e3).toISOString(),level:Fd[a.PRIO]??"info",rawLevel:String(a.PRIO),source:a.SUBSYSTEM?String(a.SUBSYSTEM):void 0,code:a.ERROR_CODE?String(a.ERROR_CODE):void 0,message:String(a.DATA),detail:he({thread:a.THREAD_ID})})))}}catch(n){let a=n.errno;if(a===qd)return re("Reading the server log needs: GRANT SELECT ON performance_schema.error_log TO <user>;");if(a===Bd)return re("The server keeps no error_log table. It needs MySQL 8.0.22 or later; MariaDB has no equivalent.");throw this.wrapError(n)}}async getTableIndexes({tableName:e,db:t}){try{return await this.listIndexes(await j(t),e)}catch(n){throw this.wrapError(n)}}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o,db:i}=e;try{let c=await j(i);await this.assertTableExists(c,t);let[l]=await c.execute("SELECT COLUMN_NAME AS columnName FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]),u=new Set(l.map(p=>String(p.columnName))),m=a.find(p=>!u.has(p));if(m!==void 0)throw new d(400,{message:`Column "${m}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});await c.query(`CREATE ${s?"UNIQUE ":""}INDEX ${oe(n)} ON ${oe(t)} (${a.map(oe).join(", ")})`)}catch(c){let l=c.errno;throw c instanceof Error&&(l===Md||l===kd)?new d(409,{message:c.message,cause:c}):c instanceof Error&&l!==void 0&&Ud.has(l)?new d(400,{message:c.message,cause:c}):this.wrapError(c)}}async dropIndex({tableName:e,indexName:t,db:n}){try{let a=await j(n),s=(await this.listIndexes(a,e)).find(o=>o.indexName===t);if(!s)throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});if(s.kind!=="index")throw new d(400,{message:`Index "${t}" backs a constraint; drop the constraint to remove it`});await a.query(`DROP INDEX ${oe(t)} ON ${oe(e)}`)}catch(a){throw a instanceof Error&&a.errno===vd?new d(400,{message:a.message,cause:a}):this.wrapError(a)}}async addRecord({db:e,params:t}){let{tableName:n,data:a}=t,s=await j(e),o=await this.getBooleanColumnSet(n,e),i=Object.keys(a),c=Object.values(a).map((u,m)=>o.has(i[m])&&typeof u=="string"?u==="true"?1:0:u),[l]=await s.execute(`INSERT INTO \`${n}\` (${i.map(u=>`\`${u}\``).join(", ")}) VALUES (${i.map(()=>"?").join(", ")})`,c);if(l.affectedRows===0)throw new d(500,{message:`Failed to insert record into "${n}"`});return{insertedCount:l.affectedRows}}async updateRecords({params:e,db:t}){let{tableName:n}=e,a=await j(t),s=await this.getBooleanColumnSet(n,t),o=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,n),o);let i=this.groupUpdatesByKey(e,o),c=await a.getConnection();await c.beginTransaction();try{let l=0;for(let{keyValues:u,rowUpdates:m}of i){let p=m.map(g=>`\`${g.columnName}\` = ?`),f=m.map(g=>g.value!==null&&typeof g.value=="object"?JSON.stringify(g.value):s.has(g.columnName)&&typeof g.value=="string"?g.value==="true"?1:0:g.value);f.push(...u);let b=o.map(g=>`\`${g}\` = ?`),[y]=await c.execute(`UPDATE \`${n}\` SET ${p.join(", ")} WHERE ${b.join(" AND ")}`,f);if(y.affectedRows===0)throw new d(404,{message:`Record with ${this.describeKey(o,u)} not found in table "${n}"`});l+=y.affectedRows}return await c.commit(),{updatedCount:l}}catch(l){throw await c.rollback(),l instanceof d?l:new d(500,{message:`Failed to update records in "${n}"`})}finally{c.release()}}async deleteRecords({tableName:e,primaryKeys:t,db:n}){let a=await j(n),s=t[0]?.columnName;if(!s)throw new d(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let o=t.map(l=>l.value),i=o.map(()=>"?").join(", "),c=await a.getConnection();await c.beginTransaction();try{let[l]=await c.execute(`DELETE FROM \`${e}\` WHERE \`${s}\` IN (${i})`,o);return await c.commit(),{deletedCount:l.affectedRows,fkViolation:!1,relatedRecords:[]}}catch(l){if(await c.rollback(),l.errno===Xi)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,n)};throw l instanceof d?l:new d(500,{message:`Failed to delete records from "${e}"`})}finally{c.release()}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:n}){let a=await j(n),s=t[0]?.columnName;if(!s)throw new d(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let o=t.map(c=>c.value),i=await a.getConnection();await i.beginTransaction();try{await i.execute("SET FOREIGN_KEY_CHECKS = 0");let c=await this.getForeignKeyReferences(e,n),l=0,u=new Set,m=new Set,p=async(y,g,S,w)=>{let D=`${y}.${g}`;if(w.has(D))return;w.add(D);let A=await this.getForeignKeyReferences(y,n);for(let _ of A){let O=S.map(()=>"?").join(", "),[$]=await i.execute(`SELECT \`${_.referencedColumn}\` FROM \`${y}\` WHERE \`${g}\` IN (${O})`,S),P=$.map(v=>v[_.referencedColumn]);P.length>0&&await p(_.referencingTable,_.referencingColumn,P,w)}let R=S.map(()=>"?").join(", "),[C]=await i.execute(`DELETE FROM \`${y}\` WHERE \`${g}\` IN (${R})`,S);l+=C.affectedRows,u.add(y)};for(let y of c)u.has(y.referencingTable)||await p(y.referencingTable,y.referencingColumn,o,m);let f=o.map(()=>"?").join(", "),[b]=await i.execute(`DELETE FROM \`${e}\` WHERE \`${s}\` IN (${f})`,o);return await i.execute("SET FOREIGN_KEY_CHECKS = 1"),await i.commit(),{deletedCount:b.affectedRows+l}}catch(c){throw await i.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{}),await i.rollback(),c instanceof d?c:new d(500,{message:`Failed to force delete records from "${e}"`})}finally{i.release()}}async bulkInsertRecords({tableName:e,records:t,db:n}){if(!t||t.length===0)throw new d(400,{message:"At least one record is required"});let s=await(await j(n)).getConnection();try{let o=Object.keys(t[0]),i=o.map(l=>`\`${l}\``).join(", "),c=await this.getBooleanColumnSet(e,n);await s.beginTransaction();for(let l=0;l<t.length;l++){let u=t[l],m=o.map(p=>{let f=u[p];return c.has(p)&&typeof f=="string"?f==="true"?1:0:f});try{await s.execute(`INSERT INTO \`${e}\` (${i}) VALUES (${o.map(()=>"?").join(", ")})`,m)}catch(p){throw new d(500,{message:`Failed to insert record ${l+1}: ${p instanceof Error?p.message:String(p)}`})}}return await s.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(o){throw await s.rollback(),o instanceof d?o:new d(500,{message:`Failed to bulk insert records into "${e}"`})}finally{s.release()}}async executeQuery({query:e,db:t}){let n=await j(t);if(!e?.trim())throw new d(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),s=performance.now(),[o,i]=await n.execute(a),c=performance.now()-s;if(Array.isArray(o)){let u=o;return{columns:i?i.map(p=>p.name):Object.keys(u[0]??{}),rows:u,rowCount:u.length,duration:c,message:u.length===0?"OK":void 0}}let l=o;return{columns:[],rows:[],rowCount:l.affectedRows,duration:c,message:`OK \u2014 ${l.affectedRows} row(s) affected`}}async rowEstimates(e,t){let n=await e.getConnection();try{await n.query("SET SESSION information_schema_stats_expiry = 0").catch(()=>{});let[a]=await n.query(`SELECT table_name AS tableName, table_rows AS estimate
|
|
278
278
|
FROM information_schema.tables
|
|
279
279
|
WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
|
|
280
280
|
${t===void 0?"":"AND table_name = ?"}
|
|
281
|
-
ORDER BY table_name`,t===void 0?[]:[t]);return new Map(a.map(s=>[s.tableName,Number(s.estimate??0)]))}finally{n.release()}}async countRows(e,t,n,a){if(!n){let o=(await this.rowEstimates(e,t)).get(t)??0;if(o>=
|
|
281
|
+
ORDER BY table_name`,t===void 0?[]:[t]);return new Map(a.map(s=>[s.tableName,Number(s.estimate??0)]))}finally{n.release()}}async countRows(e,t,n,a){if(!n){let o=(await this.rowEstimates(e,t)).get(t)??0;if(o>=it)return{total:o,estimated:!0}}let[s]=await e.execute(`SELECT COUNT(*) as total FROM ${oe(t)} ${n}`,a);return{total:Number(s[0]?.total??0),estimated:!1}}isMariaDb(e){let t=this.mariaDb.get(e);return t||(t=e.query("SELECT VERSION() LIKE '%MariaDB%' AS mariadb").then(([n])=>Number(n[0]?.mariadb)===1).catch(n=>{throw this.mariaDb.delete(e),n}),this.mariaDb.set(e,t)),t}async getPrimaryKeyColumns(e,t){let[n]=await e.execute(`SELECT COLUMN_NAME as column_name
|
|
282
282
|
FROM information_schema.COLUMNS
|
|
283
283
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_KEY = 'PRI'
|
|
284
|
-
ORDER BY ORDINAL_POSITION`,[t]);return n.map(a=>a.column_name)}async getForeignKeyReferences(e,t){let n=await
|
|
284
|
+
ORDER BY ORDINAL_POSITION`,[t]);return n.map(a=>a.column_name)}async getForeignKeyReferences(e,t){let n=await j(t),[a]=await n.execute(`SELECT
|
|
285
285
|
kcu.CONSTRAINT_NAME AS constraint_name,
|
|
286
286
|
kcu.TABLE_NAME AS referencing_table,
|
|
287
287
|
kcu.COLUMN_NAME AS referencing_column,
|
|
@@ -294,24 +294,24 @@ ${o.join(`,
|
|
|
294
294
|
AND kcu.TABLE_NAME = tc.TABLE_NAME
|
|
295
295
|
WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
|
296
296
|
AND kcu.TABLE_SCHEMA = DATABASE()
|
|
297
|
-
AND kcu.REFERENCED_TABLE_NAME = ?`,[e]);return a.map(s=>({constraintName:s.constraint_name,referencingTable:s.referencing_table,referencingColumn:s.referencing_column,referencedTable:s.referenced_table,referencedColumn:s.referenced_column}))}async getRelatedRecordsForTable(e,t){let n=await this.getForeignKeyReferences(e,t);if(n.length===0)return[];let a=await H(t),s=[];for(let o of n){let[i]=await a.execute(`SELECT * FROM \`${o.referencingTable}\` LIMIT 100`);i.length>0&&s.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:i})}return s}async getRelatedRecords(e,t,n){let a=await this.getForeignKeyReferences(e,n);if(a.length===0)return[];let s=await H(n),o=t.map(l=>l.value),i=[],c=new Map;for(let l of a){let u=`${l.referencingTable}.${l.referencingColumn}`;c.has(u)||c.set(u,[]),c.get(u)?.push(l)}for(let[,l]of c){let u=l[0];if(!u||!t.find(b=>b.columnName===u.referencedColumn))continue;let p=o.map(()=>"?").join(", "),[f]=await s.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${p}) LIMIT 100`,o);f.length>0&&i.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:f})}return i}async getTableRowCount(e,t){let[n]=await e.execute(`SELECT COUNT(*) as count FROM \`${t}\``);return Number(n[0]?.count??0)}async getBooleanColumnSet(e,t){let n=await this.getTableColumns({tableName:e,db:t});return new Set(n.filter(a=>a.dataTypeLabel==="boolean").map(a=>a.columnName))}async listIndexes(e,t){await this.assertTableExists(e,t);let[n]=await e.execute("SELECT * FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? ORDER BY INDEX_NAME, SEQ_IN_INDEX",[t]),a=new Map;for(let s of n){let o=String(s.INDEX_NAME),i=a.get(o)??{index:{indexName:o,columns:[],isUnique:Number(s.NON_UNIQUE)===0,method:s.INDEX_TYPE?String(s.INDEX_TYPE).toLowerCase():null,kind:o==="PRIMARY"?"primary":Number(s.NON_UNIQUE)===0?"unique-constraint":"index",definition:null},parts:[],hasExpression:!1};a.set(o,i);let c=s.EXPRESSION??null;s.COLUMN_NAME===null&&c!==null?(i.index.columns.push(c),i.parts.push(`(${c})${s.COLLATION==="D"?" DESC":""}`),i.hasExpression=!0):(i.index.columns.push(String(s.COLUMN_NAME)),i.parts.push(`${Xe(String(s.COLUMN_NAME))}${s.SUB_PART===null?"":`(${s.SUB_PART})`}${s.COLLATION==="D"?" DESC":""}`))}return[...a.values()].map(({index:s,parts:o,hasExpression:i})=>({...s,definition:i?`CREATE ${s.isUnique?"UNIQUE ":""}INDEX ${Xe(s.indexName)} ON ${Xe(t)} (${o.join(", ")})`:null})).sort((s,o)=>+(o.kind==="primary")-+(s.kind==="primary")||(s.indexName<o.indexName?-1:1))}async assertTableExists(e,t){let[n]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(n[0]?.cnt??0)===0)throw new d(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,n){let[a]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,n]);if(Number(a[0]?.cnt??0)===0)throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`})}parseMysqlEnumValues(e){let t=e.match(/^(?:enum|set)\((.+)\)$/i);return t?.[1]?t[1].split(",").map(n=>n.trim().replace(/^'|'$/g,"")):null}}});function zi(r,e,t){let n=[];for(let a of r){let s=I(a.columnName),o=t.get(a.columnName),i=a.value.toLowerCase()==="null";switch(a.operator){case"=":case"!=":case">":case">=":case"<":case"<=":n.push(`${s} ${a.operator} ${ve(a.value,o,e)}`);break;case"is":n.push(i?`${s} IS NULL`:`${s} = ${ve(a.value,o,e)}`);break;case"is not":n.push(i?`${s} IS NOT NULL`:`${s} != ${ve(a.value,o,e)}`);break;case"like":n.push(`${yn(s,o)} LIKE ${e(a.value)}`);break;case"not like":n.push(`${yn(s,o)} NOT LIKE ${e(a.value)}`);break;case"ilike":n.push(`UPPER(${yn(s,o)}) LIKE UPPER(${e(a.value)})`);break;case"not ilike":n.push(`UPPER(${yn(s,o)}) NOT LIKE UPPER(${e(a.value)})`);break}}return n}function cs(r,e,t){if(e)throw new d(400,{message:"Oracle has no array column type. Use a json column (JSON on Oracle 23ai) instead."});let n=r.toLowerCase().trim();return{serial:"NUMBER(10)",serial4:"NUMBER(10)",bigserial:"NUMBER(19)",serial8:"NUMBER(19)",smallserial:"NUMBER(5)",serial2:"NUMBER(5)",int:"NUMBER(10)",int4:"NUMBER(10)",integer:"NUMBER(10)",bigint:"NUMBER(19)",int8:"NUMBER(19)",smallint:"NUMBER(5)",int2:"NUMBER(5)",tinyint:"NUMBER(3)",numeric:"NUMBER",decimal:"NUMBER",real:"BINARY_FLOAT",float4:"BINARY_FLOAT",float:"BINARY_DOUBLE","double precision":"BINARY_DOUBLE",float8:"BINARY_DOUBLE",money:"NUMBER(19,4)",boolean:t?"BOOLEAN":"NUMBER(1)",bool:t?"BOOLEAN":"NUMBER(1)",text:"VARCHAR2(4000)",varchar:"VARCHAR2(255)","character varying":"VARCHAR2(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR(1)",uuid:"VARCHAR2(36)",json:t?"JSON":"CLOB",jsonb:t?"JSON":"CLOB",xml:"CLOB",date:"DATE",time:"VARCHAR2(18)","time without time zone":"VARCHAR2(18)",timestamp:"TIMESTAMP","timestamp without time zone":"TIMESTAMP","timestamp with time zone":"TIMESTAMP WITH TIME ZONE",timestamptz:"TIMESTAMP WITH TIME ZONE",interval:"INTERVAL DAY TO SECOND",bytea:"BLOB",inet:"VARCHAR2(45)",cidr:"VARCHAR2(45)",macaddr:"VARCHAR2(17)",macaddr8:"VARCHAR2(23)",point:"VARCHAR2(4000)",line:"VARCHAR2(4000)",polygon:"VARCHAR2(4000)"}[n]??r.toUpperCase()}function ls(r,e){let t=r.trim(),n=t.toLowerCase();return n==="now()"||n==="current_timestamp"?"CURRENT_TIMESTAMP":n==="current_date"?"CURRENT_DATE":n==="true"||n==="false"?e?n.toUpperCase():n==="true"?"1":"0":t}var I,ut,os,is,ji,Id,Wi,xd,yn,Ld,ve,hn,Yi,Vi,Gi,Pd,Qi,Ji,Xi=N(()=>{"use strict";y();te();I=r=>{if(r.includes('"')||r.includes("\0"))throw new d(400,{message:`Oracle identifiers cannot contain double quotes: ${r}`});return`"${r}"`},ut=()=>{let r=[];return{values:r,bind:t=>(r.push(t),`:${r.length}`)}},os='YYYY-MM-DD"T"HH24:MI:SS',is=`${os}.FF9`,ji=`${is}TZH:TZM`,Id=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?\s*(Z|[+-]\d{2}(?::?\d{2})?)?$/i,Wi=r=>{let e=r.toUpperCase();return e==="DATE"?"date":e.startsWith("TIMESTAMP")?e.includes("WITH LOCAL TIME ZONE")?"timestampLtz":e.includes("WITH TIME ZONE")?"timestampTz":"timestamp":null},xd=r=>{let e=r?Wi(r):null;return e==="date"?os:e==="timestampTz"?ji:e?is:null},yn=(r,e)=>{let t=xd(e);return t?`TO_CHAR(${r}, '${t}')`:r},Ld=(r,e)=>{let t=r instanceof Date?r.toISOString():r;if(typeof t!="string")throw new d(400,{message:`Invalid Oracle ${e} value`});let n=t.trim().match(Id);if(!n)throw new d(400,{message:`Invalid Oracle date or timestamp value: ${t}`});let[,a,s,o,i="00",c="00",l="00",u="",m]=n,p=`${a}-${s}-${o}T${i}:${c}:${l}`;if(e==="date")return p;let f=`${p}.${u.padEnd(9,"0")}`;if(e==="timestamp")return f;if(!m||m.toUpperCase()==="Z")return`${f}+00:00`;let b=m.replace(":","");return`${f}${b.slice(0,3)}:${b.slice(3).padEnd(2,"0")}`},ve=(r,e,t)=>{let n=e?Wi(e):null;if(!n)return t(r);let a=t(r==null?null:Ld(r,n));return n==="date"?`TO_DATE(${a}, '${os}')`:n==="timestamp"?`TO_TIMESTAMP(${a}, '${is}')`:`TO_TIMESTAMP_TZ(${a}, '${ji}')`},hn=(r,e)=>r.map(({COLUMN_NAME:t,DATA_TYPE:n})=>{let a=`${e?`${e}.`:""}${I(t)}`,s=yn(a,n);return s===a?a:`${s} AS ${I(t)}`}).join(", "),Yi=r=>{let e=new Map;for(let t of r){let n=e.get(t.CONSTRAINT_NAME);if(n){n.columns.push(t.REFERENCING_COLUMN),n.referencedColumns.push(t.REFERENCED_COLUMN);continue}e.set(t.CONSTRAINT_NAME,{constraintName:t.CONSTRAINT_NAME,referencingTable:t.REFERENCING_TABLE,columns:[t.REFERENCING_COLUMN],referencedTable:t.REFERENCED_TABLE,referencedColumns:[t.REFERENCED_COLUMN]})}return[...e.values()]},Vi=r=>r.length?`WHERE ${r.join(" AND ")}`:"";Gi=(r,e)=>`ORDER BY ${r.map(t=>`${e?`${e}.`:""}${t.column===null?"ROWID":I(t.column)} ${t.direction.toUpperCase()}`).join(", ")}`,Pd=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),Qi=r=>Pd.has(r.toLowerCase().trim());Ji="GENERATED BY DEFAULT ON NULL AS IDENTITY"});var Zi,ec=N(()=>{"use strict";y();Zi=r=>{if(typeof r!="string"||!/^[+-]?\d+$/.test(r))return r;let e=Number(r);return Number.isSafeInteger(e)?e:r}});var us,tc,nc,yt,rc,$d,Md,ac,cr,kd,vd,Ud,qd,Bd,ms,sc,Fd,lr,oc=N(()=>{"use strict";y();G();Qe();Je();lt();St();te();Ve();Xi();ec();us=r=>r.oracleServerVersion>=23e8,tc=r=>Buffer.isBuffer(r)?r.toString("hex"):r,nc=r=>{let e=Ke("oracle");switch(r.dbType){case e.DB_TYPE_NUMBER:return{type:e.STRING,converter:Zi};case e.DB_TYPE_CLOB:case e.DB_TYPE_NCLOB:return{type:e.STRING};case e.DB_TYPE_BLOB:return{type:e.BUFFER,converter:tc};case e.DB_TYPE_RAW:case e.DB_TYPE_LONG_RAW:return{converter:tc}}},yt=(r,e)=>r==null?null:typeof r=="boolean"?e==="BOOLEAN"?r:Number(r):typeof r=="bigint"?r.toString():r instanceof Date||typeof r!="object"?r:JSON.stringify(r),rc=r=>{let e=r.DATA_DEFAULT?.trim();return e&&e.toUpperCase()!=="NULL"?e:null},$d=r=>{switch(r.DATA_TYPE){case"NUMBER":return r.DATA_PRECISION===null?r.DATA_SCALE===0?"INTEGER":"NUMBER":r.DATA_SCALE?`NUMBER(${r.DATA_PRECISION},${r.DATA_SCALE})`:`NUMBER(${r.DATA_PRECISION})`;case"FLOAT":return`FLOAT(${r.DATA_PRECISION})`;case"VARCHAR2":case"NVARCHAR2":case"CHAR":case"NCHAR":return`${r.DATA_TYPE}(${r.CHAR_LENGTH})`;case"RAW":return`RAW(${r.DATA_LENGTH})`;default:return r.DATA_TYPE}},Md=(r,e)=>`${e?`${e}.`:""}${r==="ROWID"?"ROWID":I(r)}`,ac=r=>r.columns.map((e,t)=>`c.${I(e)} = p.${I(r.referencedColumns[t])}`).join(" AND "),cr=(r,e,t)=>`(${r.keys.map(n=>`(${r.columns.map((a,s)=>`${Md(a,e)} = ${t(n[s],a)}`).join(" AND ")})`).join(" OR ")})`,kd=r=>{let e=Ke("oracle");return r.dbType===e.DB_TYPE_DATE||r.dbType===e.DB_TYPE_TIMESTAMP||r.dbType===e.DB_TYPE_TIMESTAMP_TZ||r.dbType===e.DB_TYPE_TIMESTAMP_LTZ},vd=[["ORA-01758","A NOT NULL column added to a table with rows needs a default value."],["ORA-01439","Oracle can only change a column to an unrelated type while the column is empty."],["ORA-22858","Oracle cannot convert this column to or from a LOB (CLOB/BLOB) type."],["ORA-00932","Oracle cannot compare, sort or filter CLOB, BLOB or JSON values this way."],["ORA-22848","Oracle cannot sort or compare CLOB, BLOB or JSON values."],["ORA-12899","The value is too long for the column."],["ORA-01441","The column holds values longer than the new type allows."],["ORA-30675","Oracle identity columns must have a numeric type."],["ORA-01861","Dates must be written as YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS."],["ORA-01830","Dates must be written as YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS."],["ORA-01843","Dates must be written as YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS."]],Ud=["ORA-00955","ORA-01408","ORA-01452"],qd=["ORA-00972","ORA-01450","ORA-02327","ORA-02329"],Bd="ORA-02429",ms=(r,e)=>r instanceof Error&&e.some(t=>r.message.startsWith(t)),sc={CASCADE:" ON DELETE CASCADE","SET NULL":" ON DELETE SET NULL",RESTRICT:"","NO ACTION":""},Fd={1:"fatal",2:"error",8:"warning",16:"info"},lr=class extends se{async runQuery(e,t,n){return this.withConnection(a=>this.query(a,t,n))}quoteIdentifier(e){return I(e)}mapToUniversalType(e){return On(e)}mapFromUniversalType(e){return{text:"VARCHAR2(4000)",number:"NUMBER",boolean:"BOOLEAN",json:"JSON",date:"TIMESTAMP",array:"JSON",enum:"VARCHAR2(255)"}[e]??"VARCHAR2(4000)"}buildTableDataQuery(e){throw new Error("OracleAdapter.getTableData builds its own query")}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){throw new Error("OracleAdapter.getTableData builds its own cursors")}wrapError(e){if(e instanceof Error&&!(e instanceof d)){let t=vd.find(([n])=>e.message.startsWith(n));if(t)return new d(400,{message:`${t[1]} (${e.message.split(`
|
|
297
|
+
AND kcu.REFERENCED_TABLE_NAME = ?`,[e]);return a.map(s=>({constraintName:s.constraint_name,referencingTable:s.referencing_table,referencingColumn:s.referencing_column,referencedTable:s.referenced_table,referencedColumn:s.referenced_column}))}async getRelatedRecordsForTable(e,t){let n=await this.getForeignKeyReferences(e,t);if(n.length===0)return[];let a=await j(t),s=[];for(let o of n){let[i]=await a.execute(`SELECT * FROM \`${o.referencingTable}\` LIMIT 100`);i.length>0&&s.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:i})}return s}async getRelatedRecords(e,t,n){let a=await this.getForeignKeyReferences(e,n);if(a.length===0)return[];let s=await j(n),o=t.map(l=>l.value),i=[],c=new Map;for(let l of a){let u=`${l.referencingTable}.${l.referencingColumn}`;c.has(u)||c.set(u,[]),c.get(u)?.push(l)}for(let[,l]of c){let u=l[0];if(!u||!t.find(b=>b.columnName===u.referencedColumn))continue;let p=o.map(()=>"?").join(", "),[f]=await s.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${p}) LIMIT 100`,o);f.length>0&&i.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:f})}return i}async getTableRowCount(e,t){let[n]=await e.execute(`SELECT COUNT(*) as count FROM \`${t}\``);return Number(n[0]?.count??0)}async getBooleanColumnSet(e,t){let n=await this.getTableColumns({tableName:e,db:t});return new Set(n.filter(a=>a.dataTypeLabel==="boolean").map(a=>a.columnName))}async listIndexes(e,t){await this.assertTableExists(e,t);let[n]=await e.execute("SELECT * FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? ORDER BY INDEX_NAME, SEQ_IN_INDEX",[t]),a=new Map;for(let s of n){let o=String(s.INDEX_NAME),i=a.get(o)??{index:{indexName:o,columns:[],isUnique:Number(s.NON_UNIQUE)===0,method:s.INDEX_TYPE?String(s.INDEX_TYPE).toLowerCase():null,kind:o==="PRIMARY"?"primary":Number(s.NON_UNIQUE)===0?"unique-constraint":"index",definition:null},parts:[],hasExpression:!1};a.set(o,i);let c=s.EXPRESSION??null;s.COLUMN_NAME===null&&c!==null?(i.index.columns.push(c),i.parts.push(`(${c})${s.COLLATION==="D"?" DESC":""}`),i.hasExpression=!0):(i.index.columns.push(String(s.COLUMN_NAME)),i.parts.push(`${oe(String(s.COLUMN_NAME))}${s.SUB_PART===null?"":`(${s.SUB_PART})`}${s.COLLATION==="D"?" DESC":""}`))}return[...a.values()].map(({index:s,parts:o,hasExpression:i})=>({...s,definition:i?`CREATE ${s.isUnique?"UNIQUE ":""}INDEX ${oe(s.indexName)} ON ${oe(t)} (${o.join(", ")})`:null})).sort((s,o)=>+(o.kind==="primary")-+(s.kind==="primary")||(s.indexName<o.indexName?-1:1))}async assertTableExists(e,t){let[n]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(n[0]?.cnt??0)===0)throw new d(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,n){let[a]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,n]);if(Number(a[0]?.cnt??0)===0)throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`})}parseMysqlEnumValues(e){let t=e.match(/^(?:enum|set)\((.+)\)$/i);return t?.[1]?t[1].split(",").map(n=>n.trim().replace(/^'|'$/g,"")):null}}});function ac(r,e,t){let n=[];for(let a of r){let s=I(a.columnName),o=t.get(a.columnName),i=a.value.toLowerCase()==="null";switch(a.operator){case"=":case"!=":case">":case">=":case"<":case"<=":n.push(`${s} ${a.operator} ${qe(a.value,o,e)}`);break;case"is":n.push(i?`${s} IS NULL`:`${s} = ${qe(a.value,o,e)}`);break;case"is not":n.push(i?`${s} IS NOT NULL`:`${s} != ${qe(a.value,o,e)}`);break;case"like":n.push(`${En(s,o)} LIKE ${e(a.value)}`);break;case"not like":n.push(`${En(s,o)} NOT LIKE ${e(a.value)}`);break;case"ilike":n.push(`UPPER(${En(s,o)}) LIKE UPPER(${e(a.value)})`);break;case"not ilike":n.push(`UPPER(${En(s,o)}) NOT LIKE UPPER(${e(a.value)})`);break}}return n}function ys(r,e,t){if(e)throw new d(400,{message:"Oracle has no array column type. Use a json column (JSON on Oracle 23ai) instead."});let n=r.toLowerCase().trim();return{serial:"NUMBER(10)",serial4:"NUMBER(10)",bigserial:"NUMBER(19)",serial8:"NUMBER(19)",smallserial:"NUMBER(5)",serial2:"NUMBER(5)",int:"NUMBER(10)",int4:"NUMBER(10)",integer:"NUMBER(10)",bigint:"NUMBER(19)",int8:"NUMBER(19)",smallint:"NUMBER(5)",int2:"NUMBER(5)",tinyint:"NUMBER(3)",numeric:"NUMBER",decimal:"NUMBER",real:"BINARY_FLOAT",float4:"BINARY_FLOAT",float:"BINARY_DOUBLE","double precision":"BINARY_DOUBLE",float8:"BINARY_DOUBLE",money:"NUMBER(19,4)",boolean:t?"BOOLEAN":"NUMBER(1)",bool:t?"BOOLEAN":"NUMBER(1)",text:"VARCHAR2(4000)",varchar:"VARCHAR2(255)","character varying":"VARCHAR2(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR(1)",uuid:"VARCHAR2(36)",json:t?"JSON":"CLOB",jsonb:t?"JSON":"CLOB",xml:"CLOB",date:"DATE",time:"VARCHAR2(18)","time without time zone":"VARCHAR2(18)",timestamp:"TIMESTAMP","timestamp without time zone":"TIMESTAMP","timestamp with time zone":"TIMESTAMP WITH TIME ZONE",timestamptz:"TIMESTAMP WITH TIME ZONE",interval:"INTERVAL DAY TO SECOND",bytea:"BLOB",inet:"VARCHAR2(45)",cidr:"VARCHAR2(45)",macaddr:"VARCHAR2(17)",macaddr8:"VARCHAR2(23)",point:"VARCHAR2(4000)",line:"VARCHAR2(4000)",polygon:"VARCHAR2(4000)"}[n]??r.toUpperCase()}function gs(r,e){let t=r.trim(),n=t.toLowerCase();return n==="now()"||n==="current_timestamp"?"CURRENT_TIMESTAMP":n==="current_date"?"CURRENT_DATE":n==="true"||n==="false"?e?n.toUpperCase():n==="true"?"1":"0":t}var I,lt,fs,hs,ec,Kd,tc,Hd,En,jd,qe,wn,nc,rc,sc,Wd,oc,ic,cc=N(()=>{"use strict";h();te();I=r=>{if(r.includes('"')||r.includes("\0"))throw new d(400,{message:`Oracle identifiers cannot contain double quotes: ${r}`});return`"${r}"`},lt=()=>{let r=[];return{values:r,bind:t=>(r.push(t),`:${r.length}`)}},fs='YYYY-MM-DD"T"HH24:MI:SS',hs=`${fs}.FF9`,ec=`${hs}TZH:TZM`,Kd=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?\s*(Z|[+-]\d{2}(?::?\d{2})?)?$/i,tc=r=>{let e=r.toUpperCase();return e==="DATE"?"date":e.startsWith("TIMESTAMP")?e.includes("WITH LOCAL TIME ZONE")?"timestampLtz":e.includes("WITH TIME ZONE")?"timestampTz":"timestamp":null},Hd=r=>{let e=r?tc(r):null;return e==="date"?fs:e==="timestampTz"?ec:e?hs:null},En=(r,e)=>{let t=Hd(e);return t?`TO_CHAR(${r}, '${t}')`:r},jd=(r,e)=>{let t=r instanceof Date?r.toISOString():r;if(typeof t!="string")throw new d(400,{message:`Invalid Oracle ${e} value`});let n=t.trim().match(Kd);if(!n)throw new d(400,{message:`Invalid Oracle date or timestamp value: ${t}`});let[,a,s,o,i="00",c="00",l="00",u="",m]=n,p=`${a}-${s}-${o}T${i}:${c}:${l}`;if(e==="date")return p;let f=`${p}.${u.padEnd(9,"0")}`;if(e==="timestamp")return f;if(!m||m.toUpperCase()==="Z")return`${f}+00:00`;let b=m.replace(":","");return`${f}${b.slice(0,3)}:${b.slice(3).padEnd(2,"0")}`},qe=(r,e,t)=>{let n=e?tc(e):null;if(!n)return t(r);let a=t(r==null?null:jd(r,n));return n==="date"?`TO_DATE(${a}, '${fs}')`:n==="timestamp"?`TO_TIMESTAMP(${a}, '${hs}')`:`TO_TIMESTAMP_TZ(${a}, '${ec}')`},wn=(r,e)=>r.map(({COLUMN_NAME:t,DATA_TYPE:n})=>{let a=`${e?`${e}.`:""}${I(t)}`,s=En(a,n);return s===a?a:`${s} AS ${I(t)}`}).join(", "),nc=r=>{let e=new Map;for(let t of r){let n=e.get(t.CONSTRAINT_NAME);if(n){n.columns.push(t.REFERENCING_COLUMN),n.referencedColumns.push(t.REFERENCED_COLUMN);continue}e.set(t.CONSTRAINT_NAME,{constraintName:t.CONSTRAINT_NAME,referencingTable:t.REFERENCING_TABLE,columns:[t.REFERENCING_COLUMN],referencedTable:t.REFERENCED_TABLE,referencedColumns:[t.REFERENCED_COLUMN]})}return[...e.values()]},rc=r=>r.length?`WHERE ${r.join(" AND ")}`:"";sc=(r,e)=>`ORDER BY ${r.map(t=>`${e?`${e}.`:""}${t.column===null?"ROWID":I(t.column)} ${t.direction.toUpperCase()}`).join(", ")}`,Wd=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),oc=r=>Wd.has(r.toLowerCase().trim());ic="GENERATED BY DEFAULT ON NULL AS IDENTITY"});var lc,uc=N(()=>{"use strict";h();lc=r=>{if(typeof r!="string"||!/^[+-]?\d+$/.test(r))return r;let e=Number(r);return Number.isSafeInteger(e)?e:r}});var bs,mc,dc,ft,pc,Yd,Vd,fc,fr,zd,Gd,Qd,Jd,Xd,Ts,hc,Zd,hr,yc=N(()=>{"use strict";h();z();Xe();Ze();ct();wt();te();ze();cc();uc();bs=r=>r.oracleServerVersion>=23e8,mc=r=>Buffer.isBuffer(r)?r.toString("hex"):r,dc=r=>{let e=je("oracle");switch(r.dbType){case e.DB_TYPE_NUMBER:return{type:e.STRING,converter:lc};case e.DB_TYPE_CLOB:case e.DB_TYPE_NCLOB:return{type:e.STRING};case e.DB_TYPE_BLOB:return{type:e.BUFFER,converter:mc};case e.DB_TYPE_RAW:case e.DB_TYPE_LONG_RAW:return{converter:mc}}},ft=(r,e)=>r==null?null:typeof r=="boolean"?e==="BOOLEAN"?r:Number(r):typeof r=="bigint"?r.toString():r instanceof Date||typeof r!="object"?r:JSON.stringify(r),pc=r=>{let e=r.DATA_DEFAULT?.trim();return e&&e.toUpperCase()!=="NULL"?e:null},Yd=r=>{switch(r.DATA_TYPE){case"NUMBER":return r.DATA_PRECISION===null?r.DATA_SCALE===0?"INTEGER":"NUMBER":r.DATA_SCALE?`NUMBER(${r.DATA_PRECISION},${r.DATA_SCALE})`:`NUMBER(${r.DATA_PRECISION})`;case"FLOAT":return`FLOAT(${r.DATA_PRECISION})`;case"VARCHAR2":case"NVARCHAR2":case"CHAR":case"NCHAR":return`${r.DATA_TYPE}(${r.CHAR_LENGTH})`;case"RAW":return`RAW(${r.DATA_LENGTH})`;default:return r.DATA_TYPE}},Vd=(r,e)=>`${e?`${e}.`:""}${r==="ROWID"?"ROWID":I(r)}`,fc=r=>r.columns.map((e,t)=>`c.${I(e)} = p.${I(r.referencedColumns[t])}`).join(" AND "),fr=(r,e,t)=>`(${r.keys.map(n=>`(${r.columns.map((a,s)=>`${Vd(a,e)} = ${t(n[s],a)}`).join(" AND ")})`).join(" OR ")})`,zd=r=>{let e=je("oracle");return r.dbType===e.DB_TYPE_DATE||r.dbType===e.DB_TYPE_TIMESTAMP||r.dbType===e.DB_TYPE_TIMESTAMP_TZ||r.dbType===e.DB_TYPE_TIMESTAMP_LTZ},Gd=[["ORA-01758","A NOT NULL column added to a table with rows needs a default value."],["ORA-01439","Oracle can only change a column to an unrelated type while the column is empty."],["ORA-22858","Oracle cannot convert this column to or from a LOB (CLOB/BLOB) type."],["ORA-00932","Oracle cannot compare, sort or filter CLOB, BLOB or JSON values this way."],["ORA-22848","Oracle cannot sort or compare CLOB, BLOB or JSON values."],["ORA-12899","The value is too long for the column."],["ORA-01441","The column holds values longer than the new type allows."],["ORA-30675","Oracle identity columns must have a numeric type."],["ORA-01861","Dates must be written as YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS."],["ORA-01830","Dates must be written as YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS."],["ORA-01843","Dates must be written as YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS."]],Qd=["ORA-00955","ORA-01408","ORA-01452"],Jd=["ORA-00972","ORA-01450","ORA-02327","ORA-02329"],Xd="ORA-02429",Ts=(r,e)=>r instanceof Error&&e.some(t=>r.message.startsWith(t)),hc={CASCADE:" ON DELETE CASCADE","SET NULL":" ON DELETE SET NULL",RESTRICT:"","NO ACTION":""},Zd={1:"fatal",2:"error",8:"warning",16:"info"},hr=class extends ae{async runQuery(e,t,n){return this.withConnection(a=>this.query(a,t,n))}quoteIdentifier(e){return I(e)}mapToUniversalType(e){return Pn(e)}mapFromUniversalType(e){return{text:"VARCHAR2(4000)",number:"NUMBER",boolean:"BOOLEAN",json:"JSON",date:"TIMESTAMP",array:"JSON",enum:"VARCHAR2(255)"}[e]??"VARCHAR2(4000)"}buildTableDataQuery(e){throw new Error("OracleAdapter.getTableData builds its own query")}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){throw new Error("OracleAdapter.getTableData builds its own cursors")}wrapError(e){if(e instanceof Error&&!(e instanceof d)){let t=Gd.find(([n])=>e.message.startsWith(n));if(t)return new d(400,{message:`${t[1]} (${e.message.split(`
|
|
298
298
|
`)[0]})`,cause:e});if(e.message.startsWith("ORA-00955"))return new d(409,{message:e.message.split(`
|
|
299
|
-
`)[0],cause:e})}return super.wrapError(e)}async withConnection(e){try{let t=await(await
|
|
299
|
+
`)[0],cause:e})}return super.wrapError(e)}async withConnection(e){try{let t=await(await Za()).getConnection();try{return await e(t)}finally{await t.close()}}catch(t){throw this.wrapError(t)}}inTransaction(e){return this.withConnection(async t=>{try{let n=await e(t);return await t.commit(),n}catch(n){throw await t.rollback().catch(()=>{}),n}})}async query(e,t,n=[]){return(await e.execute(t,n,{outFormat:je("oracle").OUT_FORMAT_OBJECT,fetchTypeHandler:dc})).rows??[]}async execute(e,t,n=[]){return(await e.execute(t,n)).rowsAffected??0}async getTableData(e){let{tableName:t,limit:n=50,sort:a=[],order:s="asc",cursor:o,filters:i=[]}=e;return this.withConnection(async c=>{let l=await this.requireColumns(c,t),u=new Map(l.map(_=>[_.COLUMN_NAME,_.DATA_TYPE])),m=await this.primaryKey(c,t),p=this.orderTerms(a,s,m.length?m:[null]),f=o?Number(this.decodeCursor(o)?.values._offset??0):0,{values:b,bind:y}=lt(),g=rc(ac(i,y,u)),S=[...b],[w]=await this.query(c,`SELECT COUNT(*) AS "total" FROM ${I(t)} ${g}`,S),D="t",A=await this.query(c,`SELECT ${wn(l,D)} FROM ${I(t)} ${D} ${g} ${sc(p,D)} OFFSET ${y(f)} ROWS FETCH NEXT ${y(n+1)} ROWS ONLY`,b),R=A.length>n,C=_=>this.encodeCursor({values:{_offset:_},sortColumns:["_offset"]});return{data:A.slice(0,n).map(_=>this.normalizeRow(_)),meta:{limit:n,total:Number(w?.total??0),hasNextPage:R,hasPreviousPage:f>0,nextCursor:R?C(f+n):null,prevCursor:f>0?C(Math.max(0,f-n)):null}}})}async exportTableData({tableName:e}){return this.withConnection(async t=>{let n=await this.requireColumns(t,e),a=await this.query(t,`SELECT ${wn(n)} FROM ${I(e)}`);if(!a.length)throw new d(404,{message:`Table "${e}" does not exist or has no data`});return{cols:n.map(s=>s.COLUMN_NAME),rows:a}})}async getDatabasesList(){return this.withConnection(async e=>{let[t]=await this.query(e,`SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS name, USER AS owner,
|
|
300
300
|
(SELECT NVL(SUM(bytes), 0) FROM user_segments) AS bytes,
|
|
301
301
|
(SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET') AS encoding
|
|
302
|
-
FROM dual`);return t?[{name:t.NAME,size:this.formatBytes(Number(t.BYTES)),owner:t.OWNER,encoding:t.ENCODING}]:[]})}async getCurrentDatabase(){return this.withConnection(async e=>({db:await this.containerName(e)}))}async getDatabaseConnectionInfo(){let e=await
|
|
302
|
+
FROM dual`);return t?[{name:t.NAME,size:this.formatBytes(Number(t.BYTES)),owner:t.OWNER,encoding:t.ENCODING}]:[]})}async getCurrentDatabase(){return this.withConnection(async e=>({db:await this.containerName(e)}))}async getDatabaseConnectionInfo(){let e=await Za().catch(t=>{throw this.wrapError(t)});return this.withConnection(async t=>{let[n]=await this.query(t,"SELECT USER AS u FROM dual"),{host:a,port:s}=Oe(Ue());return{host:a,port:s,user:n?.U??"",database:await this.containerName(t),version:`Oracle ${t.oracleServerVersionString}`,active_connections:e.connectionsInUse,max_connections:e.poolMax}})}async getTablesList(e){return this.withConnection(async t=>{let n=await this.query(t,`SELECT table_name, num_rows FROM user_tables
|
|
303
303
|
WHERE dropped = 'NO' AND nested = 'NO' AND secondary = 'N' AND (iot_type IS NULL OR iot_type = 'IOT')
|
|
304
|
-
ORDER BY table_name`),a=n.filter(o=>o.NUM_ROWS===null||o.NUM_ROWS<1e5),s=new Map;if(a.length){let o=await this.query(t,a.map((i,c)=>`SELECT ${c} AS n, COUNT(*) AS c FROM ${I(i.TABLE_NAME)}`).join(" UNION ALL "));for(let i of o)s.set(a[i.N].TABLE_NAME,Number(i.C))}return n.map(o=>({tableName:o.TABLE_NAME,rowCount:s.get(o.TABLE_NAME)??Number(o.NUM_ROWS??0)}))})}async createTable({tableData:e}){let{tableName:t,fields:n,foreignKeys:a=[]}=e;for(let s of a){if(s.onUpdate!=="NO ACTION"&&s.onUpdate!=="RESTRICT")throw new d(400,{message:`Oracle foreign keys have no ON UPDATE actions (${s.onUpdate} on "${s.columnName}"). Use NO ACTION.`});if(!(s.onDelete in
|
|
304
|
+
ORDER BY table_name`),a=n.filter(o=>o.NUM_ROWS===null||o.NUM_ROWS<1e5),s=new Map;if(a.length){let o=await this.query(t,a.map((i,c)=>`SELECT ${c} AS n, COUNT(*) AS c FROM ${I(i.TABLE_NAME)}`).join(" UNION ALL "));for(let i of o)s.set(a[i.N].TABLE_NAME,Number(i.C))}return n.map(o=>({tableName:o.TABLE_NAME,rowCount:s.get(o.TABLE_NAME)??Number(o.NUM_ROWS??0)}))})}async createTable({tableData:e}){let{tableName:t,fields:n,foreignKeys:a=[]}=e;for(let s of a){if(s.onUpdate!=="NO ACTION"&&s.onUpdate!=="RESTRICT")throw new d(400,{message:`Oracle foreign keys have no ON UPDATE actions (${s.onUpdate} on "${s.columnName}"). Use NO ACTION.`});if(!(s.onDelete in hc))throw new d(400,{message:`Oracle foreign keys do not support ON DELETE ${s.onDelete} (on "${s.columnName}"). Use CASCADE, SET NULL or NO ACTION.`})}await this.withConnection(async s=>{let o=bs(s),i=n.filter(l=>l.isPrimaryKey).map(l=>l.columnName),c=n.map(l=>this.columnDefinition(l,{withConstraints:!1,native:o}));i.length&&c.push(`PRIMARY KEY (${i.map(I).join(", ")})`);for(let l of n)l.isUnique&&!l.isPrimaryKey&&c.push(`UNIQUE (${I(l.columnName)})`);for(let l of a)c.push(`FOREIGN KEY (${I(l.columnName)}) REFERENCES ${I(l.referencedTable)} (${I(l.referencedColumn)})${hc[l.onDelete]}`);await s.execute(`CREATE TABLE ${I(t)} (${c.join(", ")})`)})}async deleteTable({tableName:e,cascade:t}){return this.withConnection(async n=>{await this.requireColumns(n,e);let a=(await this.foreignKeys(n,"referenced",e)).filter(o=>o.referencingTable!==e);if(a.length&&!t)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.sampleReferencingRows(n,a)};let[s]=await this.query(n,`SELECT COUNT(*) AS c FROM ${I(e)}`);return await n.execute(`DROP TABLE ${I(e)}${t?" CASCADE CONSTRAINTS":""}`),{deletedCount:Number(s?.C??0),fkViolation:!1,relatedRecords:[]}})}async renameTable({tableName:e,newTableName:t}){this.assertDifferentTableName(e,t),await this.withConnection(async n=>{if(await this.requireColumns(n,e),(await this.columns(n,t)).length)throw new d(409,{message:`Table "${t}" already exists`});await n.execute(`ALTER TABLE ${I(e)} RENAME TO ${I(t)}`)})}async getTableSchema({tableName:e}){return this.withConnection(async t=>{await this.requireColumns(t,e),await t.execute(`BEGIN
|
|
305
305
|
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
|
|
306
306
|
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', TRUE);
|
|
307
|
-
END;`);let[n]=await this.query(t,"SELECT DBMS_METADATA.GET_DDL('TABLE', :1) AS ddl FROM dual",[e]);return n?.DDL.trim()??""})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let n=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),s=new Map((await this.foreignKeys(t,"referencing",e)).flatMap(o=>o.columns.map((i,c)=>[i,{referencedTable:o.referencedTable,referencedColumn:o.referencedColumns[c]}])));return n.map(o=>{let i=s.get(o.COLUMN_NAME),c
|
|
307
|
+
END;`);let[n]=await this.query(t,"SELECT DBMS_METADATA.GET_DDL('TABLE', :1) AS ddl FROM dual",[e]);return n?.DDL.trim()??""})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let n=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),s=new Map((await this.foreignKeys(t,"referencing",e)).flatMap(o=>o.columns.map((i,c)=>[i,{referencedTable:o.referencedTable,referencedColumn:o.referencedColumns[c]}])));return n.map(o=>{let i=s.get(o.COLUMN_NAME),c=Yd(o);return{columnName:o.COLUMN_NAME,dataType:Pn(c),dataTypeLabel:Fr(c),isNullable:o.NULLABLE==="Y",columnDefault:o.GENERATION_TYPE?`GENERATED ${o.GENERATION_TYPE}${o.DEFAULT_ON_NULL==="YES"?" ON NULL":""} AS IDENTITY`:pc(o),isPrimaryKey:a.has(o.COLUMN_NAME),isForeignKey:!!i,referencedTable:i?.referencedTable??null,referencedColumn:i?.referencedColumn??null,enumValues:null}})})}async addColumn(e){let{tableName:t,columnName:n}=e;await this.withConnection(async a=>{if((await this.requireColumns(a,t)).some(i=>i.COLUMN_NAME===n))throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let o=this.columnDefinition(e,{withConstraints:!0,native:bs(a)});await a.execute(`ALTER TABLE ${I(t)} ADD (${o})`)})}async deleteColumn({tableName:e,columnName:t}){return await this.withConnection(async n=>{await this.requireColumn(n,e,t),await n.execute(`ALTER TABLE ${I(e)} DROP COLUMN ${I(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o}=e;await this.withConnection(async i=>{let c=bs(i),l=(await this.requireColumn(i,t,n)).find(m=>m.COLUMN_NAME===n),u=`${I(n)} ${ys(a,!1,c)}`;o?.trim()?u+=` DEFAULT ${gs(o,c)}`:l&&!l.GENERATION_TYPE&&pc(l)&&(u+=" DEFAULT NULL"),l?.NULLABLE==="Y"!==s&&(u+=s?" NULL":" NOT NULL"),await i.execute(`ALTER TABLE ${I(t)} MODIFY (${u})`)})}async renameColumn({tableName:e,columnName:t,newColumnName:n}){await this.withConnection(async a=>{if((await this.requireColumn(a,e,t)).some(o=>o.COLUMN_NAME===n))throw new d(409,{message:`Column "${n}" already exists in table "${e}"`});await a.execute(`ALTER TABLE ${I(e)} RENAME COLUMN ${I(t)} TO ${I(n)}`)})}async getServerLogs(){return this.withConnection(async e=>{try{let t=await this.query(e,`${$e} SELECT TO_CHAR(SYS_EXTRACT_UTC(ORIGINATING_TIMESTAMP),
|
|
308
308
|
'YYYY-MM-DD"T"HH24:MI:SS.FF3"Z"') AS TS, MESSAGE_LEVEL, COMPONENT_ID, PROCESS_ID,
|
|
309
309
|
MODULE_ID, MESSAGE_TEXT
|
|
310
310
|
FROM V$DIAG_ALERT_EXT
|
|
311
|
-
ORDER BY ORIGINATING_TIMESTAMP DESC FETCH FIRST ${500} ROWS ONLY`);return{available:!0,source:"V$DIAG_ALERT_EXT (alert log)",entries:
|
|
312
|
-
`)[0],cause:m}):
|
|
313
|
-
`)[0],cause:m}):m}})}async dropIndex({tableName:e,indexName:t}){await this.withConnection(async n=>{let a=(await this.listIndexes(n,e)).find(s=>s.indexName===t);if(!a)throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});if(a.kind!=="index")throw new d(400,{message:`Index "${t}" backs a constraint; drop the constraint to remove it`});try{await n.execute(`DROP INDEX ${I(t)}`)}catch(s){throw
|
|
314
|
-
`)[0],cause:s}):s}})}async addRecord({params:e}){let{tableName:t,data:n}=e,a=Object.keys(n);if(!a.length)throw new d(400,{message:"No data provided for insert"});return{insertedCount:await this.inTransaction(async o=>{let i=await this.columnTypes(o,t),{values:c,bind:l}=
|
|
311
|
+
ORDER BY ORIGINATING_TIMESTAMP DESC FETCH FIRST ${500} ROWS ONLY`);return{available:!0,source:"V$DIAG_ALERT_EXT (alert log)",entries:Ie(t.reverse().map(n=>({ts:n.TS,level:Zd[n.MESSAGE_LEVEL]??"debug",rawLevel:String(n.MESSAGE_LEVEL),source:n.COMPONENT_ID??void 0,code:/ORA-\d+/.exec(n.MESSAGE_TEXT)?.[0],message:n.MESSAGE_TEXT.trim(),detail:he({process:n.PROCESS_ID,module:n.MODULE_ID})})))}}catch(t){if(t instanceof Error&&t.message.startsWith("ORA-00942:"))return re("Reading the alert log needs: GRANT SELECT ON V_$DIAG_ALERT_EXT TO <user>; or SELECT ANY DICTIONARY.");throw t}})}async getTableIndexes({tableName:e}){return this.withConnection(t=>this.listIndexes(t,e))}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o}=e;await this.withConnection(async i=>{let c=await this.requireColumns(i,t),l=a.find(m=>!c.some(p=>p.COLUMN_NAME===m));if(l!==void 0)throw new d(400,{message:`Column "${l}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});let u=`CREATE ${s?"UNIQUE ":""}INDEX ${I(n)} ON ${I(t)} (${a.map(m=>I(m)).join(", ")})`;try{await i.execute(u)}catch(m){throw Ts(m,Qd)?new d(409,{message:m.message.split(`
|
|
312
|
+
`)[0],cause:m}):Ts(m,Jd)?new d(400,{message:m.message.split(`
|
|
313
|
+
`)[0],cause:m}):m}})}async dropIndex({tableName:e,indexName:t}){await this.withConnection(async n=>{let a=(await this.listIndexes(n,e)).find(s=>s.indexName===t);if(!a)throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});if(a.kind!=="index")throw new d(400,{message:`Index "${t}" backs a constraint; drop the constraint to remove it`});try{await n.execute(`DROP INDEX ${I(t)}`)}catch(s){throw Ts(s,[Xd])?new d(400,{message:s.message.split(`
|
|
314
|
+
`)[0],cause:s}):s}})}async addRecord({params:e}){let{tableName:t,data:n}=e,a=Object.keys(n);if(!a.length)throw new d(400,{message:"No data provided for insert"});return{insertedCount:await this.inTransaction(async o=>{let i=await this.columnTypes(o,t),{values:c,bind:l}=lt(),u=a.map(m=>qe(ft(n[m],i.get(m)),i.get(m),l));return this.execute(o,`INSERT INTO ${I(t)} (${a.map(I).join(", ")}) VALUES (${u.join(", ")})`,c)})}}async updateRecords({params:e}){let{tableName:t}=e,n=this.resolveKeyColumns(e),a=this.groupUpdatesByKey(e,n);return{updatedCount:await this.inTransaction(async o=>{this.assertWholeKey(await this.primaryKey(o,t),n);let i=await this.columnTypes(o,t),c=0;for(let{keyValues:l,rowUpdates:u}of a){let{values:m,bind:p}=lt(),f=u.map(g=>`${I(g.columnName)} = ${qe(ft(g.value,i.get(g.columnName)),i.get(g.columnName),p)}`).join(", "),b=n.map((g,S)=>`${I(g)} = ${qe(ft(l[S],i.get(g)),i.get(g),p)}`).join(" AND "),y=await this.execute(o,`UPDATE ${I(t)} SET ${f} WHERE ${b}`,m);if(y===0)throw new d(404,{message:`Record with ${this.describeKey(n,l)} not found in table "${t}"`});c+=y}return c})}}async deleteRecords({tableName:e,primaryKeys:t}){let n=t[0]?.columnName;if(!n)throw new d(400,{message:"Primary key column name is required"});let a={columns:[n],keys:t.map(s=>[s.value])};return this.withConnection(async s=>{this.assertDeletableKey(await this.primaryKey(s,e));let o=await this.columnTypes(s,e);try{let{values:i,bind:c}=lt(),l=fr(a,void 0,(m,p)=>qe(ft(m,o.get(p)),o.get(p),c)),u=await this.execute(s,`DELETE FROM ${I(e)} WHERE ${l}`,i);return await s.commit(),{deletedCount:u,fkViolation:!1,relatedRecords:[]}}catch(i){if(await s.rollback().catch(()=>{}),!(i instanceof Error)||!i.message.startsWith("ORA-02292"))throw i;let c=[];for(let l of await this.foreignKeys(s,"referenced",e)){let u=await this.requireColumns(s,l.referencingTable),{values:m,bind:p}=lt(),f=fr(a,"p",(y,g)=>qe(ft(y,o.get(g)),o.get(g),p)),b=await this.query(s,`SELECT ${wn(u,"c")} FROM ${I(l.referencingTable)} c JOIN ${I(e)} p ON ${fc(l)} WHERE ${f} FETCH FIRST 100 ROWS ONLY`,m);b.length&&c.push({tableName:l.referencingTable,columnName:l.columns.join(", "),constraintName:l.constraintName,records:b})}return{deletedCount:0,fkViolation:!0,relatedRecords:c}}})}async forceDeleteRecords({tableName:e,primaryKeys:t}){let n=t[0]?.columnName;if(!n)throw new d(400,{message:"Primary key column name is required"});let a=async(o,i,c,l)=>{if(!c.keys.length)return 0;if(l.includes(i))throw new d(400,{message:`Cannot force delete: the foreign keys ${[...l,i].map(y=>`"${y}"`).join(" -> ")} form a cycle.`});let u=await this.columnTypes(o,i),m=0;for(let y of await this.foreignKeys(o,"referenced",i)){let{values:g,bind:S}=lt(),w=fr(c,"p",(A,R)=>R==="ROWID"?`CHARTOROWID(${S(A)})`:qe(ft(A,u.get(R)),u.get(R),S)),D=await this.query(o,`SELECT DISTINCT ROWIDTOCHAR(c.ROWID) AS "__rowid" FROM ${I(y.referencingTable)} c JOIN ${I(i)} p ON ${fc(y)} WHERE ${w}`,g);m+=await a(o,y.referencingTable,{columns:["ROWID"],keys:D.map(A=>[A.__rowid])},[...l,i])}let{values:p,bind:f}=lt(),b=fr(c,void 0,(y,g)=>g==="ROWID"?`CHARTOROWID(${f(y)})`:qe(ft(y,u.get(g)),u.get(g),f));return m+await this.execute(o,`DELETE FROM ${I(i)} WHERE ${b}`,p)};return{deletedCount:await this.inTransaction(async o=>(this.assertDeletableKey(await this.primaryKey(o,e)),a(o,e,{columns:[n],keys:t.map(i=>[i.value])},[])))}}async bulkInsertRecords({tableName:e,records:t}){if(!t?.length)throw new d(400,{message:"At least one record is required"});let n=Object.keys(t[0]),a=await this.inTransaction(async s=>{let o=await this.columnTypes(s,e),i=[],c=t.map((u,m)=>{let{values:p,bind:f}=lt(),b=n.map(y=>qe(ft(u[y],o.get(y)),o.get(y),f));return m===0&&(i=b),p});return(await s.executeMany(`INSERT INTO ${I(e)} (${n.map(I).join(", ")}) VALUES (${i.join(", ")})`,c)).rowsAffected??t.length});return{success:!0,message:`Bulk insert completed: ${a} records inserted`,successCount:a,failureCount:0}}async executeQuery({query:e}){if(!e?.trim())throw new d(400,{message:"Query is required"});let t=e.trim().replace(/\n\s*\/$/,"").trim(),a=/^(BEGIN|DECLARE|CREATE\s+(OR\s+REPLACE\s+)?((NON)?EDITIONABLE\s+)?(PROCEDURE|FUNCTION|PACKAGE|TRIGGER|TYPE))\b/i.test(t)?t:t.replace(/;\s*$/,"");return this.withConnection(async s=>{let o=performance.now(),i=await s.execute(a,[],{outFormat:je("oracle").OUT_FORMAT_OBJECT,fetchTypeHandler:dc,autoCommit:!0,resultSet:!0}),c=performance.now()-o;if(i.resultSet){if(i.metaData?.some(zd))throw await i.resultSet.close(),new d(400,{message:"Oracle query results with native DATE or TIMESTAMP columns must use TO_CHAR with an explicit format so fractional seconds are not lost."});let u;try{u=await i.resultSet.getRows()}finally{await i.resultSet.close()}return{columns:i.metaData?.map(m=>m.name)??[],rows:u,rowCount:u.length,duration:c,message:u.length===0?"OK":void 0}}let l=i.rowsAffected??0;return{columns:[],rows:[],rowCount:l,duration:c,message:i.rowsAffected===void 0?"OK":`OK (${l} rows affected)`}})}columnDefinition(e,{withConstraints:t,native:n}){let a=`${I(e.columnName)} ${ys(e.columnType,e.isArray??!1,n)}`;return e.isIdentity||oc(e.columnType)?a+=` ${ic}`:e.defaultValue?.trim()&&(a+=` DEFAULT ${gs(e.defaultValue,n)}`),!e.isNullable&&!e.isPrimaryKey&&(a+=" NOT NULL"),t&&(e.isPrimaryKey?a+=" PRIMARY KEY":e.isUnique&&(a+=" UNIQUE")),a}formatBytes(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}async containerName(e){let[t]=await this.query(e,"SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS db FROM dual");return t?.DB??""}columns(e,t){return this.query(e,`SELECT c.column_name, c.data_type, c.data_length, c.data_precision, c.data_scale, c.char_length,
|
|
315
315
|
c.nullable, c.data_default, c.default_on_null, i.generation_type
|
|
316
316
|
FROM user_tab_columns c
|
|
317
317
|
LEFT JOIN user_tab_identity_cols i ON i.table_name = c.table_name AND i.column_name = c.column_name
|
|
@@ -332,20 +332,20 @@ ${o.join(`,
|
|
|
332
332
|
JOIN user_constraints r ON r.constraint_name = c.r_constraint_name AND r.owner = c.r_owner
|
|
333
333
|
JOIN user_cons_columns rc ON rc.constraint_name = r.constraint_name AND rc.position = cc.position
|
|
334
334
|
WHERE c.constraint_type = 'R' AND ${t==="referencing"?"c":"r"}.table_name = :1
|
|
335
|
-
ORDER BY c.constraint_name, cc.position`,[n]);return
|
|
335
|
+
ORDER BY c.constraint_name, cc.position`,[n]);return nc(a)}async sampleReferencingRows(e,t){let n=[];for(let a of t){let s=await this.requireColumns(e,a.referencingTable),o=await this.query(e,`SELECT ${wn(s)} FROM ${I(a.referencingTable)} WHERE ${a.columns.map(i=>`${I(i)} IS NOT NULL`).join(" AND ")} FETCH FIRST 100 ROWS ONLY`);o.length&&n.push({tableName:a.referencingTable,columnName:a.columns.join(", "),constraintName:a.constraintName,records:o})}return n}}});var ep,tp,np,Es,rp,ap,sp,op,ip,cp,lp,up,mp,gc,bc=N(()=>{"use strict";h();ct();ep={PANIC:"fatal",FATAL:"fatal",ERROR:"error",WARNING:"warning",NOTICE:"info",INFO:"info",LOG:"info"},tp=/^duration: ([\d.]+) ms(?:\s+(?:statement|(?:execute|bind|parse) [^:]*): ([\s\S]*))?$/,np=/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?: (?:([A-Za-z]+)|([+-])(\d{2}):?(\d{2})?))?/,Es=(r,e)=>{let t=np.exec(r);if(!t)return;let[,n,a,s,o,i,c,l="",u,m,p,f="0"]=t,b=m?(m==="-"?-1:1)*(Number(p)*60+Number(f)):u==="UTC"||u==="GMT"?0:e,y=Number(l.padEnd(3,"0").slice(0,3)),g=Date.UTC(Number(n),Number(a)-1,Number(s),Number(o),Number(i),Number(c),y)-b*6e4;return new Date(g).toISOString()},rp=r=>{let e=tp.exec(r.message);return{ts:r.ts,level:ep[r.severity]??"debug",rawLevel:r.severity,source:r.source||void 0,code:r.code&&r.code!=="00000"?r.code:void 0,message:e?e[2]??"duration":r.message,durationMs:e?Number(e[1]):void 0,statement:r.statement||void 0,detail:r.detail}},ap=r=>r.message.includes($e)||r.statement?.includes($e),sp=/^(.*?)\b(DEBUG[1-5]|LOG|INFO|NOTICE|WARNING|ERROR|FATAL|PANIC|DETAIL|HINT|QUERY|CONTEXT|LOCATION|STATEMENT): {2}(.*)$/,op=new Set(["DETAIL","HINT","QUERY","CONTEXT","LOCATION","STATEMENT"]),ip=(r,e)=>{let t=[],n=null;for(let a of r){if(a.startsWith(" ")){n?.(a.slice(1));continue}let s=sp.exec(a);if(!s){n=null;continue}let[,o,i,c]=s,l=t.at(-1);if(op.has(i)){if(!l)continue;if(i==="STATEMENT")l.statement=c,n=p=>{l.statement=`${l.statement}
|
|
336
336
|
${p}`};else{let p=i.toLowerCase();l.detail[p]=c,n=f=>{l.detail[p]=`${l.detail[p]}
|
|
337
|
-
${f}`}}continue}let u=
|
|
338
|
-
${p}`}}return t},
|
|
339
|
-
`?(t.push(n),e.push(t),t=[],n=""):o!=="\r"&&(n+=o)}return(n||t.length)&&(t.push(n),e.push(t)),e},
|
|
340
|
-
`),s=a.findIndex((o,i)=>i>0&&
|
|
341
|
-
`)}let n=[];for(let a of
|
|
342
|
-
`);return t.truncatedStart&&e!=="csvlog"&&n.shift(),(e==="csvlog"?
|
|
337
|
+
${f}`}}continue}let u=Es(o,e.logUtcOffsetMinutes)??l?.ts;if(!u)continue;let m={ts:u,severity:i,message:c,detail:he({pid:/\[(\d+)\]/.exec(o)?.[1]})};t.push(m),n=p=>{m.message=`${m.message}
|
|
338
|
+
${p}`}}return t},cp=r=>{let e=[],t=[],n="",a=!1;for(let s=0;s<r.length;s++){let o=r[s];a?o==='"'&&r[s+1]==='"'?(n+='"',s++):o==='"'?a=!1:n+=o:o==='"'?a=!0:o===","?(t.push(n),n=""):o===`
|
|
339
|
+
`?(t.push(n),e.push(t),t=[],n=""):o!=="\r"&&(n+=o)}return(n||t.length)&&(t.push(n),e.push(t)),e},lp=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/,up=(r,e)=>{let t=r;if(e.truncatedStart){let a=r.split(`
|
|
340
|
+
`),s=a.findIndex((o,i)=>i>0&&lp.test(o));t=s===-1?"":a.slice(s).join(`
|
|
341
|
+
`)}let n=[];for(let a of cp(t)){let s=Es(a[0]??"",e.logUtcOffsetMinutes);!s||!a[11]||n.push({ts:s,severity:a[11],code:a[12],message:a[13]??"",statement:a[19],source:a[23],detail:he({user:a[1],database:a[2],pid:a[3],client:a[4],application:a[22],detail:a[14],hint:a[15],query:a[16],context:a[18]})})}return n},mp=(r,e)=>{let t=[];for(let n of r){let a;try{a=JSON.parse(n)}catch{continue}let s=Es(a.timestamp??"",e.logUtcOffsetMinutes);!s||!a.error_severity||t.push({ts:s,severity:a.error_severity,code:a.state_code,message:a.message??"",statement:a.statement,source:a.backend_type,detail:he({user:a.user,database:a.dbname,pid:a.pid,client:a.remote_host,application:a.application_name,detail:a.detail,hint:a.hint,query:a.internal_query,context:a.context})})}return t},gc=(r,e,t)=>{let n=r.split(`
|
|
342
|
+
`);return t.truncatedStart&&e!=="csvlog"&&n.shift(),(e==="csvlog"?up(r,t):e==="jsonlog"?mp(n,t):ip(n,t)).filter(s=>!ap(s)).map(rp)}});function ws(r){if(r.length===0)return{clause:"",values:[]};let e=[],t=[];for(let n of r){let a=t.length+1,s=At(n.columnName);switch(n.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${s} ${n.operator} $${a}`),t.push(n.value);break;case"is":n.value.toLowerCase()==="null"?e.push(`${s} IS NULL`):(e.push(`${s} = $${a}`),t.push(n.value));break;case"is not":n.value.toLowerCase()==="null"?e.push(`${s} IS NOT NULL`):(e.push(`${s} != $${a}`),t.push(n.value));break;case"like":e.push(`${s}::text LIKE $${a}`),t.push(n.value);break;case"not like":e.push(`${s}::text NOT LIKE $${a}`),t.push(n.value);break;case"ilike":e.push(`${s}::text ILIKE $${a}`),t.push(n.value);break;case"not ilike":e.push(`${s}::text NOT ILIKE $${a}`),t.push(n.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function Ss(r,e){return Array.isArray(r)?r.length===0?"":`ORDER BY ${r.map(n=>`${At(n.columnName)} ${n.direction.toUpperCase()}`).join(", ")}`:r&&typeof r=="string"?`ORDER BY ${At(r)} ${e?.toUpperCase()||"ASC"}`:""}function Cs(r,e,t,n){let{values:a,sortColumns:s}=r,o=[],i=[],u=t==="asc"===(e==="asc");if(s.length>0){let m=s.map(At).join(", "),p=s.map((b,y)=>`$${n+y}`).join(", "),f=u?">":"<";o.push(`(${m}) ${f} (${p})`);for(let b of s)i.push(a[b])}return{clause:o.length>0?`(${o.join(" AND ")})`:"",values:i}}var At,dp,et,ie,Tc=N(()=>{"use strict";h();At=r=>`"${r.replaceAll('"','""')}"`;dp=r=>`(SELECT sp.schema_name FROM unnest(current_schemas(false)) WITH ORDINALITY AS sp(schema_name, position)
|
|
343
343
|
JOIN information_schema.tables it
|
|
344
344
|
ON it.table_schema = sp.schema_name AND it.table_name = ${r}
|
|
345
|
-
ORDER BY sp.position LIMIT 1)`,
|
|
345
|
+
ORDER BY sp.position LIMIT 1)`,et=(r,e)=>`COALESCE(${e}::text, ${dp(r)})`,ie=(r,e)=>e?`${At(e)}.${At(r)}`:At(r)});var pp,yr,Ec=N(()=>{"use strict";h();z();Xe();Ze();ct();wt();te();ze();bc();Tc();pp=1024*1024,yr=class extends ae{databaseSizeSupport=new WeakMap;async runQuery(e,t,n){return(await(await G(e)).query(t,n)).rows}quoteIdentifier(e){return`"${e.replaceAll('"','""')}"`}mapToUniversalType(e){return _n(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"BOOLEAN",json:"JSONB",date:"TIMESTAMP WITH TIME ZONE",array:"TEXT[]",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,schemaName:n,cursor:a="",limit:s=50,direction:o="asc",sort:i=[],order:c="asc",filters:l=[],db:u}=e,m=[],p=c;Array.isArray(i)&&i.length>0?(m=i.map(v=>v.columnName),p=i[0].direction):typeof i=="string"&&i&&(m=[i]);let f=m.length>0?[...m]:["ctid"],{clause:b,values:y}=ws(l),g="",S=[];if(a){let v=this.decodeCursor(a);if(v){let M=Cs(v,o,p,y.length+1);g=M.clause,S=M.values}}let w="";b&&g?w=`WHERE ${b.replace(/^WHERE\s+/i,"")} AND ${g}`:b?w=b:g&&(w=`WHERE ${g}`);let D=Ss((Array.isArray(i),i),c),A=D;o==="desc"?D?A=D.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):A=`ORDER BY ${f.map(M=>`${this.quoteIdentifier(M)} ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!D&&f.length>0&&(A=`ORDER BY ${f.map(M=>`${this.quoteIdentifier(M)} ${p.toUpperCase()}`).join(", ")}`);let R=y.length+S.length+1,C=ie(t,n),_=`SELECT * FROM ${C} ${w} ${A} LIMIT $${R}`,O=[...y,...S,s+1],$=`SELECT COUNT(*) as total FROM ${C} ${b}`;return{sql:_,values:O,countSql:$,countValues:y}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,n){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:s=[],cursor:o}=e,i=[];Array.isArray(s)&&s.length>0?i=s.map(f=>f.columnName):typeof s=="string"&&s&&(i=[s]),i.length===0&&(i=["ctid"]);let c=f=>{let b={values:Object.fromEntries(i.map(y=>[y,f[y]])),sortColumns:i};return this.encodeCursor(b)},l=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(n&&(m=c(u)),o&&(p=c(l))):(o&&(m=c(u)),n&&(p=c(l))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,schemaName:n,db:a,limit:s=50,direction:o="asc",sort:i=[],order:c="asc",cursor:l,filters:u=[]}=e,m=await G(a),p=ie(t,n),{clause:f,values:b}=ws(u),[y,{total:g,estimated:S}]=await Promise.all([this.getPrimaryKeyColumns(m,p),this.countRows(m,p,f,b)]).catch(V=>{throw Qe(V)&&V.code==="42P01"?new d(404,{message:`Table "${t}" does not exist`}):this.wrapError(V)}),w=[],D=c;Array.isArray(i)&&i.length>0?(w=i.map(V=>V.columnName),D=i[0].direction):typeof i=="string"&&i&&(w=[i]);let A=y.length?y:["ctid"],R=[...w,...A.filter(V=>!w.includes(V))],C="",_=[];if(l){let V=this.decodeCursor(l);if(V){let be=Cs(V,o,D,b.length+1);C=be.clause,_=be.values}}let O="";f&&C?O=`WHERE ${f.replace(/^WHERE\s+/i,"")} AND ${C}`:f?O=f:C&&(O=`WHERE ${C}`);let $=Ss((Array.isArray(i),i),c),P=$;if(o==="desc"?$?P=$.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):P=`ORDER BY ${R.map(be=>`${this.quoteIdentifier(be)} ${D==="asc"?"DESC":"ASC"}`).join(", ")}`:!$&&R.length>0&&(P=`ORDER BY ${R.map(be=>`${this.quoteIdentifier(be)} ${D.toUpperCase()}`).join(", ")}`),$){let V=A.filter(Zt=>!w.includes(Zt)),be=D==="desc"!=(o==="desc")?"DESC":"ASC";V.length&&(P+=`, ${V.map(Zt=>`${this.quoteIdentifier(Zt)} ${be}`).join(", ")}`)}let v=R.includes("ctid"),M=[...y.map(V=>this.quoteIdentifier(V)),...v?["ctid"]:[]],X=b.length+_.length+1,Y=(await m.query(`SELECT ${["*",...M].join(", ")} FROM ${p} ${O} ${P} LIMIT $${X}`,[...b,..._,s+1])).rows,_e=Y.length>s;_e&&(Y=Y.slice(0,s)),o==="desc"&&(Y=Y.reverse());let yt=Y.map(V=>{if(!v)return V;let{ctid:be,...Zt}=V;return Zt}).filter(V=>Object.keys(V).length>0),ut=V=>({values:Object.fromEntries(R.map(be=>[be,V[be]])),sortColumns:R}),B=null,me=null;if(Y.length>0){let V=Y[0],be=Y[Y.length-1];o==="asc"?(_e&&(B=this.encodeCursor(ut(be))),l&&(me=this.encodeCursor(ut(V)))):(l&&(B=this.encodeCursor(ut(be))),_e&&(me=this.encodeCursor(ut(V))))}return{data:yt,meta:{limit:s,total:g,...S&&{totalEstimated:!0},hasNextPage:o==="asc"?_e:!!l,hasPreviousPage:o==="asc"?!!l:_e,nextCursor:B,prevCursor:me}}}async countRows(e,t,n,a){if(n){let{rows:o}=await e.query(`SELECT COUNT(*) as total FROM ${t} ${n}`,a);return{total:Number(o[0].total),estimated:!1}}let{rows:s}=await e.query(`SELECT CASE WHEN reltuples >= $1 THEN reltuples::bigint
|
|
346
346
|
ELSE (SELECT COUNT(*) FROM ${t}) END as total,
|
|
347
347
|
reltuples >= $1 as estimated
|
|
348
|
-
FROM pg_catalog.pg_class WHERE oid = $2::regclass`,[
|
|
348
|
+
FROM pg_catalog.pg_class WHERE oid = $2::regclass`,[it,t]);return{total:Number(s[0].total),estimated:s[0].estimated===!0}}async getDatabasesList(){try{let e=await G(),t=await this.supportsDatabaseSize(e)?"pg_size_pretty(pg_database_size(d.datname))":"'unknown'",{rows:n}=await e.query(`
|
|
349
349
|
SELECT
|
|
350
350
|
d.datname as name,
|
|
351
351
|
${t} as size,
|
|
@@ -355,7 +355,7 @@ ${p}`}}return t},Qd=r=>{let e=[],t=[],n="",a=!1;for(let s=0;s<r.length;s++){let
|
|
|
355
355
|
WHERE d.datistemplate = false
|
|
356
356
|
AND (d.datname NOT IN ('postgres', 'rdsadmin') OR d.datname = current_database())
|
|
357
357
|
ORDER BY d.datname;
|
|
358
|
-
`);if(!n[0])throw new d(500,{message:"No databases returned from database"});return n}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=await
|
|
358
|
+
`);if(!n[0])throw new d(500,{message:"No databases returned from database"});return n}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=await G(),{rows:t}=await e.query("SELECT current_database() AS db;");if(!t[0])throw new d(500,{message:"No current database returned from database"});return t[0]}async getDatabaseConnectionInfo(){let e=await G(),{rows:t}=await e.query(`
|
|
359
359
|
SELECT
|
|
360
360
|
version() as version,
|
|
361
361
|
current_database() as database,
|
|
@@ -364,7 +364,7 @@ ${p}`}}return t},Qd=r=>{let e=[],t=[],n="",a=!1;for(let s=0;s<r.length;s++){let
|
|
|
364
364
|
inet_server_port()::int4 as port,
|
|
365
365
|
(SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,
|
|
366
366
|
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;
|
|
367
|
-
`);if(!t[0])throw new d(500,{message:"No connection information returned from database"});let{connectionInfoSchema:n}=await Promise.resolve().then(()=>(
|
|
367
|
+
`);if(!t[0])throw new d(500,{message:"No connection information returned from database"});let{connectionInfoSchema:n}=await Promise.resolve().then(()=>(z(),Bo)),a=n.parse(t[0]),s=Oe(Ue());return{host:a.host||s.host,port:a.port||s.port,user:a.user,database:a.database,version:a.version.toString(),active_connections:a.active_connections,max_connections:a.max_connections}}async getTablesList(e){let t=await G(e),n=u=>u.replaceAll('"','""'),{rows:a}=await t.query(`
|
|
368
368
|
SELECT t.table_schema as "schemaName", t.table_name as "tableName", c.reltuples as "estimate"
|
|
369
369
|
FROM information_schema.tables t
|
|
370
370
|
JOIN pg_catalog.pg_namespace n ON n.nspname = t.table_schema
|
|
@@ -373,18 +373,18 @@ ${p}`}}return t},Qd=r=>{let e=[],t=[],n="",a=!1;for(let s=0;s<r.length;s++){let
|
|
|
373
373
|
AND t.table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
374
374
|
AND t.table_schema NOT LIKE 'pg_toast%'
|
|
375
375
|
ORDER BY t.table_schema, t.table_name;
|
|
376
|
-
`);if(!a[0])return[];let s=a.flatMap((u,m)=>u.estimate<
|
|
376
|
+
`);if(!a[0])return[];let s=a.flatMap((u,m)=>u.estimate<it?[{...u,index:m}]:[]),o=4,i=Array.from({length:o},()=>[]);s.forEach((u,m)=>{i[m%o]?.push(`SELECT ${u.index} AS index, COUNT(*) AS count FROM "${n(u.schemaName)}"."${n(u.tableName)}"`)});let c=await Promise.all(i.filter(u=>u.length>0).map(u=>t.query(u.join(" UNION ALL ")))),l=new Map(c.flatMap(({rows:u})=>u.map(m=>[m.index,Number(m.count)])));return a.map((u,m)=>{let p=l.get(m);return{schemaName:u.schemaName,tableName:u.tableName,rowCount:p??Math.round(u.estimate),...p===void 0&&{rowCountEstimated:!0}}})}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e,o=await G(t),i=a.filter(u=>u.isPrimaryKey).map(u=>u.columnName),c=a.map(u=>{let m=`"${u.columnName}" ${u.columnType}`;return u.isArray&&(m+="[]"),i.length===1&&u.isPrimaryKey&&(m+=" PRIMARY KEY"),u.isUnique&&!u.isPrimaryKey&&(m+=" UNIQUE"),u.isNullable||(m+=" NOT NULL"),u.isIdentity&&(m+=" GENERATED ALWAYS AS IDENTITY"),u.defaultValue&&!u.isIdentity&&(m+=` DEFAULT ${u.defaultValue}`),m});i.length>1&&c.push(`PRIMARY KEY (${i.map(u=>`"${u}"`).join(", ")})`);let l=s?.map(u=>`CONSTRAINT "${`fk_${n}_${u.columnName}_${u.referencedTable}_${u.referencedColumn}`}" FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await o.query(`CREATE TABLE "${n}" (
|
|
377
377
|
${[...c,...l].join(`,
|
|
378
378
|
`)}
|
|
379
|
-
);`)}async deleteTable(e){let{tableName:t,schemaName:n,db:a,cascade:s}=e,o=await
|
|
379
|
+
);`)}async deleteTable(e){let{tableName:t,schemaName:n,db:a,cascade:s}=e,o=await G(a),i=ie(t,n);await this.assertTableExists(o,t,n);let c=await this.getTableRowCount(o,i);if(!s&&(await this.getFkConstraints(o,t,n)).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t,n)};try{return await o.query(`DROP TABLE ${i} ${s?"CASCADE":"RESTRICT"}`),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(l){if(l.code==="2BP01")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t,n)};throw l instanceof d?l:new d(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:n,schemaName:a,db:s}=e;this.assertDifferentTableName(t,n);let o=await G(s),{rows:i}=await o.query(`SELECT table_schema as "schemaName" FROM information_schema.tables WHERE table_name = $1 AND table_schema NOT IN ('pg_catalog', 'information_schema') AND table_schema NOT LIKE 'pg_toast%';`,[t]),c=i.map(m=>m.schemaName);if(c.length===0)throw new d(404,{message:`Table "${t}" does not exist`});if(a&&!c.includes(a))throw new d(404,{message:`Table "${a}"."${t}" does not exist`});if(!a&&c.length>1)throw new d(400,{message:`Table "${t}" exists in multiple schemas (${c.join(", ")}); rename is ambiguous`});let l=a??c[0],{rows:u}=await o.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = $2) as exists;",[n,l]);if(u[0]?.exists)throw new d(409,{message:`Table "${n}" already exists`});await o.query(`ALTER TABLE "${l.replaceAll('"','""')}"."${t.replaceAll('"','""')}" RENAME TO "${n.replaceAll('"','""')}"`)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,schemaName:t,db:n}){let a=await G(n),s=et("$1","$2"),o=[e,t??null],{rows:i}=await a.query(`SELECT table_schema as "schemaName" FROM information_schema.tables WHERE table_schema = ${s} AND table_name = $1`,o),c=i[0]?.schemaName;if(!c)throw new d(404,{message:`Table "${e}" does not exist`});let{rows:l}=await a.query(`SELECT column_name, data_type, udt_name, is_nullable, column_default, character_maximum_length, numeric_precision, numeric_scale
|
|
380
380
|
FROM information_schema.columns WHERE table_schema = ${s} AND table_name = $1 ORDER BY ordinal_position`,o),{rows:u}=await a.query(`SELECT tc.constraint_name, tc.constraint_type, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
|
|
381
381
|
FROM information_schema.table_constraints tc
|
|
382
382
|
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
383
383
|
LEFT JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema AND tc.constraint_type = 'FOREIGN KEY'
|
|
384
384
|
WHERE tc.table_schema = ${s} AND tc.table_name = $1 ORDER BY tc.constraint_type, tc.constraint_name`,o),{rows:m}=await a.query(`SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = ${s} AND tablename = $1
|
|
385
|
-
AND indexname NOT IN (SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = ${s} AND table_name = $1 AND constraint_type = 'PRIMARY KEY')`,o),p=S=>{let{data_type:w,udt_name:D,character_maximum_length:A,numeric_precision:R,numeric_scale:C}=S;return w==="USER-DEFINED"?D:w==="ARRAY"?`${D.replace(/^_/,"")}[]`:(w==="character varying"||w==="varchar")&&A?`varchar(${A})`:w==="character"&&A?`char(${A})`:w==="numeric"&&R!==null?C!==null&&C>0?`numeric(${R}, ${C})`:`numeric(${R})`:w==="timestamp with time zone"?"timestamp with time zone":w==="timestamp without time zone"?"timestamp":{"character varying":"varchar",character:"char","double precision":"float8",integer:"integer",bigint:"bigint",smallint:"smallint",boolean:"boolean",text:"text",uuid:"uuid",json:"json",jsonb:"jsonb",date:"date",time:"time",bytea:"bytea"}[w]||w},f=[`create table ${c}.${e} (`],b=l.map(S=>{let w=` ${S.column_name} ${p(S)}`;return S.is_nullable==="NO"&&(w+=" not null"),S.column_default!==null&&(w+=` default ${S.column_default}`),w}),
|
|
386
|
-
`)),f.push(") tablespace pg_default;");for(let S of m)[...
|
|
387
|
-
`)}async getTableColumns({tableName:e,db:t,schemaName:n}){let a=await
|
|
385
|
+
AND indexname NOT IN (SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = ${s} AND table_name = $1 AND constraint_type = 'PRIMARY KEY')`,o),p=S=>{let{data_type:w,udt_name:D,character_maximum_length:A,numeric_precision:R,numeric_scale:C}=S;return w==="USER-DEFINED"?D:w==="ARRAY"?`${D.replace(/^_/,"")}[]`:(w==="character varying"||w==="varchar")&&A?`varchar(${A})`:w==="character"&&A?`char(${A})`:w==="numeric"&&R!==null?C!==null&&C>0?`numeric(${R}, ${C})`:`numeric(${R})`:w==="timestamp with time zone"?"timestamp with time zone":w==="timestamp without time zone"?"timestamp":{"character varying":"varchar",character:"char","double precision":"float8",integer:"integer",bigint:"bigint",smallint:"smallint",boolean:"boolean",text:"text",uuid:"uuid",json:"json",jsonb:"jsonb",date:"date",time:"time",bytea:"bytea"}[w]||w},f=[`create table ${c}.${e} (`],b=l.map(S=>{let w=` ${S.column_name} ${p(S)}`;return S.is_nullable==="NO"&&(w+=" not null"),S.column_default!==null&&(w+=` default ${S.column_default}`),w}),y=new Map;for(let S of u){let w=y.get(S.constraint_name)??[];w.push(S),y.set(S.constraint_name,w)}let g=[];for(let[S,w]of y){let D=w[0],A=w.map(R=>R.column_name).join(", ");D.constraint_type==="PRIMARY KEY"?g.push(` constraint ${S} primary key (${A})`):D.constraint_type==="FOREIGN KEY"?g.push(` constraint ${S} foreign key (${A}) references ${D.foreign_table_name} (${D.foreign_column_name})`):D.constraint_type==="UNIQUE"&&g.push(` constraint ${S} unique (${A})`)}f.push([...b,...g].join(`,
|
|
386
|
+
`)),f.push(") tablespace pg_default;");for(let S of m)[...y.values()].some(D=>D[0].constraint_type==="UNIQUE"&&D[0].constraint_name===S.indexname)||(f.push(""),f.push(`${S.indexdef};`));return f.join(`
|
|
387
|
+
`)}async getTableColumns({tableName:e,db:t,schemaName:n}){let a=await G(t),s=et("$1","$2"),{rows:o}=await a.query(`SELECT
|
|
388
388
|
c.column_name as "columnName", c.data_type as "dataType", c.udt_name as "udtName",
|
|
389
389
|
c.is_nullable = 'YES' as "isNullable", c.column_default as "columnDefault",
|
|
390
390
|
CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as "isPrimaryKey",
|
|
@@ -407,11 +407,11 @@ ${p}`}}return t},Qd=r=>{let e=[],t=[],n="",a=!1;for(let s=0;s<r.length;s++){let
|
|
|
407
407
|
JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema
|
|
408
408
|
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = ${s} AND tc.table_name = $1
|
|
409
409
|
) fk ON c.column_name = fk.column_name
|
|
410
|
-
WHERE c.table_schema = ${s} AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e,n??null]);if(!o||o.length===0)throw new d(404,{message:`Table "${e}" does not exist`});return o.map(i=>{let c=null;return i.enumValues&&(Array.isArray(i.enumValues)?c=i.enumValues:typeof i.enumValues=="string"&&(c=i.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:i.columnName,dataType:
|
|
410
|
+
WHERE c.table_schema = ${s} AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e,n??null]);if(!o||o.length===0)throw new d(404,{message:`Table "${e}" does not exist`});return o.map(i=>{let c=null;return i.enumValues&&(Array.isArray(i.enumValues)?c=i.enumValues:typeof i.enumValues=="string"&&(c=i.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:i.columnName,dataType:_n(i.dataType),dataTypeLabel:kr(i.dataType),isNullable:i.isNullable,columnDefault:i.columnDefault,isPrimaryKey:i.isPrimaryKey,isForeignKey:i.isForeignKey,referencedTable:i.referencedTable,...i.referencedSchema&&{referencedSchema:i.referencedSchema},referencedColumn:i.referencedColumn,enumValues:c}})}async addColumn(e){let{tableName:t,columnName:n,columnType:a,defaultValue:s,isPrimaryKey:o,isNullable:i,isUnique:c,isIdentity:l,isArray:u,schemaName:m,db:p}=e,f=await G(p);await this.assertTableExists(f,t,m);let b=ie(t,m),{rows:y}=await f.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${et("$1","$3")}) as exists;`,[t,n,m??null]);if(y[0]?.exists)throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let g=`"${n}" ${a}`;u&&(g+="[]"),o&&(g+=" PRIMARY KEY"),c&&!o&&(g+=" UNIQUE"),i||(g+=" NOT NULL"),l&&(g+=" GENERATED ALWAYS AS IDENTITY"),s?.trim()&&!l&&(g+=` DEFAULT ${s.trim()}`),await f.query(`ALTER TABLE ${b} ADD COLUMN ${g}`)}async deleteColumn(e){let{tableName:t,schemaName:n,columnName:a,cascade:s,db:o}=e,i=await G(o);await this.assertTableExists(i,t,n);let c=ie(t,n),{rows:l}=await i.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${et("$1","$3")}) as exists;`,[t,a,n??null]);if(!l[0]?.exists)throw new d(404,{message:`Column "${a}" does not exist in table "${t}"`});let{rowCount:u}=await i.query(`ALTER TABLE ${c} DROP COLUMN "${a}" ${s?"CASCADE":"RESTRICT"}`);return{deletedCount:u??0}}async alterColumn(e){let{tableName:t,schemaName:n,columnName:a,columnType:s,isNullable:o,defaultValue:i,db:c}=e,l=await G(c);await this.assertTableExists(l,t,n);let u=ie(t,n),{rows:m}=await l.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${et("$1","$3")}) as exists;`,[t,a,n??null]);if(!m[0]?.exists)throw new d(404,{message:`Column "${a}" does not exist in table "${t}"`});let p=await l.connect();try{await p.query("BEGIN"),await p.query(`ALTER TABLE ${u} ALTER COLUMN "${a}" TYPE ${s}`),await p.query(`ALTER TABLE ${u} ALTER COLUMN "${a}" ${o?"DROP":"SET"} NOT NULL`),i?.trim()?await p.query(`ALTER TABLE ${u} ALTER COLUMN "${a}" SET DEFAULT ${i.trim()}`):await p.query(`ALTER TABLE ${u} ALTER COLUMN "${a}" DROP DEFAULT`),await p.query("COMMIT")}catch(f){throw await p.query("ROLLBACK"),f}finally{p.release()}}async renameColumn(e){let{tableName:t,schemaName:n,columnName:a,newColumnName:s,db:o}=e,i=await G(o),c=`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${et("$1","$3")}) as exists;`;await this.assertTableExists(i,t,n);let l=ie(t,n),{rows:u}=await i.query(c,[t,a,n??null]);if(!u[0]?.exists)throw new d(404,{message:`Column "${a}" does not exist in table "${t}"`});let{rows:m}=await i.query(c,[t,s,n??null]);if(m[0]?.exists)throw new d(409,{message:`Column "${s}" already exists in table "${t}"`});await i.query(`ALTER TABLE ${l} RENAME COLUMN "${a}" TO "${s}"`)}async getServerLogs({db:e}){let t=await G(e);try{let{rows:[n]}=await t.query(`${$e} SELECT current_setting('logging_collector') AS collector,
|
|
411
411
|
current_setting('log_destination') AS destination,
|
|
412
412
|
EXTRACT(EPOCH FROM (now() AT TIME ZONE current_setting('log_timezone'))
|
|
413
|
-
- (now() AT TIME ZONE 'UTC')) / 60 AS offset`);if(n.collector!=="on")return
|
|
414
|
-
FROM pg_current_logfile($1) AS path`,[s]);if(!o.path||o.size===null)return
|
|
413
|
+
- (now() AT TIME ZONE 'UTC')) / 60 AS offset`);if(n.collector!=="on")return re("logging_collector is off, so PostgreSQL writes its log to stderr, outside the database. Turn it on to read the log here.");let a=n.destination.split(",").map(u=>u.trim()),s=["jsonlog","csvlog"].find(u=>a.includes(u))??"stderr",{rows:[o]}=await t.query(`${$e} SELECT path, (pg_stat_file(path)).size AS size
|
|
414
|
+
FROM pg_current_logfile($1) AS path`,[s]);if(!o.path||o.size===null)return re("PostgreSQL has not opened a log file yet.");let i=Number(o.size),c=Math.max(0,i-pp),{rows:[l]}=await t.query(`${$e} SELECT pg_read_binary_file($1, $2, $3) AS data`,[o.path,c,i-c]);return{available:!0,source:`${o.path} (${s})`,entries:Ie(gc(l.data.toString("utf8"),s,{logUtcOffsetMinutes:Number(n.offset),truncatedStart:c>0}))}}catch(n){if(Qe(n)&&n.code==="42501")return re("Reading the server log needs superuser, or: GRANT pg_monitor, pg_read_server_files TO <user>;");throw this.wrapError(n)}}async getTableIndexes({tableName:e,schemaName:t,db:n}){try{return(await this.listIndexes(await G(n),e,t)).map(({schemaName:s,...o})=>o)}catch(a){throw this.wrapError(a)}}async createIndex(e){let{tableName:t,schemaName:n,indexName:a,columns:s,isUnique:o,method:i="btree",db:c}=e;try{let l=await G(c);await this.assertTableExists(l,t,n);let{rows:u}=await l.query(`SELECT column_name as "columnName" FROM information_schema.columns WHERE table_name = $1 AND table_schema = ${et("$1","$2")}`,[t,n??null]),m=new Set(u.map(f=>f.columnName)),p=s.find(f=>!m.has(f));if(p!==void 0)throw new d(400,{message:`Column "${p}" does not exist in table "${t}"`});if(!W.pg.indexes.methods.includes(i))throw new d(400,{message:`Unsupported index method "${i}"`});await l.query(`CREATE ${o?"UNIQUE ":""}INDEX ${this.quoteIdentifier(a)} ON ${ie(t,n)} USING ${i} (${s.map(f=>this.quoteIdentifier(f)).join(", ")})`)}catch(l){let u=l.code;throw l instanceof Error&&(u==="42P07"||u==="23505")?new d(409,{message:l.message,cause:l}):l instanceof Error&&(u==="0A000"||u==="42704")?new d(400,{message:l.message,cause:l}):this.wrapError(l)}}async dropIndex({tableName:e,schemaName:t,indexName:n,db:a}){try{let s=await G(a),o=(await this.listIndexes(s,e,t)).find(i=>i.indexName===n);if(!o)throw new d(404,{message:`Index "${n}" does not exist on table "${e}"`});if(o.kind!=="index")throw new d(400,{message:`Index "${n}" backs a constraint; drop the constraint to remove it`});await s.query(`DROP INDEX ${this.quoteIdentifier(o.schemaName)}.${this.quoteIdentifier(n)}`)}catch(s){throw this.wrapError(s)}}async addRecord({db:e,schemaName:t,params:n}){let{tableName:a,data:s}=n,o=await G(e),i=Object.keys(s),c=Object.values(s),l=i.map((p,f)=>`$${f+1}`).join(", "),u=i.map(p=>`"${p}"`).join(", "),m=await o.query(`INSERT INTO ${ie(a,t)} (${u}) VALUES (${l}) RETURNING *`,c);if(m.rowCount===0)throw new d(500,{message:`Failed to insert record into "${a}"`});return{insertedCount:m.rowCount??0}}async updateRecords({params:e,schemaName:t,db:n}){let{tableName:a}=e,s=await G(n),o=ie(a,t),i=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(s,o),i);let c=this.groupUpdatesByKey(e,i);await s.query("BEGIN");try{let l=0;for(let{keyValues:u,rowUpdates:m}of c){let p=m.map((g,S)=>`"${g.columnName}" = $${S+1}`),f=m.map(g=>g.value!==null&&typeof g.value=="object"?JSON.stringify(g.value):g.value),b=i.map((g,S)=>`"${g}" = $${f.length+S+1}`);f.push(...u);let y=await s.query(`UPDATE ${o} SET ${p.join(", ")} WHERE ${b.join(" AND ")} RETURNING *`,f);if(y.rowCount===0)throw new d(404,{message:`Record with ${this.describeKey(i,u)} not found in table "${a}"`});l+=y.rowCount??0}return await s.query("COMMIT"),{updatedCount:l}}catch(l){throw await s.query("ROLLBACK"),l instanceof d||qt(l)?l:new d(500,{message:`Failed to update records in "${a}"`})}}async deleteRecords({tableName:e,schemaName:t,primaryKeys:n,db:a}){let s=await G(a),o=ie(e,t),i=n[0]?.columnName;if(!i)throw new d(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(s,o));let c=n.map(u=>u.value),l=c.map((u,m)=>`$${m+1}`).join(", ");try{await s.query("BEGIN");let u=await s.query(`DELETE FROM ${o} WHERE "${i}" IN (${l}) RETURNING *`,c);return await s.query("COMMIT"),{deletedCount:u.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(u){if(await s.query("ROLLBACK"),u.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(s,e,t,n)};throw u instanceof d?u:new d(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,schemaName:t,primaryKeys:n,db:a}){let s=await G(a),o=ie(e,t),i=n[0]?.columnName;if(!i)throw new d(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(s,o));let c=n.map(l=>l.value);await s.query("BEGIN");try{let l=await this.getFkConstraints(s,e,t),u=0,m=new Set,p=async(y,g,S,w)=>{let D=ie(y,g),A=await this.getFkConstraints(s,y,g);for(let _ of A){let O=w.map((v,M)=>`$${M+1}`).join(", "),{rows:$}=await s.query(`SELECT "${_.referencedColumn}" FROM ${D} WHERE "${S}" IN (${O})`,w),P=$.map(v=>v[_.referencedColumn]);P.length>0&&await p(_.referencingTable,_.referencingSchema,_.referencingColumn,P)}let R=w.map((_,O)=>`$${O+1}`).join(", "),C=await s.query(`DELETE FROM ${D} WHERE "${S}" IN (${R})`,w);u+=C.rowCount??0,m.add(D)};for(let y of l)m.has(ie(y.referencingTable,y.referencingSchema))||await p(y.referencingTable,y.referencingSchema,y.referencingColumn,c);let f=c.map((y,g)=>`$${g+1}`).join(", "),b=await s.query(`DELETE FROM ${o} WHERE "${i}" IN (${f}) RETURNING *`,c);return await s.query("COMMIT"),{deletedCount:(b.rowCount??0)+u}}catch(l){throw await s.query("ROLLBACK"),l instanceof d?l:new d(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,schemaName:t,records:n,db:a}){if(!n||n.length===0)throw new d(400,{message:"At least one record is required"});let o=await(await G(a)).connect();try{let i=Object.keys(n[0]),c=i.map(u=>`"${u}"`).join(", "),l=0;await o.query("BEGIN");for(let u of n){let m=i.map(f=>u[f]),p=i.map((f,b)=>`$${b+1}`).join(", ");try{await o.query(`INSERT INTO ${ie(e,t)} (${c}) VALUES (${p}) RETURNING *`,m),l++}catch(f){throw qt(f)?f:new d(500,{message:`Failed: ${f instanceof Error?f.message:String(f)}`})}}return await o.query("COMMIT"),{success:!0,message:`Bulk insert completed: ${l} records inserted`,successCount:l,failureCount:0}}catch(i){throw await o.query("ROLLBACK"),i instanceof d||qt(i)?i:new d(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async exportTableData({tableName:e,schemaName:t,db:n}){try{let a=await G(n),{rows:s}=await a.query(`SELECT * FROM ${ie(e,t)}`);if(s.length===0)throw new d(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(s[0]),rows:s}}catch(a){throw this.wrapError(a)}}async executeQuery({query:e,db:t}){let n=await G(t);if(!e?.trim())throw new d(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),s=performance.now(),o=await n.query(a),i=performance.now()-s;return{columns:o.fields.map(c=>c.name),rows:o.rows,rowCount:o.rows.length,duration:i,message:o.rows.length===0?"OK":void 0}}supportsDatabaseSize(e){let t=this.databaseSizeSupport.get(e);return t||(t=e.query(`SELECT to_regprocedure('pg_database_size(name)') IS NOT NULL AS "supported"`).then(({rows:n})=>n[0]?.supported===!0).catch(n=>{throw this.databaseSizeSupport.delete(e),n}),this.databaseSizeSupport.set(e,t)),t}async assertTableExists(e,t,n){let{rows:a}=await e.query(`SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ${et("$1","$2")}) as exists;`,[t,n??null]);if(!a[0]?.exists)throw new d(404,{message:`Table "${t}" does not exist`})}async listIndexes(e,t,n){await this.assertTableExists(e,t,n);let{rows:a}=await e.query(`SELECT
|
|
415
415
|
ic.relname AS "indexName",
|
|
416
416
|
n.nspname AS "schemaName",
|
|
417
417
|
ARRAY(
|
|
@@ -442,8 +442,8 @@ ${p}`}}return t},Qd=r=>{let e=[],t=[],n="",a=!1;for(let s=0;s<r.length;s++){let
|
|
|
442
442
|
FROM information_schema.table_constraints AS tc
|
|
443
443
|
JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
444
444
|
JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema
|
|
445
|
-
WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1 AND ccu.table_schema = ${
|
|
446
|
-
`){t.length>0&&(e.push(t),t=""),n++;continue}t+=o,n++}if(a||s)throw new Error("Unterminated quoted string in command");return t.length>0&&e.push(t),e}function
|
|
445
|
+
WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1 AND ccu.table_schema = ${et("$1","$2")}`,[t,n??null]);return a.map(s=>({constraintName:s.constraint_name,referencingSchema:s.referencing_schema,referencingTable:s.referencing_table,referencingColumn:s.referencing_column,referencedTable:s.referenced_table,referencedColumn:s.referenced_column}))}async getRelatedRecordsForTable(e,t,n){let a=await this.getFkConstraints(e,t,n);if(a.length===0)return[];let s=[];for(let o of a){let{rows:i}=await e.query(`SELECT * FROM ${ie(o.referencingTable,o.referencingSchema)} LIMIT 100`);i.length>0&&s.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:i})}return s}async getRelatedRecords(e,t,n,a){let s=await this.getFkConstraints(e,t,n);if(s.length===0)return[];let o=[],i=a.map(l=>l.value),c=new Map;for(let l of s){let u=`${l.referencingSchema}.${l.referencingTable}.${l.referencingColumn}`,m=c.get(u)??[];m.push(l),c.set(u,m)}for(let[,l]of c){let u=l[0];if(!u||!a.find(b=>b.columnName===u.referencedColumn))continue;let p=i.map((b,y)=>`$${y+1}`).join(", "),{rows:f}=await e.query(`SELECT * FROM ${ie(u.referencingTable,u.referencingSchema)} WHERE "${u.referencingColumn}" IN (${p}) LIMIT 100`,i);f.length>0&&o.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:f})}return o}async getTableRowCount(e,t){let{rows:n}=await e.query(`SELECT COUNT(*) as count FROM ${t}`);return Number.parseInt(n[0]?.count??"0",10)}}});function Ac(r){let e=[],t="",n=0,a=!1,s=!1;for(;n<r.length;){let o=r[n];if(a){o==="'"?a=!1:t+=o,n++;continue}if(s){if(o==="\\"&&n+1<r.length){t+=r[n+1],n+=2;continue}o==='"'?s=!1:t+=o,n++;continue}if(o==="'"){a=!0,n++;continue}if(o==='"'){s=!0,n++;continue}if(o===" "||o===" "||o===`
|
|
446
|
+
`){t.length>0&&(e.push(t),t=""),n++;continue}t+=o,n++}if(a||s)throw new Error("Unterminated quoted string in command");return t.length>0&&e.push(t),e}function Dc(r,e){if(r.length===0)return Vt(e);let t=r[0]?.toUpperCase()??"",n=r[1]?.toUpperCase();if((t==="ZRANGE"||t==="ZREVRANGE"||t==="ZRANGEBYSCORE")&&r.some(s=>s.toUpperCase()==="WITHSCORES"))return hp(e);if(n){let s=`${t} ${n}`,o=Rc[s];if(o)return o(e)}let a=Rc[t];return a?a(e):typeof e=="string"||typeof e=="number"||e===null?Ae(e):fp(e)?tt(e):Vt(e)}var fp,Nc,Vt,Ae,wc,tt,Sc,hp,yp,Cc,Rc,_c=N(()=>{"use strict";h();fp=r=>Array.isArray(r)&&r.every(e=>typeof e=="string"||e===null),Nc=r=>Array.isArray(r)&&r.length%2===0;Vt=r=>({columns:["result"],rows:[{result:typeof r=="string"?r:JSON.stringify(r,null,2)}],rowCount:1}),Ae=r=>r===null?{columns:["value"],rows:[{value:null}],rowCount:0}:{columns:["value"],rows:[{value:r}],rowCount:1},wc=r=>({columns:["status"],rows:[{status:r}],rowCount:1}),tt=r=>Array.isArray(r)?{columns:["#","value"],rows:r.map((e,t)=>({"#":t,value:e})),rowCount:r.length}:Vt(r),Sc=r=>{if(!Nc(r))return Vt(r);let e=[];for(let t=0;t<r.length;t+=2)e.push({field:r[t],value:r[t+1]});return{columns:["field","value"],rows:e,rowCount:e.length}},hp=r=>{if(!Nc(r))return tt(r);let e=[];for(let t=0;t<r.length;t+=2)e.push({member:r[t],score:r[t+1]});return{columns:["member","score"],rows:e,rowCount:e.length}},yp=r=>{if(typeof r!="string")return Vt(r);let e=[],t="";for(let n of r.split(/\r?\n/)){if(!n.trim())continue;if(n.startsWith("#")){t=n.replace(/^#\s*/,"").trim();continue}let a=n.indexOf(":");a<0||e.push({section:t,key:n.slice(0,a),value:n.slice(a+1)})}return{columns:["section","key","value"],rows:e,rowCount:e.length}},Cc=r=>{if(!Array.isArray(r))return Vt(r);let e=r.map(t=>{if(!Array.isArray(t)||t.length<2)return{id:null,fields:null};let[n,a]=t,s={};if(Array.isArray(a))for(let o=0;o<a.length;o+=2)s[String(a[o])]=a[o+1];return{id:n,fields:s}});return{columns:["id","fields"],rows:e,rowCount:e.length}},Rc={PING:wc,GET:Ae,SET:wc,TYPE:Ae,TTL:Ae,EXISTS:Ae,DBSIZE:Ae,DEL:Ae,INCR:Ae,DECR:Ae,STRLEN:Ae,LLEN:Ae,SCARD:Ae,ZCARD:Ae,HLEN:Ae,HGET:Ae,HMGET:tt,MGET:tt,KEYS:tt,LRANGE:tt,SMEMBERS:tt,HGETALL:Sc,HKEYS:tt,HVALS:tt,"CONFIG GET":Sc,ZRANGE:tt,INFO:yp,XRANGE:Cc,XREVRANGE:Cc}});import{createHash as gp,randomBytes as bp}from"crypto";import{z as rt}from"zod";function Ic(r){let e={};for(let t of r.split(/\r?\n/)){if(!t||t.startsWith("#"))continue;let n=t.indexOf(":");n<0||(e[t.slice(0,n)]=t.slice(n+1))}return e}function kp(r){let e=new Map;for(let t of r.split(/\r?\n/)){let n=t.match(/^db(\d+):keys=(\d+)/);n&&e.set(Number(n[1]),Number(n[2]))}return e}function xc(r){let e=r.key;if(e==null||e==="")throw new d(400,{message:"Field 'key' is required"});return String(e)}function Ds(r){let e=r.ttl;if(e==null||e==="")return null;let t=typeof e=="number"?e:Number.parseInt(String(e),10);return Number.isFinite(t)?t:null}function Tr(r){return typeof r=="string"?r:r==null?"":typeof r=="object"?JSON.stringify(r):String(r)}function Lc(r,e){if(typeof r=="string"){try{let t=JSON.parse(r);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}throw new d(400,{message:`Value for ${e} must be a JSON object`})}if(r&&typeof r=="object"&&!Array.isArray(r))return r;throw new d(400,{message:`Value for ${e} must be a JSON object`})}function Pc(r,e){if(Array.isArray(r))return r;if(typeof r=="string")try{let t=JSON.parse(r);if(Array.isArray(t))return t}catch{}throw new d(400,{message:`Value for ${e} must be a JSON array`})}function vp(r){let e;if(Array.isArray(r))e=r;else if(typeof r=="string")try{e=JSON.parse(r)}catch{throw new d(400,{message:"Value for zset must be an array of {member, score} entries"})}else throw new d(400,{message:"Value for zset must be an array of {member, score} entries"});let t=[];for(let n of e){if(!n||typeof n!="object")throw new d(400,{message:"Each zset entry must be an object with 'member' and 'score'"});let a=n;if(a.member===void 0||a.score===void 0)throw new d(400,{message:"Each zset entry must include 'member' and 'score'"});let s=typeof a.score=="number"?a.score:Number(a.score);if(!Number.isFinite(s))throw new d(400,{message:`Invalid score: ${String(a.score)}`});t.push({member:String(a.member),score:s})}return t}function Up(r){if(!r)return[];let e=[];for(let t=0;t<r.length;t+=2){let n=Number(r[t+1]);e.push({member:r[t],score:Number.isFinite(n)?n:0})}return e}function qp(r){if(!Array.isArray(r))return{length:0,firstId:null,lastId:null};let e={};for(let o=0;o<r.length;o+=2)e[String(r[o])]=r[o+1];let t=typeof e.length=="number"?e.length:Number.parseInt(String(e.length??"0"),10)||0,n=e["first-entry"],a=e["last-entry"],s=o=>Array.isArray(o)&&typeof o[0]=="string"?o[0]:null;return{length:t,firstId:s(n),lastId:s(a)}}var Nn,Rs,Sn,Tp,Ep,wp,Sp,Cp,Rp,Np,Ap,Dp,ht,_p,De,Op,Ip,Cn,xp,xe,Lp,gr,Z,br,Dt,Rn,Ns,Me,As,Pp,$p,nt,zt,Gt,Oc,Mp,Er,$c=N(()=>{"use strict";h();Xe();Ze();ct();te();_c();Nn=["strings","hashes","lists","sets","zsets","streams"],Rs={strings:"string",hashes:"hash",lists:"list",sets:"set",zsets:"zset",streams:"stream"},Sn="Schema is fixed for Redis tables; this operation is not supported",Tp="Sorting is not supported for Redis tables",Ep="Filtering is not supported for Redis tables",wp="Backward pagination is not supported for Redis tables (SCAN is forward-only)",Sp=10,Cp=3e4,Rp=1e4,Np=256*1024,Ap=8*1024*1024,Dp=r=>Nn.includes(r),ht=r=>{if(!Dp(r))throw new d(404,{message:`Table "${r}" does not exist in Redis. Valid tables: ${Nn.join(", ")}`});return r},_p=r=>/[\s"']/.test(r)||r===""?JSON.stringify(r):r,De=r=>{if(r==="")return Rt();let e=Number.parseInt(r,10);if(!Number.isFinite(e)||e<0)throw new d(400,{message:`Invalid Redis database index: "${r}". Expected a non-negative integer.`});return e},Op=r=>Buffer.from(JSON.stringify(r)).toString("base64url"),Ip=r=>{try{return rt.object({scanCursor:rt.string().regex(/^\d+$/),search:rt.string().max(512).optional(),exactPattern:rt.boolean(),type:rt.enum(["string","hash","list","set","zset","stream"]).optional()}).parse(JSON.parse(Buffer.from(r,"base64url").toString("utf-8")))}catch{return null}},Cn=r=>Buffer.from(JSON.stringify(r)).toString("base64url"),xp=r=>{try{return rt.object({key:rt.string().min(1).max(16*1024),type:rt.enum(["string","hash","list","set","zset","stream","unknown"]),cursor:rt.string().min(1).max(512),direction:rt.enum(["forward","backward"])}).parse(JSON.parse(Buffer.from(r,"base64url").toString("utf8")))}catch{return null}},xe=r=>{let e=r.toString("utf8");return Buffer.from(e,"utf8").equals(r)?{base64:r.toString("base64url"),utf8:e}:{base64:r.toString("base64url")}},Lp=r=>r.replaceAll(/[\\*?[\]]/g,"\\$&"),gr=r=>{let e=Buffer.isBuffer(r)?r.toString("utf8"):String(r);return["string","hash","list","set","zset","stream"].includes(e)?e:"unknown"},Z=r=>Buffer.from(r,"base64url"),br=r=>r==="-"?Buffer.alloc(0):Z(r),Dt=r=>gp("sha256").update(r).digest("base64url"),Rn=()=>new d(409,{message:"This key changed since it was loaded. Reload it or explicitly overwrite."}),Ns=r=>{let e=r instanceof Error?r.message:String(r);return/(NOPERM|unknown command|not allowed|unsupported)/i.test(e)},Me=(r,e)=>{if(r!==e)throw new d(400,{message:`This operation requires a ${e} key, but the key is ${r}.`})},As=r=>{if(r===null)throw Rn();if(!Array.isArray(r))return;let e=r.find(t=>Array.isArray(t)&&t[0]instanceof Error);if(e)throw new d(400,{message:e[0].message})},Pp=r=>Buffer.from(JSON.stringify(r)).toString("base64url"),$p=r=>{try{return JSON.parse(Buffer.from(r,"base64url").toString("utf-8"))}catch{return null}},nt=r=>({columnName:r.columnName,dataType:r.dataType,dataTypeLabel:r.dataTypeLabel??(r.dataType==="number"?"int":r.dataType==="json"?"json":r.dataType==="array"?"array":"text"),isNullable:r.isNullable??!1,columnDefault:r.columnDefault??null,isPrimaryKey:r.isPrimaryKey??!1,isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}),zt=nt({columnName:"key",dataType:"text",isPrimaryKey:!0}),Gt=nt({columnName:"ttl",dataType:"number",isNullable:!0}),Oc={strings:[zt,nt({columnName:"value",dataType:"text",isNullable:!0}),Gt],hashes:[zt,nt({columnName:"value",dataType:"json"}),Gt],lists:[zt,nt({columnName:"value",dataType:"array"}),Gt],sets:[zt,nt({columnName:"value",dataType:"array"}),Gt],zsets:[zt,nt({columnName:"value",dataType:"json"}),Gt],streams:[zt,nt({columnName:"length",dataType:"number"}),nt({columnName:"first-id",dataType:"text",isNullable:!0}),nt({columnName:"last-id",dataType:"text",isNullable:!0}),Gt]},Mp={strings:`-- Redis string keys
|
|
447
447
|
-- Columns: key (text, PK), value (text), ttl (number, seconds; -1 = no TTL, -2 = missing)
|
|
448
448
|
-- Backed by: GET / SET / EXPIRE`,hashes:`-- Redis hash keys
|
|
449
449
|
-- Columns: key (text, PK), value (json: {field: value, ...}), ttl (number)
|
|
@@ -455,24 +455,24 @@ ${p}`}}return t},Qd=r=>{let e=[],t=[],n="",a=!1;for(let s=0;s<r.length;s++){let
|
|
|
455
455
|
-- Columns: key (text, PK), value (json: [{member, score}, ...]), ttl (number)
|
|
456
456
|
-- Backed by: ZRANGE WITHSCORES / ZADD / EXPIRE`,streams:`-- Redis stream keys
|
|
457
457
|
-- Columns: key (text, PK), length (number), first-id (text), last-id (text), ttl (number)
|
|
458
|
-
-- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},fr=class extends se{countCache=new Map;runQuery(){throw new d(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new d(501,{message:"buildTableDataQuery is not supported for Redis"})}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"string":return"text";case"hash":return"json";case"list":case"set":return"array";case"zset":case"stream":return"json";case"integer":case"number":case"ttl":return"number";default:return"text"}}mapFromUniversalType(e){return"string"}async scanKeys(e){try{let{db:t,limit:n,search:a,exactPattern:s,type:o,cursor:i}=e,c=ye(t),l=await Re(c),u="0";if(i){let w=bp(i);if(!w||w.search!==a||w.exactPattern!==s||w.type!==o)throw new d(400,{message:"Invalid or stale key scan cursor"});u=w.scanCursor}let m=a?s?a:`*${Ep(a)}*`:"*",p=[u,"MATCH",m,"COUNT",n];o&&p.push("TYPE",o);let[f,b]=await l.scanBuffer(...p),h=Buffer.isBuffer(f)?f.toString("utf8"):f,g=l.pipeline();for(let w of b)g.call("TYPE",w),g.pttl(w),g.call("MEMORY","USAGE",w);let S=await g.exec()??[];return{keys:b.map((w,D)=>{let A=D*3,R=S[A+2]?.[1];return{key:Oe(w),type:mr(S[A]?.[1]),ttlMs:Number(S[A+1]?.[1]??-2),memoryBytes:R==null?null:Number(R)}}),nextCursor:h==="0"?null:gp({scanCursor:h,search:a,exactPattern:s,type:o}),hasMore:h!=="0"}}catch(t){throw this.wrapError(t)}}async getKeyDetails(e){try{let{db:t,key:n,cursor:a,limit:s,full:o,direction:i}=e,c=dr(n),l=await Re(ye(t)),[u,m,p,f]=await Promise.all([l.callBuffer("TYPE",c),l.pttl(c),l.call("MEMORY","USAGE",c).catch(()=>null),l.callBuffer("DUMP",c)]),b=f;if(!b)throw new d(404,{message:"Redis key no longer exists"});let h=mr(u),g={key:Oe(c),type:h,ttlMs:Number(m),memoryBytes:p===null?null:Number(p),revision:Nt(b)},S=a?Tp(a):null;if(a&&(!S||S.key!==n||S.type!==h||S.direction!==i))throw new d(400,{message:"Invalid or stale key details cursor"});if(h==="string"){let w=await l.strlen(c),D=o?fp:pp,A=await l.getrangeBuffer(c,0,D-1);return{...g,length:w,value:{kind:"string",value:Oe(A),truncated:w>D},nextCursor:null,hasMore:!1}}if(h==="hash"){let[w,D]=await Promise.all([l.hlen(c),l.hscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[A,R]=D,C=Buffer.isBuffer(A)?A.toString("utf8"):A,_=[];for(let O=0;O<R.length;O+=2)_.push({field:Oe(R[O]),value:Oe(R[O+1])});return{...g,length:w,value:{kind:"hash",entries:_},nextCursor:C==="0"?null:bn({key:n,type:h,cursor:C,direction:i}),hasMore:C!=="0"}}if(h==="list"){let w=Number.parseInt(S?.cursor??"0",10),D=await l.llen(c),A=await l.lrangeBuffer(c,w,w+s-1),R=w+A.length,C=R<D;return{...g,length:D,value:{kind:"list",entries:A.map((_,O)=>({index:w+O,value:Oe(_)}))},nextCursor:C?bn({key:n,type:h,cursor:String(R),direction:i}):null,hasMore:C}}if(h==="set"){let[w,D]=await Promise.all([l.scard(c),l.sscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[A,R]=D,C=Buffer.isBuffer(A)?A.toString("utf8"):A;return{...g,length:w,value:{kind:"set",members:R.map(Oe)},nextCursor:C==="0"?null:bn({key:n,type:h,cursor:C,direction:i}),hasMore:C!=="0"}}if(h==="zset"){let[w,D]=await Promise.all([l.zcard(c),l.zscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[A,R]=D,C=Buffer.isBuffer(A)?A.toString("utf8"):A,_=[];for(let O=0;O<R.length;O+=2)_.push({member:Oe(R[O]),score:(()=>{let $=R[O+1].toString("utf8");return $==="inf"?"inf":$==="-inf"?"-inf":Number($)})()});return{...g,length:w,value:{kind:"zset",entries:_},nextCursor:C==="0"?null:bn({key:n,type:h,cursor:C,direction:i}),hasMore:C!=="0"}}if(h==="stream"){let w=S?.cursor??(i==="forward"?"-":"+"),[D,A]=await Promise.all([l.xlen(c),i==="forward"?l.xrangeBuffer(c,w,"+","COUNT",s+1):l.xrevrangeBuffer(c,w,"-","COUNT",s+1)]),R=A.length>s,_=A.slice(0,s).map(([$,P])=>{let v=[];for(let M=0;M<P.length;M+=2)v.push({field:Oe(P[M]),value:Oe(P[M+1])});return{id:$.toString("utf8"),fields:v}}),O=_.at(-1)?.id;return{...g,length:D,value:{kind:"stream",entries:_},nextCursor:R&&O?bn({key:n,type:h,cursor:`(${O}`,direction:i}):null,hasMore:R}}return{...g,length:null,value:{kind:"unknown"},nextCursor:null,hasMore:!1}}catch(t){throw this.wrapError(t)}}async getStringChunk(e){try{let t=await Re(ye(e.db)),n=dr(e.key),a=mr(await t.callBuffer("TYPE",n));if(a==="unknown")throw new d(404,{message:"Redis key no longer exists"});if(Pe(a,"string"),e.expectedRevision){let c=await t.callBuffer("DUMP",n);if(!c||Nt(c)!==e.expectedRevision)throw Tn()}let s=await t.strlen(n),o=await t.getrangeBuffer(n,e.offset,e.offset+e.limit-1),i=e.offset+o.length;return{chunk:Oe(o),length:s,nextOffset:i<s?i:null,hasMore:i<s}}catch(t){throw this.wrapError(t)}}async createKey(e){let t=null;try{t=await Qn(ye(e.db));let n=Z(e.key.base64);if(await t.watch(n),await t.exists(n)!==0)throw new d(409,{message:"A Redis key with this name already exists."});if(e.type!==e.value.kind)throw new d(400,{message:"The initial value does not match the selected Redis key type."});let a=t.multi();switch(e.value.kind){case"string":a.set(n,Z(e.value.value.base64));break;case"hash":a.hset(n,...e.value.entries.flatMap(({field:o,value:i})=>[Z(o.base64),Z(i.base64)]));break;case"list":a.rpush(n,...e.value.entries.map(o=>Z(o.base64)));break;case"set":a.sadd(n,...e.value.members.map(o=>Z(o.base64)));break;case"zset":a.zadd(n,...e.value.entries.flatMap(({member:o,score:i})=>[i,Z(o.base64)]));break;case"stream":a.xadd(n,e.value.id,...e.value.fields.flatMap(({field:o,value:i})=>[Z(o.base64),Z(i.base64)]));break}e.ttlMs!==null&&a.pexpire(n,e.ttlMs),Ts(await a.exec());let s=await t.callBuffer("DUMP",n);if(!s)throw Tn();return{key:Oe(n),revision:Nt(s),deleted:!1}}catch(n){throw this.wrapError(n)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async applyKeyAction(e){let t=null;try{t=await Qn(ye(e.db));let n=dr(e.key),a=e.operation.action==="rename"?Z(e.operation.newKey.base64):null;a&&!a.equals(n)?await t.watch(n,a):await t.watch(n);let[s,o,i]=await Promise.all([t.callBuffer("DUMP",n),t.callBuffer("TYPE",n),t.pttl(n)]),c=s;if(!c)throw new d(404,{message:"Redis key no longer exists"});if(!e.force&&Nt(c)!==e.expectedRevision)throw Tn();let l=mr(o);if(a&&!a.equals(n)&&await t.exists(a)!==0)throw new d(409,{message:"A Redis key with the new name already exists."});let u=t.multi();switch(e.operation.action){case"rename":if(!a||a.equals(n))return{key:Oe(n),revision:Nt(c),deleted:!1};u.rename(n,a);break;case"setTtl":e.operation.ttlMs===null?u.persist(n):u.pexpire(n,e.operation.ttlMs);break;case"setString":Pe(l,"string"),u.set(n,Z(e.operation.value.base64)),i>0&&u.pexpire(n,i);break;case"upsertHash":Pe(l,"hash"),u.hset(n,Z(e.operation.field.base64),Z(e.operation.value.base64));break;case"deleteHash":Pe(l,"hash"),u.hdel(n,Z(e.operation.field.base64));break;case"pushList":Pe(l,"list"),e.operation.side==="left"?u.lpush(n,Z(e.operation.value.base64)):u.rpush(n,Z(e.operation.value.base64));break;case"setList":Pe(l,"list"),u.lset(n,e.operation.index,Z(e.operation.value.base64));break;case"deleteList":{Pe(l,"list");let f=Buffer.concat([Buffer.from("db-studio:list-delete:"),op(32)]);u.lset(n,e.operation.index,f),u.lrem(n,1,f);break}case"addSet":Pe(l,"set"),u.sadd(n,Z(e.operation.member.base64));break;case"removeSet":Pe(l,"set"),u.srem(n,Z(e.operation.member.base64));break;case"upsertZset":Pe(l,"zset"),u.zadd(n,e.operation.score,Z(e.operation.member.base64));break;case"removeZset":Pe(l,"zset"),u.zrem(n,Z(e.operation.member.base64));break;case"appendStream":Pe(l,"stream"),u.xadd(n,e.operation.id,...e.operation.fields.flatMap(({field:f,value:b})=>[Z(f.base64),Z(b.base64)]));break;case"deleteStream":Pe(l,"stream"),u.xdel(n,e.operation.id);break}Ts(await u.exec());let m=a&&!a.equals(n)?a:n,p=await t.callBuffer("DUMP",m);return{key:Oe(m),revision:p?Nt(p):null,deleted:p===null}}catch(n){throw this.wrapError(n)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async deleteKey(e){let t=null;try{t=await Qn(ye(e.db));let n=dr(e.key);await t.watch(n);let a=await t.callBuffer("DUMP",n);if(!a)throw new d(404,{message:"Redis key no longer exists"});if(!e.force&&Nt(a)!==e.expectedRevision)throw Tn();let s=t.multi().del(n);return Ts(await s.exec()),{deleted:!0}}catch(n){throw this.wrapError(n)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async getDatabasesList(){try{let e=await Re(Rt()),t=1,n=!1,a=null;try{a=await e.call("CONFIG","GET","databases")}catch(c){if(!bs(c))throw c}if(Array.isArray(a)&&a.length>=2){let c=Number.parseInt(String(a[1]),10);Number.isFinite(c)&&c>0&&(t=c,n=!0)}let s="";try{s=await e.info("keyspace")}catch(c){if(!bs(c))throw c}let o=Rp(s);return(n?Array.from({length:t},(c,l)=>l):[Rt()]).map(c=>({name:String(c),size:`${o.get(c)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(Rt())}}async getDatabaseConnectionInfo(){try{let e=await Re(Rt()),[t,n]=await Promise.all([e.info("server"),e.info("clients")]),a=Ec(t),s=Ec(n),o=Number.parseInt(s.maxclients??"0",10);if(!Number.isFinite(o)||o===0){let c=await e.call("CONFIG","GET","maxclients").catch(l=>{if(!bs(l))throw l;return null});Array.isArray(c)&&c.length>=2&&(o=Number.parseInt(String(c[1]),10)||0)}let i=e.options;return{host:i.host??null,port:i.port??null,user:i.username||"default",database:String(i.db??Rt()),version:a.redis_version??"unknown",active_connections:Number.parseInt(s.connected_clients??"0",10)||0,max_connections:o||0}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=ye(e),n=await this.getCachedCounts(t);return En.map(a=>({tableName:a,rowCount:n[a]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new d(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new d(400,{message:"Bulk deletion of Redis tables is not supported. Use FLUSHDB from the query runner to clear the entire logical database."})}async renameTable(e){throw new d(400,{message:gn})}async getTableSchema({tableName:e}){let t=ht(e);return Cp[t]}async getTableColumns({tableName:e}){let t=ht(e);return Tc[t]}async addColumn(e){throw new d(400,{message:gn})}async deleteColumn(e){throw new d(400,{message:gn})}async alterColumn(e){throw new d(400,{message:gn})}async renameColumn(e){throw new d(400,{message:gn})}async getTableData(e){try{let{tableName:t,db:n,cursor:a,limit:s=50,direction:o="asc",sort:i,filters:c}=e;if(o==="desc")throw new d(400,{message:lp});if(i&&i.length>0)throw new d(400,{message:ip});if(c&&c.length>0)throw new d(400,{message:cp});let l=ht(t),u=gs[l],m=ye(n),p=await Re(m),f="0";if(a){let _=Sp(a);if(!_||_.type!==l)throw new d(400,{message:"Invalid or mismatched cursor"});f=_.scanCursor}let b=[],h=0,g=!1;for(;b.length<s&&h<up;){let[_,O]=await p.scan(f,"MATCH","*","COUNT",Math.max(s*2,100),"TYPE",u);if(b.push(...O),f=_,h++,_==="0"){g=!0;break}}let S=b.slice(0,s),w=b.slice(s),D=await this.hydrateRows(p,l,S),A=await p.dbsize(),R=!g||w.length>0,C=R&&!g?wp({scanCursor:f,type:l}):null;return{data:D,meta:{limit:s,total:A,hasNextPage:R,hasPreviousPage:!1,nextCursor:C,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,n){if(n.length===0)return[];let a=e.pipeline();for(let c of n)a.ttl(c);let s=await a.exec()??[],o=e.pipeline();for(let c of n)switch(t){case"strings":o.get(c);break;case"hashes":o.hgetall(c);break;case"lists":o.lrange(c,0,-1);break;case"sets":o.smembers(c);break;case"zsets":o.zrange(c,0,-1,"WITHSCORES");break;case"streams":o.xinfo("STREAM",c);break}let i=await o.exec()??[];return n.map((c,l)=>{let u=s[l]?.[1]??-2,m=i[l]?.[1];if(t==="streams"){let f=Dp(m);return this.normalizeRow({key:c,length:f.length,"first-id":f.firstId,"last-id":f.lastId,ttl:u})}let p;switch(t){case"strings":p=m??null;break;case"hashes":p=m;break;case"lists":case"sets":p=m;break;case"zsets":p=Ap(m);break}return this.normalizeRow({key:c,value:p,ttl:u})})}async getCachedCounts(e){let t=this.countCache.get(e);if(t&&Date.now()-t.timestamp<mp)return t.counts;let n=await Re(e),a={},s=n.pipeline();for(let i of En)s.scan("0","MATCH","*","COUNT",dp,"TYPE",gs[i]);let o=await s.exec()??[];return En.forEach((i,c)=>{let l=o[c]?.[1];a[i]=l?.[1]?.length??0}),this.countCache.set(e,{timestamp:Date.now(),counts:a}),a}async addRecord({db:e,params:t}){try{let{tableName:n,data:a}=t,s=ht(n),o=wc(a),i=Es(a),c=await Re(ye(e));return await this.writeRecord(c,s,o,a.value,{mode:"create",ttl:i}),this.countCache.delete(ye(e)),{insertedCount:1}}catch(n){throw this.wrapError(n)}}async updateRecords({db:e,params:t}){try{let{tableName:n,updates:a,primaryKey:s,primaryKeys:o}=t,i=ht(n),c=o?.[0]||s||"key",l=await Re(ye(e)),u=new Map;for(let p of a){let f=p.rowData[c];if(f==null)throw new d(400,{message:`Primary key "${c}" not found in row data`});let b=String(f),h=u.get(b)??{...p.rowData};h[p.columnName]=p.value,u.set(b,h)}let m=0;for(let[p,f]of u.entries()){let b=f.value,h=Es(f);await this.writeRecord(l,i,p,b,{mode:"update",ttl:h});let g=f[c],S=g==null?p:String(g);if(S!==p&&await l.renamenx(p,S)===0)throw new d(409,{message:`Key "${S}" already exists`});m++}return{updatedCount:m}}catch(n){throw this.wrapError(n)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:n,db:a}=e;ht(t);let s=await Re(ye(a)),o=n.map(c=>String(c.value));if(o.length===0)return{deletedCount:0,fkViolation:!1,relatedRecords:[]};let i=await s.del(...o);return this.countCache.delete(ye(a)),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:n,db:a}=e;if(!n||n.length===0)throw new d(400,{message:"At least one record is required"});let s=ht(t),o=await Re(ye(a)),i=[],c=0;for(let l=0;l<n.length;l++){let u=n[l];try{let m=wc(u),p=Es(u);await this.writeRecord(o,s,m,u.value,{mode:"create",ttl:p}),c++}catch(m){i.push({recordIndex:l,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(ye(a)),{success:i.length===0,message:`Inserted ${c} of ${n.length} record${n.length===1?"":"s"}`,successCount:c,failureCount:i.length,...i.length>0?{errors:i}:{}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let n=ht(e),a=ye(t),s=await Re(a),o=gs[n],i=[],c="0";do{let[m,p]=await s.scan(c,"MATCH","*","COUNT",1e3,"TYPE",o);i.push(...p),c=m}while(c!=="0");if(i.length===0)throw new d(404,{message:`Table "${e}" has no data`});let l=await this.hydrateRows(s,n,i);return{cols:Tc[n].map(m=>m.columnName),rows:l}}catch(n){throw this.wrapError(n)}}async writeRecord(e,t,n,a,s){if(t==="streams"&&s.mode==="update")throw new d(400,{message:"Streams are append-only; updating a stream record is not supported"});if(s.mode==="create")if(t==="strings"){if(await e.set(n,typeof a=="string"?a:JSON.stringify(a),"NX")===null)throw new d(409,{message:`Key "${n}" already exists`})}else{if(await e.exists(n))throw new d(409,{message:`Key "${n}" already exists`});await this.writeCollectionValue(e,t,n,a)}else if(t==="strings"){if(await e.set(n,typeof a=="string"?a:JSON.stringify(a),"XX")===null)throw new d(404,{message:`Key "${n}" does not exist`})}else{if(!await e.exists(n))throw new d(404,{message:`Key "${n}" does not exist`});await e.del(n),await this.writeCollectionValue(e,t,n,a)}s.ttl!==null&&s.ttl>0&&await e.expire(n,s.ttl)}async writeCollectionValue(e,t,n,a){switch(t){case"hashes":{let s=Sc(a,"hash"),o=[];for(let[i,c]of Object.entries(s))o.push(i,pr(c));if(o.length===0)throw new d(400,{message:"Hash must have at least one field"});await e.hset(n,...o);return}case"lists":{let s=Cc(a,"list");if(s.length===0)throw new d(400,{message:"List must have at least one element"});await e.rpush(n,...s.map(pr));return}case"sets":{let s=Cc(a,"set");if(s.length===0)throw new d(400,{message:"Set must have at least one member"});await e.sadd(n,...s.map(pr));return}case"zsets":{let s=Np(a);if(s.length===0)throw new d(400,{message:"Sorted set must have at least one member"});let o=[];for(let i of s)o.push(i.score,i.member);await e.zadd(n,...o);return}case"streams":{let s=Sc(a,"stream"),o=[];for(let[i,c]of Object.entries(s))o.push(i,pr(c));if(o.length===0)throw new d(400,{message:"Stream entry must have at least one field"});await e.xadd(n,"*",...o);return}}}async getServerLogs({db:e}){try{let t=await Re(ye(e)),n=await t.call("SLOWLOG","GET","128"),a=await t.call("LATENCY","LATEST").catch(()=>[])??[],s=[...n.reverse().map(([o,i,c,l,u,m])=>({ts:new Date(Number(i)*1e3).toISOString(),level:"info",rawLevel:"slowlog",message:l.map(hp).join(" "),durationMs:Number(c)/1e3,detail:he({id:o,client:u,client_name:m})})),...a.map(([o,i,c,l])=>({ts:new Date(Number(i)*1e3).toISOString(),level:"warning",rawLevel:"latency",source:o,message:`latency spike: ${o}`,durationMs:Number(c),detail:he({max_ms:l})}))];return{available:!0,source:"SLOWLOG GET + LATENCY LATEST",entries:_e(s)}}catch(t){if(t instanceof Error&&t.message.startsWith("NOPERM"))return ae("Reading the slow log needs the +slowlog command, and +latency for latency spikes.");if(t instanceof Error&&t.message.startsWith("ERR unknown command"))return ae("This Redis server has SLOWLOG turned off.");throw this.wrapError(t)}}async executeQuery({query:e,db:t}){let n=performance.now();try{if(!e?.trim())throw new d(400,{message:"Query is required"});let a;try{a=hc(e.trim())}catch(u){throw new d(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(a.length===0)throw new d(400,{message:"Empty command"});let s=await Re(ye(t)),[o,...i]=a,c;try{c=await s.call(o,...i)}catch(u){let m=u instanceof Error?u.message:String(u);return{columns:["error"],rows:[{error:m}],rowCount:0,duration:performance.now()-n,error:m}}return{...gc(a,c),duration:performance.now()-n,message:typeof c=="string"?c:void 0}}catch(a){throw this.wrapError(a)}}}});function ws(r){if(!r.length)return{clause:"",values:[]};let e=[],t=[];for(let n of r){let a=`"${n.columnName}"`;switch(n.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${n.operator} ?`),t.push(n.value);break;case"is":n.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(n.value));break;case"is not":n.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(n.value));break;case"like":e.push(`CAST(${a} AS TEXT) LIKE ?`),t.push(n.value);break;case"not like":e.push(`CAST(${a} AS TEXT) NOT LIKE ?`),t.push(n.value);break;case"ilike":e.push(`CAST(${a} AS TEXT) LIKE ? COLLATE NOCASE`),t.push(n.value);break;case"not ilike":e.push(`CAST(${a} AS TEXT) NOT LIKE ? COLLATE NOCASE`),t.push(n.value);break;default:break}}return e.length?{clause:`WHERE ${e.join(" AND ")}`,values:t}:{clause:"",values:[]}}function Ss(r,e){return Array.isArray(r)?r.length?`ORDER BY ${r.map(t=>`"${t.columnName}" ${t.direction.toUpperCase()}`).join(", ")}`:"":r&&typeof r=="string"?`ORDER BY "${r}" ${e?.toUpperCase()||"ASC"}`:""}function Cs(r,e,t){let{values:n,sortColumns:a}=r;if(!a.length)return{clause:"",values:[]};let c=t==="asc"===(e==="asc")?">":"<",l=a.map(p=>`"${p}"`).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>n[p]);return{clause:`(${l}) ${c} (${u})`,values:m}}function yr(r,e){let t=e;for(;t<r.length;)if(/\s/.test(r[t]))t++;else if(r.startsWith("--",t)){let n=r.indexOf(`
|
|
459
|
-
`,t);t=n===-1?r.length:n+1}else if(r.startsWith("/*",t)){let n=r.indexOf("*/",t+2);t=n===-1?r.length:n+2}else break;return t}function
|
|
460
|
-
`,a+2),a===-1)break}else if(s==="/"&&r[a+1]==="*"){let i=r.indexOf("*/",a+2);if(i===-1)break;a=i+1}else if(s==="(")t++===0&&(n=a+1);else if(s===")"&&--t===0){e.push(r.slice(n,a).trim());break}else s===","&&t===1&&(e.push(r.slice(n,a).trim()),n=a+1)}return e},
|
|
458
|
+
-- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},Er=class extends ae{countCache=new WeakMap;runQuery(){throw new d(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new d(501,{message:"buildTableDataQuery is not supported for Redis"})}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"string":return"text";case"hash":return"json";case"list":case"set":return"array";case"zset":case"stream":return"json";case"integer":case"number":case"ttl":return"number";default:return"text"}}mapFromUniversalType(e){return"string"}async scanKeys(e){try{let{db:t,limit:n,search:a,exactPattern:s,type:o,cursor:i}=e,c=De(t),l=await Re(c),u="0";if(i){let w=Ip(i);if(!w||w.search!==a||w.exactPattern!==s||w.type!==o)throw new d(400,{message:"Invalid or stale key scan cursor"});u=w.scanCursor}let m=a?s?a:`*${Lp(a)}*`:"*",p=[u,"MATCH",m,"COUNT",n];o&&p.push("TYPE",o);let[f,b]=await l.scanBuffer(...p),y=Buffer.isBuffer(f)?f.toString("utf8"):f,g=l.pipeline();for(let w of b)g.call("TYPE",w),g.pttl(w),g.call("MEMORY","USAGE",w);let S=await g.exec()??[];return{keys:b.map((w,D)=>{let A=D*3,R=S[A+2]?.[1];return{key:xe(w),type:gr(S[A]?.[1]),ttlMs:Number(S[A+1]?.[1]??-2),memoryBytes:R==null?null:Number(R)}}),nextCursor:y==="0"?null:Op({scanCursor:y,search:a,exactPattern:s,type:o}),hasMore:y!=="0"}}catch(t){throw this.wrapError(t)}}async getKeyDetails(e){try{let{db:t,key:n,cursor:a,limit:s,full:o,direction:i}=e,c=br(n),l=await Re(De(t)),[u,m,p,f]=await Promise.all([l.callBuffer("TYPE",c),l.pttl(c),l.call("MEMORY","USAGE",c).catch(()=>null),l.callBuffer("DUMP",c)]),b=f;if(!b)throw new d(404,{message:"Redis key no longer exists"});let y=gr(u),g={key:xe(c),type:y,ttlMs:Number(m),memoryBytes:p===null?null:Number(p),revision:Dt(b)},S=a?xp(a):null;if(a&&(!S||S.key!==n||S.type!==y||S.direction!==i))throw new d(400,{message:"Invalid or stale key details cursor"});if(y==="string"){let w=await l.strlen(c),D=o?Ap:Np,A=await l.getrangeBuffer(c,0,D-1);return{...g,length:w,value:{kind:"string",value:xe(A),truncated:w>D},nextCursor:null,hasMore:!1}}if(y==="hash"){let[w,D]=await Promise.all([l.hlen(c),l.hscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[A,R]=D,C=Buffer.isBuffer(A)?A.toString("utf8"):A,_=[];for(let O=0;O<R.length;O+=2)_.push({field:xe(R[O]),value:xe(R[O+1])});return{...g,length:w,value:{kind:"hash",entries:_},nextCursor:C==="0"?null:Cn({key:n,type:y,cursor:C,direction:i}),hasMore:C!=="0"}}if(y==="list"){let w=Number.parseInt(S?.cursor??"0",10),D=await l.llen(c),A=await l.lrangeBuffer(c,w,w+s-1),R=w+A.length,C=R<D;return{...g,length:D,value:{kind:"list",entries:A.map((_,O)=>({index:w+O,value:xe(_)}))},nextCursor:C?Cn({key:n,type:y,cursor:String(R),direction:i}):null,hasMore:C}}if(y==="set"){let[w,D]=await Promise.all([l.scard(c),l.sscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[A,R]=D,C=Buffer.isBuffer(A)?A.toString("utf8"):A;return{...g,length:w,value:{kind:"set",members:R.map(xe)},nextCursor:C==="0"?null:Cn({key:n,type:y,cursor:C,direction:i}),hasMore:C!=="0"}}if(y==="zset"){let[w,D]=await Promise.all([l.zcard(c),l.zscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[A,R]=D,C=Buffer.isBuffer(A)?A.toString("utf8"):A,_=[];for(let O=0;O<R.length;O+=2)_.push({member:xe(R[O]),score:(()=>{let $=R[O+1].toString("utf8");return $==="inf"?"inf":$==="-inf"?"-inf":Number($)})()});return{...g,length:w,value:{kind:"zset",entries:_},nextCursor:C==="0"?null:Cn({key:n,type:y,cursor:C,direction:i}),hasMore:C!=="0"}}if(y==="stream"){let w=S?.cursor??(i==="forward"?"-":"+"),[D,A]=await Promise.all([l.xlen(c),i==="forward"?l.xrangeBuffer(c,w,"+","COUNT",s+1):l.xrevrangeBuffer(c,w,"-","COUNT",s+1)]),R=A.length>s,_=A.slice(0,s).map(([$,P])=>{let v=[];for(let M=0;M<P.length;M+=2)v.push({field:xe(P[M]),value:xe(P[M+1])});return{id:$.toString("utf8"),fields:v}}),O=_.at(-1)?.id;return{...g,length:D,value:{kind:"stream",entries:_},nextCursor:R&&O?Cn({key:n,type:y,cursor:`(${O}`,direction:i}):null,hasMore:R}}return{...g,length:null,value:{kind:"unknown"},nextCursor:null,hasMore:!1}}catch(t){throw this.wrapError(t)}}async getStringChunk(e){try{let t=await Re(De(e.db)),n=br(e.key),a=gr(await t.callBuffer("TYPE",n));if(a==="unknown")throw new d(404,{message:"Redis key no longer exists"});if(Me(a,"string"),e.expectedRevision){let c=await t.callBuffer("DUMP",n);if(!c||Dt(c)!==e.expectedRevision)throw Rn()}let s=await t.strlen(n),o=await t.getrangeBuffer(n,e.offset,e.offset+e.limit-1),i=e.offset+o.length;return{chunk:xe(o),length:s,nextOffset:i<s?i:null,hasMore:i<s}}catch(t){throw this.wrapError(t)}}async createKey(e){let t=null;try{t=await er(De(e.db));let n=Z(e.key.base64);if(await t.watch(n),await t.exists(n)!==0)throw new d(409,{message:"A Redis key with this name already exists."});if(e.type!==e.value.kind)throw new d(400,{message:"The initial value does not match the selected Redis key type."});let a=t.multi();switch(e.value.kind){case"string":a.set(n,Z(e.value.value.base64));break;case"hash":a.hset(n,...e.value.entries.flatMap(({field:o,value:i})=>[Z(o.base64),Z(i.base64)]));break;case"list":a.rpush(n,...e.value.entries.map(o=>Z(o.base64)));break;case"set":a.sadd(n,...e.value.members.map(o=>Z(o.base64)));break;case"zset":a.zadd(n,...e.value.entries.flatMap(({member:o,score:i})=>[i,Z(o.base64)]));break;case"stream":a.xadd(n,e.value.id,...e.value.fields.flatMap(({field:o,value:i})=>[Z(o.base64),Z(i.base64)]));break}e.ttlMs!==null&&a.pexpire(n,e.ttlMs),As(await a.exec());let s=await t.callBuffer("DUMP",n);if(!s)throw Rn();return{key:xe(n),revision:Dt(s),deleted:!1}}catch(n){throw this.wrapError(n)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async applyKeyAction(e){let t=null;try{t=await er(De(e.db));let n=br(e.key),a=e.operation.action==="rename"?Z(e.operation.newKey.base64):null;a&&!a.equals(n)?await t.watch(n,a):await t.watch(n);let[s,o,i]=await Promise.all([t.callBuffer("DUMP",n),t.callBuffer("TYPE",n),t.pttl(n)]),c=s;if(!c)throw new d(404,{message:"Redis key no longer exists"});if(!e.force&&Dt(c)!==e.expectedRevision)throw Rn();let l=gr(o);if(a&&!a.equals(n)&&await t.exists(a)!==0)throw new d(409,{message:"A Redis key with the new name already exists."});let u=t.multi();switch(e.operation.action){case"rename":if(!a||a.equals(n))return{key:xe(n),revision:Dt(c),deleted:!1};u.rename(n,a);break;case"setTtl":e.operation.ttlMs===null?u.persist(n):u.pexpire(n,e.operation.ttlMs);break;case"setString":Me(l,"string"),u.set(n,Z(e.operation.value.base64)),i>0&&u.pexpire(n,i);break;case"upsertHash":Me(l,"hash"),u.hset(n,Z(e.operation.field.base64),Z(e.operation.value.base64));break;case"deleteHash":Me(l,"hash"),u.hdel(n,Z(e.operation.field.base64));break;case"pushList":Me(l,"list"),e.operation.side==="left"?u.lpush(n,Z(e.operation.value.base64)):u.rpush(n,Z(e.operation.value.base64));break;case"setList":Me(l,"list"),u.lset(n,e.operation.index,Z(e.operation.value.base64));break;case"deleteList":{Me(l,"list");let f=Buffer.concat([Buffer.from("db-studio:list-delete:"),bp(32)]);u.lset(n,e.operation.index,f),u.lrem(n,1,f);break}case"addSet":Me(l,"set"),u.sadd(n,Z(e.operation.member.base64));break;case"removeSet":Me(l,"set"),u.srem(n,Z(e.operation.member.base64));break;case"upsertZset":Me(l,"zset"),u.zadd(n,e.operation.score,Z(e.operation.member.base64));break;case"removeZset":Me(l,"zset"),u.zrem(n,Z(e.operation.member.base64));break;case"appendStream":Me(l,"stream"),u.xadd(n,e.operation.id,...e.operation.fields.flatMap(({field:f,value:b})=>[Z(f.base64),Z(b.base64)]));break;case"deleteStream":Me(l,"stream"),u.xdel(n,e.operation.id);break}As(await u.exec());let m=a&&!a.equals(n)?a:n,p=await t.callBuffer("DUMP",m);return{key:xe(m),revision:p?Dt(p):null,deleted:p===null}}catch(n){throw this.wrapError(n)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async deleteKey(e){let t=null;try{t=await er(De(e.db));let n=br(e.key);await t.watch(n);let a=await t.callBuffer("DUMP",n);if(!a)throw new d(404,{message:"Redis key no longer exists"});if(!e.force&&Dt(a)!==e.expectedRevision)throw Rn();let s=t.multi().del(n);return As(await s.exec()),{deleted:!0}}catch(n){throw this.wrapError(n)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async getDatabasesList(){try{let e=await Re(Rt()),t=1,n=!1,a=null;try{a=await e.call("CONFIG","GET","databases")}catch(c){if(!Ns(c))throw c}if(Array.isArray(a)&&a.length>=2){let c=Number.parseInt(String(a[1]),10);Number.isFinite(c)&&c>0&&(t=c,n=!0)}let s="";try{s=await e.info("keyspace")}catch(c){if(!Ns(c))throw c}let o=kp(s);return(n?Array.from({length:t},(c,l)=>l):[Rt()]).map(c=>({name:String(c),size:`${o.get(c)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(Rt())}}async getDatabaseConnectionInfo(){try{let e=await Re(Rt()),[t,n]=await Promise.all([e.info("server"),e.info("clients")]),a=Ic(t),s=Ic(n),o=Number.parseInt(s.maxclients??"0",10);if(!Number.isFinite(o)||o===0){let c=await e.call("CONFIG","GET","maxclients").catch(l=>{if(!Ns(l))throw l;return null});Array.isArray(c)&&c.length>=2&&(o=Number.parseInt(String(c[1]),10)||0)}let i=e.options;return{host:i.host??null,port:i.port??null,user:i.username||"default",database:String(i.db??Rt()),version:a.redis_version??"unknown",active_connections:Number.parseInt(s.connected_clients??"0",10)||0,max_connections:o||0}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=De(e),n=await this.getCachedCounts(t);return Nn.map(a=>({tableName:a,rowCount:n[a]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new d(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new d(400,{message:"Bulk deletion of Redis tables is not supported. Use FLUSHDB from the query runner to clear the entire logical database."})}async renameTable(e){throw new d(400,{message:Sn})}async getTableSchema({tableName:e}){let t=ht(e);return Mp[t]}async getTableColumns({tableName:e}){let t=ht(e);return Oc[t]}async addColumn(e){throw new d(400,{message:Sn})}async deleteColumn(e){throw new d(400,{message:Sn})}async alterColumn(e){throw new d(400,{message:Sn})}async renameColumn(e){throw new d(400,{message:Sn})}async getTableData(e){try{let{tableName:t,db:n,cursor:a,limit:s=50,direction:o="asc",sort:i,filters:c}=e;if(o==="desc")throw new d(400,{message:wp});if(i&&i.length>0)throw new d(400,{message:Tp});if(c&&c.length>0)throw new d(400,{message:Ep});let l=ht(t),u=Rs[l],m=De(n),p=await Re(m),f="0";if(a){let _=$p(a);if(!_||_.type!==l)throw new d(400,{message:"Invalid or mismatched cursor"});f=_.scanCursor}let b=[],y=0,g=!1;for(;b.length<s&&y<Sp;){let[_,O]=await p.scan(f,"MATCH","*","COUNT",Math.max(s*2,100),"TYPE",u);if(b.push(...O),f=_,y++,_==="0"){g=!0;break}}let S=b.slice(0,s),w=b.slice(s),D=await this.hydrateRows(p,l,S),A=await p.dbsize(),R=!g||w.length>0,C=R&&!g?Pp({scanCursor:f,type:l}):null;return{data:D,meta:{limit:s,total:A,hasNextPage:R,hasPreviousPage:!1,nextCursor:C,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,n){if(n.length===0)return[];let a=e.pipeline();for(let c of n)a.ttl(c);let s=await a.exec()??[],o=e.pipeline();for(let c of n)switch(t){case"strings":o.get(c);break;case"hashes":o.hgetall(c);break;case"lists":o.lrange(c,0,-1);break;case"sets":o.smembers(c);break;case"zsets":o.zrange(c,0,-1,"WITHSCORES");break;case"streams":o.xinfo("STREAM",c);break}let i=await o.exec()??[];return n.map((c,l)=>{let u=s[l]?.[1]??-2,m=i[l]?.[1];if(t==="streams"){let f=qp(m);return this.normalizeRow({key:c,length:f.length,"first-id":f.firstId,"last-id":f.lastId,ttl:u})}let p;switch(t){case"strings":p=m??null;break;case"hashes":p=m;break;case"lists":case"sets":p=m;break;case"zsets":p=Up(m);break}return this.normalizeRow({key:c,value:p,ttl:u})})}async getCachedCounts(e){let t=await Re(e),n=this.countCache.get(t);if(n&&Date.now()-n.timestamp<Cp)return n.counts;let a={},s=t.pipeline();for(let i of Nn)s.scan("0","MATCH","*","COUNT",Rp,"TYPE",Rs[i]);let o=await s.exec()??[];return Nn.forEach((i,c)=>{let l=o[c]?.[1];a[i]=l?.[1]?.length??0}),this.countCache.set(t,{timestamp:Date.now(),counts:a}),a}async addRecord({db:e,params:t}){try{let{tableName:n,data:a}=t,s=ht(n),o=xc(a),i=Ds(a),c=await Re(De(e));return await this.writeRecord(c,s,o,a.value,{mode:"create",ttl:i}),this.countCache.delete(c),{insertedCount:1}}catch(n){throw this.wrapError(n)}}async updateRecords({db:e,params:t}){try{let{tableName:n,updates:a,primaryKey:s,primaryKeys:o}=t,i=ht(n),c=o?.[0]||s||"key",l=await Re(De(e)),u=new Map;for(let p of a){let f=p.rowData[c];if(f==null)throw new d(400,{message:`Primary key "${c}" not found in row data`});let b=String(f),y=u.get(b)??{...p.rowData};y[p.columnName]=p.value,u.set(b,y)}let m=0;for(let[p,f]of u.entries()){let b=f.value,y=Ds(f);await this.writeRecord(l,i,p,b,{mode:"update",ttl:y});let g=f[c],S=g==null?p:String(g);if(S!==p&&await l.renamenx(p,S)===0)throw new d(409,{message:`Key "${S}" already exists`});m++}return{updatedCount:m}}catch(n){throw this.wrapError(n)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:n,db:a}=e;ht(t);let s=await Re(De(a)),o=n.map(c=>String(c.value));if(o.length===0)return{deletedCount:0,fkViolation:!1,relatedRecords:[]};let i=await s.del(...o);return this.countCache.delete(s),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:n,db:a}=e;if(!n||n.length===0)throw new d(400,{message:"At least one record is required"});let s=ht(t),o=await Re(De(a)),i=[],c=0;for(let l=0;l<n.length;l++){let u=n[l];try{let m=xc(u),p=Ds(u);await this.writeRecord(o,s,m,u.value,{mode:"create",ttl:p}),c++}catch(m){i.push({recordIndex:l,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(o),{success:i.length===0,message:`Inserted ${c} of ${n.length} record${n.length===1?"":"s"}`,successCount:c,failureCount:i.length,...i.length>0?{errors:i}:{}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let n=ht(e),a=De(t),s=await Re(a),o=Rs[n],i=[],c="0";do{let[m,p]=await s.scan(c,"MATCH","*","COUNT",1e3,"TYPE",o);i.push(...p),c=m}while(c!=="0");if(i.length===0)throw new d(404,{message:`Table "${e}" has no data`});let l=await this.hydrateRows(s,n,i);return{cols:Oc[n].map(m=>m.columnName),rows:l}}catch(n){throw this.wrapError(n)}}async writeRecord(e,t,n,a,s){if(t==="streams"&&s.mode==="update")throw new d(400,{message:"Streams are append-only; updating a stream record is not supported"});if(s.mode==="create")if(t==="strings"){if(await e.set(n,typeof a=="string"?a:JSON.stringify(a),"NX")===null)throw new d(409,{message:`Key "${n}" already exists`})}else{if(await e.exists(n))throw new d(409,{message:`Key "${n}" already exists`});await this.writeCollectionValue(e,t,n,a)}else if(t==="strings"){if(await e.set(n,typeof a=="string"?a:JSON.stringify(a),"XX")===null)throw new d(404,{message:`Key "${n}" does not exist`})}else{if(!await e.exists(n))throw new d(404,{message:`Key "${n}" does not exist`});await e.del(n),await this.writeCollectionValue(e,t,n,a)}s.ttl!==null&&s.ttl>0&&await e.expire(n,s.ttl)}async writeCollectionValue(e,t,n,a){switch(t){case"hashes":{let s=Lc(a,"hash"),o=[];for(let[i,c]of Object.entries(s))o.push(i,Tr(c));if(o.length===0)throw new d(400,{message:"Hash must have at least one field"});await e.hset(n,...o);return}case"lists":{let s=Pc(a,"list");if(s.length===0)throw new d(400,{message:"List must have at least one element"});await e.rpush(n,...s.map(Tr));return}case"sets":{let s=Pc(a,"set");if(s.length===0)throw new d(400,{message:"Set must have at least one member"});await e.sadd(n,...s.map(Tr));return}case"zsets":{let s=vp(a);if(s.length===0)throw new d(400,{message:"Sorted set must have at least one member"});let o=[];for(let i of s)o.push(i.score,i.member);await e.zadd(n,...o);return}case"streams":{let s=Lc(a,"stream"),o=[];for(let[i,c]of Object.entries(s))o.push(i,Tr(c));if(o.length===0)throw new d(400,{message:"Stream entry must have at least one field"});await e.xadd(n,"*",...o);return}}}async getServerLogs({db:e}){try{let t=await Re(De(e)),n=await t.call("SLOWLOG","GET","128"),a=await t.call("LATENCY","LATEST").catch(()=>[])??[],s=[...n.reverse().map(([o,i,c,l,u,m])=>({ts:new Date(Number(i)*1e3).toISOString(),level:"info",rawLevel:"slowlog",message:l.map(_p).join(" "),durationMs:Number(c)/1e3,detail:he({id:o,client:u,client_name:m})})),...a.map(([o,i,c,l])=>({ts:new Date(Number(i)*1e3).toISOString(),level:"warning",rawLevel:"latency",source:o,message:`latency spike: ${o}`,durationMs:Number(c),detail:he({max_ms:l})}))];return{available:!0,source:"SLOWLOG GET + LATENCY LATEST",entries:Ie(s)}}catch(t){if(t instanceof Error&&t.message.startsWith("NOPERM"))return re("Reading the slow log needs the +slowlog command, and +latency for latency spikes.");if(t instanceof Error&&t.message.startsWith("ERR unknown command"))return re("This Redis server has SLOWLOG turned off.");throw this.wrapError(t)}}async executeQuery({query:e,db:t}){let n=performance.now();try{if(!e?.trim())throw new d(400,{message:"Query is required"});let a;try{a=Ac(e.trim())}catch(u){throw new d(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(a.length===0)throw new d(400,{message:"Empty command"});let s=await Re(De(t)),[o,...i]=a,c;try{c=await s.call(o,...i)}catch(u){let m=u instanceof Error?u.message:String(u);return{columns:["error"],rows:[{error:m}],rowCount:0,duration:performance.now()-n,error:m}}return{...Dc(a,c),duration:performance.now()-n,message:typeof c=="string"?c:void 0}}catch(a){throw this.wrapError(a)}}}});function _s(r){if(!r.length)return{clause:"",values:[]};let e=[],t=[];for(let n of r){let a=Sr(n.columnName);switch(n.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${n.operator} ?`),t.push(n.value);break;case"is":n.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(n.value));break;case"is not":n.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(n.value));break;case"like":e.push(`CAST(${a} AS TEXT) LIKE ?`),t.push(n.value);break;case"not like":e.push(`CAST(${a} AS TEXT) NOT LIKE ?`),t.push(n.value);break;case"ilike":e.push(`CAST(${a} AS TEXT) LIKE ? COLLATE NOCASE`),t.push(n.value);break;case"not ilike":e.push(`CAST(${a} AS TEXT) NOT LIKE ? COLLATE NOCASE`),t.push(n.value);break;default:break}}return e.length?{clause:`WHERE ${e.join(" AND ")}`,values:t}:{clause:"",values:[]}}function Os(r,e){return Array.isArray(r)?r.length?`ORDER BY ${r.map(t=>`${Sr(t.columnName)} ${t.direction.toUpperCase()}`).join(", ")}`:"":r&&typeof r=="string"?`ORDER BY ${Sr(r)} ${e?.toUpperCase()||"ASC"}`:""}function Is(r,e,t){let{values:n,sortColumns:a}=r;if(!a.length)return{clause:"",values:[]};let c=t==="asc"===(e==="asc")?">":"<",l=a.map(Sr).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>n[p]);return{clause:`(${l}) ${c} (${u})`,values:m}}function wr(r,e){let t=e;for(;t<r.length;)if(/\s/.test(r[t]))t++;else if(r.startsWith("--",t)){let n=r.indexOf(`
|
|
459
|
+
`,t);t=n===-1?r.length:n+1}else if(r.startsWith("/*",t)){let n=r.indexOf("*/",t+2);t=n===-1?r.length:n+2}else break;return t}function Mc(r){let e=[],t=0,n=!1,a=wr(r,0);for(;a<r.length;){let s=r[a];if(s===";"){t===0&&(n=!0,e=[]),a=wr(r,a+1);continue}if(n)return!0;let o=Bp[s];if(o){let i=r.indexOf(o,a+1);a=i===-1?r.length:i+1}else if(/[A-Za-z_]/.test(s)){let i=/^[A-Za-z_][A-Za-z0-9_$]*/.exec(r.slice(a))?.[0]??s,c=i.toUpperCase();e[0]==="CREATE"&&(e[1]==="TRIGGER"||(e[1]==="TEMP"||e[1]==="TEMPORARY")&&e[2]==="TRIGGER")&&(c==="BEGIN"||t>0&&c==="CASE")?t++:t>0&&c==="END"&&t--,e.length<3&&e.push(c),a+=i.length}else a++;a=wr(r,a)}return!1}function kc(r){return Fp.test(r.slice(wr(r,0)))}var Sr,Bp,Fp,vc=N(()=>{"use strict";h();Sr=r=>`"${r.replaceAll('"','""')}"`;Bp={"'":"'",'"':'"',"`":"`","[":"]"};Fp=/^(begin|start\s+transaction|commit|end|rollback|savepoint|release)\b/i});var Kp,Hp,Uc,jp,_t,Wp,Yp,Vp,xs,ee,qc,Cr,Bc=N(()=>{"use strict";h();z();Xe();Ze();te();vc();Kp={"'":"'",'"':'"',"`":"`","[":"]"},Hp=r=>{let e=[],t=0,n=-1;for(let a=0;a<r.length;a++){let s=r[a]??"",o=Kp[s];if(o){if(a=r.indexOf(o,a+1),a===-1)break}else if(s==="-"&&r[a+1]==="-"){if(a=r.indexOf(`
|
|
460
|
+
`,a+2),a===-1)break}else if(s==="/"&&r[a+1]==="*"){let i=r.indexOf("*/",a+2);if(i===-1)break;a=i+1}else if(s==="(")t++===0&&(n=a+1);else if(s===")"&&--t===0){e.push(r.slice(n,a).trim());break}else s===","&&t===1&&(e.push(r.slice(n,a).trim()),n=a+1)}return e},Uc=r=>r.every(e=>e!==null),jp=r=>r==null?null:typeof r=="boolean"?r?1:0:typeof r=="string"||typeof r=="number"||typeof r=="bigint"?r:r instanceof Date?r.toISOString():JSON.stringify(r),_t=(r,e=[])=>({sql:r,args:e.map(jp)}),Wp=BigInt(Number.MIN_SAFE_INTEGER),Yp=BigInt(Number.MAX_SAFE_INTEGER),Vp=r=>typeof r=="bigint"?r>=Wp&&r<=Yp?Number(r):r.toString():r instanceof ArrayBuffer?Buffer.from(r):r,xs=({columns:r,rows:e})=>e.map(t=>Object.fromEntries(r.map((n,a)=>[n,Vp(t[a])]))),ee=async(r,e,t=[])=>xs(await r.execute(_t(e,t))),qc=r=>r instanceof Error&&r.message.includes("FOREIGN KEY constraint failed"),Cr=class extends ae{schemaChange=Promise.resolve();serializeSchemaChange(e){let t=this.schemaChange.then(e);return this.schemaChange=t.catch(()=>{}),t}async runQuery(e,t,n){return await ee(await J(),t,n)}quoteIdentifier(e){return`"${e.replaceAll('"','""')}"`}mapToUniversalType(e){return xn(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"INTEGER",json:"TEXT",date:"TEXT",array:"TEXT",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:n="",limit:a=50,direction:s="asc",sort:o=[],order:i="asc",filters:c=[]}=e,l=[],u=i;Array.isArray(o)&&o.length>0?(l=o.map(R=>R.columnName),u=o[0].direction):typeof o=="string"&&o&&(l=[o]),l.length||(l=["rowid"]);let{clause:m,values:p}=_s(c),f="",b=[];if(n){let R=this.decodeCursor(n);if(R){let C=Is(R,s,u);f=C.clause,b=C.values}}let y="";m&&f?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${f}`:m?y=m:f&&(y=`WHERE ${f}`);let g=Os((Array.isArray(o),o),i),S=g;s==="desc"?g?S=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):S=`ORDER BY ${l.map(R=>`${this.quoteIdentifier(R)} ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(S=`ORDER BY ${l.map(R=>`${this.quoteIdentifier(R)} ${u.toUpperCase()}`).join(", ")}`);let w=`SELECT * FROM ${this.quoteIdentifier(t)} ${y} ${S} LIMIT ?`,D=[...p,...b,a+1],A=`SELECT COUNT(*) as total FROM ${this.quoteIdentifier(t)} ${m}`;return{sql:w,values:D,countSql:A,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,n){if(!t.length)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:s=[],cursor:o}=e,i=[];Array.isArray(s)&&s.length>0?i=s.map(f=>f.columnName):typeof s=="string"&&s&&(i=[s]),i.length||(i=["rowid"]);let c=f=>{let b={values:Object.fromEntries(i.map(y=>[y,f[y]])),sortColumns:i};return this.encodeCursor(b)},l=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(n&&(m=c(u)),o&&(p=c(l))):(o&&(m=c(u)),n&&(p=c(l))),{nextCursor:m,prevCursor:p}}async getTableData(e){try{let{tableName:t,db:n,limit:a=50,direction:s="asc",sort:o=[],order:i="asc",cursor:c,filters:l=[]}=e,u=await J(),m=await ee(u,`PRAGMA table_info(${this.quoteIdentifier(t)})`);if(m.length===0)throw new d(404,{message:`Table "${t}" does not exist`});let p=m.filter(B=>B.pk>0).sort((B,me)=>B.pk-me.pk).map(B=>B.name),f=[],b=i;Array.isArray(o)&&o.length>0?(f=o.map(B=>B.columnName),b=o[0].direction):typeof o=="string"&&o&&(f=[o]);let y=[...f,...p.filter(B=>!f.includes(B))],g=y.length===0;g&&y.push("rowid");let{clause:S,values:w}=_s(l),D="",A=[];if(c){let B=this.decodeCursor(c);if(B){let me=Is(B,s,b);D=me.clause,A=me.values}}let R="";S&&D?R=`WHERE ${S.replace(/^WHERE\s+/i,"")} AND ${D}`:S?R=S:D&&(R=`WHERE ${D}`);let C=Os((Array.isArray(o),o),i),_=p.filter(B=>!f.includes(B)),O=C;if(s==="desc")if(C){if(O=C.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),_.length){let B=b==="asc"?"DESC":"ASC";O+=`, ${_.map(me=>`${this.quoteIdentifier(me)} ${B}`).join(", ")}`}}else O=`ORDER BY ${y.map(B=>`${this.quoteIdentifier(B)} ${b==="asc"?"DESC":"ASC"}`).join(", ")}`;else C?_.length&&(O+=`, ${_.map(B=>`${this.quoteIdentifier(B)} ${b.toUpperCase()}`).join(", ")}`):O=`ORDER BY ${y.map(B=>`${this.quoteIdentifier(B)} ${b.toUpperCase()}`).join(", ")}`;let[$]=await ee(u,`SELECT COUNT(*) as total FROM ${this.quoteIdentifier(t)} ${S}`,w),P=Number($?.total??0),M=await ee(u,`SELECT ${g?"*, rowid":"*"} FROM ${this.quoteIdentifier(t)} ${R} ${O} LIMIT ?`,[...w,...A,a+1]),X=M.length>a,k=X?M.slice(0,a):M;s==="desc"&&(k=k.reverse());let Y=B=>({values:Object.fromEntries(y.map(me=>[me,B[me]])),sortColumns:y}),_e=null,yt=null;if(k.length>0){let B=k[0],me=k[k.length-1];s==="asc"?(X&&(_e=this.encodeCursor(Y(me))),c&&(yt=this.encodeCursor(Y(B)))):(c&&(_e=this.encodeCursor(Y(me))),X&&(yt=this.encodeCursor(Y(B))))}return{data:g?k.map(({rowid:B,...me})=>me):k,meta:{limit:a,total:P,hasNextPage:s==="asc"?X:!!c,hasPreviousPage:s==="asc"?!!c:X,nextCursor:_e,prevCursor:yt}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let{name:e,size:t}=await(await J()).info();return[{name:e,size:t,owner:"",encoding:"UTF-8"}]}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){try{return{db:(await(await J()).info()).name}}catch(e){throw this.wrapError(e)}}async getDatabaseConnectionInfo(){try{let{name:e,version:t}=await(await J()).info();return{host:null,port:null,user:"",database:e,version:t,active_connections:1,max_connections:1}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=await J(),n=await ee(t,`SELECT name FROM sqlite_master
|
|
461
461
|
WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT GLOB '_cf_*'
|
|
462
|
-
ORDER BY name`);if(!n.length)return[];let a=await t.batch(n.map(s=>`SELECT COUNT(*) as count FROM ${this.quoteIdentifier(s.name)}`),"read");return n.map((s,o)=>({tableName:s.name,rowCount:Rs(a[o])[0]?.count??0}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e,o=a.filter(u=>u.isPrimaryKey).map(u=>u.columnName),i=a.map(u=>{if(o.length===1&&u.isPrimaryKey&&u.isIdentity)return`"${u.columnName}" INTEGER PRIMARY KEY AUTOINCREMENT`;let m=`"${u.columnName}" ${u.columnType}`;return o.length===1&&u.isPrimaryKey&&(m+=" PRIMARY KEY"),u.isUnique&&!u.isPrimaryKey&&(m+=" UNIQUE"),!u.isNullable&&!u.isPrimaryKey&&(m+=" NOT NULL"),u.defaultValue?.trim()&&!u.isIdentity&&(m+=` DEFAULT ${u.defaultValue.trim()}`),m});o.length>1&&i.push(`PRIMARY KEY (${o.map(u=>`"${u}"`).join(", ")})`);let c=s?.map(u=>`FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await(await J()).execute(`CREATE TABLE "${n}" (${[...i,...c].join(", ")})`)}async deleteTable(e){let{tableName:t,cascade:n}=e,a=await J();if(!await this.tableExists(a,t))throw new d(404,{message:`Table "${t}" does not exist`});let[s]=await ee(a,`SELECT COUNT(*) as count FROM "${t}"`),o=s?.count??0;if(!n&&(await this.getFkReferencesForTable(a,t)).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(a,t)};try{return await a.execute(`DROP TABLE "${t}"`),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(i){if((i instanceof Error?i.message:String(i)).includes("FOREIGN KEY constraint"))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(a,t)};throw i instanceof d?i:new d(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){let{tableName:t,newTableName:n,db:a}=e;this.assertDifferentTableName(t,n);let s=await J();if(!await this.tableExists(s,t))throw new d(404,{message:`Table "${t}" does not exist`});if(await this.tableExists(s,n))throw new d(409,{message:`Table "${n}" already exists`});try{await s.execute(`ALTER TABLE ${this.quoteIdentifier(t)} RENAME TO ${this.quoteIdentifier(n)}`)}catch(o){throw this.wrapError(o)}}async getTableSchema({tableName:e,db:t}){try{let[n]=await ee(await J(),"SELECT sql FROM sqlite_master WHERE type='table' AND name=?",[e]);if(!n)throw new d(404,{message:`Table "${e}" does not exist`});return n.sql}catch(n){throw n instanceof d?n:this.wrapError(n)}}async getTableColumns({tableName:e,db:t}){try{let n=await J();if(!await this.tableExists(n,e))throw new d(404,{message:`Table "${e}" does not exist`});let a=await ee(n,`PRAGMA table_info(${this.quoteIdentifier(e)})`),s=await ee(n,`PRAGMA foreign_key_list("${e}")`),o=new Map;for(let i of s)o.set(i.from,i);return a.map(i=>{let c=o.get(i.name),l=i.type.toLowerCase();return{columnName:i.name,dataType:Dn(l),dataTypeLabel:Pr(l),isNullable:i.notnull===0&&i.pk===0,columnDefault:i.dflt_value,isPrimaryKey:i.pk>0,isForeignKey:o.has(i.name),referencedTable:c?.table??null,referencedColumn:c?.to??null,enumValues:null}})}catch(n){throw n instanceof d?n:this.wrapError(n)}}async addColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,columnType:a,defaultValue:s,isNullable:o,isUnique:i,db:c}=e,l=await J();if(!await this.tableExists(l,t))throw new d(404,{message:`Table "${t}" does not exist`});if((await ee(l,`PRAGMA table_info(${this.quoteIdentifier(t)})`)).some(p=>p.name===n))throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let m=`"${n}" ${a}`;i&&(m+=" UNIQUE"),o||(m+=" NOT NULL"),s?.trim()&&(m+=` DEFAULT ${s.trim()}`);try{await l.execute(`ALTER TABLE "${t}" ADD COLUMN ${m}`)}catch(p){throw this.wrapError(p)}})}async deleteColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,db:a}=e,s=await J();if(!await this.tableExists(s,t))throw new d(404,{message:`Table "${t}" does not exist`});if(!(await ee(s,`PRAGMA table_info(${this.quoteIdentifier(t)})`)).some(i=>i.name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});try{await s.execute(`ALTER TABLE "${t}" DROP COLUMN "${n}"`)}catch(i){throw this.wrapError(i)}return{deletedCount:1}})}async alterColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o,db:i}=e,c=await J(),l=C=>this.quoteIdentifier(C);if(!await this.tableExists(c,t))throw new d(404,{message:`Table "${t}" does not exist`});let u=await ee(c,`PRAGMA table_info(${l(t)})`);if(!u.some(C=>C.name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});let m=u.filter(C=>C.pk>0).sort((C,_)=>C.pk-_.pk),p=m.length>1,f=u.map(C=>{let _=C.name===n,O=_?a:C.type,$=_?s:C.notnull===0,P=_?o?.trim()||null:C.dflt_value,v=C.pk>0,M=`${l(C.name)} ${O}`;return!p&&v&&(M+=" PRIMARY KEY"),!v&&!$&&(M+=" NOT NULL"),P&&(M+=` DEFAULT ${P}`),M});p&&f.push(`PRIMARY KEY (${m.map(C=>l(C.name)).join(", ")})`);let b=await ee(c,`PRAGMA foreign_key_list(${l(t)})`),h=new Map;for(let C of b){let _=h.get(C.id)??[];_.push(C),h.set(C.id,_)}let g=Array.from(h.values()).map(C=>{let _=C.map(X=>l(X.from)).join(", "),O=C.map(X=>X.to),$=_c(O)?` (${O.map(l).join(", ")})`:"",{table:P,on_update:v,on_delete:M}=C[0];return`FOREIGN KEY (${_}) REFERENCES ${l(P)}${$} ON UPDATE ${v} ON DELETE ${M}`}),S=u.map(C=>l(C.name)).join(", "),w=`${t}_alter_${Date.now()}`,D=await ee(c,"SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL",[t]),A=await ee(c,"SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?",[t]),R=new Set((await this.getFkReferencesForTable(c,t,{includeSelf:!0})).map(C=>C.referencingTable));try{await c.rebuildTable([`CREATE TABLE ${l(w)} (${[...f,...g].join(", ")})`,`INSERT INTO ${l(w)} (${S}) SELECT ${S} FROM ${l(t)}`,`DROP TABLE ${l(t)}`,`ALTER TABLE ${l(w)} RENAME TO ${l(t)}`,...D.map(({sql:C})=>C),...A.map(({sql:C})=>C)],[...R])}catch(C){throw this.wrapError(C)}})}async renameColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await J();if(!await this.tableExists(o,t))throw new d(404,{message:`Table "${t}" does not exist`});let i=await ee(o,`PRAGMA table_info(${this.quoteIdentifier(t)})`);if(!i.some(c=>c.name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});if(i.some(c=>c.name===a))throw new d(409,{message:`Column "${a}" already exists in table "${t}"`});try{await o.execute(`ALTER TABLE "${t}" RENAME COLUMN "${n}" TO "${a}"`)}catch(c){throw this.wrapError(c)}})}async getTableIndexes({tableName:e}){try{return await this.listIndexes(await J(),e)}catch(t){throw this.wrapError(t)}}async createIndex(e){return this.serializeSchemaChange(async()=>{let{tableName:t,indexName:n,columns:a,isUnique:s,method:o}=e;try{let i=await J();if(!await this.tableExists(i,t))throw new d(404,{message:`Table "${t}" does not exist`});let c=await ee(i,`PRAGMA table_info(${this.quoteIdentifier(t)})`),l=a.find(u=>!c.some(m=>m.name===u));if(l!==void 0)throw new d(400,{message:`Column "${l}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});await i.execute(`CREATE ${s?"UNIQUE ":""}INDEX ${this.quoteIdentifier(n)} ON ${this.quoteIdentifier(t)} (${a.map(u=>this.quoteIdentifier(u)).join(", ")})`)}catch(i){throw i instanceof Error&&/already exists|there is already|UNIQUE constraint failed/.test(i.message)?new d(409,{message:i.message,cause:i}):i instanceof Error&&i.message.includes("reserved for internal use")?new d(400,{message:i.message,cause:i}):this.wrapError(i)}})}async dropIndex({tableName:e,indexName:t}){return this.serializeSchemaChange(async()=>{try{let n=await J(),a=(await this.listIndexes(n,e)).find(s=>s.indexName===t);if(!a)throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});if(a.kind!=="index")throw new d(400,{message:`Index "${t}" backs a constraint; drop the constraint to remove it`});await n.execute(`DROP INDEX ${this.quoteIdentifier(t)}`)}catch(n){throw this.wrapError(n)}})}async addRecord({params:e}){let{tableName:t,data:n}=e,a=Object.keys(n);if(!a.length)throw new d(400,{message:"No data provided for insert"});let s=a.map(i=>`"${i}"`).join(", "),o=a.map(()=>"?").join(", ");try{let c=await(await J()).execute(At(`INSERT INTO "${t}" (${s}) VALUES (${o})`,Object.values(n)));if(c.rowsAffected===0)throw new d(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:c.rowsAffected}}catch(i){throw this.wrapError(i)}}async updateRecords({db:e,params:t}){let{tableName:n}=t,a=this.resolveKeyColumns(t),s=this.groupUpdatesByKey(t,a),o=a.map(i=>`"${i}" = ?`).join(" AND ");try{let i=await J();this.assertWholeKey(await this.getPrimaryKeyColumns(i,n),a);let c=s.flatMap(({keyValues:l,rowUpdates:u})=>[At(`UPDATE "${n}" SET ${u.map(m=>`"${m.columnName}" = ?`).join(", ")} WHERE ${o}`,[...u.map(m=>m.value),...l]),"SELECT CASE WHEN changes() = 0 THEN abs(-9223372036854775808) END"]);try{return{updatedCount:(await i.batch(c,"write")).reduce((u,m,p)=>p%2===0?u+m.rowsAffected:u,0)}}catch(l){if(!(l instanceof Error&&l.message.includes("integer overflow")))throw l;let u=await i.batch(s.map(({keyValues:p})=>At(`SELECT 1 FROM "${n}" WHERE ${o} LIMIT 1`,p)),"read"),m=s.find((p,f)=>u[f].rows.length===0);throw m?new d(404,{message:`Record with ${this.describeKey(a,m.keyValues)} not found in table "${n}"`}):l}}catch(i){throw this.wrapError(i)}}async deleteRecords({tableName:e,primaryKeys:t,db:n}){let a=t[0]?.columnName;if(!a)throw new d(400,{message:"Primary key column name is required"});let s=t.map(c=>c.value),o=s.map(()=>"?").join(", "),i=await J();try{return this.assertDeletableKey(await this.getPrimaryKeyColumns(i,e)),{deletedCount:(await i.execute(At(`DELETE FROM "${e}" WHERE "${a}" IN (${o})`,s))).rowsAffected,fkViolation:!1,relatedRecords:[]}}catch(c){if(Oc(c))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(i,e,t)};throw this.wrapError(c)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:n}){let a=t[0]?.columnName;if(!a)throw new d(400,{message:"Primary key column name is required"});let s=c=>this.quoteIdentifier(c),o=t.map(c=>c.value),i=`${s(a)} IN (${o.map(()=>"?").join(", ")})`;try{let c=await J();this.assertDeletableKey(await this.getPrimaryKeyColumns(c,e));let l=await this.getForeignKeysByParent(c),u=[],m=async(f,b,h)=>{for(let g of l.get(f)??[]){if(h.includes(g.childTable))continue;let S=_c(g.parentColumns)?g.parentColumns:await this.getPrimaryKeyColumns(c,f),w=`(${g.childColumns.map(s).join(", ")}) IN (SELECT ${S.map(s).join(", ")} FROM ${s(f)} WHERE ${b})`;await m(g.childTable,w,[...h,g.childTable])}u.push(At(`DELETE FROM ${s(f)} WHERE ${b}`,o))};return await m(e,i,[e]),{deletedCount:(await c.batch(u,"write")).reduce((f,b)=>f+b.rowsAffected,0)}}catch(c){throw Oc(c)?new d(409,{message:`Cannot force delete from "${e}": rows are still referenced through a foreign key cycle`}):this.wrapError(c)}}async bulkInsertRecords({tableName:e,records:t,db:n}){if(!t?.length)throw new d(400,{message:"At least one record is required"});let a=Object.keys(t[0]),s=a.map(c=>`"${c}"`).join(", "),o=a.map(()=>"?").join(", "),i=`INSERT INTO "${e}" (${s}) VALUES (${o})`;try{return await(await J()).batch(t.map(l=>At(i,a.map(u=>l[u]))),"write"),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}catch(c){throw this.wrapError(c)}}async executeQuery({query:e,db:t}){if(!e?.trim())throw new d(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,"");if(Ac(n))throw new d(400,{message:"Transaction statements (BEGIN, COMMIT, ROLLBACK, SAVEPOINT, RELEASE) are not supported in the query runner: each query runs on its own connection, so a transaction cannot span queries."});if(Nc(n))throw new d(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let a=performance.now();try{let s=await(await J()).execute(n),o=performance.now()-a;if(s.columns.length>0){let i=Rs(s);return{columns:s.columns,rows:i,rowCount:i.length,duration:o,message:i.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:s.rowsAffected,duration:o,message:`OK (${s.rowsAffected} rows affected)`}}catch(s){throw this.wrapError(s)}}async tableExists(e,t){return(await ee(e,"SELECT name FROM sqlite_master WHERE type='table' AND name=?",[t])).length>0}async listIndexes(e,t){if(!await this.tableExists(e,t))throw new d(404,{message:`Table "${t}" does not exist`});let n=await ee(e,`SELECT il.name AS indexName, il."unique" AS isUnique, il.origin, il.partial, m.sql,
|
|
462
|
+
ORDER BY name`);if(!n.length)return[];let a=await t.batch(n.map(s=>`SELECT COUNT(*) as count FROM ${this.quoteIdentifier(s.name)}`),"read");return n.map((s,o)=>({tableName:s.name,rowCount:xs(a[o])[0]?.count??0}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e,o=a.filter(u=>u.isPrimaryKey).map(u=>u.columnName),i=a.map(u=>{if(o.length===1&&u.isPrimaryKey&&u.isIdentity)return`"${u.columnName}" INTEGER PRIMARY KEY AUTOINCREMENT`;let m=`"${u.columnName}" ${u.columnType}`;return o.length===1&&u.isPrimaryKey&&(m+=" PRIMARY KEY"),u.isUnique&&!u.isPrimaryKey&&(m+=" UNIQUE"),!u.isNullable&&!u.isPrimaryKey&&(m+=" NOT NULL"),u.defaultValue?.trim()&&!u.isIdentity&&(m+=` DEFAULT ${u.defaultValue.trim()}`),m});o.length>1&&i.push(`PRIMARY KEY (${o.map(u=>`"${u}"`).join(", ")})`);let c=s?.map(u=>`FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await(await J()).execute(`CREATE TABLE "${n}" (${[...i,...c].join(", ")})`)}async deleteTable(e){let{tableName:t,cascade:n}=e,a=await J();if(!await this.tableExists(a,t))throw new d(404,{message:`Table "${t}" does not exist`});let[s]=await ee(a,`SELECT COUNT(*) as count FROM "${t}"`),o=s?.count??0;if(!n&&(await this.getFkReferencesForTable(a,t)).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(a,t)};try{return await a.execute(`DROP TABLE "${t}"`),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(i){if((i instanceof Error?i.message:String(i)).includes("FOREIGN KEY constraint"))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(a,t)};throw i instanceof d?i:new d(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){let{tableName:t,newTableName:n,db:a}=e;this.assertDifferentTableName(t,n);let s=await J();if(!await this.tableExists(s,t))throw new d(404,{message:`Table "${t}" does not exist`});if(await this.tableExists(s,n))throw new d(409,{message:`Table "${n}" already exists`});try{await s.execute(`ALTER TABLE ${this.quoteIdentifier(t)} RENAME TO ${this.quoteIdentifier(n)}`)}catch(o){throw this.wrapError(o)}}async getTableSchema({tableName:e,db:t}){try{let[n]=await ee(await J(),"SELECT sql FROM sqlite_master WHERE type='table' AND name=?",[e]);if(!n)throw new d(404,{message:`Table "${e}" does not exist`});return n.sql}catch(n){throw n instanceof d?n:this.wrapError(n)}}async getTableColumns({tableName:e,db:t}){try{let n=await J();if(!await this.tableExists(n,e))throw new d(404,{message:`Table "${e}" does not exist`});let a=await ee(n,`PRAGMA table_info(${this.quoteIdentifier(e)})`),s=await ee(n,`PRAGMA foreign_key_list("${e}")`),o=new Map;for(let i of s)o.set(i.from,i);return a.map(i=>{let c=o.get(i.name),l=i.type.toLowerCase();return{columnName:i.name,dataType:xn(l),dataTypeLabel:qr(l),isNullable:i.notnull===0&&i.pk===0,columnDefault:i.dflt_value,isPrimaryKey:i.pk>0,isForeignKey:o.has(i.name),referencedTable:c?.table??null,referencedColumn:c?.to??null,enumValues:null}})}catch(n){throw n instanceof d?n:this.wrapError(n)}}async addColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,columnType:a,defaultValue:s,isNullable:o,isUnique:i,db:c}=e,l=await J();if(!await this.tableExists(l,t))throw new d(404,{message:`Table "${t}" does not exist`});if((await ee(l,`PRAGMA table_info(${this.quoteIdentifier(t)})`)).some(p=>p.name===n))throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let m=`"${n}" ${a}`;i&&(m+=" UNIQUE"),o||(m+=" NOT NULL"),s?.trim()&&(m+=` DEFAULT ${s.trim()}`);try{await l.execute(`ALTER TABLE "${t}" ADD COLUMN ${m}`)}catch(p){throw this.wrapError(p)}})}async deleteColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,db:a}=e,s=await J();if(!await this.tableExists(s,t))throw new d(404,{message:`Table "${t}" does not exist`});if(!(await ee(s,`PRAGMA table_info(${this.quoteIdentifier(t)})`)).some(i=>i.name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});try{await s.execute(`ALTER TABLE "${t}" DROP COLUMN "${n}"`)}catch(i){throw this.wrapError(i)}return{deletedCount:1}})}async alterColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o,db:i}=e,c=await J(),l=C=>this.quoteIdentifier(C);if(!await this.tableExists(c,t))throw new d(404,{message:`Table "${t}" does not exist`});let u=await ee(c,`PRAGMA table_info(${l(t)})`);if(!u.some(C=>C.name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});let m=u.filter(C=>C.pk>0).sort((C,_)=>C.pk-_.pk),p=m.length>1,f=u.map(C=>{let _=C.name===n,O=_?a:C.type,$=_?s:C.notnull===0,P=_?o?.trim()||null:C.dflt_value,v=C.pk>0,M=`${l(C.name)} ${O}`;return!p&&v&&(M+=" PRIMARY KEY"),!v&&!$&&(M+=" NOT NULL"),P&&(M+=` DEFAULT ${P}`),M});p&&f.push(`PRIMARY KEY (${m.map(C=>l(C.name)).join(", ")})`);let b=await ee(c,`PRAGMA foreign_key_list(${l(t)})`),y=new Map;for(let C of b){let _=y.get(C.id)??[];_.push(C),y.set(C.id,_)}let g=Array.from(y.values()).map(C=>{let _=C.map(X=>l(X.from)).join(", "),O=C.map(X=>X.to),$=Uc(O)?` (${O.map(l).join(", ")})`:"",{table:P,on_update:v,on_delete:M}=C[0];return`FOREIGN KEY (${_}) REFERENCES ${l(P)}${$} ON UPDATE ${v} ON DELETE ${M}`}),S=u.map(C=>l(C.name)).join(", "),w=`${t}_alter_${Date.now()}`,D=await ee(c,"SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL",[t]),A=await ee(c,"SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?",[t]),R=new Set((await this.getFkReferencesForTable(c,t,{includeSelf:!0})).map(C=>C.referencingTable));try{await c.rebuildTable([`CREATE TABLE ${l(w)} (${[...f,...g].join(", ")})`,`INSERT INTO ${l(w)} (${S}) SELECT ${S} FROM ${l(t)}`,`DROP TABLE ${l(t)}`,`ALTER TABLE ${l(w)} RENAME TO ${l(t)}`,...D.map(({sql:C})=>C),...A.map(({sql:C})=>C)],[...R])}catch(C){throw this.wrapError(C)}})}async renameColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await J();if(!await this.tableExists(o,t))throw new d(404,{message:`Table "${t}" does not exist`});let i=await ee(o,`PRAGMA table_info(${this.quoteIdentifier(t)})`);if(!i.some(c=>c.name===n))throw new d(404,{message:`Column "${n}" does not exist in table "${t}"`});if(i.some(c=>c.name===a))throw new d(409,{message:`Column "${a}" already exists in table "${t}"`});try{await o.execute(`ALTER TABLE "${t}" RENAME COLUMN "${n}" TO "${a}"`)}catch(c){throw this.wrapError(c)}})}async getTableIndexes({tableName:e}){try{return await this.listIndexes(await J(),e)}catch(t){throw this.wrapError(t)}}async createIndex(e){return this.serializeSchemaChange(async()=>{let{tableName:t,indexName:n,columns:a,isUnique:s,method:o}=e;try{let i=await J();if(!await this.tableExists(i,t))throw new d(404,{message:`Table "${t}" does not exist`});let c=await ee(i,`PRAGMA table_info(${this.quoteIdentifier(t)})`),l=a.find(u=>!c.some(m=>m.name===u));if(l!==void 0)throw new d(400,{message:`Column "${l}" does not exist in table "${t}"`});if(o!==void 0)throw new d(400,{message:`Unsupported index method "${o}"`});await i.execute(`CREATE ${s?"UNIQUE ":""}INDEX ${this.quoteIdentifier(n)} ON ${this.quoteIdentifier(t)} (${a.map(u=>this.quoteIdentifier(u)).join(", ")})`)}catch(i){throw i instanceof Error&&/already exists|there is already|UNIQUE constraint failed/.test(i.message)?new d(409,{message:i.message,cause:i}):i instanceof Error&&i.message.includes("reserved for internal use")?new d(400,{message:i.message,cause:i}):this.wrapError(i)}})}async dropIndex({tableName:e,indexName:t}){return this.serializeSchemaChange(async()=>{try{let n=await J(),a=(await this.listIndexes(n,e)).find(s=>s.indexName===t);if(!a)throw new d(404,{message:`Index "${t}" does not exist on table "${e}"`});if(a.kind!=="index")throw new d(400,{message:`Index "${t}" backs a constraint; drop the constraint to remove it`});await n.execute(`DROP INDEX ${this.quoteIdentifier(t)}`)}catch(n){throw this.wrapError(n)}})}async addRecord({params:e}){let{tableName:t,data:n}=e,a=Object.keys(n);if(!a.length)throw new d(400,{message:"No data provided for insert"});let s=a.map(i=>`"${i}"`).join(", "),o=a.map(()=>"?").join(", ");try{let c=await(await J()).execute(_t(`INSERT INTO "${t}" (${s}) VALUES (${o})`,Object.values(n)));if(c.rowsAffected===0)throw new d(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:c.rowsAffected}}catch(i){throw this.wrapError(i)}}async updateRecords({db:e,params:t}){let{tableName:n}=t,a=this.resolveKeyColumns(t),s=this.groupUpdatesByKey(t,a),o=a.map(i=>`"${i}" = ?`).join(" AND ");try{let i=await J();this.assertWholeKey(await this.getPrimaryKeyColumns(i,n),a);let c=s.flatMap(({keyValues:l,rowUpdates:u})=>[_t(`UPDATE "${n}" SET ${u.map(m=>`"${m.columnName}" = ?`).join(", ")} WHERE ${o}`,[...u.map(m=>m.value),...l]),"SELECT CASE WHEN changes() = 0 THEN abs(-9223372036854775808) END"]);try{return{updatedCount:(await i.batch(c,"write")).reduce((u,m,p)=>p%2===0?u+m.rowsAffected:u,0)}}catch(l){if(!(l instanceof Error&&l.message.includes("integer overflow")))throw l;let u=await i.batch(s.map(({keyValues:p})=>_t(`SELECT 1 FROM "${n}" WHERE ${o} LIMIT 1`,p)),"read"),m=s.find((p,f)=>u[f].rows.length===0);throw m?new d(404,{message:`Record with ${this.describeKey(a,m.keyValues)} not found in table "${n}"`}):l}}catch(i){throw this.wrapError(i)}}async deleteRecords({tableName:e,primaryKeys:t,db:n}){let a=t[0]?.columnName;if(!a)throw new d(400,{message:"Primary key column name is required"});let s=t.map(c=>c.value),o=s.map(()=>"?").join(", "),i=await J();try{return this.assertDeletableKey(await this.getPrimaryKeyColumns(i,e)),{deletedCount:(await i.execute(_t(`DELETE FROM "${e}" WHERE "${a}" IN (${o})`,s))).rowsAffected,fkViolation:!1,relatedRecords:[]}}catch(c){if(qc(c))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(i,e,t)};throw this.wrapError(c)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:n}){let a=t[0]?.columnName;if(!a)throw new d(400,{message:"Primary key column name is required"});let s=c=>this.quoteIdentifier(c),o=t.map(c=>c.value),i=`${s(a)} IN (${o.map(()=>"?").join(", ")})`;try{let c=await J();this.assertDeletableKey(await this.getPrimaryKeyColumns(c,e));let l=await this.getForeignKeysByParent(c),u=[],m=async(f,b,y)=>{for(let g of l.get(f)??[]){if(y.includes(g.childTable))continue;let S=Uc(g.parentColumns)?g.parentColumns:await this.getPrimaryKeyColumns(c,f),w=`(${g.childColumns.map(s).join(", ")}) IN (SELECT ${S.map(s).join(", ")} FROM ${s(f)} WHERE ${b})`;await m(g.childTable,w,[...y,g.childTable])}u.push(_t(`DELETE FROM ${s(f)} WHERE ${b}`,o))};return await m(e,i,[e]),{deletedCount:(await c.batch(u,"write")).reduce((f,b)=>f+b.rowsAffected,0)}}catch(c){throw qc(c)?new d(409,{message:`Cannot force delete from "${e}": rows are still referenced through a foreign key cycle`}):this.wrapError(c)}}async bulkInsertRecords({tableName:e,records:t,db:n}){if(!t?.length)throw new d(400,{message:"At least one record is required"});let a=Object.keys(t[0]),s=a.map(c=>`"${c}"`).join(", "),o=a.map(()=>"?").join(", "),i=`INSERT INTO "${e}" (${s}) VALUES (${o})`;try{return await(await J()).batch(t.map(l=>_t(i,a.map(u=>l[u]))),"write"),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}catch(c){throw this.wrapError(c)}}async executeQuery({query:e,db:t}){if(!e?.trim())throw new d(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,"");if(kc(n))throw new d(400,{message:"Transaction statements (BEGIN, COMMIT, ROLLBACK, SAVEPOINT, RELEASE) are not supported in the query runner: each query runs on its own connection, so a transaction cannot span queries."});if(Mc(n))throw new d(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let a=performance.now();try{let s=await(await J()).execute(n),o=performance.now()-a;if(s.columns.length>0){let i=xs(s);return{columns:s.columns,rows:i,rowCount:i.length,duration:o,message:i.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:s.rowsAffected,duration:o,message:`OK (${s.rowsAffected} rows affected)`}}catch(s){throw this.wrapError(s)}}async tableExists(e,t){return(await ee(e,"SELECT name FROM sqlite_master WHERE type='table' AND name=?",[t])).length>0}async listIndexes(e,t){if(!await this.tableExists(e,t))throw new d(404,{message:`Table "${t}" does not exist`});let n=await ee(e,`SELECT il.name AS indexName, il."unique" AS isUnique, il.origin, il.partial, m.sql,
|
|
463
463
|
xi.seqno, xi.cid, xi.name AS columnName
|
|
464
464
|
FROM pragma_index_list(?) il
|
|
465
465
|
JOIN pragma_index_xinfo(il.name) xi ON xi.key = 1
|
|
466
466
|
LEFT JOIN sqlite_master m ON m.type = 'index' AND m.name = il.name
|
|
467
|
-
ORDER BY il.origin = 'pk' DESC, il.name, xi.seqno`,[t]),a=new Map;for(let s of n){let o=a.get(s.indexName)??{indexName:s.indexName,columns:[],isUnique:s.isUnique===1,method:null,kind:s.origin==="pk"?"primary":s.origin==="u"?"unique-constraint":"index",definition:s.partial===1?s.sql:null};a.set(s.indexName,o),s.columnName!==null?o.columns.push(s.columnName):(o.columns.push(
|
|
467
|
+
ORDER BY il.origin = 'pk' DESC, il.name, xi.seqno`,[t]),a=new Map;for(let s of n){let o=a.get(s.indexName)??{indexName:s.indexName,columns:[],isUnique:s.isUnique===1,method:null,kind:s.origin==="pk"?"primary":s.origin==="u"?"unique-constraint":"index",definition:s.partial===1?s.sql:null};a.set(s.indexName,o),s.columnName!==null?o.columns.push(s.columnName):(o.columns.push(Hp(s.sql??"")[s.seqno]??""),o.definition=s.sql)}return[...a.values()]}async getPrimaryKeyColumns(e,t){return(await ee(e,`PRAGMA table_info(${this.quoteIdentifier(t)})`)).filter(a=>a.pk>0).sort((a,s)=>a.pk-s.pk).map(a=>a.name)}async getForeignKeysByParent(e){let t=await ee(e,`SELECT m.name AS child, f.id, f."table" AS parent, f."from", f."to"
|
|
468
468
|
FROM sqlite_master m JOIN pragma_foreign_key_list(m.name) f
|
|
469
469
|
WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%' AND m.name NOT GLOB '_cf_*'
|
|
470
470
|
ORDER BY m.name, f.id, f.seq`),n=new Map,a=new Map;for(let s of t){let o=`${s.child}\0${s.id}`,i=n.get(o);i||(i={childTable:s.child,childColumns:[],parentColumns:[]},n.set(o,i),a.set(s.parent,[...a.get(s.parent)??[],i])),i.childColumns.push(s.from),i.parentColumns.push(s.to)}return a}async getFkReferencesForTable(e,t,{includeSelf:n=!1}={}){return(await ee(e,`SELECT m.name AS child, f."from", f."to"
|
|
471
471
|
FROM sqlite_master m JOIN pragma_foreign_key_list(m.name) f
|
|
472
472
|
WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%' AND m.name NOT GLOB '_cf_*'
|
|
473
|
-
AND (m.name != ? COLLATE NOCASE OR ?) AND f."table" = ? COLLATE NOCASE`,[t,n?1:0,t])).map(s=>({constraintName:`fk_${s.child}_${s.from}_${t}_${s.to}`,referencingTable:s.child,referencingColumn:s.from,referencedTable:t,referencedColumn:s.to??""}))}async getRelatedRecordsForTable(e,t){let n=await this.getFkReferencesForTable(e,t),a=[];for(let s of n){let o=await ee(e,`SELECT * FROM "${s.referencingTable}" LIMIT 100`);o.length>0&&a.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:o})}return a}async getRelatedRecords(e,t,n){let a=await this.getFkReferencesForTable(e,t),s=[];for(let o of a){if(!n.find(m=>m.columnName===o.referencedColumn))continue;let c=n.map(m=>m.value),l=c.map(()=>"?").join(", "),u=await ee(e,`SELECT * FROM "${o.referencingTable}" WHERE "${o.referencingColumn}" IN (${l}) LIMIT 100`,c);u.length>0&&s.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:u})}return s}}});function
|
|
473
|
+
AND (m.name != ? COLLATE NOCASE OR ?) AND f."table" = ? COLLATE NOCASE`,[t,n?1:0,t])).map(s=>({constraintName:`fk_${s.child}_${s.from}_${t}_${s.to}`,referencingTable:s.child,referencingColumn:s.from,referencedTable:t,referencedColumn:s.to??""}))}async getRelatedRecordsForTable(e,t){let n=await this.getFkReferencesForTable(e,t),a=[];for(let s of n){let o=await ee(e,`SELECT * FROM "${s.referencingTable}" LIMIT 100`);o.length>0&&a.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:o})}return a}async getRelatedRecords(e,t,n){let a=await this.getFkReferencesForTable(e,t),s=[];for(let o of a){if(!n.find(m=>m.columnName===o.referencedColumn))continue;let c=n.map(m=>m.value),l=c.map(()=>"?").join(", "),u=await ee(e,`SELECT * FROM "${o.referencingTable}" WHERE "${o.referencingColumn}" IN (${l}) LIMIT 100`,c);u.length>0&&s.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:u})}return s}}});function Fc(){ye.register("pg",new yr),ye.register("mysql",new pr),ye.register("mssql",new ur),ye.register("mongodb",new cr),ye.register("sqlite",new Cr),ye.register("redis",new Er),ye.register("duckdb",new sr),ye.register("oracle",new hr),ye.register("clickhouse",new nr)}var Kc=N(()=>{"use strict";h();Ct();Oi();ki();Wi();Qi();Zi();yc();Ec();$c();Bc()});import{NotFoundError as zp,ParseError as Gp,ValidationError as Qp}from"elysia";import{ZodError as Jp}from"zod";function Hc(r,e){let{pathname:t}=new URL(e.url),n=ln(e.method,t),a=un(t),{status:s,body:o}=Zp(r);return Q(s>=500?"error":"warn","request_failed",{operation:n,db_type:a,method:e.method,status:s,...fe(r)}),ha(r,{operation:n,status:s,dbType:a}),Response.json({...o,requestId:ot()},{status:s})}var Xp,Zp,jc=N(()=>{"use strict";h();wt();te();mn();Ve();Xp=r=>{let e=r;return e.code==="ECONNREFUSED"||e.code==="ENOTFOUND"||e.code==="ETIMEDOUT"||e.code==="ER_ACCESS_DENIED_ERROR"||e.code==="ER_BAD_HOST_ERROR"||e.code==="ECONNRESET"||e.errno===1045||e.errno===2003||e.errno===2002||r.message.includes("ECONNREFUSED")||r.message.includes("connection refused")||r.message.includes("timeout expired")||r.message.includes("Connection terminated")||r.message.includes("MongoNetworkError")||r.message.includes("MongoServerSelectionError")||Qe(r)&&r.code?.startsWith("08")===!0},Zp=r=>r instanceof d?{status:r.status,body:{error:r.message}}:r instanceof Qp?{status:400,body:{error:"Validation error",details:r.all[0]?.message??"Invalid request"}}:r instanceof Jp?{status:400,body:{error:"Validation error",details:r.issues[0].message}}:r instanceof Gp?{status:400,body:{error:"Malformed JSON in request body"}}:r instanceof zp?{status:404,body:{error:"Not found"}}:qt(r)?{status:409,body:{error:r.message}}:Qe(r)&&r.code==="42501"?{status:403,body:{error:r.message}}:r instanceof Error&&Xp(r)?{status:503,body:{error:"Database connection failed",details:r.message}}:{status:500,body:{error:r instanceof Error?r.message:"Internal server error"}}});function Yc(r){if(!r)return`You are a database assistant for db-studio. Keep answers concise and focused.
|
|
474
474
|
|
|
475
|
-
The user chose not to share their database schema. Do not claim to know their table or column names. Ask for the minimum missing details needed to answer accurately, generate queries in fenced code blocks, and warn before potentially destructive or expensive operations.`;let e=r.dbType.toLowerCase(),t=
|
|
475
|
+
The user chose not to share their database schema. Do not claim to know their table or column names. Ask for the minimum missing details needed to answer accurately, generate queries in fenced code blocks, and warn before potentially destructive or expensive operations.`;let e=r.dbType.toLowerCase(),t=W[r.dbType].label;return e.includes("mongo")?`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
|
|
476
476
|
|
|
477
477
|
**Your Role:**
|
|
478
478
|
1. Keep responses SHORT - 2-3 sentences maximum unless generating a query
|
|
@@ -486,7 +486,7 @@ The user chose not to share their database schema. Do not claim to know their ta
|
|
|
486
486
|
6. IMPORTANT: When the user asks about collections, fields, or any schema information, answer DIRECTLY from the "Database Context" above \u2014 do NOT generate a query to retrieve schema info you already have
|
|
487
487
|
|
|
488
488
|
**Database Context:**
|
|
489
|
-
${
|
|
489
|
+
${Wc(r)}
|
|
490
490
|
|
|
491
491
|
**Guidelines:**
|
|
492
492
|
1. Always generate syntactically correct MongoDB queries
|
|
@@ -548,7 +548,7 @@ This will return the top 5 customers by revenue."`:`You are a database assistant
|
|
|
548
548
|
7. IMPORTANT: When the user asks about tables, columns, relationships, or any schema information, answer DIRECTLY from the "Database Context" above \u2014 do NOT generate a SQL query to retrieve schema info you already have
|
|
549
549
|
|
|
550
550
|
**Database Context:**
|
|
551
|
-
${
|
|
551
|
+
${Wc(r)}
|
|
552
552
|
|
|
553
553
|
**Guidelines:**
|
|
554
554
|
1. Always generate syntactically correct SQL for the database type (${t})
|
|
@@ -586,7 +586,7 @@ LIMIT 5;
|
|
|
586
586
|
|
|
587
587
|
This will return the 5 customers with the highest total order value. You might also want to see:
|
|
588
588
|
- Revenue trends over time for these customers
|
|
589
|
-
- Their most frequently ordered products"`}function
|
|
589
|
+
- Their most frequently ordered products"`}function Wc(r){let t=`Database Type: ${W[r.dbType].label}
|
|
590
590
|
|
|
591
591
|
`;t+=`**Tables and Columns:**
|
|
592
592
|
`;for(let n of r.tables){t+=`
|
|
@@ -600,13 +600,13 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
600
600
|
`)}if(r.relationships&&r.relationships.length>0){t+=`
|
|
601
601
|
**Relationships:**
|
|
602
602
|
`;for(let n of r.relationships)t+=` - ${n.fromTable}.${n.fromColumn} -> ${n.toTable}.${n.toColumn}
|
|
603
|
-
`}return t}var vc=N(()=>{"use strict";y();G()});function Kp(r){let e={name:r.columnName,type:r.dataTypeLabel,nullable:r.isNullable};return r.isPrimaryKey&&(e.isPrimaryKey=!0),r.isForeignKey&&r.referencedTable&&r.referencedColumn&&(e.foreignKey=`${r.referencedTable}.${r.referencedColumn}`),r.enumValues&&r.enumValues.length>0&&(e.enumValues=r.enumValues,e.description=`Enum values: ${r.enumValues.join(", ")}`),e}function Hp(r){let e=[];for(let t of r)for(let n of t.columns)if(n.foreignKey){let[a,s]=n.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:n.name,toTable:a,toColumn:s})}return e}function jp(r){if(r==null)return"";if(r instanceof Date)return r.toISOString();if(typeof r=="bigint")return r.toString();if(typeof r=="object")try{return JSON.stringify(r)}catch{return String(r)}return String(r)}async function Wp(r,e,t){try{return(await r.getTableData({tableName:e,db:t,limit:3})).data.map(a=>Object.fromEntries(Object.entries(a).map(([s,o])=>[s,jp(o)])))}catch(n){return W("warn","schema_sample_rows_failed",ne(n)),[]}}async function Yp(r,e,t){try{return await r.getTableColumns({tableName:e,db:t})}catch(n){return W("warn","schema_columns_failed",ne(n)),[]}}async function Vp(r,e={}){let t=ot(),{includeSampleData:n=!1,maxTables:a}=e,s=Bt(t);try{let o=await s.getTablesList(r),c=o.slice(0,a??o.length).map(async({schemaName:m,tableName:p})=>{let[f,b]=await Promise.all([Yp(s,p,r),n?Wp(s,p,r):Promise.resolve([])]),h={name:m?`${m}.${p}`:p,columns:f.map(Kp)};return b.length>0&&(h.sampleData=b),h}),l=await Promise.all(c),u=Hp(l);return{dbType:t,tables:l,relationships:u}}catch(o){throw W("error","schema_fetch_failed",ne(o)),new Error(`Failed to fetch database schema: ${o instanceof Error?o.message:"Unknown error"}`)}}async function Uc(r){return Vp(r,{includeSampleData:!0,includeDescriptions:!0})}var qc=N(()=>{"use strict";y();Ct();it();Ye()});import{Elysia as zp}from"elysia";var Gp,Qp,Bc,Fc,Kc=N(()=>{"use strict";y();Jt();G();te();Ye();vc();qc();Gp=new Set(["connection","keep-alive","transfer-encoding","content-length","content-encoding"]),Qp=new Set(["localhost","127.0.0.1","::1","[::1]"]),Bc=()=>{let r;try{r=new URL(at.PROXY_URL)}catch{throw new d(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=Qp.has(r.hostname)||r.hostname.endsWith(".localhost");if(r.protocol!=="https:"&&!(r.protocol==="http:"&&e))throw new d(500,{message:"DB_STUDIO_PROXY_URL must use HTTPS unless it points at loopback"});return r.origin},Fc=new zp({prefix:"/chat"}).get("/limit",async({headers:r})=>{let e=Bc();try{let t=await fetch(`${e}/chat/limit`,{headers:{"cf-connecting-ip":r["cf-connecting-ip"]??"","x-real-ip":r["x-real-ip"]??"","x-forwarded-for":r["x-forwarded-for"]??"","x-api-key":r["x-api-key"]??"","x-request-id":st()??""}});return t.ok?await t.json():(W("warn","chat_limit_unavailable",{proxy_status:t.status}),{limit:3,used:3,remaining:0})}catch(t){return W("warn","chat_limit_unavailable",ne(t)),{limit:3,used:3,remaining:0}}}).post("/",async({body:{messages:r,data:e,provider:t,model:n},headers:a,set:s})=>{let{db:o,conversationId:i,includeSchema:c}=e,l=c?await Uc(o):null,u=kc(l),m={messages:r,conversationId:i,systemPrompt:u,provider:t,model:n},p=await fetch(`${Bc()}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":a["cf-connecting-ip"]??"","x-real-ip":a["x-real-ip"]??"","x-forwarded-for":a["x-forwarded-for"]??"","x-api-key":a["x-api-key"]??"","x-byok-gemini":a["x-byok-gemini"]??"","x-byok-openai":a["x-byok-openai"]??"","x-byok-anthropic":a["x-byok-anthropic"]??"","x-byok-grok":a["x-byok-grok"]??"","x-byok-openrouter":a["x-byok-openrouter"]??"","x-request-id":st()??""},body:JSON.stringify(m)});if(!p.ok){W("warn","chat_proxy_rejected",{proxy_status:p.status,provider:t,model:n});let f=await p.json();return Response.json({error:f.error||"Proxy request failed"},{status:p.status})}for(let[f,b]of p.headers)Gp.has(f)||(s.headers[f]=b);return p.body},{body:_r})});import{Elysia as Jp}from"elysia";var Hc,jc=N(()=>{"use strict";y();G();Vn();Ta();Hc=new Jp({prefix:"/connections"}).get("/",async()=>({data:await dn()})).post("/",async({body:r})=>(await Yn(r.url,{requireExistingFile:!0}),{data:await dn()}),{body:vr}).post("/:id/connect",async({params:r})=>(await Ba(r.id),{data:await dn()})).patch("/:id",async({params:r,body:e})=>({data:Fa(await ni(r.id,e))}),{body:Ur}).delete("/:id",async({params:r})=>(await ri(r.id),{data:"Connection removed"}))});import{Elysia as Xp}from"elysia";var Wc,Yc=N(()=>{"use strict";y();Ct();it();Wc=new Xp({prefix:"/databases"}).derive(()=>{let r=ot();return{dbType:r,adapter:Bt(r)}}).get("/",async({adapter:r,dbType:e})=>({data:{databases:await r.getDatabasesList(),dbType:e}})).get("/current",async({adapter:r,dbType:e})=>({data:{db:(await r.getCurrentDatabase()).db,dbType:e}})).get("/connection",async({adapter:r})=>({data:await r.getDatabaseConnectionInfo()}))});import{Elysia as Zp}from"elysia";var rt,Gt=N(()=>{"use strict";y();G();Ct();Vn();it();te();rt=new Zp().derive({as:"scoped"},({params:r,headers:e})=>{let{dbType:t=""}=r;if(!ge.has(t))throw new d(400,{message:`Invalid database type: "${t}". Supported types: ${ge.getSupportedTypes().join(", ")}`});let n=ot();if(n!==t)throw new d(409,{message:`The open connection is ${j[n].label}. Reload the page.`});let a=e["x-connection-id"];if(a&&a!==qa())throw new d(409,{message:"The connection changed. Reload the page."});return{dbType:t,adapter:Bt(t)}})});import{Elysia as ef}from"elysia";var Vc,zc=N(()=>{"use strict";y();G();Ct();Gt();Vc=new ef({prefix:"/keys"}).use(rt).resolve(({adapter:r,dbType:e})=>({keyValueAdapter:fi(r,e)})).get("/",async({keyValueAdapter:r,query:e})=>({data:await r.scanKeys(e)}),{query:jr}).post("/",async({keyValueAdapter:r,query:{db:e},body:t})=>({data:await r.createKey({db:e,...t})}),{query:F,body:zr}).get("/:key/raw",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.getStringChunk({...e,key:t})}),{query:Vr,params:$t}).get("/:key",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.getKeyDetails({...e,key:t})}),{query:Yr,params:$t}).post("/:key/actions",async({keyValueAdapter:r,query:{db:e},params:{key:t},body:n})=>({data:await r.applyKeyAction({db:e,key:t,...n})}),{query:F,params:$t,body:Gr}).delete("/:key",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.deleteKey({...e,key:t})}),{query:Qr,params:$t})});import{Elysia as tf}from"elysia";var Gc,Qc=N(()=>{"use strict";y();G();Gt();Gc=new tf({prefix:"/logs"}).use(rt).get("/",async({adapter:r,query:e})=>({data:await r.getServerLogs(e)}),{query:F})});import{Elysia as nf}from"elysia";var Jc,Xc=N(()=>{"use strict";y();G();Gt();Jc=new nf({prefix:"/query"}).use(rt).post("/",async({adapter:r,query:{db:e},body:{query:t}})=>({data:await r.executeQuery({query:t,db:e})}),{query:F,body:Kr})});import{Elysia as rf}from"elysia";var Zc,el=N(()=>{"use strict";y();G();Gt();Zc=new rf({prefix:"/records"}).use(rt).post("/",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,data:a}})=>{let{insertedCount:s}=await r.addRecord({db:e,schemaName:t,params:{tableName:n,data:a}});return{data:`Record inserted into "${n}" with ${s} rows inserted`}},{query:U,body:Sr}).patch("/",async({adapter:r,query:{db:e,schemaName:t},body:n})=>{let{updatedCount:a}=await r.updateRecords({params:n,schemaName:t,db:e});return{data:`Updated ${a} records in "${n.tableName}"`}},{query:U,body:Zr}).delete("/",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,primaryKeys:a},status:s})=>{let{deletedCount:o,fkViolation:i,relatedRecords:c}=await r.deleteRecords({tableName:n,schemaName:t,primaryKeys:a,db:e});return i?s(409,{data:{deletedCount:0,fkViolation:!0,relatedRecords:c}}):{data:{deletedCount:o,fkViolation:!1,relatedRecords:[]}}},{query:U,body:xn}).delete("/force",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,primaryKeys:a}})=>({data:await r.forceDeleteRecords({tableName:n,schemaName:t,primaryKeys:a,db:e})}),{query:U,body:xn}).post("/bulk",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,records:a}})=>({data:await r.bulkInsertRecords({tableName:n,schemaName:t,records:a,db:e})}),{query:U,body:Dr})});async function nl({cols:r,rows:e,format:t,tableName:n}){if(t==="json"){let o=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(o,"utf-8"))}let{utils:a,write:s}=await import("xlsx");switch(t){case"csv":{let o=a.aoa_to_sheet(tl(r,e)),i=a.sheet_to_csv(o);return new Uint8Array(Buffer.from(i,"utf-8"))}case"xlsx":{let o=a.aoa_to_sheet(tl(r,e)),i=a.book_new();a.book_append_sheet(i,o,n.slice(0,31));let c=s(i,{bookType:"xlsx",type:"buffer"});return new Uint8Array(c)}}}var af,tl,rl=N(()=>{"use strict";y();af=r=>r==null||r instanceof Date?r:Buffer.isBuffer(r)?`0x${r.toString("hex")}`:typeof r=="object"?JSON.stringify(r):typeof r=="bigint"?r.toString():r,tl=(r,e)=>[r,...e?.map(t=>r?.map(n=>af(t[n])))??[]]});import{Elysia as sf}from"elysia";var of,al,sl=N(()=>{"use strict";y();G();Gt();rl();of={csv:"text/csv",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",json:"application/json"},al=new sf({prefix:"/tables"}).use(rt).get("/",async({adapter:r,query:e})=>({data:await r.getTablesList(e.db)}),{query:F}).get("/graph",async({adapter:r,query:{db:e}})=>{let t=await r.getTablesList(e);return{data:await Promise.all(t.map(async n=>({...n,columns:await r.getTableColumns({tableName:n.tableName,schemaName:n.schemaName,db:e})})))}},{query:F}).post("/",async({adapter:r,query:e,body:t})=>(await r.createTable({tableData:t,db:e.db}),{data:`Table ${t.tableName} created successfully`}),{query:F,body:Br}).delete("/:tableName",async({adapter:r,query:{db:e,schemaName:t,cascade:n},params:{tableName:a}})=>({data:await r.deleteTable({tableName:a,schemaName:t,db:e,cascade:n})}),{query:Fr,params:ce}).patch("/:tableName/rename",async({adapter:r,query:{db:e},params:{tableName:t},body:n})=>(await r.renameTable({tableName:t,db:e,...n}),{data:`Table "${t}" renamed to "${n.newTableName}"`}),{query:F,params:ce,body:tn}).delete("/:tableName/columns/:columnName",async({adapter:r,query:{db:e,schemaName:t,cascade:n},params:{tableName:a,columnName:s}})=>{let{deletedCount:o}=await r.deleteColumn({schemaName:t,tableName:a,columnName:s,cascade:n,db:e});return{data:`Column "${s}" deleted successfully from table "${a}" with ${o} rows deleted`}},{query:Ar,params:we}).post("/:tableName/columns",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n},body:a})=>(await r.addColumn({tableName:n,schemaName:t,db:e,...a}),{data:`Column "${a.columnName}" added successfully to table "${n}"`}),{query:U,params:ce,body:qe}).patch("/:tableName/columns/:columnName/rename",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n,columnName:a},body:s})=>(await r.renameColumn({tableName:n,schemaName:t,columnName:a,db:e,...s}),{data:`Column "${a}" renamed to "${s.newColumnName}" in table "${n}"`}),{query:U,params:we,body:Mn}).patch("/:tableName/columns/:columnName",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n,columnName:a},body:s})=>(await r.alterColumn({tableName:n,schemaName:t,columnName:a,db:e,...s}),{data:`Column "${a}" updated successfully in table "${n}"`}),{query:U,params:we,body:It}).get("/:tableName/columns",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n}})=>({data:await r.getTableColumns({tableName:n,schemaName:t,db:e})}),{query:U,params:ce}).get("/:tableName/indexes",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n}})=>({data:await r.getTableIndexes({tableName:n,schemaName:t,db:e})}),{query:U,params:ce}).post("/:tableName/indexes",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n},body:a})=>(await r.createIndex({tableName:n,schemaName:t,db:e,...a}),{data:`Index "${a.indexName}" created successfully on table "${n}"`}),{query:U,params:ce,body:Ln}).delete("/:tableName/indexes/:indexName",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n,indexName:a}})=>(await r.dropIndex({tableName:n,schemaName:t,indexName:a,db:e}),{data:`Index "${a}" dropped successfully from table "${n}"`}),{query:U,params:Pn}).get("/:tableName/schema",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n}})=>({data:{schema:await r.getTableSchema({tableName:n,schemaName:t,db:e})}}),{query:U,params:ce}).get("/:tableName/data",async({adapter:r,query:e,params:{tableName:t}})=>({data:await r.getTableData({tableName:t,...e})}),{query:Xr,params:ce}).get("/:tableName/export",async({adapter:r,query:{db:e,schemaName:t,format:n},params:{tableName:a}})=>{let{cols:s,rows:o}=await r.exportTableData({tableName:a,schemaName:t,db:e});return new Response(await nl({cols:s,rows:o,format:n,tableName:a}),{headers:{"Content-Type":of[n],"Content-Disposition":`attachment; filename="${a}_export.${n}"`}})},{query:Hr,params:ce})});import{Elysia as cf}from"elysia";import{z as ol}from"zod";var lf,il,cl=N(()=>{"use strict";y();cn();lf=ol.object({enabled:ol.boolean()}).strict(),il=new cf({prefix:"/telemetry"}).get("/config",({headers:r})=>((r["x-db-studio-gpc"]==="1"||r["sec-gpc"]==="1")&&Kn(!1),ca(),{data:Fn()})).put("/preference",({body:r,status:e})=>{let t=lf.safeParse(r);return t.success?(Kn(t.data.enabled),{data:Fn()}):e(400,{error:"Invalid telemetry preference"})}).post("/reset",()=>({data:{installationId:sa()}}))});var ul={};Dt(ul,{createServer:()=>Cf});import{existsSync as ll}from"fs";import{readFile as uf,stat as mf}from"fs/promises";import Ue from"path";import{fileURLToPath as df}from"url";import{cors as pf}from"@elysiajs/cors";import{node as ff}from"@elysiajs/node";import{Elysia as yf}from"elysia";var br,hf,gf,bf,Tf,Ef,wf,Sf,Cf,ml=N(()=>{"use strict";y();Jt();Ct();Lc();te();$c();cn();Ye();Kc();jc();Yc();zc();Qc();Xc();el();sl();cl();({API_PREFIX:br}=at),hf=()=>{if(process.env.NODE_ENV==="development")return Ue.resolve(process.cwd(),"../web/dist");let r=Ue.dirname(df(import.meta.url)),e=Ue.resolve(r,"./web-dist"),t=Ue.resolve(process.cwd(),"../web/dist"),n=Ue.resolve(e,"index.html"),a=Ue.resolve(t,"index.html");return!ll(n)&&ll(a)?t:e},gf={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json",".png":"image/png",".svg":"image/svg+xml",".ico":"image/x-icon",".webp":"image/webp",".ttf":"font/ttf",".woff2":"font/woff2"},bf=async(r,e)=>{let t=Ue.join(r,"index.html");try{let s=Ue.resolve(r,`.${decodeURIComponent(e)}`);s.startsWith(`${r}${Ue.sep}`)&&(await mf(s)).isFile()&&(t=s)}catch{}let n=await uf(t).catch(s=>{if(s.code==="ENOENT")return null;throw s});if(n===null)return new Response('The web app is not built. Run "bun run build" in the repository root, then restart db-studio.',{status:404,headers:{"Content-Type":"text/plain; charset=utf-8"}});let a=t.startsWith(Ue.join(r,"assets",Ue.sep));return new Response(n,{headers:{"Content-Type":gf[Ue.extname(t)]??"application/octet-stream","Cache-Control":a?"public, max-age=31536000, immutable":"no-cache"}})},Tf=r=>{if(!r)return!1;if((process.env.ALLOWED_ORIGINS?.split(",").map(t=>t.trim()).filter(Boolean)??[]).includes(r))return!0;if(process.env.NODE_ENV!=="development")return!1;try{let{hostname:t}=new URL(r);return t==="localhost"||t.endsWith(".localhost")||t==="127.0.0.1"}catch{return!1}},Ef=new Set(["localhost","127.0.0.1","[::1]","::1"]),wf=r=>{let e=r.replace(/:\d+$/,"").toLowerCase();return Ef.has(e)||e.endsWith(".localhost")?!0:(process.env.ALLOWED_HOSTS?.split(",").map(n=>n.trim().toLowerCase()).filter(Boolean)??[]).includes(e)},Sf=(r,e)=>{let{pathname:t}=new URL(r.url),n=sn(r.method,t),a=on(t),s={requestId:$o(r.headers.get("x-request-id")??void 0),operation:n,dbType:a};return Mo(s,async()=>{if(!t.startsWith(`${br}/`)||t.startsWith(`${br}/telemetry`))return e();let o=performance.now(),i=a&&ge.has(a)?a:void 0,c=await ua(n,i,e);return Hn({event:"server_operation",properties:{operation:n,method:r.method,outcome:ia(c.status),duration_bucket:oa(performance.now()-o),db_type:i}}),c})},Cf=()=>{xc();let r=hf(),e=new yf({adapter:ff()}).wrap((t,n)=>(...a)=>Sf(n,async()=>await t(...a))).onRequest(({request:t,set:n})=>{if(n.headers["x-request-id"]=st(),!wf(t.headers.get("host")??new URL(t.url).host))throw new d(403,{message:"Host not allowed"})}).use(pf({origin:t=>Tf(t.headers.get("origin")),methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowedHeaders:["Content-Type","X-Run-Id","X-Request-Id","X-Connection-Id","X-DB-Studio-GPC","x-byok-gemini","x-byok-openai","x-byok-anthropic","x-byok-grok","x-byok-openrouter"],exposeHeaders:["X-Request-Id"],credentials:!1,maxAge:600})).onTransform(t=>{t.query=Object.fromEntries(new URL(t.request.url).searchParams);let n=t.request.headers.get("content-type")??"";if(t.body!==void 0&&!/^application\/([\w.-]+\+)?json/.test(n))throw new d(400,{message:"Request body must be JSON"})}).onError(({error:t,request:n})=>Pc(t,n)).group(br,t=>t.use(Hc).use(Wc).use(Fc).use(il).group("/:dbType",n=>n.use(al).use(Zc).use(Jc).use(Vc).use(Gc)));return process.env.NODE_ENV!=="test"&&e.all("/*",({request:t,path:n})=>(t.method==="GET"||t.method==="HEAD")&&!n.startsWith(`${br}/`)?bf(r,n):Response.json({error:"Not found"},{status:404})),{app:e}}});y();y();(function(){try{var r=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new r.Error().stack;e&&(r._sentryDebugIds=r._sentryDebugIds||{},r._sentryDebugIds[e]="ff865c7e-501b-4edf-a2f7-af234a457d3d",r._sentryDebugIdIdentifier="sentry-dbid-ff865c7e-501b-4edf-a2f7-af234a457d3d")}catch{}})();y();Jt();import{intro as Rf,log as wn,outro as dl,spinner as Nf}from"@clack/prompts";import Sn from"picocolors";y();import{program as Er}from"commander";var Ms=()=>{Er.name("db-studio").option("-e, --env <path>","Path to custom .env file").option("-p, --port <port>","Port to run the server on").option("-d, --database-url <url>","Database URL to use").option("-n, --var-name <name>","Custom environment variable name (default: DATABASE_URL)").option("--open","Open db-studio in the default browser").option("--no-open","Do not open db-studio in the default browser").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv);let r=Er.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&Er.error("Do not combine --open and --no-open"),{...r,open:e?!0:t?!1:void 0}};y();var ks=(r,e="DATABASE_URL")=>r?.[e]||process.env[e]||void 0;y();import{access as fl,readFile as yl}from"fs/promises";import{dirname as hl,resolve as wr}from"path";import{parse as gl}from"dotenv";var bl=async r=>{let e=wr(r);for(;;){let t=wr(e,".env");try{return await fl(t),t}catch{}let n=hl(e);if(n===e)return null;e=n}},_t=async r=>{let e;if(r?e=wr(r):e=await bl(process.cwd()),!e)return null;try{let t=await yl(e,"utf-8");return gl(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};y();import Tl from"open";var vs=r=>r===!0,Us=async r=>{await Tl(r)};ea();y();Tr();G();import{intro as Pu,outro as $u}from"@clack/prompts";import Mt from"picocolors";var Lo=()=>{Pu(Mt.inverse(" db-studio ")),console.log(Mt.bold(`
|
|
603
|
+
`}return t}var Vc=N(()=>{"use strict";h();z()});function ef(r){let e={name:r.columnName,type:r.dataTypeLabel,nullable:r.isNullable};return r.isPrimaryKey&&(e.isPrimaryKey=!0),r.isForeignKey&&r.referencedTable&&r.referencedColumn&&(e.foreignKey=`${r.referencedTable}.${r.referencedColumn}`),r.enumValues&&r.enumValues.length>0&&(e.enumValues=r.enumValues,e.description=`Enum values: ${r.enumValues.join(", ")}`),e}function tf(r){let e=[];for(let t of r)for(let n of t.columns)if(n.foreignKey){let[a,s]=n.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:n.name,toTable:a,toColumn:s})}return e}function nf(r){if(r==null)return"";if(r instanceof Date)return r.toISOString();if(typeof r=="bigint")return r.toString();if(typeof r=="object")try{return JSON.stringify(r)}catch{return String(r)}return String(r)}async function rf(r,e,t){try{return(await r.getTableData({tableName:e,db:t,limit:3})).data.map(a=>Object.fromEntries(Object.entries(a).map(([s,o])=>[s,nf(o)])))}catch(n){return Q("warn","schema_sample_rows_failed",fe(n)),[]}}async function af(r,e,t){try{return await r.getTableColumns({tableName:e,db:t})}catch(n){return Q("warn","schema_columns_failed",fe(n)),[]}}async function sf(r,e={}){let t=St(),{includeSampleData:n=!1,maxTables:a}=e,s=Kt(t);try{let o=await s.getTablesList(r),c=o.slice(0,a??o.length).map(async({schemaName:m,tableName:p})=>{let[f,b]=await Promise.all([af(s,p,r),n?rf(s,p,r):Promise.resolve([])]),y={name:m?`${m}.${p}`:p,columns:f.map(ef)};return b.length>0&&(y.sampleData=b),y}),l=await Promise.all(c),u=tf(l);return{dbType:t,tables:l,relationships:u}}catch(o){throw Q("error","schema_fetch_failed",fe(o)),new Error(`Failed to fetch database schema: ${o instanceof Error?o.message:"Unknown error"}`)}}async function zc(r){return sf(r,{includeSampleData:!0,includeDescriptions:!0})}var Gc=N(()=>{"use strict";h();Ct();Je();Ve()});import{Elysia as of}from"elysia";var cf,lf,Qc,Jc,Xc=N(()=>{"use strict";h();en();z();te();Ve();Vc();Gc();cf=new Set(["connection","keep-alive","transfer-encoding","content-length","content-encoding"]),lf=new Set(["localhost","127.0.0.1","::1","[::1]"]),Qc=()=>{let r;try{r=new URL(st.PROXY_URL)}catch{throw new d(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=lf.has(r.hostname)||r.hostname.endsWith(".localhost");if(r.protocol!=="https:"&&!(r.protocol==="http:"&&e))throw new d(500,{message:"DB_STUDIO_PROXY_URL must use HTTPS unless it points at loopback"});return r.origin},Jc=new of({prefix:"/chat"}).get("/limit",async({headers:r})=>{let e=Qc();try{let t=await fetch(`${e}/chat/limit`,{headers:{"cf-connecting-ip":r["cf-connecting-ip"]??"","x-real-ip":r["x-real-ip"]??"","x-forwarded-for":r["x-forwarded-for"]??"","x-api-key":r["x-api-key"]??"","x-request-id":ot()??""}});return t.ok?await t.json():(Q("warn","chat_limit_unavailable",{proxy_status:t.status}),{limit:3,used:3,remaining:0})}catch{return{limit:3,used:3,remaining:0}}}).post("/",async({body:{messages:r,data:e,provider:t,model:n},headers:a,set:s})=>{let{db:o,conversationId:i,includeSchema:c}=e,l=c?await zc(o):null,u=Yc(l),m={messages:r,conversationId:i,systemPrompt:u,provider:t,model:n},p=await fetch(`${Qc()}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":a["cf-connecting-ip"]??"","x-real-ip":a["x-real-ip"]??"","x-forwarded-for":a["x-forwarded-for"]??"","x-api-key":a["x-api-key"]??"","x-byok-gemini":a["x-byok-gemini"]??"","x-byok-openai":a["x-byok-openai"]??"","x-byok-anthropic":a["x-byok-anthropic"]??"","x-byok-grok":a["x-byok-grok"]??"","x-byok-openrouter":a["x-byok-openrouter"]??"","x-request-id":ot()??""},body:JSON.stringify(m)});if(!p.ok){Q("warn","chat_proxy_rejected",{proxy_status:p.status,provider:t,model:n});let f=await p.json();return Response.json({error:f.error||"Proxy request failed"},{status:p.status})}for(let[f,b]of p.headers)cf.has(f)||(s.headers[f]=b);return p.body},{body:$r})});import{Elysia as uf}from"elysia";var Zc,el=N(()=>{"use strict";h();z();Ga();Na();Zc=new uf({prefix:"/connections"}).get("/",async()=>({data:await gn()})).post("/",async({body:r})=>{let e=await Jn(r.url,{requireExistingFile:!0});return{data:await gn(e)}},{body:Hr}).post("/:id/connect",async({params:r})=>({data:await gn(await Va(r.id))})).patch("/:id",async({params:r,body:e})=>({data:za(await mi(r.id,e))}),{body:jr}).delete("/:id",async({params:r})=>(await di(r.id),{data:"Connection removed"}))});import{Elysia as mf}from"elysia";var tl,nl=N(()=>{"use strict";h();Ct();Je();tl=new mf({prefix:"/databases"}).derive(()=>{let r=St();return{dbType:r,adapter:Kt(r)}}).get("/",async({adapter:r,dbType:e})=>({data:{databases:await r.getDatabasesList(),dbType:e}})).get("/current",async({adapter:r,dbType:e})=>({data:{db:(await r.getCurrentDatabase()).db,dbType:e}})).get("/connection",async({adapter:r})=>({data:await r.getDatabaseConnectionInfo()}))});import{Elysia as df}from"elysia";var at,Qt=N(()=>{"use strict";h();z();Ct();Je();te();at=new df().derive({as:"scoped"},({params:r,headers:e})=>{let{dbType:t=""}=r;if(!ye.has(t))throw new d(400,{message:`Invalid database type: "${t}". Supported types: ${ye.getSupportedTypes().join(", ")}`});let n=e["x-connection-id"];if(n&&!fn(n))throw new d(409,{message:"The connection closed. Reload the page."});let a=St();if(a!==t)throw new d(409,{message:`The open connection is ${W[a].label}. Reload the page.`});return{dbType:t,adapter:Kt(t)}})});import{Elysia as pf}from"elysia";var rl,al=N(()=>{"use strict";h();z();Ct();Qt();rl=new pf({prefix:"/keys"}).use(at).resolve(({adapter:r,dbType:e})=>({keyValueAdapter:Ci(r,e)})).get("/",async({keyValueAdapter:r,query:e})=>({data:await r.scanKeys(e)}),{query:Qr}).post("/",async({keyValueAdapter:r,query:{db:e},body:t})=>({data:await r.createKey({db:e,...t})}),{query:F,body:ea}).get("/:key/raw",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.getStringChunk({...e,key:t})}),{query:Zr,params:kt}).get("/:key",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.getKeyDetails({...e,key:t})}),{query:Xr,params:kt}).post("/:key/actions",async({keyValueAdapter:r,query:{db:e},params:{key:t},body:n})=>({data:await r.applyKeyAction({db:e,key:t,...n})}),{query:F,params:kt,body:ta}).delete("/:key",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.deleteKey({...e,key:t})}),{query:na,params:kt})});import{Elysia as ff}from"elysia";var sl,ol=N(()=>{"use strict";h();z();Qt();sl=new ff({prefix:"/logs"}).use(at).get("/",async({adapter:r,query:e})=>({data:await r.getServerLogs(e)}),{query:F})});import{Elysia as hf}from"elysia";var il,cl=N(()=>{"use strict";h();z();Qt();il=new hf({prefix:"/query"}).use(at).post("/",async({adapter:r,query:{db:e},body:{query:t}})=>({data:await r.executeQuery({query:t,db:e})}),{query:F,body:zr})});import{Elysia as yf}from"elysia";var ll,ul=N(()=>{"use strict";h();z();Qt();ll=new yf({prefix:"/records"}).use(at).post("/",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,data:a}})=>{let{insertedCount:s}=await r.addRecord({db:e,schemaName:t,params:{tableName:n,data:a}});return{data:`Record inserted into "${n}" with ${s} rows inserted`}},{query:U,body:_r}).patch("/",async({adapter:r,query:{db:e,schemaName:t},body:n})=>{let{updatedCount:a}=await r.updateRecords({params:n,schemaName:t,db:e});return{data:`Updated ${a} records in "${n.tableName}"`}},{query:U,body:sa}).delete("/",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,primaryKeys:a},status:s})=>{let{deletedCount:o,fkViolation:i,relatedRecords:c}=await r.deleteRecords({tableName:n,schemaName:t,primaryKeys:a,db:e});return i?s(409,{data:{deletedCount:0,fkViolation:!0,relatedRecords:c}}):{data:{deletedCount:o,fkViolation:!1,relatedRecords:[]}}},{query:U,body:Mn}).delete("/force",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,primaryKeys:a}})=>({data:await r.forceDeleteRecords({tableName:n,schemaName:t,primaryKeys:a,db:e})}),{query:U,body:Mn}).post("/bulk",async({adapter:r,query:{db:e,schemaName:t},body:{tableName:n,records:a}})=>({data:await r.bulkInsertRecords({tableName:n,schemaName:t,records:a,db:e})}),{query:U,body:Pr})});async function dl({cols:r,rows:e,format:t,tableName:n}){if(t==="json"){let o=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(o,"utf-8"))}let{utils:a,write:s}=await import("xlsx");switch(t){case"csv":{let o=a.aoa_to_sheet(ml(r,e)),i=a.sheet_to_csv(o);return new Uint8Array(Buffer.from(i,"utf-8"))}case"xlsx":{let o=a.aoa_to_sheet(ml(r,e)),i=a.book_new();a.book_append_sheet(i,o,n.slice(0,31));let c=s(i,{bookType:"xlsx",type:"buffer"});return new Uint8Array(c)}}}var gf,ml,pl=N(()=>{"use strict";h();gf=r=>r==null||r instanceof Date?r:Buffer.isBuffer(r)?`0x${r.toString("hex")}`:typeof r=="object"?JSON.stringify(r):typeof r=="bigint"?r.toString():r,ml=(r,e)=>[r,...e?.map(t=>r?.map(n=>gf(t[n])))??[]]});import{Elysia as bf}from"elysia";var Tf,fl,hl=N(()=>{"use strict";h();z();Qt();pl();Tf={csv:"text/csv",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",json:"application/json"},fl=new bf({prefix:"/tables"}).use(at).get("/",async({adapter:r,query:e})=>({data:await r.getTablesList(e.db)}),{query:F}).get("/graph",async({adapter:r,query:{db:e}})=>{let t=await r.getTablesList(e);return{data:await Promise.all(t.map(async n=>({...n,columns:await r.getTableColumns({tableName:n.tableName,schemaName:n.schemaName,db:e})})))}},{query:F}).post("/",async({adapter:r,query:e,body:t})=>(await r.createTable({tableData:t,db:e.db}),{data:`Table ${t.tableName} created successfully`}),{query:F,body:Yr}).delete("/:tableName",async({adapter:r,query:{db:e,schemaName:t,cascade:n},params:{tableName:a}})=>({data:await r.deleteTable({tableName:a,schemaName:t,db:e,cascade:n})}),{query:Vr,params:ce}).patch("/:tableName/rename",async({adapter:r,query:{db:e},params:{tableName:t},body:n})=>(await r.renameTable({tableName:t,db:e,...n}),{data:`Table "${t}" renamed to "${n.newTableName}"`}),{query:F,params:ce,body:an}).delete("/:tableName/columns/:columnName",async({adapter:r,query:{db:e,schemaName:t,cascade:n},params:{tableName:a,columnName:s}})=>{let{deletedCount:o}=await r.deleteColumn({schemaName:t,tableName:a,columnName:s,cascade:n,db:e});return{data:`Column "${s}" deleted successfully from table "${a}" with ${o} rows deleted`}},{query:Lr,params:Ee}).post("/:tableName/columns",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n},body:a})=>(await r.addColumn({tableName:n,schemaName:t,db:e,...a}),{data:`Column "${a.columnName}" added successfully to table "${n}"`}),{query:U,params:ce,body:Fe}).patch("/:tableName/columns/:columnName/rename",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n,columnName:a},body:s})=>(await r.renameColumn({tableName:n,schemaName:t,columnName:a,db:e,...s}),{data:`Column "${a}" renamed to "${s.newColumnName}" in table "${n}"`}),{query:U,params:Ee,body:qn}).patch("/:tableName/columns/:columnName",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n,columnName:a},body:s})=>(await r.alterColumn({tableName:n,schemaName:t,columnName:a,db:e,...s}),{data:`Column "${a}" updated successfully in table "${n}"`}),{query:U,params:Ee,body:Lt}).get("/:tableName/columns",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n}})=>({data:await r.getTableColumns({tableName:n,schemaName:t,db:e})}),{query:U,params:ce}).get("/:tableName/indexes",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n}})=>({data:await r.getTableIndexes({tableName:n,schemaName:t,db:e})}),{query:U,params:ce}).post("/:tableName/indexes",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n},body:a})=>(await r.createIndex({tableName:n,schemaName:t,db:e,...a}),{data:`Index "${a.indexName}" created successfully on table "${n}"`}),{query:U,params:ce,body:kn}).delete("/:tableName/indexes/:indexName",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n,indexName:a}})=>(await r.dropIndex({tableName:n,schemaName:t,indexName:a,db:e}),{data:`Index "${a}" dropped successfully from table "${n}"`}),{query:U,params:vn}).get("/:tableName/schema",async({adapter:r,query:{db:e,schemaName:t},params:{tableName:n}})=>({data:{schema:await r.getTableSchema({tableName:n,schemaName:t,db:e})}}),{query:U,params:ce}).get("/:tableName/data",async({adapter:r,query:e,params:{tableName:t}})=>({data:await r.getTableData({tableName:t,...e})}),{query:aa,params:ce}).get("/:tableName/export",async({adapter:r,query:{db:e,schemaName:t,format:n},params:{tableName:a}})=>{let{cols:s,rows:o}=await r.exportTableData({tableName:a,schemaName:t,db:e});return new Response(await dl({cols:s,rows:o,format:n,tableName:a}),{headers:{"Content-Type":Tf[n],"Content-Disposition":`attachment; filename="${a}_export.${n}"`}})},{query:Gr,params:ce})});import{Elysia as Ef}from"elysia";import{z as yl}from"zod";var wf,gl,bl=N(()=>{"use strict";h();mn();wf=yl.object({enabled:yl.boolean()}).strict(),gl=new Ef({prefix:"/telemetry"}).get("/config",({headers:r})=>((r["x-db-studio-gpc"]==="1"||r["sec-gpc"]==="1")&&Vn(!1),fa(),{data:Yn()})).put("/preference",({body:r,status:e})=>{let t=wf.safeParse(r);return t.success?(Vn(t.data.enabled),{data:Yn()}):e(400,{error:"Invalid telemetry preference"})}).post("/reset",()=>({data:{installationId:ma()}}))});var Sl={};Ot(Sl,{createServer:()=>Uf});import{createHash as Sf,timingSafeEqual as Cf}from"crypto";import{existsSync as Tl}from"fs";import{readFile as Rf,stat as Nf}from"fs/promises";import Be from"path";import{fileURLToPath as Af}from"url";import{cors as Df}from"@elysiajs/cors";import{node as _f}from"@elysiajs/node";import{Elysia as Of}from"elysia";var An,If,xf,Lf,wl,Pf,$f,Mf,El,kf,vf,Uf,Cl=N(()=>{"use strict";h();en();Ct();Kc();Je();te();jc();mn();Ve();Xc();el();nl();al();ol();cl();ul();hl();bl();({API_PREFIX:An}=st),If=()=>{if(process.env.NODE_ENV==="development")return Be.resolve(process.cwd(),"../web/dist");let r=Be.dirname(Af(import.meta.url)),e=Be.resolve(r,"./web-dist"),t=Be.resolve(process.cwd(),"../web/dist"),n=Be.resolve(e,"index.html"),a=Be.resolve(t,"index.html");return!Tl(n)&&Tl(a)?t:e},xf={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json",".png":"image/png",".svg":"image/svg+xml",".ico":"image/x-icon",".webp":"image/webp",".ttf":"font/ttf",".woff2":"font/woff2"},Lf=async(r,e)=>{let t=Be.join(r,"index.html");try{let s=Be.resolve(r,`.${decodeURIComponent(e)}`);s.startsWith(`${r}${Be.sep}`)&&(await Nf(s)).isFile()&&(t=s)}catch{}let n=await Rf(t).catch(s=>{if(s.code==="ENOENT")return null;throw s});if(n===null)return new Response('The web app is not built. Run "bun run build" in the repository root, then restart db-studio.',{status:404,headers:{"Content-Type":"text/plain; charset=utf-8"}});let a=t.startsWith(Be.join(r,"assets",Be.sep));return new Response(n,{headers:{"Content-Type":xf[Be.extname(t)]??"application/octet-stream","Cache-Control":a?"public, max-age=31536000, immutable":"no-cache"}})},wl=r=>{if(!r)return!1;if((process.env.ALLOWED_ORIGINS?.split(",").map(t=>t.trim()).filter(Boolean)??[]).includes(r))return!0;if(process.env.NODE_ENV!=="development")return!1;try{let{hostname:t}=new URL(r);return t==="localhost"||t.endsWith(".localhost")||t==="127.0.0.1"}catch{return!1}},Pf=new Set(["localhost","127.0.0.1","[::1]","::1"]),$f=r=>{let e=r.replace(/:\d+$/,"").toLowerCase();return Pf.has(e)||e.endsWith(".localhost")?!0:(process.env.ALLOWED_HOSTS?.split(",").map(n=>n.trim().toLowerCase()).filter(Boolean)??[]).includes(e)},Mf=r=>{let e=r.headers.get("sec-fetch-site");return(e==="cross-site"||e==="same-site")&&!wl(r.headers.get("origin"))},El=r=>Sf("sha256").update(r).digest(),kf=r=>{let e=process.env.DB_STUDIO_PASSWORD;if(!e)return!0;if(!r?.startsWith("Basic "))return!1;let t=Buffer.from(r.slice(6),"base64").toString("utf8"),n=t.indexOf(":");return n!==-1&&Cf(El(t.slice(n+1)),El(e))},vf=(r,e)=>{let{pathname:t}=new URL(r.url),n=ln(r.method,t),a=un(t),s={requestId:Ho(r.headers.get("x-request-id")??void 0),operation:n,dbType:a,connectionId:r.headers.get("x-connection-id")??Oa()??void 0};return jo(s,async()=>{if(!t.startsWith(`${An}/`)||t.startsWith(`${An}/telemetry`))return e();let o=performance.now(),i=a&&ye.has(a)?a:void 0,c=await ya(n,i,e);return zn({event:"server_operation",properties:{operation:n,method:r.method,outcome:pa(c.status),duration_bucket:da(performance.now()-o),db_type:i}}),c})},Uf=()=>{Fc();let r=If(),e=new Of({adapter:_f()}).wrap((t,n)=>(...a)=>vf(n,async()=>await t(...a))).onRequest(({request:t,set:n})=>{if(n.headers["x-request-id"]=ot(),!$f(t.headers.get("host")??new URL(t.url).host))throw new d(403,{message:"Host not allowed"});if(t.method!=="OPTIONS"&&!kf(t.headers.get("authorization")))return new Response("Authentication required",{status:401,headers:{"WWW-Authenticate":'Basic realm="db-studio", charset="UTF-8"'}});if(new URL(t.url).pathname.startsWith(`${An}/`)&&Mf(t))throw new d(403,{message:"Cross-site request refused"})}).use(Df({origin:t=>wl(t.headers.get("origin")),methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowedHeaders:["Content-Type","Authorization","X-Run-Id","X-Request-Id","X-Connection-Id","X-DB-Studio-GPC","x-byok-gemini","x-byok-openai","x-byok-anthropic","x-byok-grok","x-byok-openrouter"],exposeHeaders:["X-Request-Id"],credentials:!1,maxAge:600})).onTransform(t=>{t.query=Object.fromEntries(new URL(t.request.url).searchParams);let n=t.request.headers.get("content-type")??"";if(t.body!==void 0&&!/^application\/([\w.-]+\+)?json/.test(n))throw new d(400,{message:"Request body must be JSON"})}).onError(({error:t,request:n})=>Hc(t,n)).group(An,t=>t.use(Zc).use(tl).use(Jc).use(gl).group("/:dbType",n=>n.use(fl).use(ll).use(il).use(rl).use(sl)));return process.env.NODE_ENV!=="test"&&e.all("/*",({request:t,path:n})=>(t.method==="GET"||t.method==="HEAD")&&!n.startsWith(`${An}/`)?Lf(r,n):Response.json({error:"Not found"},{status:404})),{app:e}}});h();h();(function(){try{var r=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new r.Error().stack;e&&(r._sentryDebugIds=r._sentryDebugIds||{},r._sentryDebugIds[e]="1626dcf0-181c-45ea-b847-0eea8b78921a",r._sentryDebugIdIdentifier="sentry-dbid-1626dcf0-181c-45ea-b847-0eea8b78921a")}catch{}})();h();en();import{intro as qf,log as Jt,outro as Rl,spinner as Bf}from"@clack/prompts";import Xt from"picocolors";h();import{program as Ar}from"commander";var Ks=()=>{Ar.name("db-studio").option("-e, --env <path>","Path to custom .env file").option("-p, --port <port>","Port to run the server on").option("-d, --database-url <url>","Database URL to use").option("-n, --var-name <name>","Custom environment variable name (default: DATABASE_URL)").option("--open","Open db-studio in the default browser").option("--no-open","Do not open db-studio in the default browser").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv);let r=Ar.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&Ar.error("Do not combine --open and --no-open"),{...r,open:e?!0:t?!1:void 0}};h();var Hs=(r,e="DATABASE_URL")=>r?.[e]||process.env[e]||void 0;h();import{access as Al,readFile as Dl}from"fs/promises";import{dirname as _l,resolve as Dr}from"path";import{parse as Ol}from"dotenv";var Il=async r=>{let e=Dr(r);for(;;){let t=Dr(e,".env");try{return await Al(t),t}catch{}let n=_l(e);if(n===e)return null;e=n}},It=async r=>{let e;if(r?e=Dr(r):e=await Il(process.cwd()),!e)return null;try{let t=await Dl(e,"utf-8");return Ol(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};h();import xl from"open";var js=r=>r===!0,Ws=async r=>{await xl(r)};oa();h();Nr();z();import{intro as Hu,outro as ju}from"@clack/prompts";import vt from"picocolors";var Fo=()=>{Hu(vt.inverse(" db-studio ")),console.log(vt.bold(`
|
|
604
604
|
Usage:`)),console.log(` db-studio [options]
|
|
605
|
-
`),console.log(
|
|
606
|
-
`),console.log(
|
|
605
|
+
`),console.log(vt.bold("Supported Databases:")),console.log(` ${Object.values(W).map(({label:r})=>r).join(", ")}
|
|
606
|
+
`),console.log(vt.bold("Options:")),console.log(" -e, --env <path> Path to custom .env file"),console.log(" -p, --port <port> Port to run the server on (default: 3333)"),console.log(" -d, --database-url <url> Database URL to use"),console.log(" --open Open db-studio in the default browser (off by default)"),console.log(" --no-open Do not open db-studio in the default browser"),console.log(" -n, --var-name <name> Custom environment variable name (default: DATABASE_URL)"),console.log(" -s, --status Show status of the database connection"),console.log(" -h, --help Show this help message"),console.log(` -v, --version Show version number
|
|
607
607
|
`),console.log("Without a database URL, open the printed address and choose one in the browser."),console.log(`Connections are saved to ~/.dbstudio/connections.json.
|
|
608
|
-
`),console.log(
|
|
609
|
-
`)
|
|
610
|
-
To configure database connection:`)),console.log(
|
|
611
|
-
`)),
|
|
608
|
+
`),console.log(vt.bold("Examples:")),console.log(" db-studio"),console.log(" db-studio -e .env.local"),console.log(" db-studio -p 4000"),console.log(" db-studio -d postgresql://user:pass@localhost:5432/mydb"),console.log(" db-studio -n MY_DATABASE_URL"),console.log(" db-studio -e .env.production -n PROD_DB_URL"),console.log(` db-studio --status
|
|
609
|
+
`),ju(vt.green(`For more information, visit: ${Bs.SITE_DOCS_LINK}`))};h();en();z();import{intro as Xu,note as Zu,outro as Vo}from"@clack/prompts";import He from"picocolors";ze();var zo=async(r,e,t)=>{Xu(He.inverse(" db-studio "));let n=t||st.VAR_NAME,a=null;if(e)a=e;else{let s=r?await It(r):await It();s?.[n]?a=s[n]:process.env[n]&&(a=process.env[n]??null)}a?Vo(He.green(`\u2713 Database connection configured (using ${n})`)):(Zu(He.red(`\u2717 ${n} not found`),"Status"),console.log(He.yellow(`
|
|
610
|
+
To configure database connection:`)),console.log(He.dim(` \u2022 Supported databases: ${Object.values(W).map(({label:s})=>s).join(", ")}`)),console.log(He.dim(` \u2022 Also via wire-compatible URLs: ${Object.keys(Hn).map(s=>`${s}://`).join(", ")}`)),console.log(He.dim(` \u2022 Add ${n} to your .env file or set it in process.env`)),console.log(He.dim(" \u2022 Use -d flag: db-studio -d <url>")),console.log(He.dim(" \u2022 Use -e flag: db-studio -e <path-to-env>")),console.log(He.dim(` \u2022 Use -n flag: db-studio -n <var-name>
|
|
611
|
+
`)),Vo(He.yellow("\u26A0 No database connection configured")))};h();la();import{intro as tm,outro as nm}from"@clack/prompts";import Go from"picocolors";var Qo=()=>{tm(Go.inverse(" db-studio ")),nm(Go.green(`\u{1F680} db-studio v${bt.version}`))};var Ff=async()=>{let{env:r,port:e,databaseUrl:t,varName:n,open:a,status:s,help:o,version:i}=Ks();o&&(Fo(),process.exit(0)),i&&(Qo(),process.exit(0)),s&&(await zo(r,t,n),process.exit(0)),qf(Xt.inverse(" db-studio "));let c=r?await It(r):await It();if(c)for(let[A,R]of Object.entries(c))process.env[A]===void 0&&(process.env[A]=R);let l=Number.parseInt(e??process.env.PORT??String(st.PORT),10),u=process.env.HOST??"127.0.0.1";if(!["127.0.0.1","localhost","::1"].includes(u)&&!process.env.DB_STUDIO_PASSWORD){let{randomBytes:A}=await import("crypto");process.env.DB_STUDIO_PASSWORD=A(18).toString("base64url"),Jt.warn(`HOST=${u} exposes db-studio to the network, so it asks for a password (set DB_STUDIO_PASSWORD to choose one). Sign in with any username and the password ${Xt.cyan(process.env.DB_STUDIO_PASSWORD)}`)}let m=n||st.VAR_NAME,p=t||Hs(c,m),{flushServerObservability:f,initServerObservability:b}=await Promise.resolve().then(()=>(mn(),ti));if(b(),p){Jt.success(t?"Using database URL from --database-url":c?.[m]?`Found ${m} in ${r??".env"}`:`Found ${m} in environment`);let{getDatabaseConnectionDetails:A}=await Promise.resolve().then(()=>(Ta(),ni)),{connect:R}=await Promise.resolve().then(()=>(Ga(),Si)),C=A(p),_=C?`${C.name} at ${C.destination}`:"the database",O=Bf();O.start(`Connecting to ${_}...`);try{await R(p),O.stop(`Connected to ${_}`)}catch($){throw O.stop(`Could not connect to ${_}`),$}}else Jt.info(`No ${m} found. Choose a database in the browser.`);let{createServer:y}=await Promise.resolve().then(()=>(Cl(),Sl)),{closeAllDbPools:g}=await Promise.resolve().then(()=>(Je(),Wa)),{app:S}=y(),w=async()=>{let A=new Promise(R=>setTimeout(R,5e3));await Promise.race([S.server?.stop(),A]),await Promise.race([Promise.allSettled([g(),f()]),A]),process.exit(0)};process.once("SIGINT",w),process.once("SIGTERM",w),S.listen({hostname:u,port:l});let D=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${l}`;if(Jt.success(`Server listening at ${Xt.cyan(D)}`),js(a))try{await Ws(D),Jt.success("Opened db-studio in your browser")}catch{Jt.warn(`Could not open your browser. Visit ${Xt.cyan(D)}`)}Rl(Xt.green("Ready"))};process.env.NODE_ENV!=="test"&&Ff().catch(r=>{let e=r instanceof Error?r.message:String(r);Rl(Xt.red(`Startup failed: ${Fn(e)}`)),process.exit(1)});var cR=void 0;export{cR as default,Ff as main};
|
|
612
612
|
//# sourceMappingURL=index.js.map
|