db-studio 1.17.0 → 1.19.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/README.md +86 -49
- package/dist/index.js +151 -112
- package/dist/index.js.map +1 -1
- package/dist/web-dist/assets/_pathlessLayout-DFRv9XCB.js +1 -0
- package/dist/web-dist/assets/_pathlessLayout-DFy4SGet.js +2 -0
- package/dist/web-dist/assets/_queryId-BMByB2oT.js +1 -0
- package/dist/web-dist/assets/_table-Bg2023_C.js +1 -0
- package/dist/web-dist/assets/_table-CNv5UFxx.js +1 -0
- package/dist/web-dist/assets/_table-DFikg2By.js +1 -0
- package/dist/web-dist/assets/abap-dxRygfPH.js +1 -0
- package/dist/web-dist/assets/apex-zgJPDUJP.js +1 -0
- package/dist/web-dist/assets/azcli-wJHaoZMB.js +1 -0
- package/dist/web-dist/assets/badge-DKcWcYUF.js +1 -0
- package/dist/web-dist/assets/bat-C1wIr6Fe.js +1 -0
- package/dist/web-dist/assets/bicep-BvxsFQ8r.js +2 -0
- package/dist/web-dist/assets/browser-K0FP9iu-.js +1 -0
- package/dist/web-dist/assets/{bundle-mjs-CfhZe4O1.js → bundle-mjs-DnfzKk33.js} +1 -1
- package/dist/web-dist/assets/cameligo-DrYvjD55.js +1 -0
- package/dist/web-dist/assets/chat-sidebar-Cq9VUD6G.js +132 -0
- package/dist/web-dist/assets/clojure-74_l0zQh.js +1 -0
- package/dist/web-dist/assets/{code-editor-CI9i4mj3.js → code-editor-BjMRNGGr.js} +2 -2
- package/dist/web-dist/assets/coffee-C0rQZbWl.js +1 -0
- package/dist/web-dist/assets/constants-Ma2YHUjt.js +12 -0
- package/dist/web-dist/assets/cpp-B5zY1E3k.js +1 -0
- package/dist/web-dist/assets/csharp-DwtW3NHZ.js +1 -0
- package/dist/web-dist/assets/csp-JrZi5CVH.js +1 -0
- package/dist/web-dist/assets/css-C3v_G68F.js +3 -0
- package/dist/web-dist/assets/cssMode-DEx5wjaw.js +1 -0
- package/dist/web-dist/assets/cypher-BTD8b27B.js +1 -0
- package/dist/web-dist/assets/dart-CwL-_kqb.js +1 -0
- package/dist/web-dist/assets/database.store-1pbPyu5t.js +57 -0
- package/dist/web-dist/assets/{dist-CKgBcNn7.js → dist-BXhLQctj.js} +1 -1
- package/dist/web-dist/assets/dockerfile-CdgVtJCK.js +1 -0
- package/dist/web-dist/assets/ecl-BVdxv81-.js +1 -0
- package/dist/web-dist/assets/editor-1FQrmyyI.css +1 -0
- package/dist/web-dist/assets/editor.api-CYxF2O7b.js +865 -0
- package/dist/web-dist/assets/elixir-DfatOM0G.js +1 -0
- package/dist/web-dist/assets/esm-D-gZMxcU.js +501 -0
- package/dist/web-dist/assets/flow9-a4YAXy8S.js +1 -0
- package/dist/web-dist/assets/freemarker2-CfPBr1kT.js +3 -0
- package/dist/web-dist/assets/fsharp-DPMv4wkA.js +1 -0
- package/dist/web-dist/assets/go-IiZtrnqs.js +1 -0
- package/dist/web-dist/assets/graphql-CXNuaSRA.js +1 -0
- package/dist/web-dist/assets/handlebars-DxY2nPcz.js +1 -0
- package/dist/web-dist/assets/hcl-SxWYdXh8.js +1 -0
- package/dist/web-dist/assets/highlighted-body-OFNGDK62-CrpnFH8F.js +1 -0
- package/dist/web-dist/assets/html-drmbqc-0.js +1 -0
- package/dist/web-dist/assets/htmlMode-_WyzBcs8.js +1 -0
- package/dist/web-dist/assets/icons-D00FvbYk.js +1 -0
- package/dist/web-dist/assets/index-De1y1AW6.css +2 -0
- package/dist/web-dist/assets/index-DvUqe2GZ.js +45 -0
- package/dist/web-dist/assets/indexes-DKdMLQaQ.js +1 -0
- package/dist/web-dist/assets/ini-dRlOWwKj.js +1 -0
- package/dist/web-dist/assets/java-6BlUAALm.js +1 -0
- package/dist/web-dist/assets/javascript-BDJbGhjO.js +1 -0
- package/dist/web-dist/assets/json-editor-CWN4Qxy5.js +1 -0
- package/dist/web-dist/assets/jsonMode-CMZrI5JG.js +7 -0
- package/dist/web-dist/assets/julia-D9gAObN3.js +1 -0
- package/dist/web-dist/assets/keys-BNEHyGRj.js +1 -0
- package/dist/web-dist/assets/kotlin-BkNKxUBx.js +1 -0
- package/dist/web-dist/assets/label-r_iGrn1k.js +1 -0
- package/dist/web-dist/assets/less-CXD3UefM.js +2 -0
- package/dist/web-dist/assets/lexon-C_fFLl-m.js +1 -0
- package/dist/web-dist/assets/liquid-DK-C1kNz.js +1 -0
- package/dist/web-dist/assets/logs-DYp_nXQS.js +1 -0
- package/dist/web-dist/assets/lspLanguageFeatures-C43gbr5Q.js +4 -0
- package/dist/web-dist/assets/lua-D9zIDNVg.js +1 -0
- package/dist/web-dist/assets/m3-BOUXBH8W.js +1 -0
- package/dist/web-dist/assets/markdown-HYv7mtUU.js +1 -0
- package/dist/web-dist/assets/mdx-CyR2pftH.js +1 -0
- package/dist/web-dist/assets/mermaid-GHXKKRXX-BVKgPqVX.js +1 -0
- package/dist/web-dist/assets/{middleware-DGlL7Sbs.js → middleware-z4uSElcP.js} +1 -1
- package/dist/web-dist/assets/mips-BYotwMVA.js +1 -0
- package/dist/web-dist/assets/module-BcWVk-SL.js +2 -0
- package/dist/web-dist/assets/monaco-theme-BIjVxdNP.js +64 -0
- package/dist/web-dist/assets/monaco-theme-BnSsSzUH.css +1 -0
- package/dist/web-dist/assets/msdax-B5L4PZsP.js +1 -0
- package/dist/web-dist/assets/mysql-B58bnHpg.js +1 -0
- package/dist/web-dist/assets/objective-c-CFqy6rAv.js +1 -0
- package/dist/web-dist/assets/pascal-CLsa5WGA.js +1 -0
- package/dist/web-dist/assets/pascaligo-DziJFYKK.js +1 -0
- package/dist/web-dist/assets/perl-CmwL-QR-.js +1 -0
- package/dist/web-dist/assets/personal-preferences.store-D5exZVZQ.js +1 -0
- package/dist/web-dist/assets/pgsql-Do7fvYVV.js +1 -0
- package/dist/web-dist/assets/php-Dj9jihN6.js +1 -0
- package/dist/web-dist/assets/pla-L8RfOkFM.js +1 -0
- package/dist/web-dist/assets/postiats-BXpJZeqC.js +1 -0
- package/dist/web-dist/assets/powerquery-BXkVIUru.js +1 -0
- package/dist/web-dist/assets/powershell-DwW-M4zK.js +1 -0
- package/dist/web-dist/assets/preload-helper-ThWhQeFm.js +1 -0
- package/dist/web-dist/assets/protobuf-K907XPEr.js +2 -0
- package/dist/web-dist/assets/pug-C-RaYi9h.js +1 -0
- package/dist/web-dist/assets/python-CP4tLlJS.js +1 -0
- package/dist/web-dist/assets/qsharp-CzL8Ss6l.js +1 -0
- package/dist/web-dist/assets/queries.store-BY932Cz6.js +1 -0
- package/dist/web-dist/assets/query-runner-DE3oEoYe.js +17 -0
- package/dist/web-dist/assets/r-CRucCfm1.js +1 -0
- package/dist/web-dist/assets/radix-ui-C1Muznox.js +51 -0
- package/dist/web-dist/assets/razor-D5MHZkbo.js +1 -0
- package/dist/web-dist/assets/react-HGZFyY1j.js +1 -0
- package/dist/web-dist/assets/{react-dom-MwQ-XgNN.js → react-dom-DtHnGHi-.js} +1 -1
- package/dist/web-dist/assets/redis-D2ruGQTE.js +1 -0
- package/dist/web-dist/assets/redis-value-DvqdrDxN.js +1 -0
- package/dist/web-dist/assets/redshift-ClhJ3UDf.js +1 -0
- package/dist/web-dist/assets/restructuredtext-CDSduErp.js +1 -0
- package/dist/web-dist/assets/{rolldown-runtime-BCBVhuY0.js → rolldown-runtime-DglIe7XP.js} +1 -1
- package/dist/web-dist/assets/ruby-BOYci4GS.js +1 -0
- package/dist/web-dist/assets/runner-CdvyQd_7.js +1 -0
- package/dist/web-dist/assets/rust-C6GsoKwD.js +1 -0
- package/dist/web-dist/assets/sb-Byu7SwWe.js +1 -0
- package/dist/web-dist/assets/scala-BXABW78T.js +1 -0
- package/dist/web-dist/assets/schema-BG-MIF2O.js +1 -0
- package/dist/web-dist/assets/scheme-8OXsCVoc.js +1 -0
- package/dist/web-dist/assets/scss-osYiZxfm.js +3 -0
- package/dist/web-dist/assets/select-DIrPycKO.js +1 -0
- package/dist/web-dist/assets/separator-DXlD6ZPI.js +1 -0
- package/dist/web-dist/assets/sheet-sidebar-K2TU7XMc.js +1 -0
- package/dist/web-dist/assets/shell-xb0sqli5.js +1 -0
- package/dist/web-dist/assets/solidity-BaiP98Rq.js +1 -0
- package/dist/web-dist/assets/sophia-CQgWshwN.js +1 -0
- package/dist/web-dist/assets/sparql-XOTzL0Lh.js +1 -0
- package/dist/web-dist/assets/sql-DGJWoFiH.js +1 -0
- package/dist/web-dist/assets/st-BD5QOETo.js +1 -0
- package/dist/web-dist/assets/swift-lLfOkw1g.js +1 -0
- package/dist/web-dist/assets/systemverilog-BYxoqTfR.js +1 -0
- package/dist/web-dist/assets/table-DoAtaSpv.js +1 -0
- package/dist/web-dist/assets/tanstack-DeB5Eprq.js +8 -0
- package/dist/web-dist/assets/tcl-BFpZjjdK.js +1 -0
- package/dist/web-dist/assets/tooltip-B_5geL0k.js +1 -0
- package/dist/web-dist/assets/tsMode-8DDkjaCA.js +11 -0
- package/dist/web-dist/assets/twig-Ds4bsmPZ.js +1 -0
- package/dist/web-dist/assets/typescript-BD4P_hvn.js +1 -0
- package/dist/web-dist/assets/typespec-DMwDmafU.js +1 -0
- package/dist/web-dist/assets/utils-vY5qZZPu.js +1 -0
- package/dist/web-dist/assets/vb-B3EULsLk.js +1 -0
- package/dist/web-dist/assets/visualizer-CsdVT6fl.js +1 -0
- package/dist/web-dist/assets/wgsl-BCYPO-gR.js +298 -0
- package/dist/web-dist/assets/workers-DiwDrKYe.js +1 -0
- package/dist/web-dist/assets/xml-CPmvJeqm.js +1 -0
- package/dist/web-dist/assets/yaml-CGAao1xZ.js +1 -0
- package/dist/web-dist/index.html +23 -20
- package/package.json +11 -6
- package/dist/web-dist/assets/_pathlessLayout-BkAR-cxy.js +0 -132
- package/dist/web-dist/assets/_pathlessLayout-Da39Ex7I.js +0 -1
- package/dist/web-dist/assets/_queryId-DJ8Cszxw.js +0 -1
- package/dist/web-dist/assets/_table-C0a5HWX2.js +0 -1
- package/dist/web-dist/assets/_table-CSyEA1sh.js +0 -1
- package/dist/web-dist/assets/_table-D2rPjuB3.js +0 -1
- package/dist/web-dist/assets/badge-BgJ132Zp.js +0 -1
- package/dist/web-dist/assets/browser-DRVH5V78.js +0 -1
- package/dist/web-dist/assets/database.store-ybZyJeQE.js +0 -57
- package/dist/web-dist/assets/format-cell-value-FBkY2oBS.js +0 -1
- package/dist/web-dist/assets/highlighted-body-OFNGDK62-DJ_AZ-U-.js +0 -1
- package/dist/web-dist/assets/icons-Cqp8qsxp.js +0 -1
- package/dist/web-dist/assets/index-CZcDmX3V.css +0 -2
- package/dist/web-dist/assets/index-DkEjlgj_.js +0 -36
- package/dist/web-dist/assets/indexes-BJXcp3El.js +0 -1
- package/dist/web-dist/assets/logs-DEpoT_GT.js +0 -1
- package/dist/web-dist/assets/mermaid-GHXKKRXX-C-5cK5mF.js +0 -1
- package/dist/web-dist/assets/monaco-editor-Dlx7llW7.js +0 -1252
- package/dist/web-dist/assets/monaco-editor-IL9D_L0g.css +0 -1
- package/dist/web-dist/assets/monitoring-COzw_qZY.js +0 -22
- package/dist/web-dist/assets/overlay.store-CdMPivQ4.js +0 -11
- package/dist/web-dist/assets/queries.store-mYjqPBIG.js +0 -1
- package/dist/web-dist/assets/query-runner-Rk39OSFU.js +0 -17
- package/dist/web-dist/assets/radix-ui-B5VLwTAi.js +0 -51
- package/dist/web-dist/assets/react-CYwS-VST.js +0 -1
- package/dist/web-dist/assets/redis-value-D5wqUFuP.js +0 -1
- package/dist/web-dist/assets/runner--5mwKvXr.js +0 -1
- package/dist/web-dist/assets/schema-C8mv4CVD.js +0 -1
- package/dist/web-dist/assets/schema-boTdkq9l.js +0 -1
- package/dist/web-dist/assets/table-mU6PMMQx.js +0 -1
- package/dist/web-dist/assets/tanstack-DvfzCieo.js +0 -11
- package/dist/web-dist/assets/use-database-engine-FWzj-N81.js +0 -1
- package/dist/web-dist/assets/visualizer-CnmK5vq1.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var hc=Object.defineProperty;var S=(r,e)=>()=>(r&&(e=r(r=0)),e);var on=(r,e)=>{for(var t in e)hc(r,t,{get:e[t],enumerable:!0})};var h=S(()=>{"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.17.0"}}catch{}})()});var Ka=S(()=>{"use strict";h()});var Wa=S(()=>{"use strict";h()});var Va=S(()=>{"use strict";h()});var za,Ya,Ze,Ga=S(()=>{"use strict";h();za=globalThis.process?.env,Ya=za?.NODE_ENV,Ze={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:Ya==="development",PROXY_URL:za?.DB_STUDIO_PROXY_URL??(Ya==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var Qa=S(()=>{"use strict";h()});var Ja,fr=S(()=>{"use strict";h();Ja={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 Xa=S(()=>{"use strict";h()});var Ut=S(()=>{"use strict";h();Ka();Wa();Va();Ga();Qa();fr();Xa()});import{z as gt}from"zod";var L,Tt,Bt,_c,Ic,me,Ae=S(()=>{"use strict";h();L=gt.object({db:gt.string("Database name is required")}),Tt=["pg","mysql","mssql","mongodb","sqlite","redis","duckdb","oracle","clickhouse"],Bt=gt.enum(Tt,{message:"Invalid database type"}),_c=L.extend({dbType:Bt}),Ic=gt.object({dbType:Bt}),me=gt.object({tableName:gt.string("Table name is required")})});import{z as Ke}from"zod";var Ue,Oc,xc,ss=S(()=>{"use strict";h();Ae();Ue=Ke.object({columnName:Ke.string("Column name is required"),columnType:Ke.string("Column type is required"),defaultValue:Ke.string().optional(),isPrimaryKey:Ke.boolean().default(!1),isNullable:Ke.boolean().default(!1),isUnique:Ke.boolean().default(!1),isIdentity:Ke.boolean().default(!1),isArray:Ke.boolean().default(!1)}),Oc=me,xc=Ke.object({db:L.shape.db,tableName:me.shape.tableName,columnName:Ue.shape.columnName,columnType:Ue.shape.columnType,defaultValue:Ue.shape.defaultValue,isPrimaryKey:Ue.shape.isPrimaryKey,isNullable:Ue.shape.isNullable,isUnique:Ue.shape.isUnique,isIdentity:Ue.shape.isIdentity,isArray:Ue.shape.isArray})});import{z as Ft}from"zod";var Tr,os=S(()=>{"use strict";h();Tr=Ft.object({tableName:Ft.string("Table name is required"),data:Ft.record(Ft.string("Column name is required"),Ft.any())})});import{z as $c}from"zod";var is,Er,cs,wr,Cr=S(()=>{"use strict";h();is=["gemini","openai","anthropic","grok","openrouter"],Er=$c.enum(is),cs=[{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"}]}],wr=r=>cs.find(e=>e.id===r)?.models[0]?.id??"gemini-3-flash-preview"});import{z as Be}from"zod";var Sr,Ce,Pc,Lc,ln=S(()=>{"use strict";h();Ae();Sr=L.extend({cascade:Be.string().optional().transform(r=>r==="true")}),Ce=Be.object({tableName:Be.string("Table name is required"),columnName:Be.string("Column name is required")}),Pc=Be.object({db:L.shape.db,tableName:Ce.shape.tableName,columnName:Ce.shape.columnName,cascade:Be.boolean().optional()}),Lc=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 jt}from"zod";var Et,Mc,kc,ls=S(()=>{"use strict";h();Ae();ln();Et=jt.object({columnType:jt.string("Column type is required"),isNullable:jt.boolean(),defaultValue:jt.string().nullable().optional()}),Mc=Ce,kc=jt.object({db:L.shape.db,tableName:Ce.shape.tableName,columnName:Ce.shape.columnName,columnType:Et.shape.columnType,isNullable:Et.shape.isNullable,defaultValue:Et.shape.defaultValue})});var us=S(()=>{"use strict";h()});import{z as wt}from"zod";var Rr,ms=S(()=>{"use strict";h();Rr=wt.object({tableName:wt.string().min(1,"Table name is required"),records:wt.array(wt.record(wt.string(),wt.any())).min(1,"At least one record is required")})});import{z as be}from"zod";var vc,qc,Nr,ds=S(()=>{"use strict";h();Cr();Ae();vc=be.object({type:be.string(),content:be.string().optional()}).passthrough(),qc=be.object({provider:Er.optional().default("gemini"),model:be.string().min(1).optional(),messages:be.array(be.object({id:be.string(),role:be.enum(["user","assistant","system","tool","reasoning"]),content:be.union([be.string(),be.null(),be.array(be.unknown())]).optional(),parts:be.array(vc).optional()}).passthrough()),data:be.object({conversationId:be.string().optional(),db:L.shape.db,includeSchema:be.boolean().optional().default(!0)})}),Nr=qc.transform(r=>({...r,model:r.model??wr(r.provider)}))});var ps=S(()=>{"use strict";h()});import{z as Le}from"zod";var Uc,fs,M,Bc,ys,Fc,Ar=S(()=>{"use strict";h();Uc=["text","boolean","number","enum","json","date","array"],fs=Le.enum(Uc),M={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},Bc=["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"],ys=Le.enum(Bc),Fc=Le.object({columnName:Le.string(),dataType:fs,dataTypeLabel:ys,isNullable:Le.boolean(),columnDefault:Le.string().nullable(),isPrimaryKey:Le.boolean(),isForeignKey:Le.boolean(),referencedTable:Le.string().nullable(),referencedColumn:Le.string().nullable(),enumValues:Le.array(Le.string()).nullable()})});function un(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(")?M.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"?M.number:e==="boolean"||e==="bool"?M.boolean:e==="json"||e==="jsonb"?M.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?M.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"?M.text:M.text}function Dr(r){if(!r)return b.text;let e=r.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?b.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?b.bigint:e==="smallint"||e==="int2"?b.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?b.numeric:e==="real"||e==="float4"?b.float:e==="double precision"||e==="float8"||e==="float"?b.double:e==="money"?b.money:e==="boolean"||e==="bool"?b.boolean:e==="text"?b.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?b.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?b.char:e==="json"?b.json:e==="jsonb"?b.jsonb:e==="xml"?b.xml:e==="uuid"?b.uuid:e==="date"?b.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?b.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?b.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?b.timestamptz:e==="interval"||e.startsWith("interval")?b.interval:e==="bytea"?b.bytea:e==="inet"?b.inet:e==="cidr"?b.cidr:e==="macaddr"?b.macaddr:e==="macaddr8"?b.macaddr8:e==="point"?b.point:e==="line"?b.line:e==="polygon"?b.polygon:e.startsWith("array")||e.includes("[]")?b.text:e.startsWith("user-defined")||e==="enum"?b.enum:b.text}function mn(r,e){let t=r?.toLowerCase().trim()||"",n=e?.toLowerCase().trim()||"";return t==="tinyint"&&n==="tinyint(1)"?M.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"?M.number:t==="boolean"||t==="bool"?M.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?M.date:t==="json"?M.json:t==="enum"||t==="set"?M.enum:M.text}function _r(r,e){if(!r)return b.text;let t=r.toLowerCase().trim(),n=e?.toLowerCase().trim()||"";return t==="tinyint"&&n==="tinyint(1)"?b.boolean:t==="tinyint"?b.tinyint:t==="smallint"?b.smallint:t==="mediumint"?b.mediumint:t==="int"||t==="integer"?b.int:t==="bigint"?b.bigint:t==="decimal"||t==="numeric"?b.numeric:t==="float"||t==="real"?b.float:t==="double"?b.double:t==="bit"?b.bit:t==="boolean"||t==="bool"?b.boolean:t==="char"?b.char:t==="varchar"?b.varchar:t==="tinytext"?b.tinytext:t==="text"?b.text:t==="mediumtext"?b.mediumtext:t==="longtext"?b.longtext:t==="binary"?b.binary:t==="varbinary"?b.varbinary:t==="tinyblob"?b.tinyblob:t==="blob"?b.blob:t==="mediumblob"?b.mediumblob:t==="longblob"?b.longblob:t==="json"?b.json:t==="date"?b.date:t==="time"?b.time:t==="datetime"?b.datetime:t==="timestamp"?b.timestamp:t==="year"?b.year:t==="enum"?b.enum:t==="set"?b.set:b.text}function dn(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"?M.number:e==="bit"?M.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?M.date:e==="json"?M.json:M.text}function Ir(r){if(!r)return b.text;let e=r.toLowerCase().trim();return e==="tinyint"?b.tinyint:e==="smallint"?b.smallint:e==="int"?b.int:e==="bigint"?b.bigint:e==="decimal"||e==="numeric"?b.numeric:e==="float"||e==="real"?b.float:e==="money"||e==="smallmoney"?b.money:e==="bit"?b.boolean:e==="char"?b.char:e==="varchar"?b.varchar:e==="text"?b.text:e==="nchar"?b.char:e==="nvarchar"?b.varchar:e==="ntext"?b.text:e==="binary"?b.binary:e==="varbinary"?b.varbinary:e==="image"?b.blob:e==="uniqueidentifier"?b.uuid:e==="date"?b.date:e==="time"?b.time:e==="datetime"||e==="datetime2"||e==="smalldatetime"?b.datetime:e==="datetimeoffset"?b.timestamptz:e==="json"?b.json:e==="xml"?b.xml:b.text}function pn(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?M.boolean:e==="json"?M.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?M.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?M.number:M.text}function Or(r){let e=r?.toLowerCase().trim()||"";return e==="integer"||e==="int"?b.int:e==="bigint"||e.startsWith("bigint(")?b.bigint:e==="smallint"||e.startsWith("smallint(")?b.smallint:e==="tinyint"||e.startsWith("tinyint(")?b.tinyint:e==="mediumint"||e.startsWith("mediumint(")?b.mediumint:e.includes("int")?b.int:e==="real"||e==="float"||e.startsWith("float(")?b.float:e==="double"||e==="double precision"||e.startsWith("double(")?b.double:e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?b.numeric:e==="boolean"||e==="bool"?b.boolean:e==="text"||e==="clob"?b.text:e==="varchar"||e.startsWith("varchar(")?b.varchar:e==="char"||e.startsWith("char(")?b.char:e==="json"?b.json:e==="date"?b.date:e==="time"?b.time:e==="datetime"?b.datetime:e==="timestamp"?b.timestamp:e==="blob"?b.blob:b.text}function fn(r){let e=r?.toLowerCase().trim()||"";return e.endsWith("]")||e.startsWith("struct")||e.startsWith("map")||e.startsWith("union")||e==="json"?M.json:e==="boolean"||e==="bool"?M.boolean:e.startsWith("enum")?M.enum:e==="interval"?M.text:e==="date"||e.startsWith("time")||e==="datetime"?M.date:e.includes("int")||e==="float"||e==="real"||e==="double"||e.startsWith("decimal")||e.startsWith("numeric")||e==="bignum"?M.number:M.text}function xr(r){let e=r?.toLowerCase().trim()||"";return e.endsWith("]")?b.array:e.startsWith("struct")||e.startsWith("map")||e.startsWith("union")||e==="json"?b.json:e.startsWith("enum")?b.enum:e==="interval"?b.interval:e==="tinyint"||e==="utinyint"?b.tinyint:e==="smallint"||e==="usmallint"?b.smallint:e==="integer"||e==="int"?b.int:e.includes("int")||e==="bignum"?b.bigint:e.startsWith("decimal")||e.startsWith("numeric")?b.numeric:e==="float"||e==="real"?b.float:e==="double"?b.double:e==="boolean"||e==="bool"?b.boolean:e==="varchar"||e.startsWith("varchar(")?b.varchar:e==="uuid"?b.uuid:e==="date"?b.date:e==="timestamp with time zone"||e==="timestamptz"?b.timestamptz:e.startsWith("timestamp")||e==="datetime"?b.timestamp:e.startsWith("time")?b.time:e==="blob"||e==="bytea"?b.blob:e==="bit"||e==="bitstring"?b.bit:b.text}function yn(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"?M.boolean:e==="json"?M.json:e==="date"||e.startsWith("timestamp")?M.date:e.startsWith("number")||e.startsWith("float")||e==="integer"||e==="binary_float"||e==="binary_double"?M.number:M.text}function $r(r){let e=r?.toLowerCase().trim()||"";if(e==="boolean")return b.boolean;if(e==="json")return b.json;if(e==="xmltype")return b.xml;if(e==="integer")return b.int;let t=e.match(/^number\((\d+)(?:,0)?\)$/);if(t){let n=Number(t[1]);if(n<=4)return b.smallint;if(n<=10)return b.int;if(n<=19)return b.bigint}return e.startsWith("number")?b.numeric:e==="binary_float"?b.float:e==="binary_double"||e.startsWith("float")?b.double:e.startsWith("varchar")||e.startsWith("nvarchar")?b.varchar:e.startsWith("char")||e.startsWith("nchar")?b.char:e.startsWith("timestamp")&&e.endsWith("time zone")?b.timestamptz:e==="date"||e.startsWith("timestamp")?b.timestamp:e.startsWith("interval")?b.interval:e==="blob"||e==="long raw"?b.blob:e.startsWith("raw")?b.varbinary:b.text}function Ct(r){let e=r.trim();for(;;){let t=e.match(/^(?:Nullable|LowCardinality)\((.*)\)$/);if(!t?.[1])return e;e=t[1].trim()}}function hn(r){let e=Ct(r);return e.startsWith("Array(")?M.array:e.startsWith("Enum8(")||e.startsWith("Enum16(")?M.enum:e==="Bool"?M.boolean:/^(Date|Date32|DateTime|DateTime64|Time|Time64)\b/.test(e)?M.date:/^(U?Int\d+|Float\d+|BFloat16|Decimal\d*)\b/.test(e)?M.number:/^(JSON|Object|Map|Tuple|Variant|Dynamic|Nested)\b/.test(e)?M.json:M.text}function Pr(r){let e=Ct(r);return e.startsWith("Array(")?b.array:e.startsWith("Enum8(")||e.startsWith("Enum16(")?b.enum:e==="Bool"?b.boolean:/^U?Int8$/.test(e)?b.tinyint:/^U?Int16$/.test(e)?b.smallint:/^U?Int32$/.test(e)?b.int:/^U?Int(64|128|256)$/.test(e)?b.bigint:e==="Float32"||e==="BFloat16"?b.float:e==="Float64"?b.double:e.startsWith("Decimal")?b.numeric:e.startsWith("FixedString(")?b.char:e==="UUID"?b.uuid:e==="IPv4"||e==="IPv6"?b.inet:e==="Date"||e==="Date32"?b.date:e.startsWith("DateTime64")?b.timestamp:e.startsWith("DateTime")?b.datetime:e.startsWith("Time")?b.time:/^(JSON|Object|Map|Tuple|Variant|Dynamic|Nested)\b/.test(e)?b.json:b.text}var b,hs=S(()=>{"use strict";h();Ar();b={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 ge}from"zod";var bs,Lr,gs,Ts,Mr,Es=S(()=>{"use strict";h();bs=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],Lr=ge.enum(bs),gs=ge.object({columnName:ge.string("Column name is required"),columnType:ge.string("Column type is required"),defaultValue:ge.string().optional(),isPrimaryKey:ge.boolean().default(!1),isNullable:ge.boolean().default(!1),isUnique:ge.boolean().default(!1),isIdentity:ge.boolean().default(!1),isArray:ge.boolean().default(!1)}),Ts=ge.object({columnName:ge.string("Column name is required"),referencedTable:ge.string("Referenced table is required"),referencedColumn:ge.string("Referenced column is required"),onUpdate:Lr.default("NO ACTION"),onDelete:Lr.default("NO ACTION")}),Mr=ge.object({tableName:ge.string("Table name is required"),fields:ge.array(gs).min(1,"At least one field is required"),foreignKeys:ge.array(Ts).optional()})});var X,St,ws=S(()=>{"use strict";h();Ae();X={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."}},mysql:{label:"MySQL",protocols:["mysql","mysql2","mariadb","tidb"],defaultPort:3306,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null}},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."}},mongodb:{label:"MongoDB",protocols:["mongodb","mongodb+srv"],defaultPort:27017,dataModel:"document",editorLanguage:"json",liveMode:!1,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null}},sqlite:{label:"SQLite / libSQL",protocols:["sqlite","libsql"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0,indexes:{methods:[],createNote:null}},redis:{label:"Redis",protocols:["redis","rediss"],defaultPort:6379,dataModel:"key-value",editorLanguage:"plaintext",liveMode:!1,schemaSelector:!1,rowMutation:!0,indexes:!1},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."}},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."}},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."}},St=r=>Tt.find(e=>X[e].protocols.includes(r))});import{z as Se}from"zod";var Cs,jc,Hc,Ss=S(()=>{"use strict";h();Ae();Cs=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")}),jc=Se.object({databases:Se.array(Cs),dbType:Bt}),Hc=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 Rs=S(()=>{"use strict";h()});import{z as Rt}from"zod";var bn,Ns=S(()=>{"use strict";h();bn=Rt.object({tableName:Rt.string("Table name is required"),primaryKeys:Rt.array(Rt.object({columnName:Rt.string("Column name is required"),value:Rt.any()})).min(1,"At least one primary key is required")})});import{z as Kc}from"zod";var kr,As=S(()=>{"use strict";h();Ae();kr=L.extend({cascade:Kc.string().optional().transform(r=>r==="true")})});import{z as Ds}from"zod";var vr,_s=S(()=>{"use strict";h();vr=Ds.object({query:Ds.string("Query is required")})});import{z as Wc}from"zod";var Is,qr,Os=S(()=>{"use strict";h();Ae();Is=["csv","xlsx","json"],qr=L.extend({format:Wc.enum(Is,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as de}from"zod";var xs,Vc,gn,Yc,Tn,zc,$s=S(()=>{"use strict";h();Ae();xs=["primary","unique-constraint","index"],Vc=de.object({indexName:de.string(),columns:de.array(de.string()),isUnique:de.boolean(),isSparse:de.boolean().optional(),expireAfterSeconds:de.number().nonnegative().optional(),method:de.string().nullable(),kind:de.enum(xs),definition:de.string().nullable()}),gn=de.object({indexName:de.string().min(1),columns:de.array(de.string().min(1)).min(1),isUnique:de.boolean(),method:de.string().optional()}),Yc=gn.extend({db:L.shape.db,tableName:me.shape.tableName}),Tn=de.object({tableName:de.string("Table name is required"),indexName:de.string("Index name is required")}),zc=Tn.extend({db:L.shape.db})});import{z as T}from"zod";var En,W,Ur,Br,Gc,Fr,Nt,Qc,Jc,Xc,Zc,el,tl,nl,Ps,rl,jr,al,sl,ol,il,cl,ll,ul,Hr,ml,dl,pl,fl,yl,hl,bl,gl,Tl,El,wl,Cl,Sl,Rl,Nl,Kr,Wr,Al,Ls=S(()=>{"use strict";h();En=T.enum(["string","hash","list","set","zset","stream","unknown"]),W=T.object({base64:T.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:T.string().optional()}),Ur=T.object({db:T.string(),cursor:T.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:T.coerce.number().int().min(1).max(200).default(50),search:T.string().max(512).optional(),exactPattern:T.stringbool().default(!1),type:En.exclude(["unknown"]).optional()}),Br=T.object({key:W,type:En,ttlMs:T.number().int(),memoryBytes:T.number().int().nonnegative().nullable()}),Gc=T.object({keys:T.array(Br),nextCursor:T.string().nullable(),hasMore:T.boolean()}),Fr=T.object({db:T.string(),cursor:T.string().max(2048).regex(/^[A-Za-z0-9_-]+$/).optional(),limit:T.coerce.number().int().min(1).max(500).default(100),full:T.stringbool().default(!1),direction:T.enum(["forward","backward"]).default("forward")}),Nt=T.object({key:T.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),Qc=T.object({kind:T.literal("string"),value:W,truncated:T.boolean()}),Jc=T.object({kind:T.literal("hash"),entries:T.array(T.object({field:W,value:W}))}),Xc=T.object({kind:T.literal("list"),entries:T.array(T.object({index:T.number().int(),value:W}))}),Zc=T.object({kind:T.literal("set"),members:T.array(W)}),el=T.object({kind:T.literal("zset"),entries:T.array(T.object({member:W,score:T.union([T.number(),T.literal("inf"),T.literal("-inf")])}))}),tl=T.object({kind:T.literal("stream"),entries:T.array(T.object({id:T.string(),fields:T.array(T.object({field:W,value:W}))}))}),nl=T.object({kind:T.literal("unknown")}),Ps=T.discriminatedUnion("kind",[Qc,Jc,Xc,Zc,el,tl,nl]),rl=Br.extend({length:T.number().int().nonnegative().nullable(),revision:T.string(),value:Ps,nextCursor:T.string().nullable(),hasMore:T.boolean()}),jr=T.object({db:T.string(),offset:T.coerce.number().int().nonnegative().default(0),limit:T.coerce.number().int().min(1).max(1024*1024).default(1024*1024),expectedRevision:T.string().optional()}),al=T.object({chunk:W,length:T.number().int().nonnegative(),nextOffset:T.number().int().nonnegative().nullable(),hasMore:T.boolean()}),sl=T.object({kind:T.literal("string"),value:W}),ol=T.object({kind:T.literal("hash"),entries:T.array(T.object({field:W,value:W})).min(1)}),il=T.object({kind:T.literal("list"),entries:T.array(W).min(1)}),cl=T.object({kind:T.literal("set"),members:T.array(W).min(1)}),ll=T.object({kind:T.literal("zset"),entries:T.array(T.object({member:W,score:T.number()})).min(1)}),ul=T.object({kind:T.literal("stream"),id:T.string().default("*"),fields:T.array(T.object({field:W,value:W})).min(1)}),Hr=T.object({key:W,type:En.exclude(["unknown"]),value:T.discriminatedUnion("kind",[sl,ol,il,cl,ll,ul]),ttlMs:T.number().int().positive().nullable().default(null)}),ml=T.object({key:W,revision:T.string().nullable(),deleted:T.boolean()}),dl=T.object({action:T.literal("rename"),newKey:W}),pl=T.object({action:T.literal("setTtl"),ttlMs:T.number().int().positive().nullable()}),fl=T.object({action:T.literal("setString"),value:W}),yl=T.object({action:T.literal("upsertHash"),field:W,value:W}),hl=T.object({action:T.literal("deleteHash"),field:W}),bl=T.object({action:T.literal("pushList"),side:T.enum(["left","right"]),value:W}),gl=T.object({action:T.literal("setList"),index:T.number().int(),value:W}),Tl=T.object({action:T.literal("deleteList"),index:T.number().int()}),El=T.object({action:T.literal("addSet"),member:W}),wl=T.object({action:T.literal("removeSet"),member:W}),Cl=T.object({action:T.literal("upsertZset"),member:W,score:T.number()}),Sl=T.object({action:T.literal("removeZset"),member:W}),Rl=T.object({action:T.literal("appendStream"),id:T.string().default("*"),fields:T.array(T.object({field:W,value:W})).min(1)}),Nl=T.object({action:T.literal("deleteStream"),id:T.string()}),Kr=T.object({expectedRevision:T.string(),force:T.boolean().default(!1),operation:T.discriminatedUnion("action",[dl,pl,fl,yl,hl,bl,gl,Tl,El,wl,Cl,Sl,Rl,Nl])}),Wr=T.object({db:T.string(),expectedRevision:T.string(),force:T.stringbool().default(!1)}),Al=T.object({deleted:T.boolean()})});var Ms=S(()=>{"use strict";h()});import{z as Vr}from"zod";var wn,Dl,_l,ks=S(()=>{"use strict";h();Ae();ln();wn=Vr.object({newColumnName:Vr.string("New column name is required")}),Dl=Ce,_l=Vr.object({db:L.shape.db,tableName:Ce.shape.tableName,columnName:Ce.shape.columnName,newColumnName:wn.shape.newColumnName})});import{z as Cn}from"zod";var Ht,Il,Ol,vs=S(()=>{"use strict";h();Ae();Ht=Cn.object({newTableName:Cn.string("New table name is required").trim().min(1,"New table name is required"),schemaName:Cn.string().trim().min(1).optional()}),Il=me,Ol=Cn.object({db:L.shape.db,tableName:me.shape.tableName,newTableName:Ht.shape.newTableName,schemaName:Ht.shape.schemaName})});import{z as Z}from"zod";var xl,Kt,$l,qs,Pl,Yr,Us=S(()=>{"use strict";h();Ae();xl=Z.object({columnName:Z.string(),operator:Z.string(),value:Z.string()}),Kt=["asc","desc"],$l=Z.object({columnName:Z.string(),direction:Z.enum(Kt)}),qs=Z.object({limit:Z.number(),total:Z.number(),hasNextPage:Z.boolean(),hasPreviousPage:Z.boolean(),nextCursor:Z.string().nullable(),prevCursor:Z.string().nullable()}),Pl=Z.object({data:Z.array(Z.record(Z.string(),Z.unknown())),meta:qs}),Yr=Z.object({db:L.shape.db,cursor:Z.string().optional(),limit:Z.string().optional().default("50").transform(Number),direction:Z.enum(Kt).optional().default(Kt[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(Kt).optional(),filters:Z.string().optional().transform(r=>{if(!r)return[];try{return JSON.parse(r)}catch{return[]}})})});import{z as Sn}from"zod";var Ll,Bs=S(()=>{"use strict";h();Ll=Sn.object({tableName:Sn.string("Table name is required"),schemaName:Sn.string().optional(),rowCount:Sn.coerce.number("Row count is required")})});import{z as Fs}from"zod";var Ml,js=S(()=>{"use strict";h();Ml=Fs.object({schema:Fs.string()})});import{z as Me}from"zod";var zr,Hs=S(()=>{"use strict";h();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 Ks={};on(Ks,{AI_PROVIDERS:()=>is,AI_PROVIDER_OPTIONS:()=>cs,DATABASE_ENGINES:()=>X,DATABASE_TYPES:()=>Tt,DataTypes:()=>M,FOREIGN_KEY_ACTIONS:()=>bs,FORMAT_TYPES:()=>Is,INDEX_KINDS:()=>xs,StandardizedDataType:()=>b,addColumnParamSchema:()=>Oc,addColumnParamsSchema:()=>xc,addColumnSchema:()=>Ue,addRecordSchema:()=>Tr,aiProviderSchema:()=>Er,alterColumnParamSchema:()=>Mc,alterColumnParamsSchema:()=>kc,alterColumnSchema:()=>Et,bulkInsertRecordsSchema:()=>Rr,chatSchema:()=>Nr,columnInfoSchema:()=>Fc,connectionInfoSchema:()=>Hc,createIndexParamsSchema:()=>Yc,createIndexSchema:()=>gn,createKeySchema:()=>Hr,createTableSchema:()=>Mr,currentDatabaseSchema:()=>_c,dataTypesSchema:()=>fs,databaseInfoSchema:()=>Cs,databaseListSchema:()=>jc,databaseSchema:()=>L,databaseTypeParamSchema:()=>Ic,databaseTypeSchema:()=>Bt,dbTypeFromProtocol:()=>St,deleteColumnParamSchema:()=>Ce,deleteColumnParamsSchema:()=>Pc,deleteColumnQuerySchema:()=>Sr,deleteColumnSuccessResponseSchema:()=>Lc,deleteKeyQuerySchema:()=>Wr,deleteKeyResultSchema:()=>Al,deleteRecordSchema:()=>bn,deleteTableQuerySchema:()=>kr,dropIndexParamSchema:()=>Tn,dropIndexParamsSchema:()=>zc,encodedRedisValueSchema:()=>W,executeQuerySchema:()=>vr,exportTableSchema:()=>qr,fieldDataSchema:()=>gs,filterSchema:()=>xl,foreignKeyActionSchema:()=>Lr,foreignKeyDataSchema:()=>Ts,getDefaultAiModel:()=>wr,indexInfoSchema:()=>Vc,keyActionSchema:()=>Kr,keyDetailsQuerySchema:()=>Fr,keyDetailsResultSchema:()=>rl,keyParamSchema:()=>Nt,keyRawQuerySchema:()=>jr,keyRawResultSchema:()=>al,keyScanQuerySchema:()=>Ur,keyScanResultSchema:()=>Gc,keyWriteResultSchema:()=>ml,mapClickhouseToDataType:()=>hn,mapDuckdbToDataType:()=>fn,mapMssqlToDataType:()=>dn,mapMysqlToDataType:()=>mn,mapOracleToDataType:()=>yn,mapPostgresToDataType:()=>un,mapSqliteToDataType:()=>pn,redisKeySummarySchema:()=>Br,redisKeyTypeSchema:()=>En,redisKeyValueSchema:()=>Ps,renameColumnParamSchema:()=>Dl,renameColumnParamsSchema:()=>_l,renameColumnSchema:()=>wn,renameTableParamSchema:()=>Il,renameTableParamsSchema:()=>Ol,renameTableSchema:()=>Ht,sortDirections:()=>Kt,sortSchema:()=>$l,standardizeClickhouseDataTypeLabel:()=>Pr,standardizeDataTypeLabel:()=>Dr,standardizeDuckdbDataTypeLabel:()=>xr,standardizeMssqlDataTypeLabel:()=>Ir,standardizeMysqlDataTypeLabel:()=>_r,standardizeOracleDataTypeLabel:()=>$r,standardizeSqliteDataTypeLabel:()=>Or,standardizedDataTypeSchema:()=>ys,tableDataMetaSchema:()=>qs,tableDataQuerySchema:()=>Yr,tableDataResultSchema:()=>Pl,tableInfoSchema:()=>Ll,tableNameSchema:()=>me,tableSchemaResultSchema:()=>Ml,unwrapClickhouseType:()=>Ct,updateRecordsSchema:()=>zr});var ie=S(()=>{"use strict";h();ss();os();Cr();ls();us();ms();ds();ps();hs();Ar();Es();Ae();ws();Ss();Rs();ln();Ns();As();_s();Os();$s();Ls();Ms();ks();vs();Us();Bs();js();Hs()});import{AsyncLocalStorage as Fl}from"async_hooks";import{randomUUID as Ys}from"crypto";import{HTTPException as zs}from"hono/http-exception";var jl,Hl,Gr,Gs,Qs,mt,Kl,Wl,Vl,Js,Qr,pe,ee,et=S(()=>{"use strict";h();jl=Ys(),Hl=/^[A-Za-z0-9_-]{8,64}$/,Gr=new Fl,Gs=r=>r&&Hl.test(r)?r:Ys(),Qs=(r,e)=>Gr.run(r,e),mt=()=>Gr.getStore()?.requestId,Kl=r=>{let e=r instanceof zs?"HTTPException":r instanceof Error?r.name:"Error";return/^[A-Za-z][A-Za-z0-9]{0,49}$/.test(e)?e:"Error"},Wl=/^[A-Z0-9_-]{2,32}$/,Vl=[[/^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"]],Js=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"&&Wl.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]:Vl.find(([s])=>s.test(r.message))?.[1]??Js(a)},Qr=r=>r instanceof zs&&r.cause?r.cause:r,pe=r=>{let e=Qr(r);return{error_type:Kl(e),error_code:Js(e)}},ee=(r,e,t={})=>{let n=Gr.getStore();process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:r,event:e,instance_id:jl,request_id:n?.requestId,operation:n?.operation,db_type:n?.dbType,...t})}
|
|
3
|
-
`)}});function
|
|
4
|
-
`).slice(1).filter(
|
|
5
|
-
`)}return n},
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
AND nspname NOT LIKE 'pg_temp%';`).catch(o=>{ee("warn","db_search_path_widen_failed",{db_type:"pg",...pe(o)})})}),a.on("error",s=>{ee("error","db_pool_error",{db_type:"pg",...pe(s)})}),this.pgPools.set(t,a)}return this.pgPools.get(t)??new lo({connectionString:t})}getMysqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mysqlPools.has(t)){let a=new URL(t).pathname.slice(1),s=Eu({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(t,s)}return this.mysqlPools.get(t)}async getMssqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mssqlPools.has(t)){let a=new URL(t).pathname.slice(1),s={server:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},o=await new Tu.ConnectionPool(s).connect();o.on("error",c=>{ee("error","db_pool_error",{db_type:"mssql",...pe(c)})}),this.mssqlPools.set(t,o)}return this.mssqlPools.get(t)}getClickhouseClient(e){let t=new URL(this.buildConnectionString(e)),n=decodeURIComponent(t.pathname.slice(1))||"default",a=this.clickhouseClients.get(n);if(a)return a;let s=t.protocol==="clickhouses:",o=fu({url:`${s?"https":"http"}://${t.hostname}:${t.port||(s?8443:8123)}`,username:decodeURIComponent(t.username)||"default",password:decodeURIComponent(t.password),database:n,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:pu.OFF}});return this.clickhouseClients.set(n,o),o}getPool(e){return this.getPgPool(e)}async closePgPool(e){let t=this.pgPools.get(e);t&&(await t.end(),this.pgPools.delete(e),ee("info","db_pool_closed",{db_type:"pg"}))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e),ee("info","db_pool_closed",{db_type:"mysql"}))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e),ee("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){if(!this.baseConfig)throw new Error("Base configuration not initialized");let e=new gu(this.baseConfig.url);try{await e.connect(),this.mongoClient=e}catch(t){try{await e.close()}catch{}throw t}}return this.mongoClient}getMongoDbName(){if(!this.baseConfig)throw new Error("Base configuration not initialized");let e=new URL(this.baseConfig.url).pathname.replace(/^\/+|\/+$/g,"");try{return decodeURIComponent(e)||"admin"}catch{return e||"admin"}}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType!=="redis")throw new Error("DATABASE_URL is not a redis:// connection");let t=e??this.getRedisDefaultDb(),n=this.redisClients.get(t);if(n)return n;let a=new URL(this.baseConfig.url),s={host:this.baseConfig.host,port:this.baseConfig.port,db:t,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};this.baseConfig.user&&(s.username=decodeURIComponent(this.baseConfig.user)),this.baseConfig.password&&(s.password=decodeURIComponent(this.baseConfig.password)),a.protocol==="rediss:"&&(s.tls={});let o=new bu(s);try{if(await o.connect(),!this.redisClusterChecked){let c=await o.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(c))throw await o.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let i=c.match(/^redis_version:([^\r\n]+)/m)?.[1],[l=0,u=0]=i?.split(".").map(Number)??[];if(l<6||l===6&&u<2)throw await o.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${i??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(c){throw await o.quit().catch(()=>{}),c}return this.redisClients.set(t,o),o}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(),ee("info","db_pool_closed",{db_type:"pg"})}),t=Array.from(this.mysqlPools.values()).map(async s=>{await s.end(),ee("info","db_pool_closed",{db_type:"mysql"})}),n=Array.from(this.mssqlPools.values()).map(async s=>{await s.close(),ee("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(()=>{}),ee("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())]}},_e=new sa,On=r=>_e.getPgPool(r),xn=r=>_e.getMysqlPool(r),$n=async r=>_e.getMssqlPool(r),Pn=r=>_e.getClickhouseClient(r),st=()=>_e.getDbType(),Ln=()=>_e.getSqliteClient(),Mn=r=>_e.withDuckdbConnection(r),kn=()=>_e.getOraclePool(),vn=()=>_e.getMongoClient(),qn=()=>_e.getMongoDbName(),uo=r=>_e.getMongoDb(r),Un=r=>_e.getRedisClient(r),mo=r=>_e.getIsolatedRedisClient(r),po=()=>_e.getRedisDefaultDb(),Bn=r=>typeof r=="string"&&aa.isValid(r),Fn=r=>typeof r=="string"&&aa.isValid(r)?new aa(r):r});var fo={};on(fo,{checkDatabaseConnection:()=>Nu,getDatabaseConnectionDetails:()=>Ru});var Su,oa,Ru,Nu,yo=S(()=>{"use strict";h();ie();pt();We();Su=2e3,oa=async r=>{let e;try{return await Promise.race([r,new Promise((t,n)=>{e=setTimeout(()=>n(new Error("Database startup check timed out")),Su)})])}finally{e&&clearTimeout(e)}},Ru=r=>{let e=st(),{label:t,defaultPort:n}=X[e];if(r.startsWith("sqlite://"))return{type:e,name:t,destination:"local file"};if(n===null)return{type:e,name:t,destination:new URL(r).host};let{host:a,port:s}=De(r);return{type:e,name:t,destination:`${a}:${s}`}},Nu=async r=>{switch(r){case"pg":await oa(On().query("SELECT 1"));return;case"mysql":await xn().query("SELECT 1");return;case"mssql":await(await $n()).request().query("SELECT 1");return;case"mongodb":{await(await vn()).db(qn()).command({ping:1});return}case"sqlite":await oa(Ln().then(e=>e.execute("SELECT 1")));return;case"redis":await(await Un()).ping();return;case"duckdb":await Mn(e=>e.run("SELECT 1"));return;case"oracle":{let e=await(await kn()).getConnection();await e.execute("SELECT 1 FROM dual").finally(()=>e.close());return}case"clickhouse":await oa(Pn().query({query:"SELECT 1"}))}}});import{HTTPException as ho}from"hono/http-exception";function B(r){return Ee.get(r)}function ft(r,e){if(!Au(r))throw new ho(400,{message:`Key browsing is not supported for database type: "${e}"`});return r}var ia,Ee,Au,tt=S(()=>{"use strict";h();ia=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new ho(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()]}},Ee=new ia;Au=r=>"scanKeys"in r&&typeof r.scanKeys=="function"});import{HTTPException as je}from"hono/http-exception";import{DatabaseError as Du}from"pg";function fe(r){throw new je(501,{message:`${r} is not implemented for this database type`})}function ca(){throw new je(400,{message:"Indexes are not supported for this database type"})}var le,Ve=S(()=>{"use strict";h();le=class{assertDeletableKey(e){if(e.length>1)throw new je(400,{message:"Deleting rows from tables with a composite primary key is not supported yet."})}wrapError(e){if(e instanceof je)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."||e instanceof Du&&e.code?.startsWith("08")?new je(503,{message:e.message,cause:e}):new je(500,{message:e.message,cause:e})}return new je(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 je(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(i=>{let l=a.rowData[i];if(l==null)throw new je(400,{message:`Primary key "${i}" not found in row data.`});return l}),o=JSON.stringify(s.map(i=>String(i))),c=n.get(o)??{keyValues:s,rowUpdates:[]};c.rowUpdates.push({columnName:a.columnName,value:a.value}),n.set(o,c)}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(c=>c.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 je(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=await this.runQuery(t,s.countSql,s.countValues),c=Number(o[0]?.total??0),i=await this.runQuery(t,s.sql,s.values),l=i.length>n;l&&(i=i.slice(0,n));let u=this.normalizeRows(i);a==="desc"&&(u=u.reverse());let{nextCursor:m,prevCursor:d}=this.buildCursors(e,u,l);return{data:u,meta:{limit:n,total:c,hasNextPage:a==="asc"?l:!!e.cursor,hasPreviousPage:a==="asc"?!!e.cursor:l,nextCursor:m,prevCursor:d}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let n=`SELECT * FROM ${this.quoteIdentifier(e)}`,a=await this.runQuery(t,n,[]);if(!a||a.length===0)throw new je(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 fe("getDatabasesList")}getCurrentDatabase(){return fe("getCurrentDatabase")}getDatabaseConnectionInfo(){return fe("getDatabaseConnectionInfo")}getTablesList(e){return fe("getTablesList")}createTable(e){return fe("createTable")}deleteTable(e){return fe("deleteTable")}renameTable(e){return fe("renameTable")}getTableSchema(e){return fe("getTableSchema")}getTableColumns(e){return fe("getTableColumns")}addColumn(e){return fe("addColumn")}deleteColumn(e){return fe("deleteColumn")}alterColumn(e){return fe("alterColumn")}renameColumn(e){return fe("renameColumn")}getTableIndexes(e){return ca()}createIndex(e){return ca()}dropIndex(e){return ca()}addRecord(e){return fe("addRecord")}updateRecords(e){return fe("updateRecords")}deleteRecords(e){return fe("deleteRecords")}forceDeleteRecords(e){return fe("forceDeleteRecords")}bulkInsertRecords(e){return fe("bulkInsertRecords")}executeQuery(e){return fe("executeQuery")}}});var te,Q,G,re,la,ua,ma,jn,ce,Ie,Hn,yt,Yt,Ye=S(()=>{"use strict";h();pt();te=r=>On(r),Q=r=>xn(r),G=r=>$n(r),re=()=>Ln(),la=r=>Mn(r),ua=()=>kn(),ma=()=>vn(),jn=()=>qn(),ce=r=>uo(r),Ie=r=>Un(r),Hn=r=>mo(r),yt=()=>po(),Yt=r=>Pn(r)});function bo(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 c=da(a);switch(s){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${c} ${s} ${n(o)}`);break;case"is":e.push(o.toLowerCase()==="null"?`${c} IS NULL`:`${c} = ${n(o)}`);break;case"is not":e.push(o.toLowerCase()==="null"?`${c} IS NOT NULL`:`${c} != ${n(o)}`);break;case"like":e.push(`toString(${c}) LIKE ${n(o)}`);break;case"not like":e.push(`toString(${c}) NOT LIKE ${n(o)}`);break;case"ilike":e.push(`toString(${c}) ILIKE ${n(o)}`);break;case"not ilike":e.push(`toString(${c}) NOT ILIKE ${n(o)}`);break}}return{clause:e.length?`WHERE ${e.join(" AND ")}`:"",values:t}}function go(r,e,t){let n=Array.isArray(r)?r:r?[{columnName:r,direction:e}]:[],a=(n[0]?.direction??e).toUpperCase(),s=[...n.map(o=>`${da(o.columnName)} ${o.direction.toUpperCase()}`),...t.map(o=>`${o} ${a}`)];return s.length?`ORDER BY ${s.join(", ")}`:""}function _u(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 Kn(r,e){let t=da(r.columnName);if(r.isIdentity||/serial/i.test(r.columnType))return`${t} UInt64 DEFAULT generateSnowflakeID()`;let n=_u(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 ${Iu[o.toLowerCase()]??o}`),s}var ue,da,Iu,To=S(()=>{"use strict";h();ue=r=>`\`${r.replaceAll("\\","\\\\").replaceAll("`","\\`")}\``,da=ue;Iu={"now()":"now()",current_timestamp:"now()","current_timestamp()":"now()",current_date:"today()","gen_random_uuid()":"generateUUIDv4()","uuid_generate_v4()":"generateUUIDv4()"}});import{HTTPException as ye}from"hono/http-exception";var Ou,Eo,xu,Wn,wo=S(()=>{"use strict";h();ie();Ve();Ye();We();To();Ou={mutations_sync:"2"},Eo=r=>/^(LowCardinality\()?Nullable\(/.test(r),xu=(r,e)=>{if(r==null)return null;let t=Ct(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 ye(400,{message:`Invalid ${t} value: ${r}`})}return typeof r=="object"&&t==="String"?JSON.stringify(r):r},Wn=class extends le{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 ue(e)}mapToUniversalType(e){return hn(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),c=o.sorting_key?[`(${o.sorting_key})`]:[];o.engine.endsWith("MergeTree")&&c.push("_part","_part_offset");let i=this.buildPageQuery(e,c),[l,u]=await Promise.all([this.runQuery(t,i.countSql,i.countValues),this.runQuery(t,i.sql,i.values)]),m=u.length>a,d=this.normalizeRows(m?u.slice(0,a):u),p=s?this.decodeOffsetCursor(s):0;return{data:d,meta:{limit:a,total:Number(l[0]?.total??0),hasNextPage:m,hasPreviousPage:p>0,...this.buildCursors(e,d,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
|
|
2
|
+
var Nc=Object.defineProperty;var N=(r,e)=>()=>(r&&(e=r(r=0)),e);var Kt=(r,e)=>{for(var t in e)Nc(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.19.0"}}catch{}})()});var Za=N(()=>{"use strict";y()});var es=N(()=>{"use strict";y()});var ts=N(()=>{"use strict";y()});var rs,ns,Ze,as=N(()=>{"use strict";y();rs=globalThis.process?.env,ns=rs?.NODE_ENV,Ze={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:ns==="development",PROXY_URL:rs?.DB_STUDIO_PROXY_URL??(ns==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var ss=N(()=>{"use strict";y()});var os,hr=N(()=>{"use strict";y();os={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 is=N(()=>{"use strict";y()});var Ht=N(()=>{"use strict";y();Za();es();ts();as();ss();hr();is()});import{z as mt}from"zod";var K,U,Ct,jt,vc,Uc,oe,Ne=N(()=>{"use strict";y();K=mt.object({db:mt.string("Database name is required")}),U=K.extend({schemaName:mt.string().optional()}),Ct=["pg","mysql","mssql","mongodb","sqlite","redis","duckdb","oracle","clickhouse"],jt=mt.enum(Ct,{message:"Invalid database type"}),vc=K.extend({dbType:jt}),Uc=mt.object({dbType:jt}),oe=mt.object({tableName:mt.string("Table name is required")})});import{z as Ke}from"zod";var ve,qc,Bc,fs=N(()=>{"use strict";y();Ne();ve=Ke.object({columnName:Ke.string("Column name is required"),columnType:Ke.string("Column type is required"),defaultValue:Ke.string().optional(),isPrimaryKey:Ke.boolean().default(!1),isNullable:Ke.boolean().default(!1),isUnique:Ke.boolean().default(!1),isIdentity:Ke.boolean().default(!1),isArray:Ke.boolean().default(!1)}),qc=oe,Bc=Ke.object({db:K.shape.db,tableName:oe.shape.tableName,schemaName:U.shape.schemaName,columnName:ve.shape.columnName,columnType:ve.shape.columnType,defaultValue:ve.shape.defaultValue,isPrimaryKey:ve.shape.isPrimaryKey,isNullable:ve.shape.isNullable,isUnique:ve.shape.isUnique,isIdentity:ve.shape.isIdentity,isArray:ve.shape.isArray})});import{z as Wt}from"zod";var wr,ys=N(()=>{"use strict";y();wr=Wt.object({tableName:Wt.string("Table name is required"),data:Wt.record(Wt.string("Column name is required"),Wt.any())})});import{z as Fc}from"zod";var hs,Sr,gs,Cr,Rr=N(()=>{"use strict";y();hs=["gemini","openai","anthropic","grok","openrouter"],Sr=Fc.enum(hs),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"}]}],Cr=r=>gs.find(e=>e.id===r)?.models[0]?.id??"gemini-3-flash-preview"});import{z as Ue}from"zod";var Nr,Te,Kc,Hc,Rn=N(()=>{"use strict";y();Ne();Nr=U.extend({cascade:Ue.string().optional().transform(r=>r==="true")}),Te=Ue.object({tableName:Ue.string("Table name is required"),columnName:Ue.string("Column name is required")}),Kc=Ue.object({db:K.shape.db,tableName:Te.shape.tableName,schemaName:U.shape.schemaName,columnName:Te.shape.columnName,cascade:Ue.boolean().optional()}),Hc=Ue.object({message:Ue.string("Message is required"),tableName:Ue.string("Table name is required"),columnName:Ue.string("Column name is required"),deletedCount:Ue.number("Deleted count is required").default(0)})});import{z as Vt}from"zod";var Rt,jc,Wc,bs=N(()=>{"use strict";y();Ne();Rn();Rt=Vt.object({columnType:Vt.string("Column type is required"),isNullable:Vt.boolean(),defaultValue:Vt.string().nullable().optional()}),jc=Te,Wc=Vt.object({db:K.shape.db,tableName:Te.shape.tableName,schemaName:U.shape.schemaName,columnName:Te.shape.columnName,columnType:Rt.shape.columnType,isNullable:Rt.shape.isNullable,defaultValue:Rt.shape.defaultValue})});var Ts=N(()=>{"use strict";y()});import{z as Nt}from"zod";var Ar,Es=N(()=>{"use strict";y();Ar=Nt.object({tableName:Nt.string().min(1,"Table name is required"),records:Nt.array(Nt.record(Nt.string(),Nt.any())).min(1,"At least one record is required")})});import{z as de}from"zod";var Vc,Yc,Dr,ws=N(()=>{"use strict";y();Rr();Ne();Vc=de.object({type:de.string(),content:de.string().optional()}).passthrough(),Yc=de.object({provider:Sr.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(Vc).optional()}).passthrough()),data:de.object({conversationId:de.string().optional(),db:K.shape.db,includeSchema:de.boolean().optional().default(!0)})}),Dr=Yc.transform(r=>({...r,model:r.model??Cr(r.provider)}))});var Ss=N(()=>{"use strict";y()});import{z as Oe}from"zod";var zc,Cs,P,Gc,Rs,Qc,_r=N(()=>{"use strict";y();zc=["text","boolean","number","enum","json","date","array"],Cs=Oe.enum(zc),P={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},Gc=["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"],Rs=Oe.enum(Gc),Qc=Oe.object({columnName:Oe.string(),dataType:Cs,dataTypeLabel:Rs,isNullable:Oe.boolean(),columnDefault:Oe.string().nullable(),isPrimaryKey:Oe.boolean(),isForeignKey:Oe.boolean(),referencedTable:Oe.string().nullable(),referencedSchema:Oe.string().optional(),referencedColumn:Oe.string().nullable(),enumValues:Oe.array(Oe.string()).nullable()})});function Nn(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(")?P.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"?P.number:e==="boolean"||e==="bool"?P.boolean:e==="json"||e==="jsonb"?P.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?P.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"?P.text:P.text}function Or(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 An(r,e){let t=r?.toLowerCase().trim()||"",n=e?.toLowerCase().trim()||"";return t==="tinyint"&&n==="tinyint(1)"?P.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"?P.number:t==="boolean"||t==="bool"?P.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?P.date:t==="json"?P.json:t==="enum"||t==="set"?P.enum:P.text}function Ir(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 Dn(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"?P.number:e==="bit"?P.boolean:e==="date"||e==="datetime"||e==="datetime2"||e==="smalldatetime"||e==="time"||e==="datetimeoffset"?P.date:e==="json"?P.json:P.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 _n(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"||e==="bool"?P.boolean:e==="json"?P.json:e==="date"||e==="datetime"||e==="timestamp"||e==="time"?P.date:e.includes("int")||e==="real"||e.includes("floa")||e.includes("doub")||e==="numeric"||e.startsWith("numeric(")||e==="decimal"||e.startsWith("decimal(")?P.number:P.text}function xr(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 On(r){let e=r?.toLowerCase().trim()||"";return e.endsWith("]")||e.startsWith("struct")||e.startsWith("map")||e.startsWith("union")||e==="json"?P.json:e==="boolean"||e==="bool"?P.boolean:e.startsWith("enum")?P.enum:e==="interval"?P.text:e==="date"||e.startsWith("time")||e==="datetime"?P.date:e.includes("int")||e==="float"||e==="real"||e==="double"||e.startsWith("decimal")||e.startsWith("numeric")||e==="bignum"?P.number:P.text}function Pr(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 In(r){let e=r?.toLowerCase().trim()||"";return e==="boolean"?P.boolean:e==="json"?P.json:e==="date"||e.startsWith("timestamp")?P.date:e.startsWith("number")||e.startsWith("float")||e==="integer"||e==="binary_float"||e==="binary_double"?P.number:P.text}function $r(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 At(r){let e=r.trim();for(;;){let t=e.match(/^(?:Nullable|LowCardinality)\((.*)\)$/);if(!t?.[1])return e;e=t[1].trim()}}function Ln(r){let e=At(r);return e.startsWith("Array(")?P.array:e.startsWith("Enum8(")||e.startsWith("Enum16(")?P.enum:e==="Bool"?P.boolean:/^(Date|Date32|DateTime|DateTime64|Time|Time64)\b/.test(e)?P.date:/^(U?Int\d+|Float\d+|BFloat16|Decimal\d*)\b/.test(e)?P.number:/^(JSON|Object|Map|Tuple|Variant|Dynamic|Nested)\b/.test(e)?P.json:P.text}function Mr(r){let e=At(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,Ns=N(()=>{"use strict";y();_r();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 pe}from"zod";var As,kr,Ds,_s,vr,Os=N(()=>{"use strict";y();As=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],kr=pe.enum(As),Ds=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)}),_s=pe.object({columnName:pe.string("Column name is required"),referencedTable:pe.string("Referenced table is required"),referencedColumn:pe.string("Referenced column is required"),onUpdate:kr.default("NO ACTION"),onDelete:kr.default("NO ACTION")}),vr=pe.object({tableName:pe.string("Table name is required"),fields:pe.array(Ds).min(1,"At least one field is required"),foreignKeys:pe.array(_s).optional()})});var G,Dt,Is=N(()=>{"use strict";y();Ne();G={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}},Dt=r=>Ct.find(e=>G[e].protocols.includes(r))});import{z as Ee}from"zod";var Ls,Jc,Xc,xs=N(()=>{"use strict";y();Ne();Ls=Ee.object({name:Ee.string("Name is required"),size:Ee.string("Size is required"),owner:Ee.string("Owner is required"),encoding:Ee.string("Encoding is required")}),Jc=Ee.object({databases:Ee.array(Ls),dbType:jt}),Xc=Ee.object({version:Ee.string("Version is required"),database:Ee.string("Database is required"),user:Ee.string("User is required"),host:Ee.string("Host is required").nullable(),port:Ee.number("Port is required").nullable(),active_connections:Ee.coerce.number("Active connections is required"),max_connections:Ee.coerce.number("Max connections is required")})});var Ps=N(()=>{"use strict";y()});import{z as _t}from"zod";var xn,$s=N(()=>{"use strict";y();xn=_t.object({tableName:_t.string("Table name is required"),primaryKeys:_t.array(_t.object({columnName:_t.string("Column name is required"),value:_t.any()})).min(1,"At least one primary key is required")})});import{z as Zc}from"zod";var Ur,Ms=N(()=>{"use strict";y();Ne();Ur=U.extend({cascade:Zc.string().optional().transform(r=>r==="true")})});import{z as ks}from"zod";var qr,vs=N(()=>{"use strict";y();qr=ks.object({query:ks.string("Query is required")})});import{z as el}from"zod";var Us,Br,qs=N(()=>{"use strict";y();Ne();Us=["csv","xlsx","json"],Br=U.extend({format:el.enum(Us,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as ie}from"zod";var Bs,tl,Pn,nl,$n,rl,Fs=N(()=>{"use strict";y();Ne();Bs=["primary","unique-constraint","index"],tl=ie.object({indexName:ie.string(),columns:ie.array(ie.string()),isUnique:ie.boolean(),isSparse:ie.boolean().optional(),expireAfterSeconds:ie.number().nonnegative().optional(),method:ie.string().nullable(),kind:ie.enum(Bs),definition:ie.string().nullable()}),Pn=ie.object({indexName:ie.string().min(1),columns:ie.array(ie.string().min(1)).min(1),isUnique:ie.boolean(),method:ie.string().optional()}),nl=Pn.extend({db:K.shape.db,tableName:oe.shape.tableName,schemaName:U.shape.schemaName}),$n=ie.object({tableName:ie.string("Table name is required"),indexName:ie.string("Index name is required")}),rl=$n.extend({db:K.shape.db,schemaName:U.shape.schemaName})});import{z as E}from"zod";var Mn,q,Fr,Kr,al,Hr,Ot,sl,ol,il,cl,ll,ul,ml,Ks,dl,jr,pl,fl,yl,hl,gl,bl,Tl,Wr,El,wl,Sl,Cl,Rl,Nl,Al,Dl,_l,Ol,Il,Ll,xl,Pl,$l,Vr,Yr,Ml,Hs=N(()=>{"use strict";y();Mn=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()}),Fr=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:Mn.exclude(["unknown"]).optional()}),Kr=E.object({key:q,type:Mn,ttlMs:E.number().int(),memoryBytes:E.number().int().nonnegative().nullable()}),al=E.object({keys:E.array(Kr),nextCursor:E.string().nullable(),hasMore:E.boolean()}),Hr=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")}),Ot=E.object({key:E.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),sl=E.object({kind:E.literal("string"),value:q,truncated:E.boolean()}),ol=E.object({kind:E.literal("hash"),entries:E.array(E.object({field:q,value:q}))}),il=E.object({kind:E.literal("list"),entries:E.array(E.object({index:E.number().int(),value:q}))}),cl=E.object({kind:E.literal("set"),members:E.array(q)}),ll=E.object({kind:E.literal("zset"),entries:E.array(E.object({member:q,score:E.union([E.number(),E.literal("inf"),E.literal("-inf")])}))}),ul=E.object({kind:E.literal("stream"),entries:E.array(E.object({id:E.string(),fields:E.array(E.object({field:q,value:q}))}))}),ml=E.object({kind:E.literal("unknown")}),Ks=E.discriminatedUnion("kind",[sl,ol,il,cl,ll,ul,ml]),dl=Kr.extend({length:E.number().int().nonnegative().nullable(),revision:E.string(),value:Ks,nextCursor:E.string().nullable(),hasMore:E.boolean()}),jr=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()}),pl=E.object({chunk:q,length:E.number().int().nonnegative(),nextOffset:E.number().int().nonnegative().nullable(),hasMore:E.boolean()}),fl=E.object({kind:E.literal("string"),value:q}),yl=E.object({kind:E.literal("hash"),entries:E.array(E.object({field:q,value:q})).min(1)}),hl=E.object({kind:E.literal("list"),entries:E.array(q).min(1)}),gl=E.object({kind:E.literal("set"),members:E.array(q).min(1)}),bl=E.object({kind:E.literal("zset"),entries:E.array(E.object({member:q,score:E.number()})).min(1)}),Tl=E.object({kind:E.literal("stream"),id:E.string().default("*"),fields:E.array(E.object({field:q,value:q})).min(1)}),Wr=E.object({key:q,type:Mn.exclude(["unknown"]),value:E.discriminatedUnion("kind",[fl,yl,hl,gl,bl,Tl]),ttlMs:E.number().int().positive().nullable().default(null)}),El=E.object({key:q,revision:E.string().nullable(),deleted:E.boolean()}),wl=E.object({action:E.literal("rename"),newKey:q}),Sl=E.object({action:E.literal("setTtl"),ttlMs:E.number().int().positive().nullable()}),Cl=E.object({action:E.literal("setString"),value:q}),Rl=E.object({action:E.literal("upsertHash"),field:q,value:q}),Nl=E.object({action:E.literal("deleteHash"),field:q}),Al=E.object({action:E.literal("pushList"),side:E.enum(["left","right"]),value:q}),Dl=E.object({action:E.literal("setList"),index:E.number().int(),value:q}),_l=E.object({action:E.literal("deleteList"),index:E.number().int()}),Ol=E.object({action:E.literal("addSet"),member:q}),Il=E.object({action:E.literal("removeSet"),member:q}),Ll=E.object({action:E.literal("upsertZset"),member:q,score:E.number()}),xl=E.object({action:E.literal("removeZset"),member:q}),Pl=E.object({action:E.literal("appendStream"),id:E.string().default("*"),fields:E.array(E.object({field:q,value:q})).min(1)}),$l=E.object({action:E.literal("deleteStream"),id:E.string()}),Vr=E.object({expectedRevision:E.string(),force:E.boolean().default(!1),operation:E.discriminatedUnion("action",[wl,Sl,Cl,Rl,Nl,Al,Dl,_l,Ol,Il,Ll,xl,Pl,$l])}),Yr=E.object({db:E.string(),expectedRevision:E.string(),force:E.stringbool().default(!1)}),Ml=E.object({deleted:E.boolean()})});var js=N(()=>{"use strict";y()});import{z as zr}from"zod";var kn,kl,vl,Ws=N(()=>{"use strict";y();Ne();Rn();kn=zr.object({newColumnName:zr.string("New column name is required")}),kl=Te,vl=zr.object({db:K.shape.db,tableName:Te.shape.tableName,schemaName:U.shape.schemaName,columnName:Te.shape.columnName,newColumnName:kn.shape.newColumnName})});import{z as vn}from"zod";var Yt,Ul,ql,Vs=N(()=>{"use strict";y();Ne();Yt=vn.object({newTableName:vn.string("New table name is required").trim().min(1,"New table name is required"),schemaName:vn.string().trim().min(1).optional()}),Ul=oe,ql=vn.object({db:K.shape.db,tableName:oe.shape.tableName,newTableName:Yt.shape.newTableName,schemaName:Yt.shape.schemaName})});import{z as Pe}from"zod";var Ys,zs,Bl,Gs=N(()=>{"use strict";y();Ys=["fatal","error","warning","info","debug"],zs=Pe.enum(Ys),Bl=Pe.object({ts:Pe.string(),level:zs,rawLevel:Pe.string(),source:Pe.string().optional(),code:Pe.string().optional(),message:Pe.string(),durationMs:Pe.number().optional(),statement:Pe.string().optional(),detail:Pe.record(Pe.string(),Pe.string())})});import{z as Y}from"zod";var Fl,zt,Kl,Qs,Hl,Gr,Js=N(()=>{"use strict";y();Ne();Fl=Y.object({columnName:Y.string(),operator:Y.string(),value:Y.string()}),zt=["asc","desc"],Kl=Y.object({columnName:Y.string(),direction:Y.enum(zt)}),Qs=Y.object({limit:Y.number(),total:Y.number(),totalEstimated:Y.boolean().optional(),hasNextPage:Y.boolean(),hasPreviousPage:Y.boolean(),nextCursor:Y.string().nullable(),prevCursor:Y.string().nullable()}),Hl=Y.object({data:Y.array(Y.record(Y.string(),Y.unknown())),meta:Qs}),Gr=Y.object({db:K.shape.db,schemaName:U.shape.schemaName,cursor:Y.string().optional(),limit:Y.string().optional().default("50").transform(Number),direction:Y.enum(zt).optional().default(zt[0]),sort:Y.string().optional().transform(r=>{if(!r)return"";try{let e=JSON.parse(r);return Array.isArray(e)?e:r}catch{return r}}),order:Y.enum(zt).optional(),filters:Y.string().optional().transform(r=>{if(!r)return[];try{return JSON.parse(r)}catch{return[]}})})});import{z as Gt}from"zod";var jl,Xs=N(()=>{"use strict";y();jl=Gt.object({tableName:Gt.string("Table name is required"),schemaName:Gt.string().optional(),rowCount:Gt.coerce.number("Row count is required"),rowCountEstimated:Gt.boolean().optional()})});import{z as Zs}from"zod";var Wl,eo=N(()=>{"use strict";y();Wl=Zs.object({schema:Zs.string()})});import{z as $e}from"zod";var Qr,to=N(()=>{"use strict";y();Qr=$e.object({tableName:$e.string("Table name is required"),primaryKey:$e.string("Primary key is required").default("id"),primaryKeys:$e.array($e.string().min(1)).min(1).optional(),updates:$e.array($e.object({rowData:$e.record($e.string("Column name is required"),$e.any()),columnName:$e.string("Column name is required"),value:$e.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var no={};Kt(no,{AI_PROVIDERS:()=>hs,AI_PROVIDER_OPTIONS:()=>gs,DATABASE_ENGINES:()=>G,DATABASE_TYPES:()=>Ct,DataTypes:()=>P,FOREIGN_KEY_ACTIONS:()=>As,FORMAT_TYPES:()=>Us,INDEX_KINDS:()=>Bs,SERVER_LOG_LEVELS:()=>Ys,StandardizedDataType:()=>T,addColumnParamSchema:()=>qc,addColumnParamsSchema:()=>Bc,addColumnSchema:()=>ve,addRecordSchema:()=>wr,aiProviderSchema:()=>Sr,alterColumnParamSchema:()=>jc,alterColumnParamsSchema:()=>Wc,alterColumnSchema:()=>Rt,bulkInsertRecordsSchema:()=>Ar,chatSchema:()=>Dr,columnInfoSchema:()=>Qc,connectionInfoSchema:()=>Xc,createIndexParamsSchema:()=>nl,createIndexSchema:()=>Pn,createKeySchema:()=>Wr,createTableSchema:()=>vr,currentDatabaseSchema:()=>vc,dataTypesSchema:()=>Cs,databaseInfoSchema:()=>Ls,databaseListSchema:()=>Jc,databaseSchema:()=>K,databaseTypeParamSchema:()=>Uc,databaseTypeSchema:()=>jt,dbTypeFromProtocol:()=>Dt,deleteColumnParamSchema:()=>Te,deleteColumnParamsSchema:()=>Kc,deleteColumnQuerySchema:()=>Nr,deleteColumnSuccessResponseSchema:()=>Hc,deleteKeyQuerySchema:()=>Yr,deleteKeyResultSchema:()=>Ml,deleteRecordSchema:()=>xn,deleteTableQuerySchema:()=>Ur,dropIndexParamSchema:()=>$n,dropIndexParamsSchema:()=>rl,encodedRedisValueSchema:()=>q,executeQuerySchema:()=>qr,exportTableSchema:()=>Br,fieldDataSchema:()=>Ds,filterSchema:()=>Fl,foreignKeyActionSchema:()=>kr,foreignKeyDataSchema:()=>_s,getDefaultAiModel:()=>Cr,indexInfoSchema:()=>tl,keyActionSchema:()=>Vr,keyDetailsQuerySchema:()=>Hr,keyDetailsResultSchema:()=>dl,keyParamSchema:()=>Ot,keyRawQuerySchema:()=>jr,keyRawResultSchema:()=>pl,keyScanQuerySchema:()=>Fr,keyScanResultSchema:()=>al,keyWriteResultSchema:()=>El,mapClickhouseToDataType:()=>Ln,mapDuckdbToDataType:()=>On,mapMssqlToDataType:()=>Dn,mapMysqlToDataType:()=>An,mapOracleToDataType:()=>In,mapPostgresToDataType:()=>Nn,mapSqliteToDataType:()=>_n,redisKeySummarySchema:()=>Kr,redisKeyTypeSchema:()=>Mn,redisKeyValueSchema:()=>Ks,renameColumnParamSchema:()=>kl,renameColumnParamsSchema:()=>vl,renameColumnSchema:()=>kn,renameTableParamSchema:()=>Ul,renameTableParamsSchema:()=>ql,renameTableSchema:()=>Yt,serverLogEntrySchema:()=>Bl,serverLogLevelSchema:()=>zs,sortDirections:()=>zt,sortSchema:()=>Kl,standardizeClickhouseDataTypeLabel:()=>Mr,standardizeDataTypeLabel:()=>Or,standardizeDuckdbDataTypeLabel:()=>Pr,standardizeMssqlDataTypeLabel:()=>Lr,standardizeMysqlDataTypeLabel:()=>Ir,standardizeOracleDataTypeLabel:()=>$r,standardizeSqliteDataTypeLabel:()=>xr,standardizedDataTypeSchema:()=>Rs,tableDataMetaSchema:()=>Qs,tableDataQuerySchema:()=>Gr,tableDataResultSchema:()=>Hl,tableInfoSchema:()=>jl,tableNameSchema:()=>oe,tableQuerySchema:()=>U,tableSchemaResultSchema:()=>Wl,unwrapClickhouseType:()=>At,updateRecordsSchema:()=>Qr});var ee=N(()=>{"use strict";y();fs();ys();Rr();bs();Ts();Es();ws();Ss();Ns();_r();Os();Ne();Is();xs();Ps();Rn();$s();Ms();vs();qs();Fs();Hs();js();Ws();Vs();Gs();Js();Xs();eo();to()});var d,ce=N(()=>{"use strict";y();d=class extends Error{constructor(t,{message:n,cause:a}={}){super(n,{cause:a});this.status=t}}});import{AsyncLocalStorage as Jl}from"async_hooks";import{randomUUID as so}from"crypto";var Xl,Zl,Jr,oo,io,et,eu,tu,nu,co,Xr,le,Q,tt=N(()=>{"use strict";y();ce();Xl=so(),Zl=/^[A-Za-z0-9_-]{8,64}$/,Jr=new Jl,oo=r=>r&&Zl.test(r)?r:so(),io=(r,e)=>Jr.run(r,e),et=()=>Jr.getStore()?.requestId,eu=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"},tu=/^[A-Z0-9_-]{2,32}$/,nu=[[/^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"]],co=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"&&tu.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]:nu.find(([s])=>s.test(r.message))?.[1]??co(a)},Xr=r=>r instanceof d&&r.cause?r.cause:r,le=r=>{let e=Xr(r);return{error_type:eu(e),error_code:co(e)}},Q=(r,e,t={})=>{let n=Jr.getStore();process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:r,event:e,instance_id:Xl,request_id:n?.requestId,operation:n?.operation,db_type:n?.dbType,...t})}
|
|
3
|
+
`)}});function Ae(r=process.env.DATABASE_URL){if(!r)return{host:"localhost",port:5432};try{let e=new URL(r);return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||ru(e)}}catch(e){return Q("error","database_url_unparseable",le(e)),{host:"localhost",port:5432}}}var Un,ru,lo,He=N(()=>{"use strict";y();ee();tt();Un={cockroachdb:{driverScheme:"postgresql",defaultPort:26257},mariadb:{driverScheme:"mysql",defaultPort:3306},tidb:{driverScheme:"mysql",defaultPort:4e3}},ru=r=>{let e=r.protocol.replace(":",""),t=Dt(e);return Un[e]?.defaultPort??(t&&G[t].defaultPort)??5432},lo=r=>{let e=new URL(r),t=Un[e.protocol.replace(":","")];return t?(e.port||=String(t.defaultPort),e.protocol=t.driverScheme,e.toString()):r}});var dt,Zr=N(()=>{dt={name:"db-studio",type:"module",version:"1.19.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 To={};Kt(To,{captureInstallationActive:()=>aa,captureServerError:()=>sa,captureServerEvent:()=>Hn,databaseTypeForRequest:()=>Xt,durationBucket:()=>na,flushServerObservability:()=>Eu,getTelemetryConfig:()=>Fn,initServerObservability:()=>bo,operationForRequest:()=>Jt,outcomeForStatus:()=>ra,resetTelemetryId:()=>ta,setTelemetryEnabled:()=>Kn,startServerSpan:()=>oa});import{randomUUID as yo}from"crypto";import{existsSync as lu,mkdirSync as uu,readFileSync as mu,writeFileSync as du}from"fs";import{homedir as ea,platform as pu}from"os";import qn from"path";import*as Ie from"@sentry/node";import{PostHog as fu}from"posthog-node";var yu,ho,Bn,hu,gu,ot,pt,bu,Tu,ft,Qt,Fn,Kn,ta,na,ra,go,Jt,Xt,bo,Eu,Hn,aa,wu,sa,oa,Zt=N(()=>{"use strict";y();ee();tt();Zr();yu=()=>process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development",ho=()=>{let r=process.env.DB_STUDIO_DATA_DIR??process.env.XDG_STATE_HOME??(process.platform==="win32"?process.env.LOCALAPPDATA:qn.join(ea(),".local","state"));return qn.join(r||qn.join(ea(),".db-studio"),"db-studio","telemetry.json")},Bn=r=>{try{let e=ho();uu(qn.dirname(e),{recursive:!0}),du(e,JSON.stringify(r),{encoding:"utf8",mode:384})}catch{}},hu=()=>({installationId:yo(),enabled:!0}),gu=()=>{let r=ho();try{if(lu(r)){let t=JSON.parse(mu(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=hu();return Bn(e),e},bu="https://a1e890d1105f1f27fcb1dbead71c30dd@o4509725125181440.ingest.de.sentry.io/4512040493383760",Tu="phc_nxaQk54MWAehmL72J4gjVbrQCpbSTedMyHn3PvFxAhkd",ft=()=>ot??=gu(),Qt=()=>!yu()&&process.env.DB_STUDIO_TELEMETRY!=="0"&&ft().enabled,Fn=()=>({enabled:Qt(),installationId:ft().installationId,appVersion:dt.version}),Kn=r=>{ot={...ft(),enabled:r},Bn(ot),r?(pt?.enable(),bo()):(pt?.disable(),Ie.close(500))},ta=()=>(ot={...ft(),installationId:yo(),lastActiveAt:void 0},Bn(ot),ot.installationId),na=r=>r<100?"under_100ms":r<1e3?"100ms_1s":r<5e3?"1s_5s":"over_5s",ra=r=>r>=500?"server_error":r>=400?"client_error":"success",go=new RegExp(`^/api/(${Ct.join("|")})(?=/|$)`),Jt=(r,e)=>{let t=e.replace(go,"/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}`},Xt=r=>r.match(go)?.[1],bo=()=>{if(!Qt())return;let r=process.env.DB_STUDIO_SENTRY_DSN??bu;r&&(!Ie.isInitialized()||Ie.getClient()?.getOptions().enabled===!1)&&Ie.init({dsn:r,environment:process.env.NODE_ENV??"production",release:`db-studio@${dt.version}`,tracesSampleRate:.1,sendDefaultPii:!1,defaultIntegrations:!1,beforeSend(t){return delete t.request,t.user={id:ft().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??Tu;e&&!pt&&(pt=new fu(e,{host:process.env.DB_STUDIO_POSTHOG_HOST??"https://eu.i.posthog.com",flushAt:20,flushInterval:1e4,requestTimeout:2e3}))},Eu=()=>Promise.allSettled([pt?.shutdown(2e3),Ie.close(2e3)]),Hn=r=>{!Qt()||!pt||pt.capture({distinctId:ft().installationId,event:r.event,properties:{...r.properties,source:"server",app_version:dt.version,$geoip_disable:!1}})},aa=()=>{if(!Qt())return;let r=ft(),e=r.lastActiveAt?Date.parse(r.lastActiveAt):0;Date.now()-e<864e5||(ot={...r,lastActiveAt:new Date().toISOString()},Bn(ot),Hn({event:"installation_active",properties:{runtime:`node-${process.versions.node.split(".")[0]}`,os:pu()}}))},wu=(r,e,t)=>{let n=new Error(t);if(n.name=e,r instanceof Error&&r.stack){let a=ea(),s=r.stack.split(`
|
|
4
|
+
`).slice(1).filter(o=>/^\s*at\s/.test(o)).map(o=>o.replaceAll(a,"~"));n.stack=[`${e}: ${t}`,...s].join(`
|
|
5
|
+
`)}return n},sa=(r,{operation:e,status:t,dbType:n})=>{if(!Qt()||t<500)return;let{error_type:a,error_code:s}=le(r),o=et(),i=`${e} failed with ${t}${s?` ${s}`:""}`;Ie.captureException(wu(Xr(r),a,i),{tags:{operation:e,source:"server",release:dt.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"]})},oa=(r,e,t)=>Ie.startSpan({name:r,op:"http.server",attributes:{"db_studio.operation":r,...e?{"db_studio.db_type":e}:{}}},t)});import{statSync as Su}from"fs";var ia,Cu,Eo,ca=N(()=>{"use strict";y();ia=r=>r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/(1024*1024)).toFixed(1)} MB`,Cu=r=>{if(!r)return"in-memory";try{return ia(Su(r).size)}catch{return"N/A"}},Eo=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"?Cu(typeof n=="string"?n:""):"N/A",version:`SQLite ${t.rows[0]?.[0]}`}},close:()=>r.close()})});var Co,Ru,Nu,Au,wo,So,Ro,No=N(()=>{"use strict";y();ce();ca();Co=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}},Ru=BigInt(Number.MIN_SAFE_INTEGER),Nu=BigInt(Number.MAX_SAFE_INTEGER),Au=r=>typeof r!="bigint"?r:r>=Ru&&r<=Nu?Number(r):r.toString(),wo=r=>typeof r=="string"?{sql:r,params:[]}:{sql:r.sql,params:r.args.map(Au)},So=({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}),Ro=({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(wo)})).map(So):[];return{execute:async o=>So((await a("/raw",wo(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:ia(i),version:"Cloudflare D1"}},close:()=>{}}}});var Du,en,je,Be,yt,ht=N(()=>{"use strict";y();Du={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")},en={},je=async r=>{let e=en[r]??await Du[r]();return en[r]=e,e},Be=r=>{let e=en[r];if(!e)throw new Error(`The ${r} driver is used before a connection opened`);return e},yt=r=>en.pg!==void 0&&r instanceof en.pg.DatabaseError});var pa={};Kt(pa,{closeAllDbPools:()=>Iu,coerceObjectId:()=>pn,getClickhouseClient:()=>an,getDbPool:()=>tn,getDbType:()=>gt,getIsolatedRedisClient:()=>ma,getMongoClient:()=>ln,getMongoDb:()=>ua,getMongoDbName:()=>un,getMssqlPool:()=>rn,getMysqlPool:()=>nn,getOraclePool:()=>cn,getRedisClient:()=>mn,getRedisDefaultDb:()=>da,getSqliteClient:()=>sn,isValidObjectId:()=>dn,withDuckdbConnection:()=>on});import{resolve as _u}from"path";import{pathToFileURL as Ou}from"url";var la,we,tn,nn,rn,an,gt,Iu,sn,on,cn,ln,un,ua,mn,ma,da,dn,pn,it=N(()=>{"use strict";y();ee();No();ht();tt();ca();He();la=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=null;initError=null;constructor(){try{this.initializeBaseConfig()}catch(e){this.initError=e instanceof Error?e:new Error(String(e)),Q("error","db_config_invalid",le(this.initError))}}detectDbType(e){let t=e.protocol.replace(":",""),n=Dt(t);if(n)return n;let a=Object.values(G).map(({label:s,protocols:o})=>`${s} (${o.join(", ")})`).join(", ");throw new Error(`Unsupported database type: ${t}. Supported types: ${a}.`)}initializeBaseConfig(){let e=process.env.DATABASE_URL;if(!e)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");let t=Dt(e.split("://")[0]);if(t&&G[t].defaultPort===null){this.baseConfig={url:e,host:"localhost",port:0,user:"",password:"",dbType:t};return}try{let n=lo(e),a=new URL(n),s=this.detectDbType(a);this.baseConfig={url:n,host:a.hostname,port:Number.parseInt(a.port,10)||(G[s].defaultPort??0),user:a.username,password:a.password,dbType:s}}catch(n){throw new Error(n instanceof Error?n.message:String(n))}}getDbType(){if(this.initError)throw this.initError;if(!this.baseConfig)throw new Error("Base configuration not initialized");return this.baseConfig.dbType}buildConnectionString(e){if(this.initError)throw this.initError;if(!this.baseConfig)throw new Error("Base configuration not initialized");if(G[this.baseConfig.dbType].defaultPort===null)return this.baseConfig.url;e||(e=new URL(this.baseConfig.url).pathname.slice(1));try{let t=new URL(this.baseConfig.url);return t.pathname=`/${e}`,t.toString()}catch(t){throw new Error(`Failed to build connection string for database "${e}": ${t instanceof Error?t.message:String(t)}`)}}getSqliteClient(){if(!this.baseConfig||this.baseConfig.dbType!=="sqlite")throw new Error("DATABASE_URL is not a sqlite://, libsql:// or d1:// connection");let{url:e}=this.baseConfig;return this.sqliteClient??=this.openSqliteClient(e).catch(t=>{throw this.sqliteClient=null,t}),this.sqliteClient}async openSqliteClient(e){if(e.startsWith("d1://"))return Ro(Co(e));let t=e.startsWith("sqlite://")?e.slice(9):null,n=t===null?e:t===":memory:"?t:Ou(_u(t)).href,{createClient:a}=await je("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")),Eo(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(){if(!this.baseConfig||this.baseConfig.dbType!=="duckdb")throw new Error("DATABASE_URL is not a duckdb:// connection");if(!this.duckdb){let e=this.baseConfig.url.replace(/^duckdb:\/\//,"");this.duckdb=(async()=>{try{let{DuckDBInstance:t}=await je("duckdb"),n=await t.create(e,{checkpoint_threshold:"0b"});return{instance:n,connection:await n.connect()}}catch(t){this.duckdb=null;let n=t instanceof Error?t.message:String(t);throw n.includes("Could not set lock on file")?new Error(`The DuckDB file "${e}" is locked by another process. Close the other program using it and try again. (${n})`):t}})()}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(){if(!this.baseConfig||this.baseConfig.dbType!=="oracle")throw new Error("DATABASE_URL is not an oracle:// connection");let{url:e,host:t,port:n,user:a,password:s}=this.baseConfig,o=decodeURIComponent(new URL(e).pathname.slice(1));return this.oraclePool??=je("oracle").then(i=>i.createPool({user:decodeURIComponent(a),password:decodeURIComponent(s),connectString:`${t}:${n}/${o}`,poolMin:0,poolMax:10,connectTimeout:5,sessionCallback:(c,l,u)=>{c.execute("ALTER SESSION SET TIME_ZONE = '+00:00'").then(()=>c.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(()=>u(),u)}})).catch(i=>{throw this.oraclePool=null,i}),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 je("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(
|
|
6
|
+
'search_path',
|
|
7
|
+
COALESCE(
|
|
8
|
+
'public, ' || string_agg(quote_ident(nspname), ', ' ORDER BY nspname),
|
|
9
|
+
current_setting('search_path')
|
|
10
|
+
),
|
|
11
|
+
false
|
|
12
|
+
)
|
|
13
|
+
FROM pg_namespace
|
|
14
|
+
WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'public', 'crdb_internal', 'pg_extension')
|
|
15
|
+
AND nspname NOT LIKE 'pg_toast%'
|
|
16
|
+
AND nspname NOT LIKE 'pg_temp%';`).then(()=>{},i=>{Q("warn","db_search_path_widen_failed",{db_type:"pg",...le(i)})})});s.on("error",o=>{Q("error","db_pool_error",{db_type:"pg",...le(o)})}),this.pgPools.set(t,s)}return this.pgPools.get(t)}async getMysqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e),{createPool:n}=await je("mysql");if(!this.mysqlPools.has(t)){let s=new URL(t).pathname.slice(1),o=n({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:s||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(t,o)}return this.mysqlPools.get(t)}async getMssqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e),n=await je("mssql");if(!this.mssqlPools.has(t)){let s=new URL(t).pathname.slice(1),o={server:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:s||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},i=await new n.ConnectionPool(o).connect();i.on("error",c=>{Q("error","db_pool_error",{db_type:"mssql",...le(c)})}),this.mssqlPools.set(t,i)}return this.mssqlPools.get(t)}async getClickhouseClient(e){let t=new URL(this.buildConnectionString(e)),n=decodeURIComponent(t.pathname.slice(1))||"default",{ClickHouseLogLevel:a,createClient:s}=await je("clickhouse"),o=this.clickhouseClients.get(n);if(o)return o;let i=t.protocol==="clickhouses:",c=s({url:`${i?"https":"http"}://${t.hostname}:${t.port||(i?8443:8123)}`,username:decodeURIComponent(t.username)||"default",password:decodeURIComponent(t.password),database:n,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:a.OFF}});return this.clickhouseClients.set(n,c),c}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){if(!this.baseConfig)throw new Error("Base configuration not initialized");let{MongoClient:e}=await je("mongodb"),t=new e(this.baseConfig.url);try{await t.connect(),this.mongoClient=t}catch(n){try{await t.close()}catch{}throw n}}return this.mongoClient}getMongoDbName(){if(!this.baseConfig)throw new Error("Base configuration not initialized");let e=new URL(this.baseConfig.url).pathname.replace(/^\/+|\/+$/g,"");try{return decodeURIComponent(e)||"admin"}catch{return e||"admin"}}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType!=="redis")throw new Error("DATABASE_URL is not a redis:// connection");let t=e??this.getRedisDefaultDb(),n=this.redisClients.get(t);if(n)return n;let a=new URL(this.baseConfig.url),s={host:this.baseConfig.host,port:this.baseConfig.port,db:t,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};this.baseConfig.user&&(s.username=decodeURIComponent(this.baseConfig.user)),this.baseConfig.password&&(s.password=decodeURIComponent(this.baseConfig.password)),a.protocol==="rediss:"&&(s.tls={});let{Redis:o}=await je("redis"),i=new o(s);try{if(await i.connect(),!this.redisClusterChecked){let c=await i.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(c))throw await i.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let l=c.match(/^redis_version:([^\r\n]+)/m)?.[1],[u=0,m=0]=l?.split(".").map(Number)??[];if(u<6||u===6&&m<2)throw await i.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${l??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(c){throw await i.quit().catch(()=>{}),c}return this.redisClients.set(t,i),i}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())]}},we=new la,tn=r=>we.getPgPool(r),nn=r=>we.getMysqlPool(r),rn=async r=>we.getMssqlPool(r),an=r=>we.getClickhouseClient(r),gt=()=>we.getDbType(),Iu=async()=>we.closeAll(),sn=()=>we.getSqliteClient(),on=r=>we.withDuckdbConnection(r),cn=()=>we.getOraclePool(),ln=()=>we.getMongoClient(),un=()=>we.getMongoDbName(),ua=r=>we.getMongoDb(r),mn=r=>we.getRedisClient(r),ma=r=>we.getIsolatedRedisClient(r),da=()=>we.getRedisDefaultDb(),dn=r=>typeof r=="string"&&Be("mongodb").ObjectId.isValid(r),pn=r=>{let{ObjectId:e}=Be("mongodb");return typeof r=="string"&&e.isValid(r)?new e(r):r}});var Ao={};Kt(Ao,{checkDatabaseConnection:()=>Pu,getDatabaseConnectionDetails:()=>xu});var Lu,fa,xu,Pu,Do=N(()=>{"use strict";y();ee();it();He();Lu=2e3,fa=async r=>{let e;try{return await Promise.race([r,new Promise((t,n)=>{e=setTimeout(()=>n(new Error("Database startup check timed out")),Lu)})])}finally{e&&clearTimeout(e)}},xu=r=>{let e=gt(),{label:t,defaultPort:n}=G[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}=Ae(r);return{type:e,name:t,destination:`${a}:${s}`}},Pu=async r=>{switch(r){case"pg":await fa(tn().then(e=>e.query("SELECT 1")));return;case"mysql":await(await nn()).query("SELECT 1");return;case"mssql":await(await rn()).request().query("SELECT 1");return;case"mongodb":{await(await ln()).db(un()).command({ping:1});return}case"sqlite":await fa(sn().then(e=>e.execute("SELECT 1")));return;case"redis":await(await mn()).ping();return;case"duckdb":await on(e=>e.run("SELECT 1"));return;case"oracle":{let e=await(await cn()).getConnection();await e.execute("SELECT 1 FROM dual").finally(()=>e.close());return}case"clickhouse":await fa(an().then(e=>e.query({query:"SELECT 1"})))}}});function Lt(r){return he.get(r)}function _o(r,e){if(!$u(r))throw new d(400,{message:`Key browsing is not supported for database type: "${e}"`});return r}var ya,he,$u,bt=N(()=>{"use strict";y();ce();ya=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()]}},he=new ya;$u=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 Mu(){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 nt,re,We=N(()=>{"use strict";y();ht();ce();nt=5e4;re=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."||yt(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 ha()}createIndex(e){return ha()}dropIndex(e){return ha()}getServerLogs(e){return Mu()}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 z,j,H,J,ga,ba,jn,Wn,te,Se,Vn,Tt,xt,Ve=N(()=>{"use strict";y();it();z=r=>tn(r),j=r=>nn(r),H=r=>rn(r),J=()=>sn(),ga=r=>on(r),ba=()=>cn(),jn=()=>ln(),Wn=()=>un(),te=r=>ua(r),Se=r=>mn(r),Vn=r=>ma(r),Tt=()=>da(),xt=r=>an(r)});var Le,ne,De,ye,rt=N(()=>{"use strict";y();Le="/* db-studio:server-logs */",ne=r=>({available:!1,reason:r}),De=r=>r.sort((e,t)=>e.ts.localeCompare(t.ts)).slice(-500),ye=r=>Object.fromEntries(Object.entries(r).filter(([,e])=>e!=null&&e!=="").map(([e,t])=>[e,typeof t=="string"?t:JSON.stringify(t)]))});function Oo(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=Ta(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 Io(r,e,t){let n=Array.isArray(r)?r:r?[{columnName:r,direction:e}]:[],a=(n[0]?.direction??e).toUpperCase(),s=[...n.map(o=>`${Ta(o.columnName)} ${o.direction.toUpperCase()}`),...t.map(o=>`${o} ${a}`)];return s.length?`ORDER BY ${s.join(", ")}`:""}function ku(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 Yn(r,e){let t=Ta(r.columnName);if(r.isIdentity||/serial/i.test(r.columnType))return`${t} UInt64 DEFAULT generateSnowflakeID()`;let n=ku(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 ${vu[o.toLowerCase()]??o}`),s}var ae,Ta,vu,Lo=N(()=>{"use strict";y();ae=r=>`\`${r.replaceAll("\\","\\\\").replaceAll("`","\\`")}\``,Ta=ae;vu={"now()":"now()",current_timestamp:"now()","current_timestamp()":"now()",current_date:"today()","gen_random_uuid()":"generateUUIDv4()","uuid_generate_v4()":"generateUUIDv4()"}});import{ClickHouseError as xo}from"@clickhouse/client";var Uu,Po,qu,Bu,zn,$o=N(()=>{"use strict";y();ee();We();Ve();rt();ce();He();Lo();Uu={mutations_sync:"2"},Po=r=>/^(LowCardinality\()?Nullable\(/.test(r),qu=(r,e)=>{if(r==null)return null;let t=At(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},Bu={Fatal:"fatal",Critical:"fatal",Error:"error",Warning:"warning"},zn=class extends re{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 ae(e)}mapToUniversalType(e){return Ln(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
17
|
FROM system.databases AS d
|
|
18
18
|
LEFT JOIN (
|
|
19
19
|
SELECT database, sum(bytes_on_disk) AS bytes FROM system.parts WHERE active GROUP BY database
|
|
@@ -24,13 +24,24 @@ var hc=Object.defineProperty;var S=(r,e)=>()=>(r&&(e=r(r=0)),e);var on=(r,e)=>{f
|
|
|
24
24
|
currentUser() AS user,
|
|
25
25
|
currentDatabase() AS database,
|
|
26
26
|
(SELECT sum(value) FROM system.metrics WHERE metric IN ('TCPConnection', 'HTTPConnection', 'MySQLConnection', 'PostgreSQLConnection')) AS active_connections,
|
|
27
|
-
(SELECT value FROM system.server_settings WHERE name = 'max_connections') AS max_connections`);if(!e)throw new
|
|
27
|
+
(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}=Ae();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
|
|
28
28
|
FROM system.tables
|
|
29
29
|
WHERE database = currentDatabase() AND NOT is_temporary AND NOT startsWith(name, '.inner')
|
|
30
|
-
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
|
|
30
|
+
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=>Yn(u,i)),l=a.filter(u=>u.isPrimaryKey).map(u=>ae(u.columnName));await this.command(t,`CREATE TABLE ${ae(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 ${ae(e)}`);return await this.command(t,`DROP TABLE ${ae(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 ${ae(e)} TO ${ae(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 ${ae(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:Ln(a.type),dataTypeLabel:Mr(a.type),isNullable:Po(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(At(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=Yn({...e,isPrimaryKey:!1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${ae(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 ${ae(e)} DROP COLUMN ${ae(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=Yn({...e,columnName:n,isPrimaryKey:s.is_in_sorting_key===1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${ae(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 ${ae(e)} RENAME COLUMN ${ae(t)} TO ${ae(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:G.clickhouse.rowMutationReason})}async deleteRecords(e){throw new d(400,{message:G.clickhouse.rowMutationReason})}async forceDeleteRecords(e){throw new d(400,{message:G.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 xt(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:Uu}),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 xt(e),n=async a=>{try{return await(await t.query({query:`${Le} ${a}`,format:"JSONEachRow",clickhouse_settings:{log_queries:0}})).json()}catch(s){if(s instanceof xo&&s.type==="UNKNOWN_TABLE")return null;throw s}};try{let a=await n(`SELECT toUnixTimestamp64Milli(event_time_microseconds) AS ms, type, query_duration_ms,
|
|
31
|
+
query, exception, exception_code, user, query_id, read_rows,
|
|
32
|
+
formatReadableSize(memory_usage) AS memory
|
|
33
|
+
FROM system.query_log
|
|
34
|
+
WHERE event_date >= yesterday() AND type != 'QueryStart' AND is_initial_query
|
|
35
|
+
ORDER BY event_time_microseconds DESC LIMIT ${500}`),s=await n(`SELECT toUnixTimestamp64Milli(event_time_microseconds) AS ms, level, logger_name,
|
|
36
|
+
message, query_id
|
|
37
|
+
FROM system.text_log
|
|
38
|
+
WHERE event_date >= yesterday()
|
|
39
|
+
AND level IN ('Fatal', 'Critical', 'Error', 'Warning')
|
|
40
|
+
AND logger_name NOT IN ('executeQuery', 'TCPHandler', 'HTTPHandler')
|
|
41
|
+
ORDER BY event_time_microseconds DESC LIMIT ${500}`);if(!a&&!s)return ne("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:ye({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:Bu[i.level]??"info",rawLevel:i.level,source:i.logger_name,message:i.message,detail:ye({query_id:i.query_id})}))];return{available:!0,source:s?"system.query_log + system.text_log":"system.query_log",entries:De(o)}}catch(a){if(a instanceof xo&&a.type==="ACCESS_DENIED")return ne("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 xt(e)).query({query:t,query_params:n,format:"JSONEachRow"})).json()}async command(e,t,n={},a={}){await(await xt(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}=Oo(a),m=Io(s,o,t),p=c?this.decodeOffsetCursor(c):0,f=u.length;return{sql:`SELECT * FROM ${ae(n)} ${l} ${m} LIMIT {p${f+1}:UInt64} OFFSET {p${f}:UInt64}`,values:[...u,p,i+1],countSql:`SELECT count() AS total FROM ${ae(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
|
|
31
42
|
FROM system.columns
|
|
32
43
|
WHERE database = currentDatabase() AND table = {table:String}
|
|
33
|
-
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 ye(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(([c,i])=>{let l=a.get(c);if(!l)throw new ye(400,{message:`Column "${c}" does not exist in table "${t}"`});let u=xu(i,l);return u===null&&!Eo(l)?[]:[[c,u]]})));await Yt(e).insert({table:ue(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 Co(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 No(r,e,t){let n=[],a=[],s=[],o=[];for(let c of r){let i=x(c.column),l=e[c.column]??null,{descending:u,nullsLast:m}=So(c,t),d=l===null?m?null:`${i} IS NOT NULL`:`${i} ${u?"<":">"} ?${m?` OR ${i} IS NULL`:""}`;d&&(n.push(`(${[...s,`(${d})`].join(" AND ")})`),a.push(...o,...l===null?[]:[l])),l===null?s.push(`${i} IS NULL`):(s.push(`${i} = ?`),o.push(l))}return{clause:n.length?`(${n.join(" OR ")})`:"FALSE",values:a}}function Vn(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,pa,So,Ro,$u,fa,Ao=S(()=>{"use strict";h();x=r=>`"${r.replaceAll('"','""')}"`,pa=r=>r.length?`WHERE ${r.join(" AND ")}`:"";So=(r,e)=>({descending:r.direction==="desc"!==e,nullsLast:!e}),Ro=(r,e=!1)=>`ORDER BY ${r.map(t=>{let{descending:n,nullsLast:a}=So(t,e);return`${x(t.column)} ${n?"DESC":"ASC"} NULLS ${a?"LAST":"FIRST"}`}).join(", ")}`;$u=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),fa=r=>$u.has(r.toLowerCase().trim())});import{statSync as Pu}from"fs";import{DuckDBTypeId as Yn,ResultReturnType as Do,StatementType as Lu}from"@duckdb/node-api";import{HTTPException as oe}from"hono/http-exception";var xt,Mu,_o,ha,we,ya,zt,zn,ku,vu,qu,Uu,Gn,Io=S(()=>{"use strict";h();ie();Ve();Ye();Ao();xt="database_name = current_database() AND schema_name = current_schema()",Mu=new Set([Yn.BIGINT,Yn.UBIGINT,Yn.HUGEINT,Yn.UHUGEINT]),_o=r=>{let e=r.columnTypes(),t=r.columnNames().filter((a,s)=>Mu.has(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},ha=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),we=async(r,e,t=[])=>_o(await r.runAndReadAll(e,t.map(ha))),ya=async(r,e,t=[])=>(await r.runAndReadAll(e,t.map(ha))).rowsChanged,zt=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}},zn=r=>r.map(()=>"?").join(", "),ku=r=>r.columns.map((e,t)=>`c.${x(e)} = p.${x(r.referencedColumns[t])}`).join(" AND "),vu=r=>r.flatMap(e=>[...(e.column_default??"").matchAll(/nextval\('([^']+)'\)/g)].map(t=>t[1])),qu=[["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."]],Uu=new Set(["CASCADE","SET NULL","SET DEFAULT"]),Gn=class extends le{async runQuery(e,t,n){return la(a=>we(a,t,n))}quoteIdentifier(e){return x(e)}mapToUniversalType(e){return fn(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=qu.find(([n])=>e.message.includes(n));if(t)return new oe(400,{message:`${t[1]} (${e.message})`,cause:e})}return super.wrapError(e)}withConnection(e){return la(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:c,filters:i=[]}=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"]),d=a==="desc",p=Co(i),f=c?this.decodeCursor(c):null,y=f?No(m,f.values,d):null,g=Ro(m,d),w=u.length?"*":"*, rowid",C=pa(y?[...p.conditions,y.clause]:p.conditions),[A]=await we(l,`SELECT COUNT(*) AS total FROM ${x(t)} ${pa(p.conditions)}`,p.values),N=await we(l,`SELECT ${w} FROM ${x(t)} ${C} ${g} LIMIT ?`,[...p.values,...y?.values??[],n+1]),E=N.length>n,R=N.slice(0,n);d&&R.reverse();let D=se=>this.encodeCursor({values:Object.fromEntries(m.map(z=>[z.column,se[z.column]])),sortColumns:m.map(z=>z.column)}),$=R[0],H=R.at(-1),P=d?!!c:E,K=d?E:!!c;return{data:R.map(se=>{if(u.length)return this.normalizeRow(se);let{rowid:z,...v}=se;return this.normalizeRow(v)}),meta:{limit:n,total:Number(A?.total??0),hasNextPage:P,hasPreviousPage:K,nextCursor:P&&H?D(H):null,prevCursor:K&&$?D($):null}}})}async getDatabasesList(){return this.withConnection(async e=>(await we(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 we(e,"SELECT current_database() AS db");return{db:t.db}})}async getDatabaseConnectionInfo(){return this.withConnection(async e=>{let[t]=await we(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 we(t,`SELECT table_name FROM duckdb_tables() WHERE ${xt} AND NOT temporary ORDER BY table_name`),a=[];for(let{table_name:s}of n){let[o]=await we(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=>Uu.has(m));if(u)throw new oe(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),c=n.map(l=>{let u=`${x(l.columnName)} ${Vn(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||fa(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&&c.push(`PRIMARY KEY (${o.map(x).join(", ")})`);let i=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=>zt(l,async()=>{for(let u of s)await l.run(`CREATE SEQUENCE ${x(u)}`);await l.run(`CREATE TABLE ${x(t)} (${[...c,...i].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(c=>c.table!==e);if(s.length){if(t)throw new oe(400,{message:`DuckDB cannot drop "${e}" while ${[...new Set(s.map(c=>`"${c.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 we(n,`SELECT COUNT(*) AS count FROM ${x(e)}`);await n.run(`DROP TABLE ${x(e)}`);for(let c of vu(a))await n.run(`DROP SEQUENCE IF EXISTS ${x(c)}`).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 oe(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 we(t,`SELECT sql FROM duckdb_tables() WHERE ${xt} AND table_name = ?`,[e]);if(!n)throw new oe(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((c,i)=>[c,{table:o.referencedTable,column:o.referencedColumns[i]}])));return n.map(o=>{let c=s.get(o.column_name),i=a.has(o.column_name);return{columnName:o.column_name,dataType:fn(o.data_type),dataTypeLabel:xr(o.data_type),isNullable:o.is_nullable&&!i,columnDefault:o.column_default,isPrimaryKey:i,isForeignKey:!!c,referencedTable:c?.table??null,referencedColumn:c?.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:c,isPrimaryKey:i}=e;if(c||i)throw new oe(400,{message:`DuckDB cannot add a ${i?"PRIMARY KEY":"UNIQUE"} column to an existing table. Add the column without it, or recreate the table.`});let l=e.isIdentity||fa(a)?`${t}_${n}_seq`:null,u=`${x(n)} ${Vn(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(p=>p.column_name===n))throw new oe(409,{message:`Column "${n}" already exists in table "${t}"`});await zt(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(p=>{throw String(p).includes("NOT NULL constraint failed")?new oe(400,{message:`Column "${n}" needs a default value to be NOT NULL, because "${t}" already has rows.`}):p})})})}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,c=`ALTER TABLE ${x(t)} ALTER COLUMN ${x(n)}`;await this.withConnection(async i=>{await this.requireColumn(i,t,n),await zt(i,async()=>{await i.run(`${c} TYPE ${Vn(a,!1)}`),await i.run(`${c} ${s?"DROP":"SET"} NOT NULL`),await i.run(o?.trim()?`${c} SET DEFAULT ${o.trim()}`:`${c} 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 oe(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 c=>{let i=await this.requireColumns(c,t),l=a.find(u=>!i.some(m=>m.column_name===u));if(l!==void 0)throw new oe(400,{message:`Column "${l}" does not exist in table "${t}"`});if(o!==void 0)throw new oe(400,{message:`Unsupported index method "${o}"`});try{await c.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 oe(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 oe(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 oe(400,{message:"No data provided for insert"});return{insertedCount:await this.withConnection(o=>ya(o,`INSERT INTO ${x(t)} (${a.map(x).join(", ")}) VALUES (${zn(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=>zt(o,async()=>{this.assertWholeKey(await this.primaryKey(o,t),n);let c=0;for(let{keyValues:i,rowUpdates:l}of a){let u=await ya(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),...i]);if(u===0)throw new oe(404,{message:`Record with ${this.describeKey(n,i)} not found in table "${t}"`});c+=u}return c}))}}async deleteRecords({tableName:e,primaryKeys:t}){let n=t[0]?.columnName;if(!n)throw new oe(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 ya(s,`DELETE FROM ${x(e)} WHERE ${x(n)} IN (${zn(a)})`,a),fkViolation:!1,relatedRecords:[]}}catch(o){if(!(o instanceof Error)||!o.message.includes("Violates foreign key constraint"))throw o;let c=[];for(let i of await this.foreignKeys(s,"referenced_table",e)){let l=await we(s,`SELECT c.* FROM ${x(i.table)} c JOIN ${x(e)} p ON ${ku(i)} WHERE p.${x(n)} IN (${zn(a)}) LIMIT 100`,a);l.length&&c.push({tableName:i.table,columnName:i.columns.join(", "),constraintName:i.constraintName,records:l})}return{deletedCount:0,fkViolation:!0,relatedRecords:c}}})}async forceDeleteRecords(e){let t=await this.deleteRecords(e);if(t.fkViolation)throw new oe(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 oe(400,{message:"At least one record is required"});let n=Object.keys(t[0]),a=await this.withConnection(s=>zt(s,async()=>{let o=await s.prepare(`INSERT INTO ${x(e)} (${n.map(x).join(", ")}) VALUES (${zn(n)})`);for(let c of t)o.bind(n.map(i=>ha(c[i]))),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 oe(400,{message:"Query is required"});return this.withConnection(async t=>{let n=performance.now(),a=await t.extractStatements(e);if(a.count!==1)throw new oe(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let s=await a.prepare(0);try{if(s.statementType===Lu.TRANSACTION)throw new oe(400,{message:"Transactions cannot span query-runner requests. BEGIN, COMMIT, and ROLLBACK are not supported."});let o=await s.runAndReadAll(),c=performance.now()-n;if(o.returnType===Do.CHANGED_ROWS)return{columns:[],rows:[],rowCount:o.rowsChanged,duration:c,message:`OK (${o.rowsChanged} rows affected)`};if(o.returnType===Do.NOTHING)return{columns:[],rows:[],rowCount:0,duration:c,message:"OK"};let i=_o(o);return{columns:o.columnNames(),rows:i,rowCount:i.length,duration:c,message:i.length===0?"OK":void 0}}finally{s.destroySync()}})}getFileSize(e){if(!e)return"in-memory";try{let t=Pu(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 we(e,`SELECT column_name, data_type, is_nullable, column_default FROM duckdb_columns() WHERE ${xt} AND table_name = ? ORDER BY column_index`,[t])}async requireColumns(e,t){let n=await this.columns(e,t);if(!n.length)throw new oe(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 oe(404,{message:`Column "${n}" does not exist in table "${t}"`});return a}async listIndexes(e,t){return await this.requireColumns(e,t),(await we(e,`SELECT index_name, is_unique, expressions::VARCHAR[] AS keys, sql FROM duckdb_indexes() WHERE ${xt} 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 we(e,`SELECT constraint_column_names AS columns FROM duckdb_constraints() WHERE ${xt} AND table_name = ? AND constraint_type = 'PRIMARY KEY'`,[t]);return n?.columns??[]}async foreignKeys(e,t,n){return we(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 ${xt} AND constraint_type = 'FOREIGN KEY' AND ${t} = ?`,[n])}async sampleReferencingRows(e,t){let n=[];for(let a of t){let s=await we(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 Bu,Oo,xo=S(()=>{"use strict";h();Bu=new Set(["admin","config","local"]),Oo=(r,e)=>{let t=r.filter(n=>!Bu.has(n.name)||n.name===e);return!e||t.some(n=>n.name===e)?t:[...t,{name:e,sizeOnDisk:0}]}});function $o(r){if(!r||r.length===0)return{};let e=[];for(let t of r){let n=t.columnName,a=Fu(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:Qn(String(a)),$options:""}});break;case"not like":e.push({[n]:{$not:{$regex:Qn(String(a)),$options:""}}});break;case"ilike":e.push({[n]:{$regex:Qn(String(a)),$options:"i"}});break;case"not ilike":e.push({[n]:{$not:{$regex:Qn(String(a)),$options:"i"}}});break;default:e.push({[n]:a});break}}return e.length?{$and:e}:{}}function ba(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 ga(r){return Buffer.from(JSON.stringify({offset:r})).toString("base64url")}function Po(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 Qn,Fu,Lo=S(()=>{"use strict";h();pt();Qn=r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Fu=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:Bn(e)?Fn(e):e}});import{HTTPException as q}from"hono/http-exception";var Jn,$t,ju,Hu,Ku,Wu,Vu,Mo,Gt,Yu,ko,zu,Gu,Qu,Pt,Xn,vo=S(()=>{"use strict";h();Ve();Ye();pt();et();xo();We();Lo();Jn=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=>Jn(e)):Object.fromEntries(Object.entries(r).map(([e,t])=>[e,Jn(t)])):r,$t=r=>Jn(r),ju=["sparse","expireAfterSeconds","partialFilterExpression","collation"],Hu=r=>{let e=r.name??"",t=e==="_id_",n=Object.values(r.key),a=r.weights,s=a?Object.keys(r.key).flatMap(i=>i==="_fts"?Object.keys(a):i==="_ftsx"?[]:[i]):Object.keys(r.key),o={};a&&(o.weights=a);for(let i of ju){let l=r[i];l!=null&&l!==!1&&(o[i]=Jn(l))}let c=n.every(i=>i===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(i=>typeof i=="string")??null,kind:t?"primary":"index",definition:c?null:JSON.stringify({key:r.key,...o})}},Ku=new Set([85,86,11e3]),Wu=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",Vu=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"}},Mo=r=>typeof r=="string"&&Bn(r),Gt=r=>Fn(r),Yu=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]}`},ko=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),zu=r=>{let e=r.trim();if(ko.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},Gu=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"},Qu=(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}},Pt=r=>{if(r._id&&typeof r._id=="string")return{...r,_id:Gt(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"?Gt(t):t)}};if(Array.isArray(e.$nin))return{...r,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?Gt(t):t)}}}return r},Xn=class extends le{runQuery(){throw new q(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new q(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow($t(t)))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"int":case"long":case"double":case"decimal":return"number";case"bool":return"boolean";case"date":return"date";case"array":return"array";case"object":return"json";default:return"text"}}mapFromUniversalType(e){switch(e){case"number":return"double";case"boolean":return"bool";case"date":return"date";case"array":return"array";case"json":return"object";default:return"string"}}wrapError(e){if(e instanceof q)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new q(503,{message:e.message,cause:e})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:n,cursor:a,limit:s,direction:o="asc",sort:c,order:i,filters:l}=e,m=(await ce(n)).collection(t),d=$o(l??[]),p=ba(c??"",i),f=s&&s>0?s:50,y=Po(a),g=Number.isFinite(y)&&y>=0?y:0,w=o==="desc"?Math.max(g-f,0):g,[C,A]=await Promise.all([m.countDocuments(d),m.find(d).sort(p).skip(w).limit(f).toArray()]),N=A.map(D=>$t(D)),E=w+f,R=Math.max(w-f,0);return{data:N,meta:{limit:f,total:C,hasNextPage:E<C,hasPreviousPage:w>0,nextCursor:E<C?ga(E):null,prevCursor:w>0?ga(R):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let o=(await(await ce(t)).collection(e).find({}).limit(1e4).toArray()).map(i=>$t(i));return{cols:Array.from(new Set(o.flatMap(i=>Object.keys(i)))),rows:o}}catch(n){throw this.wrapError(n)}}async getDatabasesList(){try{let a=(await(await ma()).db().admin().listDatabases()).databases??[];if(!a[0])throw new q(500,{message:"No databases returned from MongoDB"});return Oo(a,jn()).map(s=>({name:s.name,size:Yu(s.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:jn()}}async getDatabaseConnectionInfo(){try{let t=(await ma()).db().admin(),n=De(),a={};try{a=await t.serverStatus()}catch(s){ee("warn","db_server_status_failed",pe(s))}return{host:n.host,port:n.port,user:"n/a",database:jn(),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 ce(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 ce(t);if((await a.listCollections({name:n}).toArray()).length>0)throw new q(400,{message:`Collection "${n}" already exists`});let o=e?.fields??[];if(o.length===0){await a.createCollection(n);return}let c={},i=[];for(let l of o){let u=zu(l.columnType);if(!ko.has(u))throw new q(400,{message:`Unsupported MongoDB BSON type "${l.columnType}" for field "${l.columnName}"`});l.isArray?c[l.columnName]={bsonType:"array",...u!=="array"?{items:{bsonType:u}}:{}}:c[l.columnName]={bsonType:u},l.isNullable||i.push(l.columnName)}await a.createCollection(n,{validator:{$jsonSchema:{bsonType:"object",required:i,properties:c,additionalProperties:!0}},validationAction:"error"})}catch(n){throw this.wrapError(n)}}async deleteTable({tableName:e,db:t}){try{let a=(await ce(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 ce(a);if((await s.listCollections({name:t}).toArray()).length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if((await s.listCollections({name:n}).toArray()).length>0)throw new q(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 ce(t);if((await n.listCollections({name:e}).toArray()).length===0)throw new q(404,{message:`Collection "${e}" does not exist`});let s=n.collection(e),o=await s.find({}).limit(200).toArray(),c=await s.estimatedDocumentCount(),i=new Map,l=new Map;for(let p of o)for(let[f,y]of Object.entries(p)){let g=Gu(y);i.has(f)||(i.set(f,new Set),l.set(f,0)),i.get(f)?.add(g),l.set(f,(l.get(f)??0)+1)}let u={},m=[];for(let[p,f]of i.entries()){let y=l.get(p)??0,g=Array.from(f).filter(C=>C!=="null"),w=f.has("null")||y<o.length;y===o.length&&o.length>0&&!w&&m.push(p),u[p]=g.length===1?{bsonType:w?[g[0],"null"]:g[0]}:{bsonType:w?[...g,"null"]:g}}let d={collection:e,estimatedDocumentCount:c,sampledDocuments:o.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(d,null,2)}catch(n){throw this.wrapError(n)}}async getTableColumns({tableName:e,db:t}){try{let s=await(await ce(t)).collection(e).find({}).limit(200).toArray(),o=s.length,c=new Map,i=(l,u)=>{let m=Wu(u);if(!c.has(l))c.set(l,{types:new Set([m]),nullable:!1,presentCount:1});else{let d=c.get(l);d.types.add(m),d.presentCount+=1}};for(let l of s)for(let[u,m]of Object.entries(l)){if(m==null){if(!c.has(u))c.set(u,{types:new Set(["text"]),nullable:!0,presentCount:1});else{let d=c.get(u);d.nullable=!0,d.presentCount+=1}continue}i(u,m)}if(o>0)for(let l of c.values())l.presentCount<o&&(l.nullable=!0);return c.has("_id")||c.set("_id",{types:new Set(["text"]),nullable:!1,presentCount:o}),Array.from(c.entries()).map(([l,u])=>{let m=u.types.values().next().value??"text";return{columnName:l,dataType:m,dataTypeLabel:Vu(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:c}=e,i=await ce(c),l=await i.listCollections({name:t}).toArray();if(l.length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if(await i.collection(t).findOne({[n]:{$exists:!0}}))throw new q(409,{message:`Field "${n}" already exists in collection "${t}"`});let m=Qu(s,a);await i.collection(t).updateMany({},{$set:{[n]:m}});let p=l[0].options?.validator?.$jsonSchema??{},f={...p.properties??{},[n]:{bsonType:o?[a,"null"]:a}},y=[...p.required??[]];!o&&!y.includes(n)&&y.push(n),await i.command({collMod:t,validator:{$jsonSchema:{...p,bsonType:"object",properties:f,...y.length>0?{required:y}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:n}){try{return{deletedCount:(await(await ce(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,c=await ce(o),i=await c.listCollections({name:t}).toArray();if(i.length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if(n==="_id")throw new q(400,{message:'Cannot alter the "_id" field'});let u=i[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},d=[...u.required??[]];m[n]={bsonType:s?[a,"null"]:a};let p=d.indexOf(n);!s&&p===-1?d.push(n):s&&p!==-1&&d.splice(p,1),await c.command({collMod:t,validator:{$jsonSchema:{...u,bsonType:"object",properties:m,...d.length>0?{required:d}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async renameColumn(e){try{let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await ce(s);if((await o.listCollections({name:t}).toArray()).length===0)throw new q(404,{message:`Collection "${t}" does not exist`});if(n==="_id")throw new q(400,{message:'Cannot rename the "_id" field'});if(!await o.collection(t).findOne({[n]:{$exists:!0}}))throw new q(404,{message:`Field "${n}" does not exist in collection "${t}"`});if(await o.collection(t).findOne({[a]:{$exists:!0}}))throw new q(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 listIndexes(e,t){if((await e.listCollections({name:t}).toArray()).length===0)throw new q(404,{message:`Collection "${t}" does not exist`});return(await e.collection(t).listIndexes().toArray()).map(Hu).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 ce(t),e)}catch(n){throw this.wrapError(n)}}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o,db:c}=e;try{if(o!==void 0)throw new q(400,{message:`Unsupported index method "${o}"`});let i=a.find(m=>m.split(".").some(d=>d===""||d.startsWith("$")));if(i!==void 0)throw new q(400,{message:`Invalid field path "${i}"`});if(new Set(a).size!==a.length)throw new q(400,{message:"A field can appear only once in an index"});let l=await ce(c);if((await this.listIndexes(l,t)).some(m=>m.indexName===n))throw new q(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(i){let l=i.code;throw i instanceof Error&&typeof l=="number"&&Ku.has(l)?new q(409,{message:i.message,cause:i}):this.wrapError(i)}}async dropIndex({tableName:e,indexName:t,db:n}){try{let a=await ce(n),s=(await this.listIndexes(a,e)).find(o=>o.indexName===t);if(!s)throw new q(404,{message:`Index "${t}" does not exist on collection "${e}"`});if(s.kind==="primary")throw new q(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 ce(e)).collection(n),c=$t(a);if((c._id===""||c._id===null)&&delete c._id,!(await o.insertOne(c)).insertedId)throw new q(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 ce(e)).collection(n),o=0,c=this.resolveKeyColumns(t).map(l=>l||"_id"),i=this.groupUpdatesByKey({...t,primaryKeys:c},c);for(let{keyValues:l,rowUpdates:u}of i){if(u.some(f=>f.columnName==="_id"))throw new q(400,{message:'The "_id" field is immutable and cannot be updated.'});let m={};for(let f of u)m[f.columnName]=f.value;let d={};c.forEach((f,y)=>{let g=l[y];d[f]=f==="_id"&&Mo(g)?Gt(g):g});let p=await s.updateOne(d,{$set:m});if(p.matchedCount===0)throw new q(404,{message:`Record with ${this.describeKey(c,l)} not found in "${n}"`});o+=p.modifiedCount}return{updatedCount:o}}catch(n){throw this.wrapError(n)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:n,db:a}=e,o=(await ce(a)).collection(t),c=n[0]?.columnName??"_id",i=n.map(u=>c==="_id"&&Mo(u.value)?Gt(u.value):u.value);return{deletedCount:(await o.deleteMany({[c]:{$in:i}})).deletedCount??0,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:n,db:a}=e;if(!n||n.length===0)throw new q(400,{message:"At least one record is required"});let o=(await ce(a)).collection(t),c=n.map(l=>{let u=$t(l);return(u._id===""||u._id===null)&&delete u._id,u}),i=await o.insertMany(c,{ordered:!1});return{success:!0,message:`Successfully inserted ${i.insertedCount} record${i.insertedCount!==1?"s":""}`,successCount:i.insertedCount,failureCount:n.length-i.insertedCount}}catch(t){throw this.wrapError(t)}}async executeQuery({query:e,db:t}){try{if(!e?.trim())throw new q(400,{message:"Query is required"});let n;try{n=JSON.parse(e)}catch{throw new q(400,{message:"Mongo query must be valid JSON"})}if(!n.collection||!n.operation)throw new q(400,{message:"Mongo query must include collection and operation"});let s=(await ce(t)).collection(n.collection),o=performance.now(),c=[],i=0,l;switch(n.operation){case"find":{let p=Pt(n.filter??{}),f=s.find(p,n.options??{});f.sort(n.sort??ba("",void 0)),n.skip&&f.skip(n.skip),n.limit&&f.limit(n.limit),c=await f.toArray(),i=c.length;break}case"aggregate":{c=await s.aggregate(n.pipeline??[],n.options??{}).toArray(),i=c.length;break}case"insertOne":{let p=n.document;if(!p)throw new q(400,{message:"document is required"});i=(await s.insertOne(p)).insertedId?1:0,l="OK";break}case"insertMany":{let p=n.document;if(!Array.isArray(p))throw new q(400,{message:"document array is required"});i=(await s.insertMany(p)).insertedCount??0,l="OK";break}case"updateOne":{let p=Pt(n.filter??{});if(!n.update)throw new q(400,{message:"update is required"});let f=await s.updateOne(p,n.update,n.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"updateMany":{let p=Pt(n.filter??{});if(!n.update)throw new q(400,{message:"update is required"});let f=await s.updateMany(p,n.update,n.options??{});i=f.matchedCount??0,l=`OK (${f.modifiedCount??0} modified)`;break}case"deleteOne":{let p=Pt(n.filter??{});i=(await s.deleteOne(p,n.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let p=Pt(n.filter??{});i=(await s.deleteMany(p,n.options??{})).deletedCount??0,l="OK";break}case"count":{let p=Pt(n.filter??{});i=await s.countDocuments(p),c=[{count:i}],l="OK";break}default:throw new q(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-o,m=c.map(p=>$t(p));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:i,duration:u,message:l}}catch(n){throw this.wrapError(n)}}}});function Ta(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 Ea(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 qo(r,e,t){let n=Ea(r,e),a=Array.isArray(r)?r.map(c=>c.columnName):[r],s=(Array.isArray(r)?r[0]?.direction??e:e).toUpperCase(),o=t.filter(c=>!a.includes(c)).map(c=>`[${c}] ${s}`).join(", ");return o?n?`${n}, ${o}`:`ORDER BY ${o}`:n||"ORDER BY (SELECT NULL)"}function wa(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 Ca(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 Uo(r,e={}){let t=wa(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=Ca(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 Bo=S(()=>{"use strict";h()});import{HTTPException as j}from"hono/http-exception";var Ju,Xu,Zu,em,tm,nm,nt,Zn,Fo=S(()=>{"use strict";h();ie();Ve();Ye();We();Bo();Ju=547,Xu=3726,Zu=1913,em=1505,tm=new Set([1919,1978]),nm=3723,nt=r=>`[${r.replaceAll("]","]]")}]`,Zn=class extends le{async runQuery(e,t,n){let s=(await G(e)).request();return n.forEach((c,i)=>{s.input(`p${i}`,c)}),(await s.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return dn(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:c}=e,{clause:i,values:l,nextIdx:u}=Ta(n,0),m=Ea(a,s)||"ORDER BY (SELECT NULL)",d=c?this.decodeOffsetCursor(c):0,p=`SELECT * FROM [${t}] ${i} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,f=[...l,d,o+1],y=`SELECT COUNT(*) as total FROM [${t}] ${i}`;return{sql:p,values:f,countSql:y,countValues:l}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,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:c,filters:i=[]}=e,l=await G(n),u=await this.getPrimaryKeyColumns(l,t),m=c?this.decodeOffsetCursor(c):0,{clause:d,values:p,nextIdx:f}=Ta(i,0),y=qo(s,o,u),g=l.request();p.forEach((D,$)=>{g.input(`p${$}`,D)});let w=await g.query(`SELECT COUNT(*) as total FROM [${t}] ${d}`),C=Number(w.recordset[0]?.total??0),A=l.request();p.forEach((D,$)=>{A.input(`p${$}`,D)}),A.input(`p${f}`,m),A.input(`p${f+1}`,a+1);let E=(await A.query(`SELECT * FROM [${t}] ${d} ${y} OFFSET @p${f} ROWS FETCH NEXT @p${f+1} ROWS ONLY`)).recordset,R=E.length>a;return R&&(E=E.slice(0,a)),{data:E,meta:{limit:a,total:C,hasNextPage:R,hasPreviousPage:m>0,nextCursor:R?this.makeCursor(m+a):null,prevCursor:m>0?this.makeCursor(Math.max(0,m-a)):null}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let t=await(await G()).request().query(`
|
|
44
|
+
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=qu(c,l);return u===null&&!Po(l)?[]:[[i,u]]})));await(await xt(e)).insert({table:ae(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 Mo(r){let e=[],t=[];for(let n of r){let a=L(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 Uo(r,e,t){let n=[],a=[],s=[],o=[];for(let i of r){let c=L(i.column),l=e[i.column]??null,{descending:u,nullsLast:m}=ko(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 Gn(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 L,Ea,ko,vo,Fu,wa,qo=N(()=>{"use strict";y();L=r=>`"${r.replaceAll('"','""')}"`,Ea=r=>r.length?`WHERE ${r.join(" AND ")}`:"";ko=(r,e)=>({descending:r.direction==="desc"!==e,nullsLast:!e}),vo=(r,e=!1)=>`ORDER BY ${r.map(t=>{let{descending:n,nullsLast:a}=ko(t,e);return`${L(t.column)} ${n?"DESC":"ASC"} NULLS ${a?"LAST":"FIRST"}`}).join(", ")}`;Fu=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),wa=r=>Fu.has(r.toLowerCase().trim())});import{statSync as Ku}from"fs";var $t,Hu,Bo,Ca,ge,Sa,fn,Qn,ju,Wu,Vu,Yu,Jn,Fo=N(()=>{"use strict";y();ee();We();Ve();ht();ce();qo();$t="database_name = current_database() AND schema_name = current_schema()",Hu=r=>{let{DuckDBTypeId:e}=Be("duckdb");return r===e.BIGINT||r===e.UBIGINT||r===e.HUGEINT||r===e.UHUGEINT},Bo=r=>{let e=r.columnTypes(),t=r.columnNames().filter((a,s)=>Hu(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},Ca=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=[])=>Bo(await r.runAndReadAll(e,t.map(Ca))),Sa=async(r,e,t=[])=>(await r.runAndReadAll(e,t.map(Ca))).rowsChanged,fn=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}},Qn=r=>r.map(()=>"?").join(", "),ju=r=>r.columns.map((e,t)=>`c.${L(e)} = p.${L(r.referencedColumns[t])}`).join(" AND "),Wu=r=>r.flatMap(e=>[...(e.column_default??"").matchAll(/nextval\('([^']+)'\)/g)].map(t=>t[1])),Vu=[["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."]],Yu=new Set(["CASCADE","SET NULL","SET DEFAULT"]),Jn=class extends re{async runQuery(e,t,n){return ga(a=>ge(a,t,n))}quoteIdentifier(e){return L(e)}mapToUniversalType(e){return On(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=Vu.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 ga(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=Mo(c),b=i?this.decodeCursor(i):null,h=b?Uo(m,b.values,p):null,g=vo(m,p),S=u.length?"*":"*, rowid",w=Ea(h?[...f.conditions,h.clause]:f.conditions),[A]=await ge(l,`SELECT COUNT(*) AS total FROM ${L(t)} ${Ea(f.conditions)}`,f.values),D=await ge(l,`SELECT ${S} FROM ${L(t)} ${w} ${g} LIMIT ?`,[...f.values,...h?.values??[],n+1]),R=D.length>n,C=D.slice(0,n);p&&C.reverse();let _=$=>this.encodeCursor({values:Object.fromEntries(m.map(B=>[B.column,$[B.column]])),sortColumns:m.map(B=>B.column)}),O=C[0],k=C.at(-1),x=p?!!i:R,v=p?R:!!i;return{data:C.map($=>{if(u.length)return this.normalizeRow($);let{rowid:B,...M}=$;return this.normalizeRow(M)}),meta:{limit:n,total:Number(A?.total??0),hasNextPage:x,hasPreviousPage:v,nextCursor:x&&k?_(k):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 ${$t} 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 ${L(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=>Yu.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=`${L(l.columnName)} ${Gn(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||wa(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(L).join(", ")})`);let c=a.map(l=>`FOREIGN KEY (${L(l.columnName)}) REFERENCES ${L(l.referencedTable)} (${L(l.referencedColumn)}) ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`);await this.withConnection(l=>fn(l,async()=>{for(let u of s)await l.run(`CREATE SEQUENCE ${L(u)}`);await l.run(`CREATE TABLE ${L(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 ${L(e)}`);await n.run(`DROP TABLE ${L(e)}`);for(let i of Wu(a))await n.run(`DROP SEQUENCE IF EXISTS ${L(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 ${L(e)} RENAME TO ${L(t)}`)})}async getTableSchema({tableName:e}){return this.withConnection(async t=>{let[n]=await ge(t,`SELECT sql FROM duckdb_tables() WHERE ${$t} 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:On(o.data_type),dataTypeLabel:Pr(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||wa(a)?`${t}_${n}_seq`:null,u=`${L(n)} ${Gn(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 fn(m,async()=>{l&&await m.run(`CREATE SEQUENCE ${L(l)}`),await m.run(`ALTER TABLE ${L(t)} ADD COLUMN ${u}`),o||await m.run(`ALTER TABLE ${L(t)} ALTER COLUMN ${L(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 ${L(e)} DROP COLUMN ${L(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o}=e,i=`ALTER TABLE ${L(t)} ALTER COLUMN ${L(n)}`;await this.withConnection(async c=>{await this.requireColumn(c,t,n),await fn(c,async()=>{await c.run(`${i} TYPE ${Gn(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 ${L(e)} RENAME COLUMN ${L(t)} TO ${L(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 ${L(n)} ON ${L(t)} (${a.map(L).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 ${L(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=>Sa(o,`INSERT INTO ${L(t)} (${a.map(L).join(", ")}) VALUES (${Qn(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=>fn(o,async()=>{this.assertWholeKey(await this.primaryKey(o,t),n);let i=0;for(let{keyValues:c,rowUpdates:l}of a){let u=await Sa(o,`UPDATE ${L(t)} SET ${l.map(m=>`${L(m.columnName)} = ?`).join(", ")} WHERE ${n.map(m=>`${L(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 Sa(s,`DELETE FROM ${L(e)} WHERE ${L(n)} IN (${Qn(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 ${L(c.table)} c JOIN ${L(e)} p ON ${ju(c)} WHERE p.${L(n)} IN (${Qn(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=>fn(s,async()=>{let o=await s.prepare(`INSERT INTO ${L(e)} (${n.map(L).join(", ")}) VALUES (${Qn(n)})`);for(let i of t)o.bind(n.map(c=>Ca(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}=Be("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=Bo(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=Ku(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 ${$t} 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 ${$t} 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 ${$t} 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 ${$t} 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 ${L(a.table)} WHERE ${a.columns.map(o=>`${L(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 zu,Ko,Ho=N(()=>{"use strict";y();zu=new Set(["admin","config","local"]),Ko=(r,e)=>{let t=r.filter(n=>!zu.has(n.name)||n.name===e);return!e||t.some(n=>n.name===e)?t:[...t,{name:e,sizeOnDisk:0}]}});function jo(r){if(!r||r.length===0)return{};let e=[];for(let t of r){let n=t.columnName,a=Gu(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:Xn(String(a)),$options:""}});break;case"not like":e.push({[n]:{$not:{$regex:Xn(String(a)),$options:""}}});break;case"ilike":e.push({[n]:{$regex:Xn(String(a)),$options:"i"}});break;case"not ilike":e.push({[n]:{$not:{$regex:Xn(String(a)),$options:"i"}}});break;default:e.push({[n]:a});break}}return e.length?{$and:e}:{}}function Ra(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 Na(r){return Buffer.from(JSON.stringify({offset:r})).toString("base64url")}function Wo(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 Xn,Gu,Vo=N(()=>{"use strict";y();it();Xn=r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Gu=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:dn(e)?pn(e):e}});var Zn,Mt,Qu,Ju,Xu,Zu,em,Yo,yn,tm,Go,nm,rm,am,kt,sm,om,im,zo,cm,er,Qo=N(()=>{"use strict";y();We();Ve();rt();it();ce();tt();Ho();He();Vo();Zn=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=>Zn(e)):Object.fromEntries(Object.entries(r).map(([e,t])=>[e,Zn(t)])):r,Mt=r=>Zn(r),Qu=["sparse","expireAfterSeconds","partialFilterExpression","collation"],Ju=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 Qu){let l=r[c];l!=null&&l!==!1&&(o[c]=Zn(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})}},Xu=new Set([85,86,11e3]),Zu=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",em=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"}},Yo=r=>typeof r=="string"&&dn(r),yn=r=>pn(r),tm=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]}`},Go=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),nm=r=>{let e=r.trim();if(Go.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},rm=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"},am=(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}},kt=r=>{if(r._id&&typeof r._id=="string")return{...r,_id:yn(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"?yn(t):t)}};if(Array.isArray(e.$nin))return{...r,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?yn(t):t)}}}return r},sm=13,om=8e3,im=51803,zo={F:"fatal",E:"error",W:"warning",I:"info"},cm=({t:r,s:e,c:t,id:n,ctx:a,msg:s,attr:o={}})=>{if(n===im){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:zo[e]??"debug",rawLevel:e,source:t,message:`${i} ${JSON.stringify(m)}`,durationMs:Number(l),detail:ye({id:n,ctx:a,...u})}}return{ts:new Date(r.$date).toISOString(),level:zo[e]??"debug",rawLevel:e,source:t,message:s,detail:ye({id:n,ctx:a,...o})}},er=class extends re{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(Mt(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 te(n)).collection(t),p=jo(l??[]),f=Ra(i??"",c),b=s&&s>0?s:50,h=Wo(a),g=Number.isFinite(h)&&h>=0?h:0,S=o==="desc"?Math.max(g-b,0):g,[w,A]=await Promise.all([m.countDocuments(p),m.find(p).sort(f).skip(S).limit(b).toArray()]),D=A.map(_=>Mt(_)),R=S+b,C=Math.max(S-b,0);return{data:D,meta:{limit:b,total:w,hasNextPage:R<w,hasPreviousPage:S>0,nextCursor:R<w?Na(R):null,prevCursor:S>0?Na(C):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let o=(await(await te(t)).collection(e).find({}).limit(1e4).toArray()).map(c=>Mt(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 jn()).db().admin().listDatabases()).databases??[];if(!a[0])throw new d(500,{message:"No databases returned from MongoDB"});return Ko(a,Wn()).map(s=>({name:s.name,size:tm(s.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:Wn()}}async getDatabaseConnectionInfo(){try{let t=(await jn()).db().admin(),n=Ae(),a={};try{a=await t.serverStatus()}catch(s){Q("warn","db_server_status_failed",le(s))}return{host:n.host,port:n.port,user:"n/a",database:Wn(),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 te(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 te(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=nm(l.columnType);if(!Go.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 te(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 te(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 te(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=rm(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 te(t)).collection(e).find({}).limit(200).toArray(),o=s.length,i=new Map,c=(l,u)=>{let m=Zu(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:em(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 te(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=am(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 te(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 te(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 te(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 jn(),{log:t}=await e.db("admin").command({getLog:"global"}),n=t.flatMap(a=>{try{return[cm(JSON.parse(a))]}catch{return[]}});return{available:!0,source:"getLog: 'global' (the server keeps the newest 1024 entries)",entries:De(n)}}catch(e){let t=e.code;if(t===sm)return ne("Reading the server log needs the getLog action, which the clusterMonitor role grants.");if(t===om)return ne("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(Ju).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 te(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 te(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"&&Xu.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 te(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 te(e)).collection(n),i=Mt(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 te(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"&&Yo(g)?yn(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 te(a)).collection(t),i=n[0]?.columnName??"_id",c=n.map(u=>i==="_id"&&Yo(u.value)?yn(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 te(a)).collection(t),i=n.map(l=>{let u=Mt(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 te(t)).collection(n.collection),o=performance.now(),i=[],c=0,l;switch(n.operation){case"find":{let f=kt(n.filter??{}),b=s.find(f,n.options??{});b.sort(n.sort??Ra("",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=kt(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=kt(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=kt(n.filter??{});c=(await s.deleteOne(f,n.options??{})).deletedCount??0,l="OK";break}case"deleteMany":{let f=kt(n.filter??{});c=(await s.deleteMany(f,n.options??{})).deletedCount??0,l="OK";break}case"count":{let f=kt(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=>Mt(f));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:c,duration:u,message:l}}catch(n){throw this.wrapError(n)}}}});function Aa(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 Da(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 Jo(r,e,t){let n=Da(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 _a(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 Oa(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 Xo(r,e={}){let t=_a(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=Oa(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 Zo=N(()=>{"use strict";y()});var lm,um,mm,dm,pm,fm,ym,hm,gm,Fe,tr,ei=N(()=>{"use strict";y();ee();We();Ve();rt();ce();He();Zo();lm=547,um=15003,mm=2812,dm=/^Error: (\d+), Severity: (\d+), State: (\d+)\.?$/,pm=3726,fm=1913,ym=1505,hm=new Set([1919,1978]),gm=3723,Fe=r=>`[${r.replaceAll("]","]]")}]`,tr=class extends re{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`[${e}]`}mapToUniversalType(e){return Dn(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}=Aa(n,0),m=Da(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 H(n),u=i?this.decodeOffsetCursor(i):0,{clause:m,values:p,nextIdx:f}=Aa(c,0),[b,{total:h,estimated:g}]=await Promise.all([this.getPrimaryKeyColumns(l,t),this.countRows(l,t,m,p)]),S=Jo(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 D=(await w.query(`SELECT * FROM [${t}] ${m} ${S} OFFSET @p${f} ROWS FETCH NEXT @p${f+1} ROWS ONLY`)).recordset,R=D.length>a;return R&&(D=D.slice(0,a)),{data:D,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 H()).request().query(`
|
|
34
45
|
SELECT
|
|
35
46
|
d.name AS name,
|
|
36
47
|
CAST(ROUND(CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)), 2) AS VARCHAR(20)) + ' MB' AS size,
|
|
@@ -41,7 +52,7 @@ var hc=Object.defineProperty;var S=(r,e)=>()=>(r&&(e=r(r=0)),e);var on=(r,e)=>{f
|
|
|
41
52
|
WHERE (d.database_id > 4 OR d.name = DB_NAME())
|
|
42
53
|
GROUP BY d.name, d.owner_sid, d.collation_name
|
|
43
54
|
ORDER BY d.name
|
|
44
|
-
`);if(!t.recordset[0])throw new
|
|
55
|
+
`);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(`
|
|
45
56
|
SELECT
|
|
46
57
|
@@VERSION AS version,
|
|
47
58
|
DB_NAME() AS database_name,
|
|
@@ -50,26 +61,19 @@ var hc=Object.defineProperty;var S=(r,e)=>()=>(r&&(e=r(r=0)),e);var on=(r,e)=>{f
|
|
|
50
61
|
(SELECT local_tcp_port FROM sys.dm_exec_connections WHERE session_id = @@SPID) AS port,
|
|
51
62
|
@@MAX_CONNECTIONS AS max_connections,
|
|
52
63
|
(SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1) AS active_connections
|
|
53
|
-
`);if(!t.recordset[0])throw new
|
|
54
|
-
|
|
55
|
-
FROM information_schema.tables
|
|
56
|
-
WHERE table_catalog = DB_NAME()
|
|
57
|
-
AND table_type = 'BASE TABLE'
|
|
58
|
-
AND table_schema = 'dbo'
|
|
59
|
-
ORDER BY table_name
|
|
60
|
-
`);return!n.recordset||n.recordset.length===0?[]:Promise.all(n.recordset.map(async a=>{let s=await t.request().query(`SELECT COUNT(*) as count FROM [${a.tableName}]`);return{tableName:a.tableName,rowCount:s.recordset[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e,o=await G(t),c=a.map(m=>{let d=wa(m.columnType,m.isArray??!1),p=`[${m.columnName}] ${d}`;if(!m.isNullable&&!m.isPrimaryKey&&(p+=" NOT NULL"),m.defaultValue&&!d.includes("IDENTITY")){let f=Ca(m.defaultValue,d);f!==null&&(p+=` DEFAULT ${f}`)}return p}),i=[],l=a.filter(m=>m.isPrimaryKey);l.length>0&&i.push(`PRIMARY KEY (${l.map(m=>`[${m.columnName}]`).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&i.push(`UNIQUE ([${m.columnName}])`);let u=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}] (
|
|
61
|
-
${[...c,...i,...u].join(`,
|
|
64
|
+
`);if(!t.recordset[0])throw new d(500,{message:"No connection information returned from server"});let n=t.recordset[0],a=Ae();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>=nt)return{tableName:a,rowCount:s,rowCountEstimated:!0};let o=await t.request().query(`SELECT COUNT(*) as count FROM ${Fe(a)}`);return{tableName:a,rowCount:Number(o.recordset[0]?.count??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=_a(m.columnType,m.isArray??!1),f=`[${m.columnName}] ${p}`;if(!m.isNullable&&!m.isPrimaryKey&&(f+=" NOT NULL"),m.defaultValue&&!p.includes("IDENTITY")){let b=Oa(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}] (
|
|
65
|
+
${[...i,...c,...u].join(`,
|
|
62
66
|
`)}
|
|
63
|
-
)`)}async deleteTable(e){let{tableName:t,db:n,cascade:a}=e,s=await
|
|
67
|
+
)`)}async deleteTable(e){let{tableName:t,db:n,cascade:a}=e,s=await H(n),o=await s.request().input("tableName",t).query(`
|
|
64
68
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
65
69
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
66
|
-
`);if(Number(o.recordset[0]?.cnt??0)===0)throw new
|
|
70
|
+
`);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===pm)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(`
|
|
67
71
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
68
72
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
69
|
-
`);if(Number(o.recordset[0]?.cnt??0)>0)throw new
|
|
73
|
+
`);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(`
|
|
70
74
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
71
75
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
72
|
-
`);if(Number(a.recordset[0]?.cnt??0)===0)throw new
|
|
76
|
+
`);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(`
|
|
73
77
|
SELECT
|
|
74
78
|
c.COLUMN_NAME,
|
|
75
79
|
c.DATA_TYPE,
|
|
@@ -105,10 +109,10 @@ var hc=Object.defineProperty;var S=(r,e)=>()=>(r&&(e=r(r=0)),e);var on=(r,e)=>{f
|
|
|
105
109
|
AND c.TABLE_NAME = @tableName
|
|
106
110
|
AND c.TABLE_SCHEMA = 'dbo'
|
|
107
111
|
ORDER BY c.ORDINAL_POSITION
|
|
108
|
-
`);if(!s.recordset||s.recordset.length===0)throw new
|
|
112
|
+
`);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}] (
|
|
109
113
|
${o.join(`,
|
|
110
114
|
`)}
|
|
111
|
-
)`}async getTableColumns({tableName:e,db:t}){let n=await
|
|
115
|
+
)`}async getTableColumns({tableName:e,db:t}){let n=await H(t),a=await n.request().input("tableName",e).query(`
|
|
112
116
|
SELECT
|
|
113
117
|
c.COLUMN_NAME AS columnName,
|
|
114
118
|
c.DATA_TYPE AS dataType,
|
|
@@ -146,28 +150,28 @@ ${o.join(`,
|
|
|
146
150
|
AND c.TABLE_NAME = @tableName
|
|
147
151
|
AND c.TABLE_SCHEMA = 'dbo'
|
|
148
152
|
ORDER BY c.ORDINAL_POSITION
|
|
149
|
-
`);if(!a.recordset||a.recordset.length===0)throw new
|
|
153
|
+
`);if(!a.recordset||a.recordset.length===0)throw new d(404,{message:`Table "${e}" does not exist`});let s=await n.request().input("tableName",e).query(`
|
|
150
154
|
SELECT cc.COLUMN_NAME AS columnName, chk.CHECK_CLAUSE AS checkClause
|
|
151
155
|
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS chk
|
|
152
156
|
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cc
|
|
153
157
|
ON chk.CONSTRAINT_NAME = cc.CONSTRAINT_NAME AND cc.TABLE_SCHEMA = 'dbo'
|
|
154
158
|
WHERE cc.TABLE_NAME = @tableName AND cc.TABLE_CATALOG = DB_NAME()
|
|
155
|
-
`),o=new Map;for(let
|
|
159
|
+
`),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":Dn(i.dataType),dataTypeLabel:c?"enum":Lr(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(`
|
|
156
160
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
157
161
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
158
|
-
`);if(Number(
|
|
162
|
+
`);if(Number(p.recordset[0]?.cnt??0)>0)throw new d(409,{message:`Column "${n}" already exists in table "${t}"`});let f=Xo({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(`
|
|
159
163
|
SELECT dc.name AS constraint_name
|
|
160
164
|
FROM sys.default_constraints dc
|
|
161
165
|
JOIN sys.columns c
|
|
162
166
|
ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
|
|
163
167
|
WHERE OBJECT_NAME(dc.parent_object_id) = @tableName AND c.name = @columnName
|
|
164
|
-
`)).recordset[0]?.constraint_name;u&&await
|
|
168
|
+
`)).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(`
|
|
165
169
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
166
170
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
167
|
-
`);if(Number(
|
|
171
|
+
`);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=dm.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:De(o)}}catch(n){let a=n.number;if(a===um)return ne("Reading the error log needs the securityadmin server role: ALTER SERVER ROLE securityadmin ADD MEMBER <login>;");if(a===mm)return ne("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(`
|
|
168
172
|
SELECT COLUMN_NAME AS columnName FROM INFORMATION_SCHEMA.COLUMNS
|
|
169
173
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
170
|
-
`),u=new Set(l.recordset.map(
|
|
174
|
+
`),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 ${Fe(n)} ON [dbo].${Fe(t)} (${a.map(Fe).join(", ")})`)}catch(c){let l=c.number;throw c instanceof Error&&(l===fm||l===ym)?new d(409,{message:c.message,cause:c}):c instanceof Error&&l!==void 0&&hm.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 ${Fe(t)} ON [dbo].${Fe(e)}`)}catch(a){throw a instanceof Error&&a.number===gm?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(h=>h.name)),l=Object.keys(a).filter(h=>!c.has(h)),u=l.map(h=>{let g=a[h];return o.has(h)&&typeof g=="string"?g==="true"?1:0:g}),m=l.map(h=>`[${h}]`).join(", "),p=l.map((h,g)=>`@param${g}`).join(", "),f=s.request();l.forEach((h,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}`),h=await p.query(`UPDATE [${n}] SET ${f.join(", ")} WHERE ${b.join(" AND ")}`);if(h.rowsAffected[0]===0)throw new d(404,{message:`Record with ${this.describeKey(o,u)} not found in table "${n}"`});l+=h.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===lm)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,A)=>{let D=`${g}.${S}`;if(A.has(D))return;A.add(D);let R=await this.getForeignKeyReferences(g,n);for(let k of R){let x=i.request();w.forEach((M,W)=>{x.input(`val${W}`,M)});let v=w.map((M,W)=>`@val${W}`).join(", "),B=(await x.query(`SELECT [${k.referencedColumn}] FROM [${g}] WHERE [${S}] IN (${v})`)).recordset.map(M=>M[k.referencedColumn]);B.length>0&&await p(k.referencingTable,k.referencingColumn,B,A)}let C=i.request();w.forEach((k,x)=>{C.input(`delVal${x}`,k)});let _=w.map((k,x)=>`@delVal${x}`).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(", "),h=await f.query(`DELETE FROM [${e}] WHERE [${s}] IN (${b})`);return await i.commit(),{deletedCount:(h.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 h=u[b];return c.has(b)&&typeof h=="string"?h==="true"?1:0:h}),f=o.map((b,h)=>`@p${l}_${h}`).join(", ");o.forEach((b,h)=>{m.input(`p${l}_${h}`,p[h])});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),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(`
|
|
171
175
|
SELECT
|
|
172
176
|
fk.name AS constraint_name,
|
|
173
177
|
OBJECT_NAME(fk.parent_object_id) AS referencing_table,
|
|
@@ -177,7 +181,15 @@ ${o.join(`,
|
|
|
177
181
|
FROM sys.foreign_keys fk
|
|
178
182
|
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
|
|
179
183
|
WHERE OBJECT_NAME(fk.referenced_object_id) = @tableName
|
|
180
|
-
`)).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
|
|
184
|
+
`)).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(h=>h.columnName===u.referencedColumn))continue;let p=s.request();o.forEach((h,g)=>{p.input(`pk${g}`,h)});let f=o.map((h,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(`
|
|
185
|
+
SELECT t.name AS tableName, SUM(p.rows) AS estimate
|
|
186
|
+
FROM sys.tables t
|
|
187
|
+
JOIN sys.partitions p ON p.object_id = t.object_id AND p.index_id IN (0, 1)
|
|
188
|
+
WHERE t.schema_id = SCHEMA_ID('dbo')
|
|
189
|
+
${t===void 0?"":"AND t.name = @tableName"}
|
|
190
|
+
GROUP BY t.name
|
|
191
|
+
ORDER BY t.name
|
|
192
|
+
`);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>=nt)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 ${Fe(t)} ${n}`);return{total:Number(o.recordset[0]?.total??0),estimated:!1}}async getTableRowCount(e,t){let a=await(await H(t)).request().query(`SELECT COUNT(*) as count FROM [${e}]`);return Number(a.recordset[0]?.count??0)}async getPrimaryKeyColumns(e,t){return(await e.request().input("tableName",t).query(`
|
|
181
193
|
SELECT ku.COLUMN_NAME AS columnName
|
|
182
194
|
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
|
|
183
195
|
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku
|
|
@@ -205,13 +217,13 @@ ${o.join(`,
|
|
|
205
217
|
WHERE i.object_id = OBJECT_ID(QUOTENAME('dbo') + '.' + QUOTENAME(@tableName))
|
|
206
218
|
AND i.type > 0 AND i.is_hypothetical = 0
|
|
207
219
|
ORDER BY i.is_primary_key DESC, i.name, ic.is_included_column, ic.key_ordinal, ic.index_column_id
|
|
208
|
-
`),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(
|
|
220
|
+
`),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(Fe(s.columnName)):(o.index.columns.push(s.columnName),o.keys.push(`${Fe(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 ${Fe(o.indexName)} ON ${Fe(t)} (${i.join(", ")})${c.length?` INCLUDE (${c.join(", ")})`:""} WHERE ${o.filterDefinition}`}))}async assertTableExists(e,t){let n=await e.request().input("tableName",t).query(`
|
|
209
221
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
|
|
210
222
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
|
|
211
|
-
`);if(Number(n.recordset[0]?.cnt??0)===0)throw new
|
|
223
|
+
`);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(`
|
|
212
224
|
SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
|
|
213
225
|
WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
|
|
214
|
-
`);if(Number(a.recordset[0]?.cnt??0)===0)throw new
|
|
226
|
+
`);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 Ia(r){if(r.length===0)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":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 La(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 xa(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(p=>`\`${p}\``).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>n[p]);return{clause:`(${l}) ${c} (${u})`,values:m}}function bm(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 Tm(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 nr(r,e={}){let t=bm(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=Tm(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 ti=N(()=>{"use strict";y()});var ni,Em,wm,Sm,Cm,Rm,Nm,Am,Dm,Ye,rr,ri=N(()=>{"use strict";y();ee();We();Ve();rt();ce();He();ti();ni=1451,Em=1217,wm=1061,Sm=1062,Cm=1553,Rm=new Set([1059,1071,1167,1170,1280,3152]),Nm=1142,Am=1146,Dm={System:"info",Error:"error",Warning:"warning",Note:"info"},Ye=r=>`\`${r.replaceAll("`","``")}\``,rr=class extends re{mariaDb;async runQuery(e,t,n){let a=await j(e),[s]=await a.execute(t,n);return s}quoteIdentifier(e){return`\`${e}\``}mapToUniversalType(e){return An(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}=Ia(c),f="",b=[];if(n){let R=this.decodeCursor(n);if(R){let C=xa(R,s,u);f=C.clause,b=C.values}}let h="";m&&f?h=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${f}`:m?h=m:f&&(h=`WHERE ${f}`);let g=La((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=>`\`${R}\` ${u==="asc"?"DESC":"ASC"}`).join(", ")}`):!g&&l.length>0&&(S=`ORDER BY ${l.map(R=>`\`${R}\` ${u.toUpperCase()}`).join(", ")}`);let w=`SELECT * FROM \`${t}\` ${h} ${S} LIMIT ${a+1}`,A=[...p,...b],D=`SELECT COUNT(*) as total FROM \`${t}\` ${m}`;return{sql:w,values:A,countSql:D,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}=Ia(l),[f,{total:b,estimated:h}]=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(M=>M.columnName),S=o[0].direction):typeof o=="string"&&o&&(g=[o]);let w=[...g,...f.filter(M=>!g.includes(M))],A="",D=[];if(c){let M=this.decodeCursor(c);if(M){let W=xa(M,s,S);A=W.clause,D=W.values}}let R="";m&&A?R=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${A}`:m?R=m:A&&(R=`WHERE ${A}`);let C=La((Array.isArray(o),o),i),_=f.filter(M=>!g.includes(M)),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 M=S==="asc"?"DESC":"ASC";O+=`, ${_.map(W=>`\`${W}\` ${M}`).join(", ")}`}}else w.length>0&&(O=`ORDER BY ${w.map(M=>`\`${M}\` ${S==="asc"?"DESC":"ASC"}`).join(", ")}`);else!C&&w.length>0?O=`ORDER BY ${w.map(M=>`\`${M}\` ${S.toUpperCase()}`).join(", ")}`:_.length&&(O+=`, ${_.map(M=>`\`${M}\` ${S.toUpperCase()}`).join(", ")}`);let[k]=await u.execute(`SELECT * FROM \`${t}\` ${R} ${O} LIMIT ${Math.floor(a)+1}`,[...p,...D]),x=k,v=x.length>a;v&&(x=x.slice(0,a)),s==="desc"&&(x=x.reverse());let $=null,B=null;if(x.length>0&&w.length>0){let M=x[0],W=x[x.length-1],Re=ut=>({values:Object.fromEntries(w.map(st=>[st,ut[st]])),sortColumns:w});s==="asc"?(v&&($=this.encodeCursor(Re(W))),c&&(B=this.encodeCursor(Re(M)))):(c&&($=this.encodeCursor(Re(W))),v&&(B=this.encodeCursor(Re(M))))}return{data:x,meta:{limit:a,total:b,...h&&{totalEstimated:!0},hasNextPage:s==="asc"?v:!!c,hasPreviousPage:s==="asc"?!!c:v,nextCursor:$,prevCursor:B}}}async getDatabasesList(){try{let e=await j(),[t]=await e.execute(`
|
|
215
227
|
SELECT
|
|
216
228
|
s.SCHEMA_NAME AS name,
|
|
217
229
|
CONCAT(ROUND(COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024, 2), ' MB') AS size,
|
|
@@ -222,7 +234,7 @@ ${o.join(`,
|
|
|
222
234
|
WHERE (s.SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') OR s.SCHEMA_NAME = DATABASE())
|
|
223
235
|
GROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME
|
|
224
236
|
ORDER BY s.SCHEMA_NAME
|
|
225
|
-
`);if(!t[0])throw new
|
|
237
|
+
`);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(`
|
|
226
238
|
SELECT
|
|
227
239
|
VERSION() AS version,
|
|
228
240
|
DATABASE() AS database_name,
|
|
@@ -230,15 +242,10 @@ ${o.join(`,
|
|
|
230
242
|
@@hostname AS host,
|
|
231
243
|
@@port AS port,
|
|
232
244
|
@@max_connections AS max_connections
|
|
233
|
-
`),[n]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new
|
|
234
|
-
|
|
235
|
-
FROM information_schema.tables
|
|
236
|
-
WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
|
|
237
|
-
ORDER BY table_name
|
|
238
|
-
`);return!n||n.length===0?[]:Promise.all(n.map(async a=>{let[s]=await t.execute(`SELECT COUNT(*) as count FROM \`${a.tableName}\``);return{tableName:a.tableName,rowCount:s[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:n,fields:a,foreignKeys:s}=e,o=Q(t),c=a.map(m=>er(m)),i=[],l=a.filter(m=>m.isPrimaryKey);l.length>0&&i.push(`PRIMARY KEY (${l.map(m=>`\`${m.columnName}\``).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&i.push(`UNIQUE KEY \`uq_${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}\` (
|
|
239
|
-
${[...c,...i,...u].join(`,
|
|
245
|
+
`),[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=Ae();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>=nt)return{tableName:a,rowCount:s,rowCountEstimated:!0};let[o]=await t.execute(`SELECT COUNT(*) as count FROM ${Ye(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=>nr(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}\` (
|
|
246
|
+
${[...i,...c,...u].join(`,
|
|
240
247
|
`)}
|
|
241
|
-
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:n,cascade:a}=e,s=
|
|
248
|
+
) 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===Em||l.errno===ni)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 (
|
|
242
249
|
SELECT 1 FROM information_schema.CHECK_CONSTRAINTS cc
|
|
243
250
|
WHERE cc.CONSTRAINT_SCHEMA = c.TABLE_SCHEMA
|
|
244
251
|
AND cc.TABLE_NAME = c.TABLE_NAME
|
|
@@ -253,6 +260,8 @@ ${o.join(`,
|
|
|
253
260
|
(c.COLUMN_KEY = 'PRI') AS isPrimaryKey,
|
|
254
261
|
(kcu.REFERENCED_TABLE_NAME IS NOT NULL) AS isForeignKey,
|
|
255
262
|
kcu.REFERENCED_TABLE_NAME AS referencedTable,
|
|
263
|
+
-- Tables of this database are listed without a schema: only another database's is named.
|
|
264
|
+
NULLIF(kcu.REFERENCED_TABLE_SCHEMA, DATABASE()) AS referencedSchema,
|
|
256
265
|
kcu.REFERENCED_COLUMN_NAME AS referencedColumn
|
|
257
266
|
FROM information_schema.COLUMNS c
|
|
258
267
|
LEFT JOIN information_schema.KEY_COLUMN_USAGE kcu
|
|
@@ -262,10 +271,16 @@ ${o.join(`,
|
|
|
262
271
|
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
263
272
|
WHERE c.TABLE_SCHEMA = DATABASE()
|
|
264
273
|
AND c.TABLE_NAME = ?
|
|
265
|
-
ORDER BY c.ORDINAL_POSITION`,[e]);if(!s||s.length===0)throw new
|
|
274
|
+
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:An(c,l),dataTypeLabel:Ir(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=nr({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=nr({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(`${Le} SELECT UNIX_TIMESTAMP(LOGGED) AS epoch, THREAD_ID, PRIO,
|
|
275
|
+
ERROR_CODE, SUBSYSTEM, DATA
|
|
276
|
+
FROM performance_schema.error_log ORDER BY LOGGED DESC LIMIT ${500}`);return{available:!0,source:"performance_schema.error_log",entries:De(n.reverse().map(a=>({ts:new Date(Number(a.epoch)*1e3).toISOString(),level:Dm[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:ye({thread:a.THREAD_ID})})))}}catch(n){let a=n.errno;if(a===Nm)return ne("Reading the server log needs: GRANT SELECT ON performance_schema.error_log TO <user>;");if(a===Am)return ne("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 ${Ye(n)} ON ${Ye(t)} (${a.map(Ye).join(", ")})`)}catch(c){let l=c.errno;throw c instanceof Error&&(l===wm||l===Sm)?new d(409,{message:c.message,cause:c}):c instanceof Error&&l!==void 0&&Rm.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 ${Ye(t)} ON ${Ye(e)}`)}catch(a){throw a instanceof Error&&a.errno===Cm?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}\` = ?`),[h]=await c.execute(`UPDATE \`${n}\` SET ${p.join(", ")} WHERE ${b.join(" AND ")}`,f);if(h.affectedRows===0)throw new d(404,{message:`Record with ${this.describeKey(o,u)} not found in table "${n}"`});l+=h.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===ni)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(h,g,S,w)=>{let A=`${h}.${g}`;if(w.has(A))return;w.add(A);let D=await this.getForeignKeyReferences(h,n);for(let _ of D){let O=S.map(()=>"?").join(", "),[k]=await i.execute(`SELECT \`${_.referencedColumn}\` FROM \`${h}\` WHERE \`${g}\` IN (${O})`,S),x=k.map(v=>v[_.referencedColumn]);x.length>0&&await p(_.referencingTable,_.referencingColumn,x,w)}let R=S.map(()=>"?").join(", "),[C]=await i.execute(`DELETE FROM \`${h}\` WHERE \`${g}\` IN (${R})`,S);l+=C.affectedRows,u.add(h)};for(let h of c)u.has(h.referencingTable)||await p(h.referencingTable,h.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
|
|
277
|
+
FROM information_schema.tables
|
|
278
|
+
WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
|
|
279
|
+
${t===void 0?"":"AND table_name = ?"}
|
|
280
|
+
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>=nt)return{total:o,estimated:!0}}let[s]=await e.execute(`SELECT COUNT(*) as total FROM ${Ye(t)} ${n}`,a);return{total:Number(s[0]?.total??0),estimated:!1}}isMariaDb(e){return this.mariaDb??=e.query("SELECT VERSION() LIKE '%MariaDB%' AS mariadb").then(([t])=>Number(t[0]?.mariadb)===1).catch(t=>{throw this.mariaDb=void 0,t}),this.mariaDb}async getPrimaryKeyColumns(e,t){let[n]=await e.execute(`SELECT COLUMN_NAME as column_name
|
|
266
281
|
FROM information_schema.COLUMNS
|
|
267
282
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_KEY = 'PRI'
|
|
268
|
-
ORDER BY ORDINAL_POSITION`,[t]);return n.map(a=>a.column_name)}async getForeignKeyReferences(e,t){let n=
|
|
283
|
+
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
|
|
269
284
|
kcu.CONSTRAINT_NAME AS constraint_name,
|
|
270
285
|
kcu.TABLE_NAME AS referencing_table,
|
|
271
286
|
kcu.COLUMN_NAME AS referencing_column,
|
|
@@ -278,31 +293,35 @@ ${o.join(`,
|
|
|
278
293
|
AND kcu.TABLE_NAME = tc.TABLE_NAME
|
|
279
294
|
WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
|
280
295
|
AND kcu.TABLE_SCHEMA = DATABASE()
|
|
281
|
-
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=Q(t),s=[];for(let o of n){let[c]=await a.execute(`SELECT * FROM \`${o.referencingTable}\` LIMIT 100`);c.length>0&&s.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:c})}return s}async getRelatedRecords(e,t,n){let a=await this.getForeignKeyReferences(e,n);if(a.length===0)return[];let s=Q(n),o=t.map(l=>l.value),c=[],i=new Map;for(let l of a){let u=`${l.referencingTable}.${l.referencingColumn}`;i.has(u)||i.set(u,[]),i.get(u)?.push(l)}for(let[,l]of i){let u=l[0];if(!u||!t.find(f=>f.columnName===u.referencedColumn))continue;let d=o.map(()=>"?").join(", "),[p]=await s.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${d}) LIMIT 100`,o);p.length>0&&c.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:p})}return c}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),c=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,c);let i=s.EXPRESSION??null;s.COLUMN_NAME===null&&i!==null?(c.index.columns.push(i),c.parts.push(`(${i})${s.COLLATION==="D"?" DESC":""}`),c.hasExpression=!0):(c.index.columns.push(String(s.COLUMN_NAME)),c.parts.push(`${ot(String(s.COLUMN_NAME))}${s.SUB_PART===null?"":`(${s.SUB_PART})`}${s.COLLATION==="D"?" DESC":""}`))}return[...a.values()].map(({index:s,parts:o,hasExpression:c})=>({...s,definition:c?`CREATE ${s.isUnique?"UNIQUE ":""}INDEX ${ot(s.indexName)} ON ${ot(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 F(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 F(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}}});import{HTTPException as nr}from"hono/http-exception";function Go(r,e,t){let n=[];for(let a of r){let s=_(a.columnName),o=t.get(a.columnName),c=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(c?`${s} IS NULL`:`${s} = ${ve(a.value,o,e)}`);break;case"is not":n.push(c?`${s} IS NOT NULL`:`${s} != ${ve(a.value,o,e)}`);break;case"like":n.push(`${Qt(s,o)} LIKE ${e(a.value)}`);break;case"not like":n.push(`${Qt(s,o)} NOT LIKE ${e(a.value)}`);break;case"ilike":n.push(`UPPER(${Qt(s,o)}) LIKE UPPER(${e(a.value)})`);break;case"not ilike":n.push(`UPPER(${Qt(s,o)}) NOT LIKE UPPER(${e(a.value)})`);break}}return n}function _a(r,e,t){if(e)throw new nr(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 Ia(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 _,rt,Aa,Da,Wo,um,Vo,mm,Qt,dm,ve,Jt,Yo,zo,Qo,pm,Jo,Xo,Zo=S(()=>{"use strict";h();_=r=>{if(r.includes('"')||r.includes("\0"))throw new nr(400,{message:`Oracle identifiers cannot contain double quotes: ${r}`});return`"${r}"`},rt=()=>{let r=[];return{values:r,bind:t=>(r.push(t),`:${r.length}`)}},Aa='YYYY-MM-DD"T"HH24:MI:SS',Da=`${Aa}.FF9`,Wo=`${Da}TZH:TZM`,um=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?\s*(Z|[+-]\d{2}(?::?\d{2})?)?$/i,Vo=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},mm=r=>{let e=r?Vo(r):null;return e==="date"?Aa:e==="timestampTz"?Wo:e?Da:null},Qt=(r,e)=>{let t=mm(e);return t?`TO_CHAR(${r}, '${t}')`:r},dm=(r,e)=>{let t=r instanceof Date?r.toISOString():r;if(typeof t!="string")throw new nr(400,{message:`Invalid Oracle ${e} value`});let n=t.trim().match(um);if(!n)throw new nr(400,{message:`Invalid Oracle date or timestamp value: ${t}`});let[,a,s,o,c="00",i="00",l="00",u="",m]=n,d=`${a}-${s}-${o}T${c}:${i}:${l}`;if(e==="date")return d;let p=`${d}.${u.padEnd(9,"0")}`;if(e==="timestamp")return p;if(!m||m.toUpperCase()==="Z")return`${p}+00:00`;let f=m.replace(":","");return`${p}${f.slice(0,3)}:${f.slice(3).padEnd(2,"0")}`},ve=(r,e,t)=>{let n=e?Vo(e):null;if(!n)return t(r);let a=t(r==null?null:dm(r,n));return n==="date"?`TO_DATE(${a}, '${Aa}')`:n==="timestamp"?`TO_TIMESTAMP(${a}, '${Da}')`:`TO_TIMESTAMP_TZ(${a}, '${Wo}')`},Jt=(r,e)=>r.map(({COLUMN_NAME:t,DATA_TYPE:n})=>{let a=`${e?`${e}.`:""}${_(t)}`,s=Qt(a,n);return s===a?a:`${s} AS ${_(t)}`}).join(", "),Yo=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()]},zo=r=>r.length?`WHERE ${r.join(" AND ")}`:"";Qo=(r,e)=>`ORDER BY ${r.map(t=>`${e?`${e}.`:""}${t.column===null?"ROWID":_(t.column)} ${t.direction.toUpperCase()}`).join(", ")}`,pm=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),Jo=r=>pm.has(r.toLowerCase().trim());Xo="GENERATED BY DEFAULT ON NULL AS IDENTITY"});var ei,ti=S(()=>{"use strict";h();ei=r=>{if(typeof r!="string"||!/^[+-]?\d+$/.test(r))return r;let e=Number(r);return Number.isSafeInteger(e)?e:r}});import{HTTPException as ne}from"hono/http-exception";import Re from"oracledb";var Oa,ni,ri,it,ai,fm,ym,si,rr,hm,bm,gm,Tm,Em,xa,oi,ar,ii=S(()=>{"use strict";h();ie();Ve();Ye();We();Zo();ti();Oa=r=>r.oracleServerVersion>=23e8,ni=r=>Buffer.isBuffer(r)?r.toString("hex"):r,ri=r=>{switch(r.dbType){case Re.DB_TYPE_NUMBER:return{type:Re.STRING,converter:ei};case Re.DB_TYPE_CLOB:case Re.DB_TYPE_NCLOB:return{type:Re.STRING};case Re.DB_TYPE_BLOB:return{type:Re.BUFFER,converter:ni};case Re.DB_TYPE_RAW:case Re.DB_TYPE_LONG_RAW:return{converter:ni}}},it=(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),ai=r=>{let e=r.DATA_DEFAULT?.trim();return e&&e.toUpperCase()!=="NULL"?e:null},fm=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}},ym=(r,e)=>`${e?`${e}.`:""}${r==="ROWID"?"ROWID":_(r)}`,si=r=>r.columns.map((e,t)=>`c.${_(e)} = p.${_(r.referencedColumns[t])}`).join(" AND "),rr=(r,e,t)=>`(${r.keys.map(n=>`(${r.columns.map((a,s)=>`${ym(a,e)} = ${t(n[s],a)}`).join(" AND ")})`).join(" OR ")})`,hm=r=>r.dbType===Re.DB_TYPE_DATE||r.dbType===Re.DB_TYPE_TIMESTAMP||r.dbType===Re.DB_TYPE_TIMESTAMP_TZ||r.dbType===Re.DB_TYPE_TIMESTAMP_LTZ,bm=[["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."]],gm=["ORA-00955","ORA-01408","ORA-01452"],Tm=["ORA-00972","ORA-01450","ORA-02327","ORA-02329"],Em="ORA-02429",xa=(r,e)=>r instanceof Error&&e.some(t=>r.message.startsWith(t)),oi={CASCADE:" ON DELETE CASCADE","SET NULL":" ON DELETE SET NULL",RESTRICT:"","NO ACTION":""},ar=class extends le{async runQuery(e,t,n){return this.withConnection(a=>this.query(a,t,n))}quoteIdentifier(e){return _(e)}mapToUniversalType(e){return yn(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 ne)){let t=bm.find(([n])=>e.message.startsWith(n));if(t)return new ne(400,{message:`${t[1]} (${e.message.split(`
|
|
282
|
-
`)[0]})`,cause:e});if(e.message.startsWith("ORA-00955"))return new
|
|
283
|
-
`)[0],cause:e})}return super.wrapError(e)}async withConnection(e){try{let t=await(await
|
|
296
|
+
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(`${Ye(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 ${Ye(s.indexName)} ON ${Ye(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 ci(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} ${Me(a.value,o,e)}`);break;case"is":n.push(i?`${s} IS NULL`:`${s} = ${Me(a.value,o,e)}`);break;case"is not":n.push(i?`${s} IS NOT NULL`:`${s} != ${Me(a.value,o,e)}`);break;case"like":n.push(`${hn(s,o)} LIKE ${e(a.value)}`);break;case"not like":n.push(`${hn(s,o)} NOT LIKE ${e(a.value)}`);break;case"ilike":n.push(`UPPER(${hn(s,o)}) LIKE UPPER(${e(a.value)})`);break;case"not ilike":n.push(`UPPER(${hn(s,o)}) NOT LIKE UPPER(${e(a.value)})`);break}}return n}function Ma(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 ka(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,at,Pa,$a,ai,_m,si,Om,hn,Im,Me,gn,oi,ii,li,Lm,ui,mi,di=N(()=>{"use strict";y();ce();I=r=>{if(r.includes('"')||r.includes("\0"))throw new d(400,{message:`Oracle identifiers cannot contain double quotes: ${r}`});return`"${r}"`},at=()=>{let r=[];return{values:r,bind:t=>(r.push(t),`:${r.length}`)}},Pa='YYYY-MM-DD"T"HH24:MI:SS',$a=`${Pa}.FF9`,ai=`${$a}TZH:TZM`,_m=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?\s*(Z|[+-]\d{2}(?::?\d{2})?)?$/i,si=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},Om=r=>{let e=r?si(r):null;return e==="date"?Pa:e==="timestampTz"?ai:e?$a:null},hn=(r,e)=>{let t=Om(e);return t?`TO_CHAR(${r}, '${t}')`:r},Im=(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(_m);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")}`},Me=(r,e,t)=>{let n=e?si(e):null;if(!n)return t(r);let a=t(r==null?null:Im(r,n));return n==="date"?`TO_DATE(${a}, '${Pa}')`:n==="timestamp"?`TO_TIMESTAMP(${a}, '${$a}')`:`TO_TIMESTAMP_TZ(${a}, '${ai}')`},gn=(r,e)=>r.map(({COLUMN_NAME:t,DATA_TYPE:n})=>{let a=`${e?`${e}.`:""}${I(t)}`,s=hn(a,n);return s===a?a:`${s} AS ${I(t)}`}).join(", "),oi=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()]},ii=r=>r.length?`WHERE ${r.join(" AND ")}`:"";li=(r,e)=>`ORDER BY ${r.map(t=>`${e?`${e}.`:""}${t.column===null?"ROWID":I(t.column)} ${t.direction.toUpperCase()}`).join(", ")}`,Lm=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),ui=r=>Lm.has(r.toLowerCase().trim());mi="GENERATED BY DEFAULT ON NULL AS IDENTITY"});var pi,fi=N(()=>{"use strict";y();pi=r=>{if(typeof r!="string"||!/^[+-]?\d+$/.test(r))return r;let e=Number(r);return Number.isSafeInteger(e)?e:r}});var va,yi,hi,ct,gi,xm,Pm,bi,ar,$m,Mm,km,vm,Um,Ua,Ti,qm,sr,Ei=N(()=>{"use strict";y();ee();We();Ve();rt();ht();ce();He();di();fi();va=r=>r.oracleServerVersion>=23e8,yi=r=>Buffer.isBuffer(r)?r.toString("hex"):r,hi=r=>{let e=Be("oracle");switch(r.dbType){case e.DB_TYPE_NUMBER:return{type:e.STRING,converter:pi};case e.DB_TYPE_CLOB:case e.DB_TYPE_NCLOB:return{type:e.STRING};case e.DB_TYPE_BLOB:return{type:e.BUFFER,converter:yi};case e.DB_TYPE_RAW:case e.DB_TYPE_LONG_RAW:return{converter:yi}}},ct=(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),gi=r=>{let e=r.DATA_DEFAULT?.trim();return e&&e.toUpperCase()!=="NULL"?e:null},xm=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}},Pm=(r,e)=>`${e?`${e}.`:""}${r==="ROWID"?"ROWID":I(r)}`,bi=r=>r.columns.map((e,t)=>`c.${I(e)} = p.${I(r.referencedColumns[t])}`).join(" AND "),ar=(r,e,t)=>`(${r.keys.map(n=>`(${r.columns.map((a,s)=>`${Pm(a,e)} = ${t(n[s],a)}`).join(" AND ")})`).join(" OR ")})`,$m=r=>{let e=Be("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},Mm=[["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."]],km=["ORA-00955","ORA-01408","ORA-01452"],vm=["ORA-00972","ORA-01450","ORA-02327","ORA-02329"],Um="ORA-02429",Ua=(r,e)=>r instanceof Error&&e.some(t=>r.message.startsWith(t)),Ti={CASCADE:" ON DELETE CASCADE","SET NULL":" ON DELETE SET NULL",RESTRICT:"","NO ACTION":""},qm={1:"fatal",2:"error",8:"warning",16:"info"},sr=class extends re{async runQuery(e,t,n){return this.withConnection(a=>this.query(a,t,n))}quoteIdentifier(e){return I(e)}mapToUniversalType(e){return In(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=Mm.find(([n])=>e.message.startsWith(n));if(t)return new d(400,{message:`${t[1]} (${e.message.split(`
|
|
297
|
+
`)[0]})`,cause:e});if(e.message.startsWith("ORA-00955"))return new d(409,{message:e.message.split(`
|
|
298
|
+
`)[0],cause:e})}return super.wrapError(e)}async withConnection(e){try{let t=await(await ba()).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:Be("oracle").OUT_FORMAT_OBJECT,fetchTypeHandler:hi})).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:h}=at(),g=ii(ci(i,h,u)),S=[...b],[w]=await this.query(c,`SELECT COUNT(*) AS "total" FROM ${I(t)} ${g}`,S),A="t",D=await this.query(c,`SELECT ${gn(l,A)} FROM ${I(t)} ${A} ${g} ${li(p,A)} OFFSET ${h(f)} ROWS FETCH NEXT ${h(n+1)} ROWS ONLY`,b),R=D.length>n,C=_=>this.encodeCursor({values:{_offset:_},sortColumns:["_offset"]});return{data:D.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 ${gn(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,
|
|
284
299
|
(SELECT NVL(SUM(bytes), 0) FROM user_segments) AS bytes,
|
|
285
300
|
(SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET') AS encoding
|
|
286
|
-
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
|
|
301
|
+
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 ba().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}=Ae();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
|
|
287
302
|
WHERE dropped = 'NO' AND nested = 'NO' AND secondary = 'N' AND (iot_type IS NULL OR iot_type = 'IOT')
|
|
288
|
-
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((c
|
|
303
|
+
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 Ti))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=va(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)})${Ti[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
|
|
289
304
|
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
|
|
290
305
|
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', TRUE);
|
|
291
|
-
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((c
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
306
|
+
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=xm(o);return{columnName:o.COLUMN_NAME,dataType:In(c),dataTypeLabel:$r(c),isNullable:o.NULLABLE==="Y",columnDefault:o.GENERATION_TYPE?`GENERATED ${o.GENERATION_TYPE}${o.DEFAULT_ON_NULL==="YES"?" ON NULL":""} AS IDENTITY`:gi(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:va(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=va(i),l=(await this.requireColumn(i,t,n)).find(m=>m.COLUMN_NAME===n),u=`${I(n)} ${Ma(a,!1,c)}`;o?.trim()?u+=` DEFAULT ${ka(o,c)}`:l&&!l.GENERATION_TYPE&&gi(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,`${Le} SELECT TO_CHAR(SYS_EXTRACT_UTC(ORIGINATING_TIMESTAMP),
|
|
307
|
+
'YYYY-MM-DD"T"HH24:MI:SS.FF3"Z"') AS TS, MESSAGE_LEVEL, COMPONENT_ID, PROCESS_ID,
|
|
308
|
+
MODULE_ID, MESSAGE_TEXT
|
|
309
|
+
FROM V$DIAG_ALERT_EXT
|
|
310
|
+
ORDER BY ORIGINATING_TIMESTAMP DESC FETCH FIRST ${500} ROWS ONLY`);return{available:!0,source:"V$DIAG_ALERT_EXT (alert log)",entries:De(t.reverse().map(n=>({ts:n.TS,level:qm[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:ye({process:n.PROCESS_ID,module:n.MODULE_ID})})))}}catch(t){if(t instanceof Error&&t.message.startsWith("ORA-00942:"))return ne("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 Ua(m,km)?new d(409,{message:m.message.split(`
|
|
311
|
+
`)[0],cause:m}):Ua(m,vm)?new d(400,{message:m.message.split(`
|
|
312
|
+
`)[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 Ua(s,[Um])?new d(400,{message:s.message.split(`
|
|
313
|
+
`)[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}=at(),u=a.map(m=>Me(ct(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}=at(),f=u.map(g=>`${I(g.columnName)} = ${Me(ct(g.value,i.get(g.columnName)),i.get(g.columnName),p)}`).join(", "),b=n.map((g,S)=>`${I(g)} = ${Me(ct(l[S],i.get(g)),i.get(g),p)}`).join(" AND "),h=await this.execute(o,`UPDATE ${I(t)} SET ${f} WHERE ${b}`,m);if(h===0)throw new d(404,{message:`Record with ${this.describeKey(n,l)} not found in table "${t}"`});c+=h}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}=at(),l=ar(a,void 0,(m,p)=>Me(ct(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}=at(),f=ar(a,"p",(h,g)=>Me(ct(h,o.get(g)),o.get(g),p)),b=await this.query(s,`SELECT ${gn(u,"c")} FROM ${I(l.referencingTable)} c JOIN ${I(e)} p ON ${bi(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(h=>`"${h}"`).join(" -> ")} form a cycle.`});let u=await this.columnTypes(o,i),m=0;for(let h of await this.foreignKeys(o,"referenced",i)){let{values:g,bind:S}=at(),w=ar(c,"p",(D,R)=>R==="ROWID"?`CHARTOROWID(${S(D)})`:Me(ct(D,u.get(R)),u.get(R),S)),A=await this.query(o,`SELECT DISTINCT ROWIDTOCHAR(c.ROWID) AS "__rowid" FROM ${I(h.referencingTable)} c JOIN ${I(i)} p ON ${bi(h)} WHERE ${w}`,g);m+=await a(o,h.referencingTable,{columns:["ROWID"],keys:A.map(D=>[D.__rowid])},[...l,i])}let{values:p,bind:f}=at(),b=ar(c,void 0,(h,g)=>g==="ROWID"?`CHARTOROWID(${f(h)})`:Me(ct(h,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}=at(),b=n.map(h=>Me(ct(u[h],o.get(h)),o.get(h),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:Be("oracle").OUT_FORMAT_OBJECT,fetchTypeHandler:hi,autoCommit:!0,resultSet:!0}),c=performance.now()-o;if(i.resultSet){if(i.metaData?.some($m))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)} ${Ma(e.columnType,e.isArray??!1,n)}`;return e.isIdentity||ui(e.columnType)?a+=` ${mi}`:e.defaultValue?.trim()&&(a+=` DEFAULT ${ka(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,
|
|
295
314
|
c.nullable, c.data_default, c.default_on_null, i.generation_type
|
|
296
315
|
FROM user_tab_columns c
|
|
297
316
|
LEFT JOIN user_tab_identity_cols i ON i.table_name = c.table_name AND i.column_name = c.column_name
|
|
298
|
-
WHERE c.table_name = :1 ORDER BY c.column_id`,[t])}async columnTypes(e,t){let n=await this.requireColumns(e,t);return new Map(n.map(a=>[a.COLUMN_NAME,a.DATA_TYPE]))}async requireColumns(e,t){let n=await this.columns(e,t);if(!n.length)throw new
|
|
317
|
+
WHERE c.table_name = :1 ORDER BY c.column_id`,[t])}async columnTypes(e,t){let n=await this.requireColumns(e,t);return new Map(n.map(a=>[a.COLUMN_NAME,a.DATA_TYPE]))}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){await this.requireColumns(e,t);let n=await this.query(e,`SELECT i.index_name, i.index_type, i.uniqueness, ic.column_name, ic.descend, ie.column_expression,
|
|
299
318
|
(SELECT MIN(c.constraint_type) FROM user_constraints c
|
|
300
319
|
WHERE c.index_name = i.index_name AND c.table_name = i.table_name AND c.constraint_type IN ('P', 'U')) AS constraint_type
|
|
301
320
|
FROM user_indexes i
|
|
302
321
|
JOIN user_ind_columns ic ON ic.index_name = i.index_name
|
|
303
322
|
LEFT JOIN user_ind_expressions ie ON ie.index_name = ic.index_name AND ie.column_position = ic.column_position
|
|
304
323
|
WHERE i.table_name = :1 AND i.table_owner = USER AND i.index_type <> 'LOB'
|
|
305
|
-
ORDER BY i.index_name, ic.column_position`,[t]),a=new Map;for(let s of n){let o=a.get(s.INDEX_NAME)??{index:{indexName:s.INDEX_NAME,columns:[],isUnique:s.UNIQUENESS==="UNIQUE",method:s.INDEX_TYPE.toLowerCase(),kind:s.CONSTRAINT_TYPE==="P"?"primary":s.CONSTRAINT_TYPE==="U"?"unique-constraint":"index",definition:null},row:s,keys:[],hasExpression:!1};a.set(s.INDEX_NAME,o);let
|
|
324
|
+
ORDER BY i.index_name, ic.column_position`,[t]),a=new Map;for(let s of n){let o=a.get(s.INDEX_NAME)??{index:{indexName:s.INDEX_NAME,columns:[],isUnique:s.UNIQUENESS==="UNIQUE",method:s.INDEX_TYPE.toLowerCase(),kind:s.CONSTRAINT_TYPE==="P"?"primary":s.CONSTRAINT_TYPE==="U"?"unique-constraint":"index",definition:null},row:s,keys:[],hasExpression:!1};a.set(s.INDEX_NAME,o);let i=s.DESCEND==="DESC"?" DESC":"",c=s.COLUMN_EXPRESSION===null?s.COLUMN_NAME:/^"([^"]+)"$/.exec(s.COLUMN_EXPRESSION.trim())?.[1]??null;if(c!==null)o.index.columns.push(c),o.keys.push(`${I(c)}${i}`);else{let l=(s.COLUMN_EXPRESSION??"").trim();o.index.columns.push(l),o.keys.push(`${l}${i}`),o.hasExpression=!0}}return[...a.values()].map(({index:s,row:o,keys:i,hasExpression:c})=>({...s,definition:c?`CREATE ${s.isUnique?"UNIQUE ":""}${o.INDEX_TYPE.includes("BITMAP")?"BITMAP ":""}INDEX ${I(s.indexName)} ON ${I(t)} (${i.join(", ")})`:null})).sort((s,o)=>+(o.kind==="primary")-+(s.kind==="primary"))}async primaryKey(e,t){return(await this.query(e,`SELECT cc.column_name FROM user_constraints c
|
|
306
325
|
JOIN user_cons_columns cc ON cc.constraint_name = c.constraint_name
|
|
307
326
|
WHERE c.constraint_type = 'P' AND c.table_name = :1
|
|
308
327
|
ORDER BY cc.position`,[t])).map(a=>a.COLUMN_NAME)}async foreignKeys(e,t,n){let a=await this.query(e,`SELECT c.constraint_name, c.table_name AS referencing_table, cc.column_name AS referencing_column,
|
|
@@ -312,10 +331,20 @@ ${o.join(`,
|
|
|
312
331
|
JOIN user_constraints r ON r.constraint_name = c.r_constraint_name AND r.owner = c.r_owner
|
|
313
332
|
JOIN user_cons_columns rc ON rc.constraint_name = r.constraint_name AND rc.position = cc.position
|
|
314
333
|
WHERE c.constraint_type = 'R' AND ${t==="referencing"?"c":"r"}.table_name = :1
|
|
315
|
-
ORDER BY c.constraint_name, cc.position`,[n]);return
|
|
334
|
+
ORDER BY c.constraint_name, cc.position`,[n]);return oi(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 ${gn(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 Bm,Fm,Km,qa,Hm,jm,Wm,Vm,Ym,zm,Gm,Qm,Jm,wi,Si=N(()=>{"use strict";y();rt();Bm={PANIC:"fatal",FATAL:"fatal",ERROR:"error",WARNING:"warning",NOTICE:"info",INFO:"info",LOG:"info"},Fm=/^duration: ([\d.]+) ms(?:\s+(?:statement|(?:execute|bind|parse) [^:]*): ([\s\S]*))?$/,Km=/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?: (?:([A-Za-z]+)|([+-])(\d{2}):?(\d{2})?))?/,qa=(r,e)=>{let t=Km.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,h=Number(l.padEnd(3,"0").slice(0,3)),g=Date.UTC(Number(n),Number(a)-1,Number(s),Number(o),Number(i),Number(c),h)-b*6e4;return new Date(g).toISOString()},Hm=r=>{let e=Fm.exec(r.message);return{ts:r.ts,level:Bm[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}},jm=r=>r.message.includes(Le)||r.statement?.includes(Le),Wm=/^(.*?)\b(DEBUG[1-5]|LOG|INFO|NOTICE|WARNING|ERROR|FATAL|PANIC|DETAIL|HINT|QUERY|CONTEXT|LOCATION|STATEMENT): {2}(.*)$/,Vm=new Set(["DETAIL","HINT","QUERY","CONTEXT","LOCATION","STATEMENT"]),Ym=(r,e)=>{let t=[],n=null;for(let a of r){if(a.startsWith(" ")){n?.(a.slice(1));continue}let s=Wm.exec(a);if(!s){n=null;continue}let[,o,i,c]=s,l=t.at(-1);if(Vm.has(i)){if(!l)continue;if(i==="STATEMENT")l.statement=c,n=p=>{l.statement=`${l.statement}
|
|
335
|
+
${p}`};else{let p=i.toLowerCase();l.detail[p]=c,n=f=>{l.detail[p]=`${l.detail[p]}
|
|
336
|
+
${f}`}}continue}let u=qa(o,e.logUtcOffsetMinutes)??l?.ts;if(!u)continue;let m={ts:u,severity:i,message:c,detail:ye({pid:/\[(\d+)\]/.exec(o)?.[1]})};t.push(m),n=p=>{m.message=`${m.message}
|
|
337
|
+
${p}`}}return t},zm=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===`
|
|
338
|
+
`?(t.push(n),e.push(t),t=[],n=""):o!=="\r"&&(n+=o)}return(n||t.length)&&(t.push(n),e.push(t)),e},Gm=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/,Qm=(r,e)=>{let t=r;if(e.truncatedStart){let a=r.split(`
|
|
339
|
+
`),s=a.findIndex((o,i)=>i>0&&Gm.test(o));t=s===-1?"":a.slice(s).join(`
|
|
340
|
+
`)}let n=[];for(let a of zm(t)){let s=qa(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:ye({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},Jm=(r,e)=>{let t=[];for(let n of r){let a;try{a=JSON.parse(n)}catch{continue}let s=qa(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:ye({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},wi=(r,e,t)=>{let n=r.split(`
|
|
341
|
+
`);return t.truncatedStart&&e!=="csvlog"&&n.shift(),(e==="csvlog"?Qm(r,t):e==="jsonlog"?Jm(n,t):Ym(n,t)).filter(s=>!jm(s)).map(Hm)}});function Fa(r){if(r.length===0)return{clause:"",values:[]};let e=[],t=[];for(let n of r){let a=t.length+1,s=`"${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 Ka(r,e){return Array.isArray(r)?r.length===0?"":`ORDER BY ${r.map(n=>`"${n.columnName}" ${n.direction.toUpperCase()}`).join(", ")}`:r&&typeof r=="string"?`ORDER BY "${r}" ${e?.toUpperCase()||"ASC"}`:""}function Ha(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(b=>`"${b}"`).join(", "),p=s.map((b,h)=>`$${n+h}`).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 Xm,ze,Ba,se,Ci=N(()=>{"use strict";y();Xm=r=>`(SELECT sp.schema_name FROM unnest(current_schemas(false)) WITH ORDINALITY AS sp(schema_name, position)
|
|
316
342
|
JOIN information_schema.tables it
|
|
317
343
|
ON it.table_schema = sp.schema_name AND it.table_name = ${r}
|
|
318
|
-
ORDER BY sp.position LIMIT 1)
|
|
344
|
+
ORDER BY sp.position LIMIT 1)`,ze=(r,e)=>`COALESCE(${e}::text, ${Xm(r)})`,Ba=r=>`"${r.replaceAll('"','""')}"`,se=(r,e)=>e?`${Ba(e)}.${Ba(r)}`:Ba(r)});var Zm,or,Ri=N(()=>{"use strict";y();ee();We();Ve();rt();ht();ce();He();Si();Ci();Zm=1024*1024,or=class extends re{databaseSizeSupport;async runQuery(e,t,n){return(await(await z(e)).query(t,n)).rows}quoteIdentifier(e){return`"${e.replaceAll('"','""')}"`}mapToUniversalType(e){return Nn(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:h}=Fa(l),g="",S=[];if(a){let v=this.decodeCursor(a);if(v){let $=Ha(v,o,p,h.length+1);g=$.clause,S=$.values}}let w="";b&&g?w=`WHERE ${b.replace(/^WHERE\s+/i,"")} AND ${g}`:b?w=b:g&&(w=`WHERE ${g}`);let A=Ka((Array.isArray(i),i),c),D=A;o==="desc"?A?D=A.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):D=`ORDER BY ${f.map($=>`"${$}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!A&&f.length>0&&(D=`ORDER BY ${f.map($=>`"${$}" ${p.toUpperCase()}`).join(", ")}`);let R=h.length+S.length+1,C=se(t,n),_=`SELECT * FROM ${C} ${w} ${D} LIMIT $${R}`,O=[...h,...S,s+1],k=`SELECT COUNT(*) as total FROM ${C} ${b}`;return{sql:_,values:O,countSql:k,countValues:h}}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(h=>[h,f[h]])),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 z(a),p=se(t,n),{clause:f,values:b}=Fa(u),[h,{total:g,estimated:S}]=await Promise.all([this.getPrimaryKeyColumns(m,p),this.countRows(m,p,f,b)]).catch(V=>{throw yt(V)&&V.code==="42P01"?new d(404,{message:`Table "${t}" does not exist`}):this.wrapError(V)}),w=[],A=c;Array.isArray(i)&&i.length>0?(w=i.map(V=>V.columnName),A=i[0].direction):typeof i=="string"&&i&&(w=[i]);let D=h.length?h:["ctid"],R=[...w,...D.filter(V=>!w.includes(V))],C="",_=[];if(l){let V=this.decodeCursor(l);if(V){let be=Ha(V,o,A,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 k=Ka((Array.isArray(i),i),c),x=k;if(o==="desc"?k?x=k.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):x=`ORDER BY ${R.map(be=>`"${be}" ${A==="asc"?"DESC":"ASC"}`).join(", ")}`:!k&&R.length>0&&(x=`ORDER BY ${R.map(be=>`"${be}" ${A.toUpperCase()}`).join(", ")}`),k){let V=D.filter(Ft=>!w.includes(Ft)),be=A==="desc"!=(o==="desc")?"DESC":"ASC";V.length&&(x+=`, ${V.map(Ft=>`${this.quoteIdentifier(Ft)} ${be}`).join(", ")}`)}let v=R.includes("ctid"),$=[...h.map(V=>`"${V}"`),...v?["ctid"]:[]],B=b.length+_.length+1,W=(await m.query(`SELECT ${["*",...$].join(", ")} FROM ${p} ${O} ${x} LIMIT $${B}`,[...b,..._,s+1])).rows,Re=W.length>s;Re&&(W=W.slice(0,s)),o==="desc"&&(W=W.reverse());let ut=W.map(V=>{if(!v)return V;let{ctid:be,...Ft}=V;return Ft}).filter(V=>Object.keys(V).length>0),st=V=>({values:Object.fromEntries(R.map(be=>[be,V[be]])),sortColumns:R}),F=null,me=null;if(W.length>0){let V=W[0],be=W[W.length-1];o==="asc"?(Re&&(F=this.encodeCursor(st(be))),l&&(me=this.encodeCursor(st(V)))):(l&&(F=this.encodeCursor(st(be))),Re&&(me=this.encodeCursor(st(V))))}return{data:ut,meta:{limit:s,total:g,...S&&{totalEstimated:!0},hasNextPage:o==="asc"?Re:!!l,hasPreviousPage:o==="asc"?!!l:Re,nextCursor:F,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
|
|
345
|
+
ELSE (SELECT COUNT(*) FROM ${t}) END as total,
|
|
346
|
+
reltuples >= $1 as estimated
|
|
347
|
+
FROM pg_catalog.pg_class WHERE oid = $2::regclass`,[nt,t]);return{total:Number(s[0].total),estimated:s[0].estimated===!0}}async getDatabasesList(){try{let e=await z(),t=await this.supportsDatabaseSize(e)?"pg_size_pretty(pg_database_size(d.datname))":"'unknown'",{rows:n}=await e.query(`
|
|
319
348
|
SELECT
|
|
320
349
|
d.datname as name,
|
|
321
350
|
${t} as size,
|
|
@@ -325,7 +354,7 @@ ${o.join(`,
|
|
|
325
354
|
WHERE d.datistemplate = false
|
|
326
355
|
AND (d.datname NOT IN ('postgres', 'rdsadmin') OR d.datname = current_database())
|
|
327
356
|
ORDER BY d.datname;
|
|
328
|
-
`);if(!n[0])throw new
|
|
357
|
+
`);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 z(),{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 z(),{rows:t}=await e.query(`
|
|
329
358
|
SELECT
|
|
330
359
|
version() as version,
|
|
331
360
|
current_database() as database,
|
|
@@ -334,30 +363,33 @@ ${o.join(`,
|
|
|
334
363
|
inet_server_port()::int4 as port,
|
|
335
364
|
(SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,
|
|
336
365
|
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;
|
|
337
|
-
`);if(!t[0])throw new
|
|
338
|
-
SELECT table_schema as "schemaName", table_name as "tableName"
|
|
339
|
-
FROM information_schema.tables
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
366
|
+
`);if(!t[0])throw new d(500,{message:"No connection information returned from database"});let{connectionInfoSchema:n}=await Promise.resolve().then(()=>(ee(),no)),a=n.parse(t[0]),s=Ae();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 z(e),n=u=>u.replaceAll('"','""'),{rows:a}=await t.query(`
|
|
367
|
+
SELECT t.table_schema as "schemaName", t.table_name as "tableName", c.reltuples as "estimate"
|
|
368
|
+
FROM information_schema.tables t
|
|
369
|
+
JOIN pg_catalog.pg_namespace n ON n.nspname = t.table_schema
|
|
370
|
+
JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid AND c.relname = t.table_name
|
|
371
|
+
WHERE t.table_type = 'BASE TABLE'
|
|
372
|
+
AND t.table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
373
|
+
AND t.table_schema NOT LIKE 'pg_toast%'
|
|
374
|
+
ORDER BY t.table_schema, t.table_name;
|
|
375
|
+
`);if(!a[0])return[];let s=a.flatMap((u,m)=>u.estimate<nt?[{...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 z(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}" (
|
|
376
|
+
${[...c,...l].join(`,
|
|
346
377
|
`)}
|
|
347
|
-
);`)}async deleteTable(e){let{tableName:t,
|
|
348
|
-
FROM information_schema.columns WHERE table_schema = ${
|
|
378
|
+
);`)}async deleteTable(e){let{tableName:t,schemaName:n,db:a,cascade:s}=e,o=await z(a),i=se(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 z(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 z(n),s=ze("$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
|
|
379
|
+
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
|
|
349
380
|
FROM information_schema.table_constraints tc
|
|
350
381
|
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
351
382
|
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'
|
|
352
|
-
WHERE tc.table_schema = ${
|
|
353
|
-
AND indexname NOT IN (SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = ${
|
|
354
|
-
`)),
|
|
355
|
-
`)}async getTableColumns({tableName:e,db:t}){let
|
|
383
|
+
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
|
|
384
|
+
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:A,character_maximum_length:D,numeric_precision:R,numeric_scale:C}=S;return w==="USER-DEFINED"?A:w==="ARRAY"?`${A.replace(/^_/,"")}[]`:(w==="character varying"||w==="varchar")&&D?`varchar(${D})`:w==="character"&&D?`char(${D})`: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}),h=new Map;for(let S of u){let w=h.get(S.constraint_name)??[];w.push(S),h.set(S.constraint_name,w)}let g=[];for(let[S,w]of h){let A=w[0],D=w.map(R=>R.column_name).join(", ");A.constraint_type==="PRIMARY KEY"?g.push(` constraint ${S} primary key (${D})`):A.constraint_type==="FOREIGN KEY"?g.push(` constraint ${S} foreign key (${D}) references ${A.foreign_table_name} (${A.foreign_column_name})`):A.constraint_type==="UNIQUE"&&g.push(` constraint ${S} unique (${D})`)}f.push([...b,...g].join(`,
|
|
385
|
+
`)),f.push(") tablespace pg_default;");for(let S of m)[...h.values()].some(A=>A[0].constraint_type==="UNIQUE"&&A[0].constraint_name===S.indexname)||(f.push(""),f.push(`${S.indexdef};`));return f.join(`
|
|
386
|
+
`)}async getTableColumns({tableName:e,db:t,schemaName:n}){let a=await z(t),s=ze("$1","$2"),{rows:o}=await a.query(`SELECT
|
|
356
387
|
c.column_name as "columnName", c.data_type as "dataType", c.udt_name as "udtName",
|
|
357
388
|
c.is_nullable = 'YES' as "isNullable", c.column_default as "columnDefault",
|
|
358
389
|
CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as "isPrimaryKey",
|
|
359
390
|
CASE WHEN fk.column_name IS NOT NULL THEN true ELSE false END as "isForeignKey",
|
|
360
|
-
fk.
|
|
391
|
+
fk.referenced_schema as "referencedSchema", fk.referenced_table as "referencedTable",
|
|
392
|
+
fk.referenced_column as "referencedColumn",
|
|
361
393
|
CASE WHEN c.data_type = 'USER-DEFINED' THEN
|
|
362
394
|
(SELECT array_agg(e.enumlabel ORDER BY e.enumsortorder) FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid WHERE t.typname = c.udt_name)
|
|
363
395
|
ELSE NULL END as "enumValues"
|
|
@@ -365,16 +397,20 @@ ${o.join(`,
|
|
|
365
397
|
LEFT JOIN (
|
|
366
398
|
SELECT ku.column_name FROM information_schema.table_constraints tc
|
|
367
399
|
JOIN information_schema.key_column_usage ku ON tc.constraint_name = ku.constraint_name AND tc.table_schema = ku.table_schema
|
|
368
|
-
WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = ${
|
|
400
|
+
WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = ${s} AND tc.table_name = $1
|
|
369
401
|
) pk ON c.column_name = pk.column_name
|
|
370
402
|
LEFT JOIN (
|
|
371
|
-
SELECT kcu.column_name, ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
|
|
403
|
+
SELECT kcu.column_name, ccu.table_schema AS referenced_schema, ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
|
|
372
404
|
FROM information_schema.table_constraints tc
|
|
373
405
|
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
374
406
|
JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema
|
|
375
|
-
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = ${
|
|
407
|
+
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = ${s} AND tc.table_name = $1
|
|
376
408
|
) fk ON c.column_name = fk.column_name
|
|
377
|
-
WHERE c.table_schema = ${$e("$1")} AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e]);if(!a||a.length===0)throw new k(404,{message:`Table "${e}" does not exist`});return a.map(s=>{let o=null;return s.enumValues&&(Array.isArray(s.enumValues)?o=s.enumValues:typeof s.enumValues=="string"&&(o=s.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:s.columnName,dataType:un(s.dataType),dataTypeLabel:Dr(s.dataType),isNullable:s.isNullable,columnDefault:s.columnDefault,isPrimaryKey:s.isPrimaryKey,isForeignKey:s.isForeignKey,referencedTable:s.referencedTable,referencedColumn:s.referencedColumn,enumValues:o}})}async addColumn(e){let{tableName:t,columnName:n,columnType:a,defaultValue:s,isPrimaryKey:o,isNullable:c,isUnique:i,isIdentity:l,isArray:u,db:m}=e,d=te(m),{rows:p}=await d.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!p[0]?.exists)throw new k(404,{message:`Table "${t}" does not exist`});let{rows:f}=await d.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${$e("$1")}) as exists;`,[t,n]);if(f[0]?.exists)throw new k(409,{message:`Column "${n}" already exists in table "${t}"`});let y=`"${n}" ${a}`;u&&(y+="[]"),o&&(y+=" PRIMARY KEY"),i&&!o&&(y+=" UNIQUE"),c||(y+=" NOT NULL"),l&&(y+=" GENERATED ALWAYS AS IDENTITY"),s?.trim()&&!l&&(y+=` DEFAULT ${s.trim()}`),await d.query(`ALTER TABLE "${t}" ADD COLUMN ${y}`)}async deleteColumn(e){let{tableName:t,columnName:n,cascade:a,db:s}=e,o=te(s),{rows:c}=await o.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!c[0]?.exists)throw new k(404,{message:`Table "${t}" does not exist`});let{rows:i}=await o.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${$e("$1")}) as exists;`,[t,n]);if(!i[0]?.exists)throw new k(404,{message:`Column "${n}" does not exist in table "${t}"`});let{rowCount:l}=await o.query(`ALTER TABLE "${t}" DROP COLUMN "${n}" ${a?"CASCADE":"RESTRICT"}`);return{deletedCount:l??0}}async alterColumn(e){let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o,db:c}=e,i=te(c),{rows:l}=await i.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!l[0]?.exists)throw new k(404,{message:`Table "${t}" does not exist`});let{rows:u}=await i.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${$e("$1")}) as exists;`,[t,n]);if(!u[0]?.exists)throw new k(404,{message:`Column "${n}" does not exist in table "${t}"`});let m=await i.connect();try{await m.query("BEGIN"),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${n}" TYPE ${a}`),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${n}" ${s?"DROP":"SET"} NOT NULL`),o?.trim()?await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${n}" SET DEFAULT ${o.trim()}`):await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${n}" DROP DEFAULT`),await m.query("COMMIT")}catch(d){throw await m.query("ROLLBACK"),d}finally{m.release()}}async renameColumn(e){let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=te(s),c=`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${$e("$1")}) as exists;`,{rows:i}=await o.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!i[0]?.exists)throw new k(404,{message:`Table "${t}" does not exist`});let{rows:l}=await o.query(c,[t,n]);if(!l[0]?.exists)throw new k(404,{message:`Column "${n}" does not exist in table "${t}"`});let{rows:u}=await o.query(c,[t,a]);if(u[0]?.exists)throw new k(409,{message:`Column "${a}" already exists in table "${t}"`});await o.query(`ALTER TABLE "${t}" RENAME COLUMN "${n}" TO "${a}"`)}async getTableIndexes({tableName:e,db:t}){try{return(await this.listIndexes(te(t),e)).map(({schemaName:a,...s})=>s)}catch(n){throw this.wrapError(n)}}async createIndex(e){let{tableName:t,indexName:n,columns:a,isUnique:s,method:o="btree",db:c}=e;try{let i=te(c);await this.assertTableExists(i,t);let{rows:l}=await i.query(`SELECT column_name as "columnName" FROM information_schema.columns WHERE table_name = $1 AND table_schema = ${$e("$1")}`,[t]),u=new Set(l.map(d=>d.columnName)),m=a.find(d=>!u.has(d));if(m!==void 0)throw new k(400,{message:`Column "${m}" does not exist in table "${t}"`});if(!X.pg.indexes.methods.includes(o))throw new k(400,{message:`Unsupported index method "${o}"`});await i.query(`CREATE ${s?"UNIQUE ":""}INDEX ${this.quoteIdentifier(n)} ON ${this.quoteIdentifier(t)} USING ${o} (${a.map(d=>this.quoteIdentifier(d)).join(", ")})`)}catch(i){let l=i.code;throw i instanceof Error&&(l==="42P07"||l==="23505")?new k(409,{message:i.message,cause:i}):i instanceof Error&&(l==="0A000"||l==="42704")?new k(400,{message:i.message,cause:i}):this.wrapError(i)}}async dropIndex({tableName:e,indexName:t,db:n}){try{let a=te(n),s=(await this.listIndexes(a,e)).find(o=>o.indexName===t);if(!s)throw new k(404,{message:`Index "${t}" does not exist on table "${e}"`});if(s.kind!=="index")throw new k(400,{message:`Index "${t}" backs a constraint; drop the constraint to remove it`});await a.query(`DROP INDEX ${this.quoteIdentifier(s.schemaName)}.${this.quoteIdentifier(t)}`)}catch(a){throw this.wrapError(a)}}async addRecord({db:e,params:t}){let{tableName:n,data:a}=t,s=te(e),o=Object.keys(a),c=Object.values(a),i=o.map((m,d)=>`$${d+1}`).join(", "),l=o.map(m=>`"${m}"`).join(", "),u=await s.query(`INSERT INTO "${n}" (${l}) VALUES (${i}) RETURNING *`,c);if(u.rowCount===0)throw new k(500,{message:`Failed to insert record into "${n}"`});return{insertedCount:u.rowCount??0}}async updateRecords({params:e,db:t}){let{tableName:n}=e,a=te(t),s=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,n),s);let o=this.groupUpdatesByKey(e,s);await a.query("BEGIN");try{let c=0;for(let{keyValues:i,rowUpdates:l}of o){let u=l.map((f,y)=>`"${f.columnName}" = $${y+1}`),m=l.map(f=>f.value!==null&&typeof f.value=="object"?JSON.stringify(f.value):f.value),d=s.map((f,y)=>`"${f}" = $${m.length+y+1}`);m.push(...i);let p=await a.query(`UPDATE "${n}" SET ${u.join(", ")} WHERE ${d.join(" AND ")} RETURNING *`,m);if(p.rowCount===0)throw new k(404,{message:`Record with ${this.describeKey(s,i)} not found in table "${n}"`});c+=p.rowCount??0}return await a.query("COMMIT"),{updatedCount:c}}catch(c){throw await a.query("ROLLBACK"),c instanceof k?c:new k(500,{message:`Failed to update records in "${n}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:n}){let a=te(n),s=t[0]?.columnName;if(!s)throw new k(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let o=t.map(i=>i.value),c=o.map((i,l)=>`$${l+1}`).join(", ");try{await a.query("BEGIN");let i=await a.query(`DELETE FROM "${e}" WHERE "${s}" IN (${c}) RETURNING *`,o);return await a.query("COMMIT"),{deletedCount:i.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(i){if(await a.query("ROLLBACK"),i.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(a,e,t,n)};throw i instanceof k?i:new k(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:n}){let a=te(n),s=t[0]?.columnName;if(!s)throw new k(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let o=t.map(c=>c.value);await a.query("BEGIN");try{let c=await this.getFkConstraints(a,e),i=0,l=new Set,u=async(p,f,y)=>{let g=await this.getFkConstraints(a,p);for(let A of g){let N=y.map((D,$)=>`$${$+1}`).join(", "),{rows:E}=await a.query(`SELECT "${A.referencedColumn}" FROM "${p}" WHERE "${f}" IN (${N})`,y),R=E.map(D=>D[A.referencedColumn]);R.length>0&&await u(A.referencingTable,A.referencingColumn,R)}let w=y.map((A,N)=>`$${N+1}`).join(", "),C=await a.query(`DELETE FROM "${p}" WHERE "${f}" IN (${w})`,y);i+=C.rowCount??0,l.add(p)};for(let p of c)l.has(p.referencingTable)||await u(p.referencingTable,p.referencingColumn,o);let m=o.map((p,f)=>`$${f+1}`).join(", "),d=await a.query(`DELETE FROM "${e}" WHERE "${s}" IN (${m}) RETURNING *`,o);return await a.query("COMMIT"),{deletedCount:(d.rowCount??0)+i}}catch(c){throw await a.query("ROLLBACK"),c instanceof k?c:new k(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:n}){if(!t||t.length===0)throw new k(400,{message:"At least one record is required"});let s=await te(n).connect();try{let o=Object.keys(t[0]),c=o.map(l=>`"${l}"`).join(", "),i=0;await s.query("BEGIN");for(let l of t){let u=o.map(d=>l[d]),m=o.map((d,p)=>`$${p+1}`).join(", ");try{await s.query(`INSERT INTO "${e}" (${c}) VALUES (${m}) RETURNING *`,u),i++}catch(d){throw new k(500,{message:`Failed: ${d instanceof Error?d.message:String(d)}`})}}return await s.query("COMMIT"),{success:!0,message:`Bulk insert completed: ${i} records inserted`,successCount:i,failureCount:0}}catch(o){throw await s.query("ROLLBACK"),o instanceof k?o:new k(500,{message:`Failed to bulk insert records into "${e}"`})}finally{s.release()}}async executeQuery({query:e,db:t}){let n=te(t);if(!e?.trim())throw new k(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),s=performance.now(),o=await n.query(a),c=performance.now()-s;return{columns:o.fields.map(i=>i.name),rows:o.rows,rowCount:o.rows.length,duration:c,message:o.rows.length===0?"OK":void 0}}supportsDatabaseSize(e){return this.databaseSizeSupport??=e.query(`SELECT to_regprocedure('pg_database_size(name)') IS NOT NULL AS "supported"`).then(({rows:t})=>t[0]?.supported===!0).catch(t=>{throw this.databaseSizeSupport=void 0,t}),this.databaseSizeSupport}async assertTableExists(e,t){let{rows:n}=await e.query(`SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ${ci}) as exists;`,[t]);if(!n[0]?.exists)throw new k(404,{message:`Table "${t}" does not exist`})}async listIndexes(e,t){await this.assertTableExists(e,t);let{rows:n}=await e.query(`SELECT
|
|
409
|
+
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:Nn(i.dataType),dataTypeLabel:Or(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 z(p);await this.assertTableExists(f,t,m);let b=se(t,m),{rows:h}=await f.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${ze("$1","$3")}) as exists;`,[t,n,m??null]);if(h[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 z(o);await this.assertTableExists(i,t,n);let c=se(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 = ${ze("$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 z(c);await this.assertTableExists(l,t,n);let u=se(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 = ${ze("$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 z(o),c=`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${ze("$1","$3")}) as exists;`;await this.assertTableExists(i,t,n);let l=se(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 z(e);try{let{rows:[n]}=await t.query(`${Le} SELECT current_setting('logging_collector') AS collector,
|
|
410
|
+
current_setting('log_destination') AS destination,
|
|
411
|
+
EXTRACT(EPOCH FROM (now() AT TIME ZONE current_setting('log_timezone'))
|
|
412
|
+
- (now() AT TIME ZONE 'UTC')) / 60 AS offset`);if(n.collector!=="on")return ne("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(`${Le} SELECT path, (pg_stat_file(path)).size AS size
|
|
413
|
+
FROM pg_current_logfile($1) AS path`,[s]);if(!o.path||o.size===null)return ne("PostgreSQL has not opened a log file yet.");let i=Number(o.size),c=Math.max(0,i-Zm),{rows:[l]}=await t.query(`${Le} SELECT pg_read_binary_file($1, $2, $3) AS data`,[o.path,c,i-c]);return{available:!0,source:`${o.path} (${s})`,entries:De(wi(l.data.toString("utf8"),s,{logUtcOffsetMinutes:Number(n.offset),truncatedStart:c>0}))}}catch(n){if(yt(n)&&n.code==="42501")return ne("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 z(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 z(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 = ${ze("$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(!G.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 ${se(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 z(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 z(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 ${se(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 z(n),o=se(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 h=await s.query(`UPDATE ${o} SET ${p.join(", ")} WHERE ${b.join(" AND ")} RETURNING *`,f);if(h.rowCount===0)throw new d(404,{message:`Record with ${this.describeKey(i,u)} not found in table "${a}"`});l+=h.rowCount??0}return await s.query("COMMIT"),{updatedCount:l}}catch(l){throw await s.query("ROLLBACK"),l instanceof d?l:new d(500,{message:`Failed to update records in "${a}"`})}}async deleteRecords({tableName:e,schemaName:t,primaryKeys:n,db:a}){let s=await z(a),o=se(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 z(a),o=se(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(h,g,S,w)=>{let A=se(h,g),D=await this.getFkConstraints(s,h,g);for(let _ of D){let O=w.map((v,$)=>`$${$+1}`).join(", "),{rows:k}=await s.query(`SELECT "${_.referencedColumn}" FROM ${A} WHERE "${S}" IN (${O})`,w),x=k.map(v=>v[_.referencedColumn]);x.length>0&&await p(_.referencingTable,_.referencingSchema,_.referencingColumn,x)}let R=w.map((_,O)=>`$${O+1}`).join(", "),C=await s.query(`DELETE FROM ${A} WHERE "${S}" IN (${R})`,w);u+=C.rowCount??0,m.add(A)};for(let h of l)m.has(se(h.referencingTable,h.referencingSchema))||await p(h.referencingTable,h.referencingSchema,h.referencingColumn,c);let f=c.map((h,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 z(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 ${se(e,t)} (${c}) VALUES (${p}) RETURNING *`,m),l++}catch(f){throw 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?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 z(n),{rows:s}=await a.query(`SELECT * FROM ${se(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 z(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){return this.databaseSizeSupport??=e.query(`SELECT to_regprocedure('pg_database_size(name)') IS NOT NULL AS "supported"`).then(({rows:t})=>t[0]?.supported===!0).catch(t=>{throw this.databaseSizeSupport=void 0,t}),this.databaseSizeSupport}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 = ${ze("$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
|
|
378
414
|
ic.relname AS "indexName",
|
|
379
415
|
n.nspname AS "schemaName",
|
|
380
416
|
ARRAY(
|
|
@@ -396,17 +432,17 @@ ${o.join(`,
|
|
|
396
432
|
JOIN pg_namespace n ON n.oid = ic.relnamespace
|
|
397
433
|
JOIN pg_am am ON am.oid = ic.relam
|
|
398
434
|
WHERE i.indrelid = $1::regclass
|
|
399
|
-
ORDER BY i.indisprimary DESC, ic.relname`,[
|
|
435
|
+
ORDER BY i.indisprimary DESC, ic.relname`,[se(t,n)]);return a}async getPrimaryKeyColumns(e,t){return(await e.query(`SELECT a.attname as column_name
|
|
400
436
|
FROM pg_index i
|
|
401
437
|
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
402
438
|
WHERE i.indrelid = $1::regclass AND i.indisprimary
|
|
403
|
-
ORDER BY array_position(i.indkey, a.attnum)`,[
|
|
439
|
+
ORDER BY array_position(i.indkey, a.attnum)`,[t])).rows.map(a=>a.column_name)}async getFkConstraints(e,t,n){let{rows:a}=await e.query(`SELECT tc.constraint_name, tc.table_schema as referencing_schema, tc.table_name as referencing_table, kcu.column_name as referencing_column,
|
|
404
440
|
ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
|
|
405
441
|
FROM information_schema.table_constraints AS tc
|
|
406
442
|
JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
407
443
|
JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema
|
|
408
|
-
WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1`,[t]);return
|
|
409
|
-
`){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
|
|
444
|
+
WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1 AND ccu.table_schema = ${ze("$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 ${se(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,h)=>`$${h+1}`).join(", "),{rows:f}=await e.query(`SELECT * FROM ${se(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 Ii(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===`
|
|
445
|
+
`){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 Li(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 td(e);if(n){let s=`${t} ${n}`,o=_i[s];if(o)return o(e)}let a=_i[t];return a?a(e):typeof e=="string"||typeof e=="number"||e===null?Ce(e):ed(e)?Ge(e):vt(e)}var ed,Oi,vt,Ce,Ni,Ge,Ai,td,nd,Di,_i,xi=N(()=>{"use strict";y();ed=r=>Array.isArray(r)&&r.every(e=>typeof e=="string"||e===null),Oi=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}),Ce=r=>r===null?{columns:["value"],rows:[{value:null}],rowCount:0}:{columns:["value"],rows:[{value:r}],rowCount:1},Ni=r=>({columns:["status"],rows:[{status:r}],rowCount:1}),Ge=r=>Array.isArray(r)?{columns:["#","value"],rows:r.map((e,t)=>({"#":t,value:e})),rowCount:r.length}:vt(r),Ai=r=>{if(!Oi(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}},td=r=>{if(!Oi(r))return Ge(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}},nd=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}},Di=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}},_i={PING:Ni,GET:Ce,SET:Ni,TYPE:Ce,TTL:Ce,EXISTS:Ce,DBSIZE:Ce,DEL:Ce,INCR:Ce,DECR:Ce,STRLEN:Ce,LLEN:Ce,SCARD:Ce,ZCARD:Ce,HLEN:Ce,HGET:Ce,HMGET:Ge,MGET:Ge,KEYS:Ge,LRANGE:Ge,SMEMBERS:Ge,HGETALL:Ai,HKEYS:Ge,HVALS:Ge,"CONFIG GET":Ai,ZRANGE:Ge,INFO:nd,XRANGE:Di,XREVRANGE:Di}});import{createHash as rd,randomBytes as ad}from"crypto";import{z as Je}from"zod";function $i(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 Sd(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 Mi(r){let e=r.key;if(e==null||e==="")throw new d(400,{message:"Field 'key' is required"});return String(e)}function Ya(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 lr(r){return typeof r=="string"?r:r==null?"":typeof r=="object"?JSON.stringify(r):String(r)}function ki(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 vi(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 Cd(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 Rd(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 Nd(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 wn,ja,bn,sd,od,id,cd,ld,ud,md,dd,pd,lt,fd,fe,yd,hd,Tn,gd,_e,bd,ir,X,cr,Et,En,Wa,xe,Va,Td,Ed,Qe,Ut,qt,Pi,wd,ur,Ui=N(()=>{"use strict";y();We();Ve();rt();ce();xi();wn=["strings","hashes","lists","sets","zsets","streams"],ja={strings:"string",hashes:"hash",lists:"list",sets:"set",zsets:"zset",streams:"stream"},bn="Schema is fixed for Redis tables; this operation is not supported",sd="Sorting is not supported for Redis tables",od="Filtering is not supported for Redis tables",id="Backward pagination is not supported for Redis tables (SCAN is forward-only)",cd=10,ld=3e4,ud=1e4,md=256*1024,dd=8*1024*1024,pd=r=>wn.includes(r),lt=r=>{if(!pd(r))throw new d(404,{message:`Table "${r}" does not exist in Redis. Valid tables: ${wn.join(", ")}`});return r},fd=r=>/[\s"']/.test(r)||r===""?JSON.stringify(r):r,fe=r=>{if(r==="")return Tt();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},yd=r=>Buffer.from(JSON.stringify(r)).toString("base64url"),hd=r=>{try{return Je.object({scanCursor:Je.string().regex(/^\d+$/),search:Je.string().max(512).optional(),exactPattern:Je.boolean(),type:Je.enum(["string","hash","list","set","zset","stream"]).optional()}).parse(JSON.parse(Buffer.from(r,"base64url").toString("utf-8")))}catch{return null}},Tn=r=>Buffer.from(JSON.stringify(r)).toString("base64url"),gd=r=>{try{return Je.object({key:Je.string().min(1).max(16*1024),type:Je.enum(["string","hash","list","set","zset","stream","unknown"]),cursor:Je.string().min(1).max(512),direction:Je.enum(["forward","backward"])}).parse(JSON.parse(Buffer.from(r,"base64url").toString("utf8")))}catch{return null}},_e=r=>{let e=r.toString("utf8");return Buffer.from(e,"utf8").equals(r)?{base64:r.toString("base64url"),utf8:e}:{base64:r.toString("base64url")}},bd=r=>r.replaceAll(/[\\*?[\]]/g,"\\$&"),ir=r=>{let e=Buffer.isBuffer(r)?r.toString("utf8"):String(r);return["string","hash","list","set","zset","stream"].includes(e)?e:"unknown"},X=r=>Buffer.from(r,"base64url"),cr=r=>r==="-"?Buffer.alloc(0):X(r),Et=r=>rd("sha256").update(r).digest("base64url"),En=()=>new d(409,{message:"This key changed since it was loaded. Reload it or explicitly overwrite."}),Wa=r=>{let e=r instanceof Error?r.message:String(r);return/(NOPERM|unknown command|not allowed|unsupported)/i.test(e)},xe=(r,e)=>{if(r!==e)throw new d(400,{message:`This operation requires a ${e} key, but the key is ${r}.`})},Va=r=>{if(r===null)throw En();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})},Td=r=>Buffer.from(JSON.stringify(r)).toString("base64url"),Ed=r=>{try{return JSON.parse(Buffer.from(r,"base64url").toString("utf-8"))}catch{return null}},Qe=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}),Ut=Qe({columnName:"key",dataType:"text",isPrimaryKey:!0}),qt=Qe({columnName:"ttl",dataType:"number",isNullable:!0}),Pi={strings:[Ut,Qe({columnName:"value",dataType:"text",isNullable:!0}),qt],hashes:[Ut,Qe({columnName:"value",dataType:"json"}),qt],lists:[Ut,Qe({columnName:"value",dataType:"array"}),qt],sets:[Ut,Qe({columnName:"value",dataType:"array"}),qt],zsets:[Ut,Qe({columnName:"value",dataType:"json"}),qt],streams:[Ut,Qe({columnName:"length",dataType:"number"}),Qe({columnName:"first-id",dataType:"text",isNullable:!0}),Qe({columnName:"last-id",dataType:"text",isNullable:!0}),qt]},wd={strings:`-- Redis string keys
|
|
410
446
|
-- Columns: key (text, PK), value (text), ttl (number, seconds; -1 = no TTL, -2 = missing)
|
|
411
447
|
-- Backed by: GET / SET / EXPIRE`,hashes:`-- Redis hash keys
|
|
412
448
|
-- Columns: key (text, PK), value (json: {field: value, ...}), ttl (number)
|
|
@@ -418,21 +454,24 @@ ${o.join(`,
|
|
|
418
454
|
-- Columns: key (text, PK), value (json: [{member, score}, ...]), ttl (number)
|
|
419
455
|
-- Backed by: ZRANGE WITHSCORES / ZADD / EXPIRE`,streams:`-- Redis stream keys
|
|
420
456
|
-- Columns: key (text, PK), length (number), first-id (text), last-id (text), ttl (number)
|
|
421
|
-
-- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},lr=class extends le{countCache=new Map;runQuery(){throw new I(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new I(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:c}=e,i=Te(t),l=await Ie(i),u="0";if(c){let C=km(c);if(!C||C.search!==a||C.exactPattern!==s||C.type!==o)throw new I(400,{message:"Invalid or stale key scan cursor"});u=C.scanCursor}let m=a?s?a:`*${qm(a)}*`:"*",d=[u,"MATCH",m,"COUNT",n];o&&d.push("TYPE",o);let[p,f]=await l.scanBuffer(...d),y=Buffer.isBuffer(p)?p.toString("utf8"):p,g=l.pipeline();for(let C of f)g.call("TYPE",C),g.pttl(C),g.call("MEMORY","USAGE",C);let w=await g.exec()??[];return{keys:f.map((C,A)=>{let N=A*3,E=w[N+2]?.[1];return{key:Oe(C),type:or(w[N]?.[1]),ttlMs:Number(w[N+1]?.[1]??-2),memoryBytes:E==null?null:Number(E)}}),nextCursor:y==="0"?null:Mm({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:c}=e,i=ir(n),l=await Ie(Te(t)),[u,m,d,p]=await Promise.all([l.callBuffer("TYPE",i),l.pttl(i),l.call("MEMORY","USAGE",i).catch(()=>null),l.callBuffer("DUMP",i)]),f=p;if(!f)throw new I(404,{message:"Redis key no longer exists"});let y=or(u),g={key:Oe(i),type:y,ttlMs:Number(m),memoryBytes:d===null?null:Number(d),revision:ht(f)},w=a?vm(a):null;if(a&&(!w||w.key!==n||w.type!==y||w.direction!==c))throw new I(400,{message:"Invalid or stale key details cursor"});if(y==="string"){let C=await l.strlen(i),A=o?Pm:$m,N=await l.getrangeBuffer(i,0,A-1);return{...g,length:C,value:{kind:"string",value:Oe(N),truncated:C>A},nextCursor:null,hasMore:!1}}if(y==="hash"){let[C,A]=await Promise.all([l.hlen(i),l.hscanBuffer(i,w?.cursor??"0","COUNT",String(s))]),[N,E]=A,R=Buffer.isBuffer(N)?N.toString("utf8"):N,D=[];for(let $=0;$<E.length;$+=2)D.push({field:Oe(E[$]),value:Oe(E[$+1])});return{...g,length:C,value:{kind:"hash",entries:D},nextCursor:R==="0"?null:Zt({key:n,type:y,cursor:R,direction:c}),hasMore:R!=="0"}}if(y==="list"){let C=Number.parseInt(w?.cursor??"0",10),A=await l.llen(i),N=await l.lrangeBuffer(i,C,C+s-1),E=C+N.length,R=E<A;return{...g,length:A,value:{kind:"list",entries:N.map((D,$)=>({index:C+$,value:Oe(D)}))},nextCursor:R?Zt({key:n,type:y,cursor:String(E),direction:c}):null,hasMore:R}}if(y==="set"){let[C,A]=await Promise.all([l.scard(i),l.sscanBuffer(i,w?.cursor??"0","COUNT",String(s))]),[N,E]=A,R=Buffer.isBuffer(N)?N.toString("utf8"):N;return{...g,length:C,value:{kind:"set",members:E.map(Oe)},nextCursor:R==="0"?null:Zt({key:n,type:y,cursor:R,direction:c}),hasMore:R!=="0"}}if(y==="zset"){let[C,A]=await Promise.all([l.zcard(i),l.zscanBuffer(i,w?.cursor??"0","COUNT",String(s))]),[N,E]=A,R=Buffer.isBuffer(N)?N.toString("utf8"):N,D=[];for(let $=0;$<E.length;$+=2)D.push({member:Oe(E[$]),score:(()=>{let H=E[$+1].toString("utf8");return H==="inf"?"inf":H==="-inf"?"-inf":Number(H)})()});return{...g,length:C,value:{kind:"zset",entries:D},nextCursor:R==="0"?null:Zt({key:n,type:y,cursor:R,direction:c}),hasMore:R!=="0"}}if(y==="stream"){let C=w?.cursor??(c==="forward"?"-":"+"),[A,N]=await Promise.all([l.xlen(i),c==="forward"?l.xrangeBuffer(i,C,"+","COUNT",s+1):l.xrevrangeBuffer(i,C,"-","COUNT",s+1)]),E=N.length>s,D=N.slice(0,s).map(([H,P])=>{let K=[];for(let se=0;se<P.length;se+=2)K.push({field:Oe(P[se]),value:Oe(P[se+1])});return{id:H.toString("utf8"),fields:K}}),$=D.at(-1)?.id;return{...g,length:A,value:{kind:"stream",entries:D},nextCursor:E&&$?Zt({key:n,type:y,cursor:`(${$}`,direction:c}):null,hasMore:E}}return{...g,length:null,value:{kind:"unknown"},nextCursor:null,hasMore:!1}}catch(t){throw this.wrapError(t)}}async getStringChunk(e){try{let t=await Ie(Te(e.db)),n=ir(e.key),a=or(await t.callBuffer("TYPE",n));if(a==="unknown")throw new I(404,{message:"Redis key no longer exists"});if(Pe(a,"string"),e.expectedRevision){let i=await t.callBuffer("DUMP",n);if(!i||ht(i)!==e.expectedRevision)throw en()}let s=await t.strlen(n),o=await t.getrangeBuffer(n,e.offset,e.offset+e.limit-1),c=e.offset+o.length;return{chunk:Oe(o),length:s,nextOffset:c<s?c:null,hasMore:c<s}}catch(t){throw this.wrapError(t)}}async createKey(e){let t=null;try{t=await Hn(Te(e.db));let n=ae(e.key.base64);if(await t.watch(n),await t.exists(n)!==0)throw new I(409,{message:"A Redis key with this name already exists."});if(e.type!==e.value.kind)throw new I(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,ae(e.value.value.base64));break;case"hash":a.hset(n,...e.value.entries.flatMap(({field:o,value:c})=>[ae(o.base64),ae(c.base64)]));break;case"list":a.rpush(n,...e.value.entries.map(o=>ae(o.base64)));break;case"set":a.sadd(n,...e.value.members.map(o=>ae(o.base64)));break;case"zset":a.zadd(n,...e.value.entries.flatMap(({member:o,score:c})=>[c,ae(o.base64)]));break;case"stream":a.xadd(n,e.value.id,...e.value.fields.flatMap(({field:o,value:c})=>[ae(o.base64),ae(c.base64)]));break}e.ttlMs!==null&&a.pexpire(n,e.ttlMs),va(await a.exec());let s=await t.callBuffer("DUMP",n);if(!s)throw en();return{key:Oe(n),revision:ht(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 Hn(Te(e.db));let n=ir(e.key),a=e.operation.action==="rename"?ae(e.operation.newKey.base64):null;a&&!a.equals(n)?await t.watch(n,a):await t.watch(n);let[s,o,c]=await Promise.all([t.callBuffer("DUMP",n),t.callBuffer("TYPE",n),t.pttl(n)]),i=s;if(!i)throw new I(404,{message:"Redis key no longer exists"});if(!e.force&&ht(i)!==e.expectedRevision)throw en();let l=or(o);if(a&&!a.equals(n)&&await t.exists(a)!==0)throw new I(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:ht(i),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,ae(e.operation.value.base64)),c>0&&u.pexpire(n,c);break;case"upsertHash":Pe(l,"hash"),u.hset(n,ae(e.operation.field.base64),ae(e.operation.value.base64));break;case"deleteHash":Pe(l,"hash"),u.hdel(n,ae(e.operation.field.base64));break;case"pushList":Pe(l,"list"),e.operation.side==="left"?u.lpush(n,ae(e.operation.value.base64)):u.rpush(n,ae(e.operation.value.base64));break;case"setList":Pe(l,"list"),u.lset(n,e.operation.index,ae(e.operation.value.base64));break;case"deleteList":{Pe(l,"list");let p=Buffer.concat([Buffer.from("db-studio:list-delete:"),Nm(32)]);u.lset(n,e.operation.index,p),u.lrem(n,1,p);break}case"addSet":Pe(l,"set"),u.sadd(n,ae(e.operation.member.base64));break;case"removeSet":Pe(l,"set"),u.srem(n,ae(e.operation.member.base64));break;case"upsertZset":Pe(l,"zset"),u.zadd(n,e.operation.score,ae(e.operation.member.base64));break;case"removeZset":Pe(l,"zset"),u.zrem(n,ae(e.operation.member.base64));break;case"appendStream":Pe(l,"stream"),u.xadd(n,e.operation.id,...e.operation.fields.flatMap(({field:p,value:f})=>[ae(p.base64),ae(f.base64)]));break;case"deleteStream":Pe(l,"stream"),u.xdel(n,e.operation.id);break}va(await u.exec());let m=a&&!a.equals(n)?a:n,d=await t.callBuffer("DUMP",m);return{key:Oe(m),revision:d?ht(d):null,deleted:d===null}}catch(n){throw this.wrapError(n)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async deleteKey(e){let t=null;try{t=await Hn(Te(e.db));let n=ir(e.key);await t.watch(n);let a=await t.callBuffer("DUMP",n);if(!a)throw new I(404,{message:"Redis key no longer exists"});if(!e.force&&ht(a)!==e.expectedRevision)throw en();let s=t.multi().del(n);return va(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 Ie(yt()),t=1,n=!1,a=null;try{a=await e.call("CONFIG","GET","databases")}catch(i){if(!ka(i))throw i}if(Array.isArray(a)&&a.length>=2){let i=Number.parseInt(String(a[1]),10);Number.isFinite(i)&&i>0&&(t=i,n=!0)}let s="";try{s=await e.info("keyspace")}catch(i){if(!ka(i))throw i}let o=jm(s);return(n?Array.from({length:t},(i,l)=>l):[yt()]).map(i=>({name:String(i),size:`${o.get(i)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(yt())}}async getDatabaseConnectionInfo(){try{let e=await Ie(yt()),[t,n]=await Promise.all([e.info("server"),e.info("clients")]),a=Ei(t),s=Ei(n),o=Number.parseInt(s.maxclients??"0",10);if(!Number.isFinite(o)||o===0){let i=await e.call("CONFIG","GET","maxclients").catch(l=>{if(!ka(l))throw l;return null});Array.isArray(i)&&i.length>=2&&(o=Number.parseInt(String(i[1]),10)||0)}let c=e.options;return{host:c.host??null,port:c.port??null,user:c.username||"default",database:String(c.db??yt()),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=Te(e),n=await this.getCachedCounts(t);return tn.map(a=>({tableName:a,rowCount:n[a]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new I(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new I(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 I(400,{message:Xt})}async getTableSchema({tableName:e}){let t=ct(e);return Fm[t]}async getTableColumns({tableName:e}){let t=ct(e);return Ti[t]}async addColumn(e){throw new I(400,{message:Xt})}async deleteColumn(e){throw new I(400,{message:Xt})}async alterColumn(e){throw new I(400,{message:Xt})}async renameColumn(e){throw new I(400,{message:Xt})}async getTableData(e){try{let{tableName:t,db:n,cursor:a,limit:s=50,direction:o="asc",sort:c,filters:i}=e;if(o==="desc")throw new I(400,{message:_m});if(c&&c.length>0)throw new I(400,{message:Am});if(i&&i.length>0)throw new I(400,{message:Dm});let l=ct(t),u=Ma[l],m=Te(n),d=await Ie(m),p="0";if(a){let D=Bm(a);if(!D||D.type!==l)throw new I(400,{message:"Invalid or mismatched cursor"});p=D.scanCursor}let f=[],y=0,g=!1;for(;f.length<s&&y<Im;){let[D,$]=await d.scan(p,"MATCH","*","COUNT",Math.max(s*2,100),"TYPE",u);if(f.push(...$),p=D,y++,D==="0"){g=!0;break}}let w=f.slice(0,s),C=f.slice(s),A=await this.hydrateRows(d,l,w),N=await d.dbsize(),E=!g||C.length>0,R=E&&!g?Um({scanCursor:p,type:l}):null;return{data:A,meta:{limit:s,total:N,hasNextPage:E,hasPreviousPage:!1,nextCursor:R,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,n){if(n.length===0)return[];let a=e.pipeline();for(let i of n)a.ttl(i);let s=await a.exec()??[],o=e.pipeline();for(let i of n)switch(t){case"strings":o.get(i);break;case"hashes":o.hgetall(i);break;case"lists":o.lrange(i,0,-1);break;case"sets":o.smembers(i);break;case"zsets":o.zrange(i,0,-1,"WITHSCORES");break;case"streams":o.xinfo("STREAM",i);break}let c=await o.exec()??[];return n.map((i,l)=>{let u=s[l]?.[1]??-2,m=c[l]?.[1];if(t==="streams"){let p=Wm(m);return this.normalizeRow({key:i,length:p.length,"first-id":p.firstId,"last-id":p.lastId,ttl:u})}let d;switch(t){case"strings":d=m??null;break;case"hashes":d=m;break;case"lists":case"sets":d=m;break;case"zsets":d=Km(m);break}return this.normalizeRow({key:i,value:d,ttl:u})})}async getCachedCounts(e){let t=this.countCache.get(e);if(t&&Date.now()-t.timestamp<Om)return t.counts;let n=await Ie(e),a={},s=n.pipeline();for(let c of tn)s.scan("0","MATCH","*","COUNT",xm,"TYPE",Ma[c]);let o=await s.exec()??[];return tn.forEach((c,i)=>{let l=o[i]?.[1];a[c]=l?.[1]?.length??0}),this.countCache.set(e,{timestamp:Date.now(),counts:a}),a}async addRecord({db:e,params:t}){try{let{tableName:n,data:a}=t,s=ct(n),o=wi(a),c=qa(a),i=await Ie(Te(e));return await this.writeRecord(i,s,o,a.value,{mode:"create",ttl:c}),this.countCache.delete(Te(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,c=ct(n),i=o?.[0]||s||"key",l=await Ie(Te(e)),u=new Map;for(let d of a){let p=d.rowData[i];if(p==null)throw new I(400,{message:`Primary key "${i}" not found in row data`});let f=String(p),y=u.get(f)??{...d.rowData};y[d.columnName]=d.value,u.set(f,y)}let m=0;for(let[d,p]of u.entries()){let f=p.value,y=qa(p);await this.writeRecord(l,c,d,f,{mode:"update",ttl:y});let g=p[i],w=g==null?d:String(g);if(w!==d&&await l.renamenx(d,w)===0)throw new I(409,{message:`Key "${w}" already exists`});m++}return{updatedCount:m}}catch(n){throw this.wrapError(n)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:n,db:a}=e;ct(t);let s=await Ie(Te(a)),o=n.map(i=>String(i.value));if(o.length===0)return{deletedCount:0,fkViolation:!1,relatedRecords:[]};let c=await s.del(...o);return this.countCache.delete(Te(a)),{deletedCount:c,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:n,db:a}=e;if(!n||n.length===0)throw new I(400,{message:"At least one record is required"});let s=ct(t),o=await Ie(Te(a)),c=[],i=0;for(let l=0;l<n.length;l++){let u=n[l];try{let m=wi(u),d=qa(u);await this.writeRecord(o,s,m,u.value,{mode:"create",ttl:d}),i++}catch(m){c.push({recordIndex:l,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(Te(a)),{success:c.length===0,message:`Inserted ${i} of ${n.length} record${n.length===1?"":"s"}`,successCount:i,failureCount:c.length,...c.length>0?{errors:c}:{}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let n=ct(e),a=Te(t),s=await Ie(a),o=Ma[n],c=[],i="0";do{let[m,d]=await s.scan(i,"MATCH","*","COUNT",1e3,"TYPE",o);c.push(...d),i=m}while(i!=="0");if(c.length===0)throw new I(404,{message:`Table "${e}" has no data`});let l=await this.hydrateRows(s,n,c);return{cols:Ti[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 I(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 I(409,{message:`Key "${n}" already exists`})}else{if(await e.exists(n))throw new I(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 I(404,{message:`Key "${n}" does not exist`})}else{if(!await e.exists(n))throw new I(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=Ci(a,"hash"),o=[];for(let[c,i]of Object.entries(s))o.push(c,cr(i));if(o.length===0)throw new I(400,{message:"Hash must have at least one field"});await e.hset(n,...o);return}case"lists":{let s=Si(a,"list");if(s.length===0)throw new I(400,{message:"List must have at least one element"});await e.rpush(n,...s.map(cr));return}case"sets":{let s=Si(a,"set");if(s.length===0)throw new I(400,{message:"Set must have at least one member"});await e.sadd(n,...s.map(cr));return}case"zsets":{let s=Hm(a);if(s.length===0)throw new I(400,{message:"Sorted set must have at least one member"});let o=[];for(let c of s)o.push(c.score,c.member);await e.zadd(n,...o);return}case"streams":{let s=Ci(a,"stream"),o=[];for(let[c,i]of Object.entries(s))o.push(c,cr(i));if(o.length===0)throw new I(400,{message:"Stream entry must have at least one field"});await e.xadd(n,"*",...o);return}}}async executeQuery({query:e,db:t}){let n=performance.now();try{if(!e?.trim())throw new I(400,{message:"Query is required"});let a;try{a=hi(e.trim())}catch(u){throw new I(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(a.length===0)throw new I(400,{message:"Empty command"});let s=await Ie(Te(t)),[o,...c]=a,i;try{i=await s.call(o,...c)}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{...bi(a,i),duration:performance.now()-n,message:typeof i=="string"?i:void 0}}catch(a){throw this.wrapError(a)}}}});function Ua(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 Ba(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 Fa(r,e,t){let{values:n,sortColumns:a}=r;if(!a.length)return{clause:"",values:[]};let i=t==="asc"===(e==="asc")?">":"<",l=a.map(d=>`"${d}"`).join(", "),u=a.map(()=>"?").join(", "),m=a.map(d=>n[d]);return{clause:`(${l}) ${i} (${u})`,values:m}}function ur(r,e){let t=e;for(;t<r.length;)if(/\s/.test(r[t]))t++;else if(r.startsWith("--",t)){let n=r.indexOf(`
|
|
422
|
-
`,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
|
|
423
|
-
`,a+2),a===-1)break}else if(s==="/"&&r[a+1]==="*"){let c=r.indexOf("*/",a+2);if(c===-1)break;a=c+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},_i=r=>r.every(e=>e!==null),Jm=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),vt=(r,e=[])=>({sql:r,args:e.map(Jm)}),Xm=BigInt(Number.MIN_SAFE_INTEGER),Zm=BigInt(Number.MAX_SAFE_INTEGER),ed=r=>typeof r=="bigint"?r>=Xm&&r<=Zm?Number(r):r.toString():r instanceof ArrayBuffer?Buffer.from(r):r,ja=({columns:r,rows:e})=>e.map(t=>Object.fromEntries(r.map((n,a)=>[n,ed(t[a])]))),J=async(r,e,t=[])=>ja(await r.execute(vt(e,t))),Ii=r=>r instanceof Error&&r.message.includes("FOREIGN KEY constraint failed"),mr=class extends le{schemaChange=Promise.resolve();serializeSchemaChange(e){let t=this.schemaChange.then(e);return this.schemaChange=t.catch(()=>{}),t}async runQuery(e,t,n){return await J(await re(),t,n)}quoteIdentifier(e){return`"${e.replaceAll('"','""')}"`}mapToUniversalType(e){return pn(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:c="asc",filters:i=[]}=e,l=[],u=c;Array.isArray(o)&&o.length>0?(l=o.map(E=>E.columnName),u=o[0].direction):typeof o=="string"&&o&&(l=[o]),l.length||(l=["rowid"]);let{clause:m,values:d}=Ua(i),p="",f=[];if(n){let E=this.decodeCursor(n);if(E){let R=Fa(E,s,u);p=R.clause,f=R.values}}let y="";m&&p?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${p}`:m?y=m:p&&(y=`WHERE ${p}`);let g=Ba((Array.isArray(o),o),c),w=g;s==="desc"?g?w=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):w=`ORDER BY ${l.map(E=>`"${E}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(w=`ORDER BY ${l.map(E=>`"${E}" ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM "${t}" ${y} ${w} LIMIT ?`,A=[...d,...f,a+1],N=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:C,values:A,countSql:N,countValues:d}}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,c=[];Array.isArray(s)&&s.length>0?c=s.map(p=>p.columnName):typeof s=="string"&&s&&(c=[s]),c.length||(c=["rowid"]);let i=p=>{let f={values:Object.fromEntries(c.map(y=>[y,p[y]])),sortColumns:c};return this.encodeCursor(f)},l=t[0],u=t[t.length-1],m=null,d=null;return a==="asc"?(n&&(m=i(u)),o&&(d=i(l))):(o&&(m=i(u)),n&&(d=i(l))),{nextCursor:m,prevCursor:d}}async getTableData(e){try{let{tableName:t,db:n,limit:a=50,direction:s="asc",sort:o=[],order:c="asc",cursor:i,filters:l=[]}=e,u=await re(),d=(await J(u,`PRAGMA table_info("${t}")`)).filter(O=>O.pk>0).sort((O,Y)=>O.pk-Y.pk).map(O=>O.name),p=[],f=c;Array.isArray(o)&&o.length>0?(p=o.map(O=>O.columnName),f=o[0].direction):typeof o=="string"&&o&&(p=[o]);let y=[...p,...d.filter(O=>!p.includes(O))],g=y.length===0;g&&y.push("rowid");let{clause:w,values:C}=Ua(l),A="",N=[];if(i){let O=this.decodeCursor(i);if(O){let Y=Fa(O,s,f);A=Y.clause,N=Y.values}}let E="";w&&A?E=`WHERE ${w.replace(/^WHERE\s+/i,"")} AND ${A}`:w?E=w:A&&(E=`WHERE ${A}`);let R=Ba((Array.isArray(o),o),c),D=d.filter(O=>!p.includes(O)),$=R;if(s==="desc")if(R){if($=R.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),D.length){let O=f==="asc"?"DESC":"ASC";$+=`, ${D.map(Y=>`"${Y}" ${O}`).join(", ")}`}}else $=`ORDER BY ${y.map(O=>`"${O}" ${f==="asc"?"DESC":"ASC"}`).join(", ")}`;else R?D.length&&($+=`, ${D.map(O=>`"${O}" ${f.toUpperCase()}`).join(", ")}`):$=`ORDER BY ${y.map(O=>`"${O}" ${f.toUpperCase()}`).join(", ")}`;let[H]=await J(u,`SELECT COUNT(*) as total FROM "${t}" ${w}`,C),P=Number(H?.total??0),se=await J(u,`SELECT ${g?"*, rowid":"*"} FROM "${t}" ${E} ${$} LIMIT ?`,[...C,...N,a+1]),z=se.length>a,v=z?se.slice(0,a):se;s==="desc"&&(v=v.reverse());let he=O=>({values:Object.fromEntries(y.map(Y=>[Y,O[Y]])),sortColumns:y}),xe=null,Xe=null;if(v.length>0){let O=v[0],Y=v[v.length-1];s==="asc"?(z&&(xe=this.encodeCursor(he(Y))),i&&(Xe=this.encodeCursor(he(O)))):(i&&(xe=this.encodeCursor(he(Y))),z&&(Xe=this.encodeCursor(he(O))))}return{data:g?v.map(({rowid:O,...Y})=>Y):v,meta:{limit:a,total:P,hasNextPage:s==="asc"?z:!!i,hasPreviousPage:s==="asc"?!!i:z,nextCursor:xe,prevCursor:Xe}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let e=await re(),t=await J(e,"PRAGMA database_list");if(!t.length)throw new U(500,{message:"No databases returned from SQLite"});return t.filter(n=>n.name!=="temp").map(n=>({name:n.name,size:e.protocol==="file"?this.getFileSize(n.file):"N/A",owner:"",encoding:"UTF-8"}))}catch(e){throw e instanceof U?e:this.wrapError(e)}}async getCurrentDatabase(){try{return{db:(await J(await re(),"PRAGMA database_list")).find(n=>n.name==="main")?.name??"main"}}catch(e){throw this.wrapError(e)}}async getDatabaseConnectionInfo(){try{let[e]=await J(await re(),"SELECT sqlite_version() as version");return{host:null,port:null,user:"",database:"main",version:`SQLite ${e.version}`,active_connections:1,max_connections:1}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=await re(),n=await J(t,"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' 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:ja(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),c=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&&c.push(`PRIMARY KEY (${o.map(u=>`"${u}"`).join(", ")})`);let i=s?.map(u=>`FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await(await re()).execute(`CREATE TABLE "${n}" (${[...c,...i].join(", ")})`)}async deleteTable(e){let{tableName:t,cascade:n}=e,a=await re();if(!await this.tableExists(a,t))throw new U(404,{message:`Table "${t}" does not exist`});let[s]=await J(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(c){if((c instanceof Error?c.message:String(c)).includes("FOREIGN KEY constraint"))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(a,t)};throw c instanceof U?c:new U(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 re();if(!await this.tableExists(s,t))throw new U(404,{message:`Table "${t}" does not exist`});if(await this.tableExists(s,n))throw new U(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 J(await re(),"SELECT sql FROM sqlite_master WHERE type='table' AND name=?",[e]);if(!n)throw new U(404,{message:`Table "${e}" does not exist`});return n.sql}catch(n){throw n instanceof U?n:this.wrapError(n)}}async getTableColumns({tableName:e,db:t}){try{let n=await re();if(!await this.tableExists(n,e))throw new U(404,{message:`Table "${e}" does not exist`});let a=await J(n,`PRAGMA table_info("${e}")`),s=await J(n,`PRAGMA foreign_key_list("${e}")`),o=new Map;for(let c of s)o.set(c.from,c);return a.map(c=>{let i=o.get(c.name),l=c.type.toLowerCase();return{columnName:c.name,dataType:pn(l),dataTypeLabel:Or(l),isNullable:c.notnull===0&&c.pk===0,columnDefault:c.dflt_value,isPrimaryKey:c.pk>0,isForeignKey:o.has(c.name),referencedTable:i?.table??null,referencedColumn:i?.to??null,enumValues:null}})}catch(n){throw n instanceof U?n:this.wrapError(n)}}async addColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,columnType:a,defaultValue:s,isNullable:o,isUnique:c,db:i}=e,l=await re();if(!await this.tableExists(l,t))throw new U(404,{message:`Table "${t}" does not exist`});if((await J(l,`PRAGMA table_info("${t}")`)).some(d=>d.name===n))throw new U(409,{message:`Column "${n}" already exists in table "${t}"`});let m=`"${n}" ${a}`;c&&(m+=" UNIQUE"),o||(m+=" NOT NULL"),s?.trim()&&(m+=` DEFAULT ${s.trim()}`);try{await l.execute(`ALTER TABLE "${t}" ADD COLUMN ${m}`)}catch(d){throw this.wrapError(d)}})}async deleteColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,db:a}=e,s=await re();if(!await this.tableExists(s,t))throw new U(404,{message:`Table "${t}" does not exist`});if(!(await J(s,`PRAGMA table_info("${t}")`)).some(c=>c.name===n))throw new U(404,{message:`Column "${n}" does not exist in table "${t}"`});try{await s.execute(`ALTER TABLE "${t}" DROP COLUMN "${n}"`)}catch(c){throw this.wrapError(c)}return{deletedCount:1}})}async alterColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,columnType:a,isNullable:s,defaultValue:o,db:c}=e,i=await re(),l=E=>this.quoteIdentifier(E);if(!await this.tableExists(i,t))throw new U(404,{message:`Table "${t}" does not exist`});let u=await J(i,`PRAGMA table_info(${l(t)})`);if(!u.some(E=>E.name===n))throw new U(404,{message:`Column "${n}" does not exist in table "${t}"`});let m=u.filter(E=>E.pk>0).sort((E,R)=>E.pk-R.pk),d=m.length>1,p=u.map(E=>{let R=E.name===n,D=R?a:E.type,$=R?s:E.notnull===0,H=R?o?.trim()||null:E.dflt_value,P=E.pk>0,K=`${l(E.name)} ${D}`;return!d&&P&&(K+=" PRIMARY KEY"),!P&&!$&&(K+=" NOT NULL"),H&&(K+=` DEFAULT ${H}`),K});d&&p.push(`PRIMARY KEY (${m.map(E=>l(E.name)).join(", ")})`);let f=await J(i,`PRAGMA foreign_key_list(${l(t)})`),y=new Map;for(let E of f){let R=y.get(E.id)??[];R.push(E),y.set(E.id,R)}let g=Array.from(y.values()).map(E=>{let R=E.map(se=>l(se.from)).join(", "),D=E.map(se=>se.to),$=_i(D)?` (${D.map(l).join(", ")})`:"",{table:H,on_update:P,on_delete:K}=E[0];return`FOREIGN KEY (${R}) REFERENCES ${l(H)}${$} ON UPDATE ${P} ON DELETE ${K}`}),w=u.map(E=>l(E.name)).join(", "),C=`${t}_alter_${Date.now()}`,A=await J(i,"SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL",[t]),N=await J(i,"SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?",[t]);try{await i.migrate([`CREATE TABLE ${l(C)} (${[...p,...g].join(", ")})`,`INSERT INTO ${l(C)} (${w}) SELECT ${w} FROM ${l(t)}`,`DROP TABLE ${l(t)}`,`ALTER TABLE ${l(C)} RENAME TO ${l(t)}`,...A.map(({sql:E})=>E),...N.map(({sql:E})=>E)])}catch(E){throw this.wrapError(E)}})}async renameColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:n,newColumnName:a,db:s}=e,o=await re();if(!await this.tableExists(o,t))throw new U(404,{message:`Table "${t}" does not exist`});let c=await J(o,`PRAGMA table_info("${t}")`);if(!c.some(i=>i.name===n))throw new U(404,{message:`Column "${n}" does not exist in table "${t}"`});if(c.some(i=>i.name===a))throw new U(409,{message:`Column "${a}" already exists in table "${t}"`});try{await o.execute(`ALTER TABLE "${t}" RENAME COLUMN "${n}" TO "${a}"`)}catch(i){throw this.wrapError(i)}})}async getTableIndexes({tableName:e}){try{return await this.listIndexes(await re(),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 c=await re();if(!await this.tableExists(c,t))throw new U(404,{message:`Table "${t}" does not exist`});let i=await J(c,`PRAGMA table_info(${this.quoteIdentifier(t)})`),l=a.find(u=>!i.some(m=>m.name===u));if(l!==void 0)throw new U(400,{message:`Column "${l}" does not exist in table "${t}"`});if(o!==void 0)throw new U(400,{message:`Unsupported index method "${o}"`});await c.execute(`CREATE ${s?"UNIQUE ":""}INDEX ${this.quoteIdentifier(n)} ON ${this.quoteIdentifier(t)} (${a.map(u=>this.quoteIdentifier(u)).join(", ")})`)}catch(c){throw c instanceof Error&&/already exists|there is already|UNIQUE constraint failed/.test(c.message)?new U(409,{message:c.message,cause:c}):c instanceof Error&&c.message.includes("reserved for internal use")?new U(400,{message:c.message,cause:c}):this.wrapError(c)}})}async dropIndex({tableName:e,indexName:t}){return this.serializeSchemaChange(async()=>{try{let n=await re(),a=(await this.listIndexes(n,e)).find(s=>s.indexName===t);if(!a)throw new U(404,{message:`Index "${t}" does not exist on table "${e}"`});if(a.kind!=="index")throw new U(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 U(400,{message:"No data provided for insert"});let s=a.map(c=>`"${c}"`).join(", "),o=a.map(()=>"?").join(", ");try{let i=await(await re()).execute(vt(`INSERT INTO "${t}" (${s}) VALUES (${o})`,Object.values(n)));if(i.rowsAffected===0)throw new U(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:i.rowsAffected}}catch(c){throw this.wrapError(c)}}async updateRecords({db:e,params:t}){let{tableName:n}=t,a=this.resolveKeyColumns(t),s=this.groupUpdatesByKey(t,a);try{let o=await re();this.assertWholeKey(await this.getPrimaryKeyColumns(o,n),a);let c=await o.transaction("write");try{let i=0;for(let{keyValues:l,rowUpdates:u}of s){let m=u.map(f=>`"${f.columnName}" = ?`).join(", "),d=a.map(f=>`"${f}" = ?`).join(" AND "),p=await c.execute(vt(`UPDATE "${n}" SET ${m} WHERE ${d}`,[...u.map(f=>f.value),...l]));if(p.rowsAffected===0)throw new U(404,{message:`Record with ${this.describeKey(a,l)} not found in table "${n}"`});i+=p.rowsAffected}return await c.commit(),{updatedCount:i}}catch(i){throw await c.rollback(),i}finally{c.close()}}catch(o){throw this.wrapError(o)}}async deleteRecords({tableName:e,primaryKeys:t,db:n}){let a=t[0]?.columnName;if(!a)throw new U(400,{message:"Primary key column name is required"});let s=t.map(i=>i.value),o=s.map(()=>"?").join(", "),c=await re();try{return this.assertDeletableKey(await this.getPrimaryKeyColumns(c,e)),{deletedCount:(await c.execute(vt(`DELETE FROM "${e}" WHERE "${a}" IN (${o})`,s))).rowsAffected,fkViolation:!1,relatedRecords:[]}}catch(i){if(Ii(i))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(c,e,t)};throw this.wrapError(i)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:n}){let a=t[0]?.columnName;if(!a)throw new U(400,{message:"Primary key column name is required"});let s=i=>this.quoteIdentifier(i),o=t.map(i=>i.value),c=`${s(a)} IN (${o.map(()=>"?").join(", ")})`;try{let i=await re();this.assertDeletableKey(await this.getPrimaryKeyColumns(i,e));let l=await this.getForeignKeysByParent(i),u=[],m=async(p,f,y)=>{for(let g of l.get(p)??[]){if(y.includes(g.childTable))continue;let w=_i(g.parentColumns)?g.parentColumns:await this.getPrimaryKeyColumns(i,p),C=`(${g.childColumns.map(s).join(", ")}) IN (SELECT ${w.map(s).join(", ")} FROM ${s(p)} WHERE ${f})`;await m(g.childTable,C,[...y,g.childTable])}u.push(vt(`DELETE FROM ${s(p)} WHERE ${f}`,o))};return await m(e,c,[e]),{deletedCount:(await i.batch(u,"write")).reduce((p,f)=>p+f.rowsAffected,0)}}catch(i){throw Ii(i)?new U(409,{message:`Cannot force delete from "${e}": rows are still referenced through a foreign key cycle`}):this.wrapError(i)}}async bulkInsertRecords({tableName:e,records:t,db:n}){if(!t?.length)throw new U(400,{message:"At least one record is required"});let a=Object.keys(t[0]),s=a.map(i=>`"${i}"`).join(", "),o=a.map(()=>"?").join(", "),c=`INSERT INTO "${e}" (${s}) VALUES (${o})`;try{return await(await re()).batch(t.map(l=>vt(c,a.map(u=>l[u]))),"write"),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}catch(i){throw this.wrapError(i)}}async executeQuery({query:e,db:t}){if(!e?.trim())throw new U(400,{message:"Query is required"});let n=e.trim().replace(/;+$/,"");if(Ai(n))throw new U(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(Ni(n))throw new U(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let a=performance.now();try{let s=await(await re()).execute(n),o=performance.now()-a;if(s.columns.length>0){let c=ja(s);return{columns:s.columns,rows:c,rowCount:c.length,duration:o,message:c.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 J(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 U(404,{message:`Table "${t}" does not exist`});let n=await J(e,`SELECT il.name AS indexName, il."unique" AS isUnique, il.origin, il.partial, m.sql,
|
|
457
|
+
-- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},ur=class extends re{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=fe(t),l=await Se(c),u="0";if(i){let w=hd(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:`*${bd(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,A)=>{let D=A*3,R=S[D+2]?.[1];return{key:_e(w),type:ir(S[D]?.[1]),ttlMs:Number(S[D+1]?.[1]??-2),memoryBytes:R==null?null:Number(R)}}),nextCursor:h==="0"?null:yd({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=cr(n),l=await Se(fe(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=ir(u),g={key:_e(c),type:h,ttlMs:Number(m),memoryBytes:p===null?null:Number(p),revision:Et(b)},S=a?gd(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),A=o?dd:md,D=await l.getrangeBuffer(c,0,A-1);return{...g,length:w,value:{kind:"string",value:_e(D),truncated:w>A},nextCursor:null,hasMore:!1}}if(h==="hash"){let[w,A]=await Promise.all([l.hlen(c),l.hscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[D,R]=A,C=Buffer.isBuffer(D)?D.toString("utf8"):D,_=[];for(let O=0;O<R.length;O+=2)_.push({field:_e(R[O]),value:_e(R[O+1])});return{...g,length:w,value:{kind:"hash",entries:_},nextCursor:C==="0"?null:Tn({key:n,type:h,cursor:C,direction:i}),hasMore:C!=="0"}}if(h==="list"){let w=Number.parseInt(S?.cursor??"0",10),A=await l.llen(c),D=await l.lrangeBuffer(c,w,w+s-1),R=w+D.length,C=R<A;return{...g,length:A,value:{kind:"list",entries:D.map((_,O)=>({index:w+O,value:_e(_)}))},nextCursor:C?Tn({key:n,type:h,cursor:String(R),direction:i}):null,hasMore:C}}if(h==="set"){let[w,A]=await Promise.all([l.scard(c),l.sscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[D,R]=A,C=Buffer.isBuffer(D)?D.toString("utf8"):D;return{...g,length:w,value:{kind:"set",members:R.map(_e)},nextCursor:C==="0"?null:Tn({key:n,type:h,cursor:C,direction:i}),hasMore:C!=="0"}}if(h==="zset"){let[w,A]=await Promise.all([l.zcard(c),l.zscanBuffer(c,S?.cursor??"0","COUNT",String(s))]),[D,R]=A,C=Buffer.isBuffer(D)?D.toString("utf8"):D,_=[];for(let O=0;O<R.length;O+=2)_.push({member:_e(R[O]),score:(()=>{let k=R[O+1].toString("utf8");return k==="inf"?"inf":k==="-inf"?"-inf":Number(k)})()});return{...g,length:w,value:{kind:"zset",entries:_},nextCursor:C==="0"?null:Tn({key:n,type:h,cursor:C,direction:i}),hasMore:C!=="0"}}if(h==="stream"){let w=S?.cursor??(i==="forward"?"-":"+"),[A,D]=await Promise.all([l.xlen(c),i==="forward"?l.xrangeBuffer(c,w,"+","COUNT",s+1):l.xrevrangeBuffer(c,w,"-","COUNT",s+1)]),R=D.length>s,_=D.slice(0,s).map(([k,x])=>{let v=[];for(let $=0;$<x.length;$+=2)v.push({field:_e(x[$]),value:_e(x[$+1])});return{id:k.toString("utf8"),fields:v}}),O=_.at(-1)?.id;return{...g,length:A,value:{kind:"stream",entries:_},nextCursor:R&&O?Tn({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 Se(fe(e.db)),n=cr(e.key),a=ir(await t.callBuffer("TYPE",n));if(a==="unknown")throw new d(404,{message:"Redis key no longer exists"});if(xe(a,"string"),e.expectedRevision){let c=await t.callBuffer("DUMP",n);if(!c||Et(c)!==e.expectedRevision)throw En()}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:_e(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 Vn(fe(e.db));let n=X(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,X(e.value.value.base64));break;case"hash":a.hset(n,...e.value.entries.flatMap(({field:o,value:i})=>[X(o.base64),X(i.base64)]));break;case"list":a.rpush(n,...e.value.entries.map(o=>X(o.base64)));break;case"set":a.sadd(n,...e.value.members.map(o=>X(o.base64)));break;case"zset":a.zadd(n,...e.value.entries.flatMap(({member:o,score:i})=>[i,X(o.base64)]));break;case"stream":a.xadd(n,e.value.id,...e.value.fields.flatMap(({field:o,value:i})=>[X(o.base64),X(i.base64)]));break}e.ttlMs!==null&&a.pexpire(n,e.ttlMs),Va(await a.exec());let s=await t.callBuffer("DUMP",n);if(!s)throw En();return{key:_e(n),revision:Et(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 Vn(fe(e.db));let n=cr(e.key),a=e.operation.action==="rename"?X(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&&Et(c)!==e.expectedRevision)throw En();let l=ir(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:_e(n),revision:Et(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":xe(l,"string"),u.set(n,X(e.operation.value.base64)),i>0&&u.pexpire(n,i);break;case"upsertHash":xe(l,"hash"),u.hset(n,X(e.operation.field.base64),X(e.operation.value.base64));break;case"deleteHash":xe(l,"hash"),u.hdel(n,X(e.operation.field.base64));break;case"pushList":xe(l,"list"),e.operation.side==="left"?u.lpush(n,X(e.operation.value.base64)):u.rpush(n,X(e.operation.value.base64));break;case"setList":xe(l,"list"),u.lset(n,e.operation.index,X(e.operation.value.base64));break;case"deleteList":{xe(l,"list");let f=Buffer.concat([Buffer.from("db-studio:list-delete:"),ad(32)]);u.lset(n,e.operation.index,f),u.lrem(n,1,f);break}case"addSet":xe(l,"set"),u.sadd(n,X(e.operation.member.base64));break;case"removeSet":xe(l,"set"),u.srem(n,X(e.operation.member.base64));break;case"upsertZset":xe(l,"zset"),u.zadd(n,e.operation.score,X(e.operation.member.base64));break;case"removeZset":xe(l,"zset"),u.zrem(n,X(e.operation.member.base64));break;case"appendStream":xe(l,"stream"),u.xadd(n,e.operation.id,...e.operation.fields.flatMap(({field:f,value:b})=>[X(f.base64),X(b.base64)]));break;case"deleteStream":xe(l,"stream"),u.xdel(n,e.operation.id);break}Va(await u.exec());let m=a&&!a.equals(n)?a:n,p=await t.callBuffer("DUMP",m);return{key:_e(m),revision:p?Et(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 Vn(fe(e.db));let n=cr(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&&Et(a)!==e.expectedRevision)throw En();let s=t.multi().del(n);return Va(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 Se(Tt()),t=1,n=!1,a=null;try{a=await e.call("CONFIG","GET","databases")}catch(c){if(!Wa(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(!Wa(c))throw c}let o=Sd(s);return(n?Array.from({length:t},(c,l)=>l):[Tt()]).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(Tt())}}async getDatabaseConnectionInfo(){try{let e=await Se(Tt()),[t,n]=await Promise.all([e.info("server"),e.info("clients")]),a=$i(t),s=$i(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(!Wa(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??Tt()),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=fe(e),n=await this.getCachedCounts(t);return wn.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:bn})}async getTableSchema({tableName:e}){let t=lt(e);return wd[t]}async getTableColumns({tableName:e}){let t=lt(e);return Pi[t]}async addColumn(e){throw new d(400,{message:bn})}async deleteColumn(e){throw new d(400,{message:bn})}async alterColumn(e){throw new d(400,{message:bn})}async renameColumn(e){throw new d(400,{message:bn})}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:id});if(i&&i.length>0)throw new d(400,{message:sd});if(c&&c.length>0)throw new d(400,{message:od});let l=lt(t),u=ja[l],m=fe(n),p=await Se(m),f="0";if(a){let _=Ed(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<cd;){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),A=await this.hydrateRows(p,l,S),D=await p.dbsize(),R=!g||w.length>0,C=R&&!g?Td({scanCursor:f,type:l}):null;return{data:A,meta:{limit:s,total:D,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=Nd(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=Rd(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<ld)return t.counts;let n=await Se(e),a={},s=n.pipeline();for(let i of wn)s.scan("0","MATCH","*","COUNT",ud,"TYPE",ja[i]);let o=await s.exec()??[];return wn.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=lt(n),o=Mi(a),i=Ya(a),c=await Se(fe(e));return await this.writeRecord(c,s,o,a.value,{mode:"create",ttl:i}),this.countCache.delete(fe(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=lt(n),c=o?.[0]||s||"key",l=await Se(fe(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=Ya(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;lt(t);let s=await Se(fe(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(fe(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=lt(t),o=await Se(fe(a)),i=[],c=0;for(let l=0;l<n.length;l++){let u=n[l];try{let m=Mi(u),p=Ya(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(fe(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=lt(e),a=fe(t),s=await Se(a),o=ja[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:Pi[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=ki(a,"hash"),o=[];for(let[i,c]of Object.entries(s))o.push(i,lr(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=vi(a,"list");if(s.length===0)throw new d(400,{message:"List must have at least one element"});await e.rpush(n,...s.map(lr));return}case"sets":{let s=vi(a,"set");if(s.length===0)throw new d(400,{message:"Set must have at least one member"});await e.sadd(n,...s.map(lr));return}case"zsets":{let s=Cd(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=ki(a,"stream"),o=[];for(let[i,c]of Object.entries(s))o.push(i,lr(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 Se(fe(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(fd).join(" "),durationMs:Number(c)/1e3,detail:ye({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:ye({max_ms:l})}))];return{available:!0,source:"SLOWLOG GET + LATENCY LATEST",entries:De(s)}}catch(t){if(t instanceof Error&&t.message.startsWith("NOPERM"))return ne("Reading the slow log needs the +slowlog command, and +latency for latency spikes.");if(t instanceof Error&&t.message.startsWith("ERR unknown command"))return ne("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=Ii(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 Se(fe(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{...Li(a,c),duration:performance.now()-n,message:typeof c=="string"?c:void 0}}catch(a){throw this.wrapError(a)}}}});function za(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 Ga(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 Qa(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 mr(r,e){let t=e;for(;t<r.length;)if(/\s/.test(r[t]))t++;else if(r.startsWith("--",t)){let n=r.indexOf(`
|
|
458
|
+
`,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 qi(r){let e=[],t=0,n=!1,a=mr(r,0);for(;a<r.length;){let s=r[a];if(s===";"){t===0&&(n=!0,e=[]),a=mr(r,a+1);continue}if(n)return!0;let o=Ad[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=mr(r,a)}return!1}function Bi(r){return Dd.test(r.slice(mr(r,0)))}var Ad,Dd,Fi=N(()=>{"use strict";y();Ad={"'":"'",'"':'"',"`":"`","[":"]"};Dd=/^(begin|start\s+transaction|commit|end|rollback|savepoint|release)\b/i});var _d,Od,Ki,Id,wt,Ld,xd,Pd,Ja,Z,Hi,dr,ji=N(()=>{"use strict";y();ee();We();Ve();ce();Fi();_d={"'":"'",'"':'"',"`":"`","[":"]"},Od=r=>{let e=[],t=0,n=-1;for(let a=0;a<r.length;a++){let s=r[a]??"",o=_d[s];if(o){if(a=r.indexOf(o,a+1),a===-1)break}else if(s==="-"&&r[a+1]==="-"){if(a=r.indexOf(`
|
|
459
|
+
`,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},Ki=r=>r.every(e=>e!==null),Id=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),wt=(r,e=[])=>({sql:r,args:e.map(Id)}),Ld=BigInt(Number.MIN_SAFE_INTEGER),xd=BigInt(Number.MAX_SAFE_INTEGER),Pd=r=>typeof r=="bigint"?r>=Ld&&r<=xd?Number(r):r.toString():r instanceof ArrayBuffer?Buffer.from(r):r,Ja=({columns:r,rows:e})=>e.map(t=>Object.fromEntries(r.map((n,a)=>[n,Pd(t[a])]))),Z=async(r,e,t=[])=>Ja(await r.execute(wt(e,t))),Hi=r=>r instanceof Error&&r.message.includes("FOREIGN KEY constraint failed"),dr=class extends re{schemaChange=Promise.resolve();serializeSchemaChange(e){let t=this.schemaChange.then(e);return this.schemaChange=t.catch(()=>{}),t}async runQuery(e,t,n){return await Z(await J(),t,n)}quoteIdentifier(e){return`"${e.replaceAll('"','""')}"`}mapToUniversalType(e){return _n(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}=za(c),f="",b=[];if(n){let R=this.decodeCursor(n);if(R){let C=Qa(R,s,u);f=C.clause,b=C.values}}let h="";m&&f?h=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${f}`:m?h=m:f&&(h=`WHERE ${f}`);let g=Ga((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=>`"${R}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(S=`ORDER BY ${l.map(R=>`"${R}" ${u.toUpperCase()}`).join(", ")}`);let w=`SELECT * FROM "${t}" ${h} ${S} LIMIT ?`,A=[...p,...b,a+1],D=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:w,values:A,countSql:D,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(h=>[h,f[h]])),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(),p=(await Z(u,`PRAGMA table_info("${t}")`)).filter(F=>F.pk>0).sort((F,me)=>F.pk-me.pk).map(F=>F.name),f=[],b=i;Array.isArray(o)&&o.length>0?(f=o.map(F=>F.columnName),b=o[0].direction):typeof o=="string"&&o&&(f=[o]);let h=[...f,...p.filter(F=>!f.includes(F))],g=h.length===0;g&&h.push("rowid");let{clause:S,values:w}=za(l),A="",D=[];if(c){let F=this.decodeCursor(c);if(F){let me=Qa(F,s,b);A=me.clause,D=me.values}}let R="";S&&A?R=`WHERE ${S.replace(/^WHERE\s+/i,"")} AND ${A}`:S?R=S:A&&(R=`WHERE ${A}`);let C=Ga((Array.isArray(o),o),i),_=p.filter(F=>!f.includes(F)),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 F=b==="asc"?"DESC":"ASC";O+=`, ${_.map(me=>`"${me}" ${F}`).join(", ")}`}}else O=`ORDER BY ${h.map(F=>`"${F}" ${b==="asc"?"DESC":"ASC"}`).join(", ")}`;else C?_.length&&(O+=`, ${_.map(F=>`"${F}" ${b.toUpperCase()}`).join(", ")}`):O=`ORDER BY ${h.map(F=>`"${F}" ${b.toUpperCase()}`).join(", ")}`;let[k]=await Z(u,`SELECT COUNT(*) as total FROM "${t}" ${S}`,w),x=Number(k?.total??0),$=await Z(u,`SELECT ${g?"*, rowid":"*"} FROM "${t}" ${R} ${O} LIMIT ?`,[...w,...D,a+1]),B=$.length>a,M=B?$.slice(0,a):$;s==="desc"&&(M=M.reverse());let W=F=>({values:Object.fromEntries(h.map(me=>[me,F[me]])),sortColumns:h}),Re=null,ut=null;if(M.length>0){let F=M[0],me=M[M.length-1];s==="asc"?(B&&(Re=this.encodeCursor(W(me))),c&&(ut=this.encodeCursor(W(F)))):(c&&(Re=this.encodeCursor(W(me))),B&&(ut=this.encodeCursor(W(F))))}return{data:g?M.map(({rowid:F,...me})=>me):M,meta:{limit:a,total:x,hasNextPage:s==="asc"?B:!!c,hasPreviousPage:s==="asc"?!!c:B,nextCursor:Re,prevCursor:ut}}}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 Z(t,`SELECT name FROM sqlite_master
|
|
460
|
+
WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT GLOB '_cf_*'
|
|
461
|
+
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:Ja(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 Z(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 Z(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 Z(n,`PRAGMA table_info("${e}")`),s=await Z(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:_n(l),dataTypeLabel:xr(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 Z(l,`PRAGMA table_info("${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 Z(s,`PRAGMA table_info("${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 Z(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,k=_?s:C.notnull===0,x=_?o?.trim()||null:C.dflt_value,v=C.pk>0,$=`${l(C.name)} ${O}`;return!p&&v&&($+=" PRIMARY KEY"),!v&&!k&&($+=" NOT NULL"),x&&($+=` DEFAULT ${x}`),$});p&&f.push(`PRIMARY KEY (${m.map(C=>l(C.name)).join(", ")})`);let b=await Z(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(B=>l(B.from)).join(", "),O=C.map(B=>B.to),k=Ki(O)?` (${O.map(l).join(", ")})`:"",{table:x,on_update:v,on_delete:$}=C[0];return`FOREIGN KEY (${_}) REFERENCES ${l(x)}${k} ON UPDATE ${v} ON DELETE ${$}`}),S=u.map(C=>l(C.name)).join(", "),w=`${t}_alter_${Date.now()}`,A=await Z(c,"SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL",[t]),D=await Z(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)}`,...A.map(({sql:C})=>C),...D.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 Z(o,`PRAGMA table_info("${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 Z(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(wt(`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})=>[wt(`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})=>wt(`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(wt(`DELETE FROM "${e}" WHERE "${a}" IN (${o})`,s))).rowsAffected,fkViolation:!1,relatedRecords:[]}}catch(c){if(Hi(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=Ki(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(wt(`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 Hi(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=>wt(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(Bi(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(qi(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=Ja(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 Z(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 Z(e,`SELECT il.name AS indexName, il."unique" AS isUnique, il.origin, il.partial, m.sql,
|
|
424
462
|
xi.seqno, xi.cid, xi.name AS columnName
|
|
425
463
|
FROM pragma_index_list(?) il
|
|
426
464
|
JOIN pragma_index_xinfo(il.name) xi ON xi.key = 1
|
|
427
465
|
LEFT JOIN sqlite_master m ON m.type = 'index' AND m.name = il.name
|
|
428
|
-
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(
|
|
466
|
+
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(Od(s.sql??"")[s.seqno]??""),o.definition=s.sql)}return[...a.values()]}async getPrimaryKeyColumns(e,t){return(await Z(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 Z(e,`SELECT m.name AS child, f.id, f."table" AS parent, f."from", f."to"
|
|
429
467
|
FROM sqlite_master m JOIN pragma_foreign_key_list(m.name) f
|
|
430
|
-
WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%'
|
|
431
|
-
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}`,
|
|
468
|
+
WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%' AND m.name NOT GLOB '_cf_*'
|
|
469
|
+
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 Z(e,`SELECT m.name AS child, f."from", f."to"
|
|
432
470
|
FROM sqlite_master m JOIN pragma_foreign_key_list(m.name) f
|
|
433
|
-
WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%' AND m.name
|
|
471
|
+
WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%' AND m.name NOT GLOB '_cf_*'
|
|
472
|
+
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 Z(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 Z(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 Wi(){he.register("pg",new or),he.register("mysql",new rr),he.register("mssql",new tr),he.register("mongodb",new er),he.register("sqlite",new dr),he.register("redis",new ur),he.register("duckdb",new Jn),he.register("oracle",new sr),he.register("clickhouse",new zn)}var Vi=N(()=>{"use strict";y();bt();$o();Fo();Qo();ei();ri();Ei();Ri();Ui();ji()});import{NotFoundError as $d,ParseError as Md,ValidationError as kd}from"elysia";import{ZodError as vd}from"zod";function Yi(r,e){let{pathname:t}=new URL(e.url),n=Jt(e.method,t),a=Xt(t),{status:s,body:o}=qd(r);return Q(s>=500?"error":"warn","request_failed",{operation:n,db_type:a,method:e.method,status:s,...le(r)}),sa(r,{operation:n,status:s,dbType:a}),Response.json({...o,requestId:et()},{status:s})}var Ud,qd,zi=N(()=>{"use strict";y();ht();ce();Zt();tt();Ud=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")||yt(r)&&r.code?.startsWith("08")===!0},qd=r=>r instanceof d?{status:r.status,body:{error:r.message}}:r instanceof kd?{status:400,body:{error:"Validation error",details:r.all[0]?.message??"Invalid request"}}:r instanceof vd?{status:400,body:{error:"Validation error",details:r.issues[0].message}}:r instanceof Md?{status:400,body:{error:"Malformed JSON in request body"}}:r instanceof $d?{status:404,body:{error:"Not found"}}:r instanceof Error&&Ud(r)?{status:503,body:{error:"Database connection failed",details:r.message}}:{status:500,body:{error:r instanceof Error?r.message:"Internal server error"}}});function Qi(r){if(!r)return`You are a database assistant for db-studio. Keep answers concise and focused.
|
|
434
473
|
|
|
435
|
-
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=
|
|
474
|
+
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=G[r.dbType].label;return e.includes("mongo")?`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
|
|
436
475
|
|
|
437
476
|
**Your Role:**
|
|
438
477
|
1. Keep responses SHORT - 2-3 sentences maximum unless generating a query
|
|
@@ -446,7 +485,7 @@ The user chose not to share their database schema. Do not claim to know their ta
|
|
|
446
485
|
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
|
|
447
486
|
|
|
448
487
|
**Database Context:**
|
|
449
|
-
${
|
|
488
|
+
${Gi(r)}
|
|
450
489
|
|
|
451
490
|
**Guidelines:**
|
|
452
491
|
1. Always generate syntactically correct MongoDB queries
|
|
@@ -508,7 +547,7 @@ This will return the top 5 customers by revenue."`:`You are a database assistant
|
|
|
508
547
|
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
|
|
509
548
|
|
|
510
549
|
**Database Context:**
|
|
511
|
-
${
|
|
550
|
+
${Gi(r)}
|
|
512
551
|
|
|
513
552
|
**Guidelines:**
|
|
514
553
|
1. Always generate syntactically correct SQL for the database type (${t})
|
|
@@ -546,26 +585,26 @@ LIMIT 5;
|
|
|
546
585
|
|
|
547
586
|
This will return the 5 customers with the highest total order value. You might also want to see:
|
|
548
587
|
- Revenue trends over time for these customers
|
|
549
|
-
- Their most frequently ordered products"`}function
|
|
588
|
+
- Their most frequently ordered products"`}function Gi(r){let t=`Database Type: ${G[r.dbType].label}
|
|
550
589
|
|
|
551
590
|
`;t+=`**Tables and Columns:**
|
|
552
591
|
`;for(let n of r.tables){t+=`
|
|
553
592
|
### ${n.name}
|
|
554
593
|
`,n.description&&(t+=`Description: ${n.description}
|
|
555
594
|
`),t+=`Columns:
|
|
556
|
-
`;for(let a of n.columns){let s=a.isPrimaryKey?" [PRIMARY KEY]":"",o=a.foreignKey?` [FK -> ${a.foreignKey}]`:"",
|
|
595
|
+
`;for(let a of n.columns){let s=a.isPrimaryKey?" [PRIMARY KEY]":"",o=a.foreignKey?` [FK -> ${a.foreignKey}]`:"",i=a.nullable?"NULL":"NOT NULL";t+=` - ${a.name}: ${a.type} ${i}${s}${o}
|
|
557
596
|
`,a.description&&(t+=` ${a.description}
|
|
558
597
|
`)}n.sampleData&&n.sampleData.length>0&&(t+=`Sample data (${n.sampleData.length} rows):
|
|
559
598
|
`,t+=`${JSON.stringify(n.sampleData.slice(0,3),null,2)}
|
|
560
599
|
`)}if(r.relationships&&r.relationships.length>0){t+=`
|
|
561
600
|
**Relationships:**
|
|
562
601
|
`;for(let n of r.relationships)t+=` - ${n.fromTable}.${n.fromColumn} -> ${n.toTable}.${n.toColumn}
|
|
563
|
-
`}return t}var Bi=S(()=>{"use strict";h();ie()});function rd(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 ad(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 sd(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 od(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,sd(o)])))}catch(n){return ee("warn","schema_sample_rows_failed",pe(n)),[]}}async function id(r,e,t){try{return await r.getTableColumns({tableName:e,db:t})}catch(n){return ee("warn","schema_columns_failed",pe(n)),[]}}async function cd(r,e={}){let t=st(),{includeSampleData:n=!1,maxTables:a}=e,s=B(t);try{let o=await s.getTablesList(r),i=o.slice(0,a??o.length).map(async({schemaName:m,tableName:d})=>{let[p,f]=await Promise.all([id(s,d,r),n?od(s,d,r):Promise.resolve([])]),y={name:m?`${m}.${d}`:d,columns:p.map(rd)};return f.length>0&&(y.sampleData=f),y}),l=await Promise.all(i),u=ad(l);return{dbType:t,tables:l,relationships:u}}catch(o){throw ee("error","schema_fetch_failed",pe(o)),new Error(`Failed to fetch database schema: ${o instanceof Error?o.message:"Unknown error"}`)}}async function Fi(r){return cd(r,{includeSampleData:!0,includeDescriptions:!0})}var ji=S(()=>{"use strict";h();tt();pt();et()});import{zValidator as ld}from"@hono/zod-validator";import{Hono as ud}from"hono";import{HTTPException as Hi}from"hono/http-exception";var md,Ki,Wi,Vi=S(()=>{"use strict";h();Ut();ie();et();Bi();ji();md=new Set(["localhost","127.0.0.1","::1","[::1]"]),Ki=()=>{let r;try{r=new URL(Ze.PROXY_URL)}catch{throw new Hi(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=md.has(r.hostname)||r.hostname.endsWith(".localhost");if(r.protocol!=="https:"&&!(r.protocol==="http:"&&e))throw new Hi(500,{message:"DB_STUDIO_PROXY_URL must use HTTPS unless it points at loopback"});return r.origin},Wi=new ud().basePath("/chat").get("/limit",async r=>{let e=Ki();try{let t=await fetch(`${e}/chat/limit`,{headers:{"cf-connecting-ip":r.req.header("cf-connecting-ip")??"","x-real-ip":r.req.header("x-real-ip")??"","x-forwarded-for":r.req.header("x-forwarded-for")??"","x-api-key":r.req.header("x-api-key")??"","x-request-id":mt()??""}});return t.ok?r.json(await t.json(),200):(ee("warn","chat_limit_unavailable",{proxy_status:t.status}),r.json({limit:3,used:3,remaining:0},200))}catch(t){return ee("warn","chat_limit_unavailable",pe(t)),r.json({limit:3,used:3,remaining:0},200)}}).post("/",ld("json",Nr),async r=>{let{messages:e,data:t,provider:n,model:a}=r.req.valid("json"),{db:s,conversationId:o,includeSchema:c}=t,i=c?await Fi(s):null,l=Ui(i),u={messages:e,conversationId:o,systemPrompt:l,provider:n,model:a},m=await fetch(`${Ki()}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":r.req.header("cf-connecting-ip")??"","x-real-ip":r.req.header("x-real-ip")??"","x-forwarded-for":r.req.header("x-forwarded-for")??"","x-api-key":r.req.header("x-api-key")??"","x-byok-gemini":r.req.header("x-byok-gemini")??"","x-byok-openai":r.req.header("x-byok-openai")??"","x-byok-anthropic":r.req.header("x-byok-anthropic")??"","x-byok-grok":r.req.header("x-byok-grok")??"","x-byok-openrouter":r.req.header("x-byok-openrouter")??"","x-request-id":mt()??""},body:JSON.stringify(u)});if(!m.ok){ee("warn","chat_proxy_rejected",{proxy_status:m.status,provider:n,model:a});let d=await m.json();return r.json({error:d.error||"Proxy request failed"},m.status)}return new Response(m.body,{status:m.status,headers:m.headers})})});import{Hono as dd}from"hono";var Yi,zi=S(()=>{"use strict";h();tt();pt();Yi=new dd().basePath("/databases").get("/",async r=>{let e=st(),n=await B(e).getDatabasesList();return r.json({data:{databases:n,dbType:e}},200)}).get("/current",async r=>{let e=st(),n=await B(e).getCurrentDatabase();return r.json({data:{db:n.db,dbType:e}},200)}).get("/connection",async r=>{let e=st(),n=await B(e).getDatabaseConnectionInfo();return r.json({data:n},200)})});import{zValidator as qe}from"@hono/zod-validator";import{Hono as pd}from"hono";var Gi,Qi=S(()=>{"use strict";h();ie();tt();Gi=new pd().basePath("/keys").get("/",qe("query",Ur),async r=>{let e=r.req.valid("query"),t=r.get("dbType"),n=ft(B(t),t);return r.json({data:await n.scanKeys(e)},200)}).post("/",qe("query",L),qe("json",Hr),async r=>{let{db:e}=r.req.valid("query"),t=r.req.valid("json"),n=r.get("dbType"),a=ft(B(n),n);return r.json({data:await a.createKey({db:e,...t})},200)}).get("/:key/raw",qe("param",Nt),qe("query",jr),async r=>{let{key:e}=r.req.valid("param"),t=r.req.valid("query"),n=r.get("dbType"),a=ft(B(n),n);return r.json({data:await a.getStringChunk({...t,key:e})},200)}).get("/:key",qe("param",Nt),qe("query",Fr),async r=>{let{key:e}=r.req.valid("param"),t=r.req.valid("query"),n=r.get("dbType"),a=ft(B(n),n);return r.json({data:await a.getKeyDetails({...t,key:e})},200)}).post("/:key/actions",qe("param",Nt),qe("query",L),qe("json",Kr),async r=>{let{key:e}=r.req.valid("param"),{db:t}=r.req.valid("query"),n=r.req.valid("json"),a=r.get("dbType"),s=ft(B(a),a);return r.json({data:await s.applyKeyAction({db:t,key:e,...n})},200)}).delete("/:key",qe("param",Nt),qe("query",Wr),async r=>{let{key:e}=r.req.valid("param"),t=r.req.valid("query"),n=r.get("dbType"),a=ft(B(n),n);return r.json({data:await a.deleteKey({...t,key:e})},200)})});import{zValidator as Ji}from"@hono/zod-validator";import{Hono as fd}from"hono";var Xi,Zi=S(()=>{"use strict";h();ie();tt();Xi=new fd().basePath("/query").post("/",Ji("query",L),Ji("json",vr),async r=>{let{query:e}=r.req.valid("json"),{db:t}=r.req.valid("query"),n=r.get("dbType"),s=await B(n).executeQuery({query:e,db:t});return r.json({data:s},200)})});import{zValidator as Je}from"@hono/zod-validator";import{Hono as yd}from"hono";var ec,tc=S(()=>{"use strict";h();ie();tt();ec=new yd().basePath("/records").post("/",Je("query",L),Je("json",Tr),async r=>{let{db:e}=r.req.valid("query"),{tableName:t,data:n}=r.req.valid("json"),a=r.get("dbType"),s=B(a),{insertedCount:o}=await s.addRecord({db:e,params:{tableName:t,data:n}});return r.json({data:`Record inserted into "${t}" with ${o} rows inserted`},200)}).patch("/",Je("query",L),Je("json",zr),async r=>{let{db:e}=r.req.valid("query"),t=r.req.valid("json"),n=r.get("dbType"),a=B(n),{updatedCount:s}=await a.updateRecords({params:t,db:e});return r.json({data:`Updated ${s} records in "${t.tableName}"`},200)}).delete("/",Je("query",L),Je("json",bn),async r=>{let{db:e}=r.req.valid("query"),{tableName:t,primaryKeys:n}=r.req.valid("json"),a=r.get("dbType"),s=B(a),{deletedCount:o,fkViolation:c,relatedRecords:i}=await s.deleteRecords({tableName:t,primaryKeys:n,db:e});return c?r.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:i}},409):r.json({data:{deletedCount:o,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",Je("query",L),Je("json",bn),async r=>{let{db:e}=r.req.valid("query"),{tableName:t,primaryKeys:n}=r.req.valid("json"),a=r.get("dbType"),o=await B(a).forceDeleteRecords({tableName:t,primaryKeys:n,db:e});return r.json({data:o},200)}).post("/bulk",Je("query",L),Je("json",Rr),async r=>{let{db:e}=r.req.valid("query"),{tableName:t,records:n}=r.req.valid("json"),a=r.get("dbType"),o=await B(a).bulkInsertRecords({tableName:t,records:n,db:e});return r.json({data:o},200)})});import{utils as nn,write as hd}from"xlsx";function rc({cols:r,rows:e,format:t,tableName:n}){switch(t){case"json":{let a=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(a,"utf-8"))}case"csv":{let a=nn.aoa_to_sheet(nc(r,e)),s=nn.sheet_to_csv(a);return new Uint8Array(Buffer.from(s,"utf-8"))}case"xlsx":{let a=nn.aoa_to_sheet(nc(r,e)),s=nn.book_new();nn.book_append_sheet(s,a,n.slice(0,31));let o=hd(s,{bookType:"xlsx",type:"buffer"});return new Uint8Array(o)}}}var bd,nc,ac=S(()=>{"use strict";h();bd=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,nc=(r,e)=>[r,...e?.map(t=>r?.map(n=>bd(t[n])))??[]]});import{zValidator as V}from"@hono/zod-validator";import{Hono as gd}from"hono";var sc,oc=S(()=>{"use strict";h();ie();tt();ac();sc=new gd().basePath("/tables").get("/",V("query",L),async r=>{let{db:e}=r.req.valid("query"),t=r.get("dbType"),a=await B(t).getTablesList(e);return r.json({data:a},200)}).post("/",V("query",L),V("json",Mr),async r=>{let{db:e}=r.req.valid("query"),t=r.req.valid("json"),n=r.get("dbType");return await B(n).createTable({tableData:t,db:e}),r.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",V("query",kr),V("param",me),async r=>{let{db:e,cascade:t}=r.req.valid("query"),{tableName:n}=r.req.valid("param"),a=r.get("dbType"),o=await B(a).deleteTable({tableName:n,db:e,cascade:t});return r.json({data:o},200)}).patch("/:tableName/rename",V("query",L),V("param",me),V("json",Ht),async r=>{let{db:e}=r.req.valid("query"),{tableName:t}=r.req.valid("param"),n=r.req.valid("json"),a=r.get("dbType");return await B(a).renameTable({tableName:t,db:e,...n}),r.json({data:`Table "${t}" renamed to "${n.newTableName}"`},200)}).delete("/:tableName/columns/:columnName",V("query",Sr),V("param",Ce),async r=>{let{db:e,cascade:t}=r.req.valid("query"),{tableName:n,columnName:a}=r.req.valid("param"),s=r.get("dbType"),o=B(s),{deletedCount:c}=await o.deleteColumn({tableName:n,columnName:a,cascade:t,db:e});return r.json({data:`Column "${a}" deleted successfully from table "${n}" with ${c} rows deleted`},200)}).post("/:tableName/columns",V("query",L),V("param",me),V("json",Ue),async r=>{let{db:e}=r.req.valid("query"),{tableName:t}=r.req.valid("param"),n=r.req.valid("json"),a=r.get("dbType");return await B(a).addColumn({tableName:t,db:e,...n}),r.json({data:`Column "${n.columnName}" added successfully to table "${t}"`},200)}).patch("/:tableName/columns/:columnName/rename",V("query",L),V("param",Ce),V("json",wn),async r=>{let{db:e}=r.req.valid("query"),{tableName:t,columnName:n}=r.req.valid("param"),a=r.req.valid("json"),s=r.get("dbType");return await B(s).renameColumn({tableName:t,columnName:n,db:e,...a}),r.json({data:`Column "${n}" renamed to "${a.newColumnName}" in table "${t}"`},200)}).patch("/:tableName/columns/:columnName",V("query",L),V("param",Ce),V("json",Et),async r=>{let{db:e}=r.req.valid("query"),{tableName:t,columnName:n}=r.req.valid("param"),a=r.req.valid("json"),s=r.get("dbType");return await B(s).alterColumn({tableName:t,columnName:n,db:e,...a}),r.json({data:`Column "${n}" updated successfully in table "${t}"`},200)}).get("/:tableName/columns",V("query",L),V("param",me),async r=>{let{db:e}=r.req.valid("query"),{tableName:t}=r.req.valid("param"),n=r.get("dbType"),s=await B(n).getTableColumns({tableName:t,db:e});return r.json({data:s},200)}).get("/:tableName/indexes",V("query",L),V("param",me),async r=>{let{db:e}=r.req.valid("query"),{tableName:t}=r.req.valid("param"),n=r.get("dbType"),s=await B(n).getTableIndexes({tableName:t,db:e});return r.json({data:s},200)}).post("/:tableName/indexes",V("query",L),V("param",me),V("json",gn),async r=>{let{db:e}=r.req.valid("query"),{tableName:t}=r.req.valid("param"),n=r.req.valid("json"),a=r.get("dbType");return await B(a).createIndex({tableName:t,db:e,...n}),r.json({data:`Index "${n.indexName}" created successfully on table "${t}"`},200)}).delete("/:tableName/indexes/:indexName",V("query",L),V("param",Tn),async r=>{let{db:e}=r.req.valid("query"),{tableName:t,indexName:n}=r.req.valid("param"),a=r.get("dbType");return await B(a).dropIndex({tableName:t,indexName:n,db:e}),r.json({data:`Index "${n}" dropped successfully from table "${t}"`},200)}).get("/:tableName/schema",V("query",L),V("param",me),async r=>{let{db:e}=r.req.valid("query"),{tableName:t}=r.req.valid("param"),n=r.get("dbType"),s=await B(n).getTableSchema({tableName:t,db:e});return r.json({data:{schema:s}},200)}).get("/:tableName/data",V("param",me),V("query",Yr),async r=>{let{tableName:e}=r.req.valid("param"),{cursor:t,limit:n,direction:a,sort:s,order:o,filters:c,db:i}=r.req.valid("query"),l=r.get("dbType"),m=await B(l).getTableData({tableName:e,cursor:t,limit:n,direction:a,sort:s,order:o,filters:c,db:i});return r.json({data:m},200)}).get("/:tableName/export",V("param",me),V("query",qr),async r=>{let{tableName:e}=r.req.valid("param"),{db:t,format:n}=r.req.valid("query"),a=r.get("dbType"),s=B(a),{cols:o,rows:c}=await s.exportTableData({tableName:e,db:t}),i=rc({cols:o,rows:c,format:n,tableName:e}),l;switch(n){case"csv":l="text/csv";break;case"xlsx":l="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";break;case"json":l="application/json";break}return new Response(i,{headers:{"Content-Type":l??"","Content-Disposition":`attachment; filename="${e}_export.${n}"`}})})});import{Hono as Td}from"hono";import{z as ic}from"zod";var Ed,cc,lc=S(()=>{"use strict";h();Vt();Ed=ic.object({enabled:ic.boolean()}).strict(),cc=new Td().basePath("/telemetry").get("/config",async r=>((r.req.header("x-db-studio-gpc")==="1"||r.req.header("sec-gpc")==="1")&&_n(!1),ta(),r.json({data:Dn()},200))).put("/preference",async r=>{let e=Ed.safeParse(await r.req.json().catch(()=>{}));return e.success?(_n(e.data.enabled),r.json({data:Dn()},200)):r.json({error:"Invalid telemetry preference"},400)}).post("/reset",async r=>r.json({data:{installationId:Xr()}},200))});var pc={};on(pc,{createServer:()=>_d});import{existsSync as uc}from"fs";import lt from"path";import{fileURLToPath as wd}from"url";import{serveStatic as rn}from"@hono/node-server/serve-static";import{zValidator as Cd}from"@hono/zod-validator";import{Hono as Sd}from"hono";import{cors as Rd}from"hono/cors";import{HTTPException as Nd}from"hono/http-exception";import{logger as Ad}from"hono/logger";import{prettyJSON as Dd}from"hono/pretty-json";import{z as mc}from"zod";var He,an,dc,_d,fc=S(()=>{"use strict";h();Ut();tt();$i();vi();Vt();et();Vi();zi();Qi();Zi();tc();oc();lc();({API_PREFIX:He}=Ze),an=()=>{if(process.env.NODE_ENV==="development")return lt.resolve(process.cwd(),"../web/dist");let r=lt.dirname(wd(import.meta.url)),e=lt.resolve(r,"./web-dist"),t=lt.resolve(process.cwd(),"../web/dist"),n=lt.resolve(e,"index.html"),a=lt.resolve(t,"index.html");return!uc(n)&&uc(a)?t:e},dc=mc.object({dbType:mc.string().refine(r=>Ee.getSupportedTypes().includes(r),{message:`Invalid database type. Supported types: ${Ee.getSupportedTypes().join(", ")}`})}),_d=()=>{xi();let r=new Sd({strict:!1}).use("/*",(e,t)=>{let n=Gs(e.req.header("x-request-id"));return Qs({requestId:n,operation:Ot(e.req.method,e.req.path),dbType:Wt(e.req.path)},async()=>{await t(),e.header("X-Request-Id",n)})}).use("/*",Rd({origin:e=>{if(!e)return;if((process.env.ALLOWED_ORIGINS?.split(",").map(n=>n.trim()).filter(Boolean)??[]).includes(e))return e;if(process.env.NODE_ENV==="development")try{let n=new URL(e);if(n.hostname==="localhost"||n.hostname.endsWith(".localhost")||n.hostname==="127.0.0.1")return e}catch{}},allowMethods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowHeaders:["Content-Type","X-Run-Id","X-Request-Id","X-DB-Studio-GPC","x-byok-gemini","x-byok-openai","x-byok-anthropic","x-byok-grok","x-byok-openrouter"],exposeHeaders:["X-Request-Id"],maxAge:600})).use(Dd({space:2})).use(process.env.NODE_ENV==="development"?Ad():(e,t)=>t()).use(`${He}/*`,async(e,t)=>{if(e.req.path.startsWith(`${He}/telemetry`))return t();let n=performance.now(),a=Ot(e.req.method,e.req.path),s=e.req.path.split("/")[2],o=Ee.getSupportedTypes().find(c=>c===s);await ra(a,o,t),In({event:"server_operation",properties:{operation:a,method:e.req.method,outcome:ea(e.res.status),duration_bucket:Zr(performance.now()-n),db_type:o}})}).use("/favicon.ico",rn({path:lt.resolve(an(),"favicon.ico")})).onError(ki).route(He,Yi).route(He,Wi).route(He,cc).use("/assets/*",rn({root:an()})).use("/image.png",rn({root:an()})).use(`${He}/:dbType/*`,Cd("param",dc,(e,t)=>{if(!e.success){let n=t.req.param("dbType");throw new Nd(400,{message:`Invalid database type: "${n}". Supported types: ${Ee.getSupportedTypes().join(", ")}`})}}),async(e,t)=>{let{dbType:n}=dc.parse({dbType:e.req.param("dbType")});e.set("dbType",n),await t()}).route(`${He}/:dbType`,sc).route(`${He}/:dbType`,ec).route(`${He}/:dbType`,Xi).route(`${He}/:dbType`,Gi);return process.env.NODE_ENV!=="test"&&(r.all(`${He}/*`,e=>e.json({error:"Not found"},404)),r.use("/*",rn({root:an()})),r.get("/*",rn({path:lt.resolve(an(),"index.html")}))),{app:r}}});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]="ee360d59-c56e-4889-833e-b684b76bfbbc",r._sentryDebugIdIdentifier="sentry-dbid-ee360d59-c56e-4889-833e-b684b76bfbbc")}catch{}})();h();Ut();import{intro as Id,log as pr,outro as yc,spinner as Od}from"@clack/prompts";import{serve as xd}from"@hono/node-server";import sn from"picocolors";h();import{program as yr}from"commander";var Za=()=>{yr.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=yr.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&yr.error("Do not combine --open and --no-open"),{...r,open:e?!0:t?!1:void 0}};h();import{readFile as bc}from"fs/promises";import{resolve as gc}from"path";import{cancel as cn,isCancel as hr,note as es,select as Tc,spinner as Ec,text as ts}from"@clack/prompts";import{parse as wc}from"dotenv";import br from"picocolors";var ns=async(r,e)=>{let t=e||"DATABASE_URL";if(r?.[t])return r[t];if(process.env[t])return process.env[t];let n=Ec();n.start("Looking for database connection..."),r?es(br.red(`${t} not found in .env or process.env`)):es(br.red(`No .env file found and ${t} not set in process.env`));let a=await Tc({message:`How do you want to provide ${t}?`,options:[{value:"manual",label:"Enter connection string manually"},{value:"other-env",label:"Use different .env file"},{value:"cancel",label:"Cancel / Exit"}],initialValue:"manual"});if((hr(a)||a==="cancel")&&(cn("No database connection provided. Exiting..."),process.exit(0)),a==="other-env"){n.start("Waiting for path...");let o=await ts({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(i){if(!i?.trim())return"Path is required"}});hr(o)&&(cn("Cancelled."),process.exit(0)),n.stop("Trying custom .env...");let c=gc(o);try{let i=await bc(c,"utf-8"),l=wc(i);if(l[t])return l[t];throw new Error(`${t} still missing in custom file`)}catch(i){let l=i;cn(`Cannot read or parse file: ${br.dim(l.message)}`),process.exit(1)}}n.stop("Manual input...");let s=await ts({message:`Paste your ${t}`,placeholder:"postgresql://user:password@localhost:5432/mydb or sqlite:///path/to/db.sqlite",validate(o){if(!o?.trim())return"Connection string is required!";if(!o.trim().startsWith("sqlite://"))try{new URL(o);return}catch{return"Must be a valid URL format"}}});return hr(s)&&(cn("Cancelled."),process.exit(0)),s.trim()};h();import{access as Cc,readFile as Sc}from"fs/promises";import{dirname as Rc,resolve as gr}from"path";import{parse as Nc}from"dotenv";var Ac=async r=>{let e=gr(r);for(;;){let t=gr(e,".env");try{return await Cc(t),t}catch{}let n=Rc(e);if(n===e)return null;e=n}},bt=async r=>{let e;if(r?e=gr(r):e=await Ac(process.cwd()),!e)return null;try{let t=await Sc(e,"utf-8");return Nc(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};h();import Dc from"open";var rs=r=>r===!0,as=async r=>{await Dc(r)};h();ie();var kl=Object.values(X).flatMap(({protocols:r})=>r).map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),vl=new RegExp(`\\b(?:${kl}):\\/\\/\\S+`,"gi"),ql=/\b(authToken=)[^&\s]+/gi,Ws=r=>r.replace(vl,e=>`the configured database${e.match(/[),.]+$/)?.[0]??""}`).replace(ql,"$1[redacted]");h();fr();ie();import{intro as Ul,outro as Bl}from"@clack/prompts";import At from"picocolors";var Vs=()=>{Ul(At.inverse(" db-studio ")),console.log(At.bold(`
|
|
602
|
+
`}return t}var Ji=N(()=>{"use strict";y();ee()});function Bd(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 Fd(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 Kd(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 Hd(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,Kd(o)])))}catch(n){return Q("warn","schema_sample_rows_failed",le(n)),[]}}async function jd(r,e,t){try{return await r.getTableColumns({tableName:e,db:t})}catch(n){return Q("warn","schema_columns_failed",le(n)),[]}}async function Wd(r,e={}){let t=gt(),{includeSampleData:n=!1,maxTables:a}=e,s=Lt(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([jd(s,p,r),n?Hd(s,p,r):Promise.resolve([])]),h={name:m?`${m}.${p}`:p,columns:f.map(Bd)};return b.length>0&&(h.sampleData=b),h}),l=await Promise.all(c),u=Fd(l);return{dbType:t,tables:l,relationships:u}}catch(o){throw Q("error","schema_fetch_failed",le(o)),new Error(`Failed to fetch database schema: ${o instanceof Error?o.message:"Unknown error"}`)}}async function Xi(r){return Wd(r,{includeSampleData:!0,includeDescriptions:!0})}var Zi=N(()=>{"use strict";y();bt();it();tt()});import{Elysia as Vd}from"elysia";var Yd,zd,ec,tc,nc=N(()=>{"use strict";y();Ht();ee();ce();tt();Ji();Zi();Yd=new Set(["connection","keep-alive","transfer-encoding","content-length","content-encoding"]),zd=new Set(["localhost","127.0.0.1","::1","[::1]"]),ec=()=>{let r;try{r=new URL(Ze.PROXY_URL)}catch{throw new d(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=zd.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},tc=new Vd({prefix:"/chat"}).get("/limit",async({headers:r})=>{let e=ec();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":et()??""}});return t.ok?await t.json():(Q("warn","chat_limit_unavailable",{proxy_status:t.status}),{limit:3,used:3,remaining:0})}catch(t){return Q("warn","chat_limit_unavailable",le(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 Xi(o):null,u=Qi(l),m={messages:r,conversationId:i,systemPrompt:u,provider:t,model:n},p=await fetch(`${ec()}/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":et()??""},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)Yd.has(f)||(s.headers[f]=b);return p.body},{body:Dr})});import{Elysia as Gd}from"elysia";var rc,ac=N(()=>{"use strict";y();bt();it();rc=new Gd({prefix:"/databases"}).derive(()=>{let r=gt();return{dbType:r,adapter:Lt(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 Qd}from"elysia";var Xe,Bt=N(()=>{"use strict";y();bt();ce();Xe=new Qd().derive({as:"scoped"},({params:r})=>{let{dbType:e=""}=r;if(!he.has(e))throw new d(400,{message:`Invalid database type: "${e}". Supported types: ${he.getSupportedTypes().join(", ")}`});return{dbType:e,adapter:Lt(e)}})});import{Elysia as Jd}from"elysia";var sc,oc=N(()=>{"use strict";y();ee();bt();Bt();sc=new Jd({prefix:"/keys"}).use(Xe).resolve(({adapter:r,dbType:e})=>({keyValueAdapter:_o(r,e)})).get("/",async({keyValueAdapter:r,query:e})=>({data:await r.scanKeys(e)}),{query:Fr}).post("/",async({keyValueAdapter:r,query:{db:e},body:t})=>({data:await r.createKey({db:e,...t})}),{query:K,body:Wr}).get("/:key/raw",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.getStringChunk({...e,key:t})}),{query:jr,params:Ot}).get("/:key",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.getKeyDetails({...e,key:t})}),{query:Hr,params:Ot}).post("/:key/actions",async({keyValueAdapter:r,query:{db:e},params:{key:t},body:n})=>({data:await r.applyKeyAction({db:e,key:t,...n})}),{query:K,params:Ot,body:Vr}).delete("/:key",async({keyValueAdapter:r,query:e,params:{key:t}})=>({data:await r.deleteKey({...e,key:t})}),{query:Yr,params:Ot})});import{Elysia as Xd}from"elysia";var ic,cc=N(()=>{"use strict";y();ee();Bt();ic=new Xd({prefix:"/logs"}).use(Xe).get("/",async({adapter:r,query:e})=>({data:await r.getServerLogs(e)}),{query:K})});import{Elysia as Zd}from"elysia";var lc,uc=N(()=>{"use strict";y();ee();Bt();lc=new Zd({prefix:"/query"}).use(Xe).post("/",async({adapter:r,query:{db:e},body:{query:t}})=>({data:await r.executeQuery({query:t,db:e})}),{query:K,body:qr})});import{Elysia as ep}from"elysia";var mc,dc=N(()=>{"use strict";y();ee();Bt();mc=new ep({prefix:"/records"}).use(Xe).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:wr}).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:Qr}).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:Ar})});async function fc({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(pc(r,e)),i=a.sheet_to_csv(o);return new Uint8Array(Buffer.from(i,"utf-8"))}case"xlsx":{let o=a.aoa_to_sheet(pc(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 tp,pc,yc=N(()=>{"use strict";y();tp=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,pc=(r,e)=>[r,...e?.map(t=>r?.map(n=>tp(t[n])))??[]]});import{Elysia as np}from"elysia";var rp,hc,gc=N(()=>{"use strict";y();ee();Bt();yc();rp={csv:"text/csv",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",json:"application/json"},hc=new np({prefix:"/tables"}).use(Xe).get("/",async({adapter:r,query:e})=>({data:await r.getTablesList(e.db)}),{query:K}).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:K}).post("/",async({adapter:r,query:e,body:t})=>(await r.createTable({tableData:t,db:e.db}),{data:`Table ${t.tableName} created successfully`}),{query:K,body:vr}).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:Ur,params:oe}).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:K,params:oe,body:Yt}).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:Nr,params:Te}).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:oe,body:ve}).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:Te,body:kn}).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:Te,body:Rt}).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:oe}).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:oe}).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:oe,body:Pn}).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:$n}).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:oe}).get("/:tableName/data",async({adapter:r,query:e,params:{tableName:t}})=>({data:await r.getTableData({tableName:t,...e})}),{query:Gr,params:oe}).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 fc({cols:s,rows:o,format:n,tableName:a}),{headers:{"Content-Type":rp[n],"Content-Disposition":`attachment; filename="${a}_export.${n}"`}})},{query:Br,params:oe})});import{Elysia as ap}from"elysia";import{z as bc}from"zod";var sp,Tc,Ec=N(()=>{"use strict";y();Zt();sp=bc.object({enabled:bc.boolean()}).strict(),Tc=new ap({prefix:"/telemetry"}).get("/config",({headers:r})=>((r["x-db-studio-gpc"]==="1"||r["sec-gpc"]==="1")&&Kn(!1),aa(),{data:Fn()})).put("/preference",({body:r,status:e})=>{let t=sp.safeParse(r);return t.success?(Kn(t.data.enabled),{data:Fn()}):e(400,{error:"Invalid telemetry preference"})}).post("/reset",()=>({data:{installationId:ta()}}))});var Sc={};Kt(Sc,{createServer:()=>gp});import{existsSync as wc}from"fs";import{readFile as op,stat as ip}from"fs/promises";import ke from"path";import{fileURLToPath as cp}from"url";import{cors as lp}from"@elysiajs/cors";import{node as up}from"@elysiajs/node";import{Elysia as mp}from"elysia";var fr,dp,pp,fp,yp,hp,gp,Cc=N(()=>{"use strict";y();Ht();bt();Vi();ce();zi();Zt();tt();nc();ac();oc();cc();uc();dc();gc();Ec();({API_PREFIX:fr}=Ze),dp=()=>{if(process.env.NODE_ENV==="development")return ke.resolve(process.cwd(),"../web/dist");let r=ke.dirname(cp(import.meta.url)),e=ke.resolve(r,"./web-dist"),t=ke.resolve(process.cwd(),"../web/dist"),n=ke.resolve(e,"index.html"),a=ke.resolve(t,"index.html");return!wc(n)&&wc(a)?t:e},pp={".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"},fp=async(r,e)=>{let t=ke.join(r,"index.html");try{let a=ke.resolve(r,`.${decodeURIComponent(e)}`);a.startsWith(`${r}${ke.sep}`)&&(await ip(a)).isFile()&&(t=a)}catch{}let n=t.startsWith(ke.join(r,"assets",ke.sep));return new Response(await op(t),{headers:{"Content-Type":pp[ke.extname(t)]??"application/octet-stream","Cache-Control":n?"public, max-age=31536000, immutable":"no-cache"}})},yp=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}},hp=(r,e)=>{let{pathname:t}=new URL(r.url),n=Jt(r.method,t),a=Xt(t),s={requestId:oo(r.headers.get("x-request-id")??void 0),operation:n,dbType:a};return io(s,async()=>{if(!t.startsWith(`${fr}/`)||t.startsWith(`${fr}/telemetry`))return e();let o=performance.now(),i=a&&he.has(a)?a:void 0,c=await oa(n,i,e);return Hn({event:"server_operation",properties:{operation:n,method:r.method,outcome:ra(c.status),duration_bucket:na(performance.now()-o),db_type:i}}),c})},gp=()=>{Wi();let r=dp(),e=new mp({adapter:up()}).wrap((t,n)=>(...a)=>hp(n,async()=>await t(...a))).onRequest(({set:t})=>{t.headers["x-request-id"]=et()}).use(lp({origin:t=>yp(t.headers.get("origin")),methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowedHeaders:["Content-Type","X-Run-Id","X-Request-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})=>Yi(t,n)).group(fr,t=>t.use(rc).use(tc).use(Tc).group("/:dbType",n=>n.use(hc).use(mc).use(lc).use(sc).use(ic)));return process.env.NODE_ENV!=="test"&&e.all("/*",({request:t,path:n})=>(t.method==="GET"||t.method==="HEAD")&&!n.startsWith(`${fr}/`)?fp(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]="07303039-2540-407b-ab3a-6c2946759636",r._sentryDebugIdIdentifier="sentry-dbid-07303039-2540-407b-ab3a-6c2946759636")}catch{}})();y();Ht();import{intro as bp,log as yr,outro as Rc,spinner as Tp}from"@clack/prompts";import Sn from"picocolors";y();import{program as gr}from"commander";var cs=()=>{gr.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=gr.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&gr.error("Do not combine --open and --no-open"),{...r,open:e?!0:t?!1:void 0}};y();import{readFile as Ac}from"fs/promises";import{resolve as Dc}from"path";import{cancel as Cn,isCancel as br,note as ls,select as _c,spinner as Oc,text as us}from"@clack/prompts";import{parse as Ic}from"dotenv";import Tr from"picocolors";var ms=async(r,e)=>{let t=e||"DATABASE_URL";if(r?.[t])return r[t];if(process.env[t])return process.env[t];let n=Oc();n.start("Looking for database connection..."),r?ls(Tr.red(`${t} not found in .env or process.env`)):ls(Tr.red(`No .env file found and ${t} not set in process.env`));let a=await _c({message:`How do you want to provide ${t}?`,options:[{value:"manual",label:"Enter connection string manually"},{value:"other-env",label:"Use different .env file"},{value:"cancel",label:"Cancel / Exit"}],initialValue:"manual"});if((br(a)||a==="cancel")&&(Cn("No database connection provided. Exiting..."),process.exit(0)),a==="other-env"){n.start("Waiting for path...");let o=await us({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(c){if(!c?.trim())return"Path is required"}});br(o)&&(Cn("Cancelled."),process.exit(0)),n.stop("Trying custom .env...");let i=Dc(o);try{let c=await Ac(i,"utf-8"),l=Ic(c);if(l[t])return l[t];throw new Error(`${t} still missing in custom file`)}catch(c){let l=c;Cn(`Cannot read or parse file: ${Tr.dim(l.message)}`),process.exit(1)}}n.stop("Manual input...");let s=await us({message:`Paste your ${t}`,placeholder:"postgresql://user:password@localhost:5432/mydb or sqlite:///path/to/db.sqlite",validate(o){if(!o?.trim())return"Connection string is required!";if(!o.trim().startsWith("sqlite://"))try{new URL(o);return}catch{return"Must be a valid URL format"}}});return br(s)&&(Cn("Cancelled."),process.exit(0)),s.trim()};y();import{access as Lc,readFile as xc}from"fs/promises";import{dirname as Pc,resolve as Er}from"path";import{parse as $c}from"dotenv";var Mc=async r=>{let e=Er(r);for(;;){let t=Er(e,".env");try{return await Lc(t),t}catch{}let n=Pc(e);if(n===e)return null;e=n}},St=async r=>{let e;if(r?e=Er(r):e=await Mc(process.cwd()),!e)return null;try{let t=await xc(e,"utf-8");return $c(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};y();import kc from"open";var ds=r=>r===!0,ps=async r=>{await kc(r)};y();ee();var Vl=Object.values(G).flatMap(({protocols:r})=>r).map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),Yl=new RegExp(`\\b(?:${Vl}):\\/\\/\\S+`,"gi"),zl=/\b(authToken=)[^&\s]+/gi,ro=r=>r.replace(Yl,e=>`the configured database${e.match(/[),.]+$/)?.[0]??""}`).replace(zl,"$1[redacted]");y();hr();ee();import{intro as Gl,outro as Ql}from"@clack/prompts";import It from"picocolors";var ao=()=>{Gl(It.inverse(" db-studio ")),console.log(It.bold(`
|
|
564
603
|
Usage:`)),console.log(` db-studio [options]
|
|
565
|
-
`),console.log(
|
|
566
|
-
`),console.log(
|
|
567
|
-
`),console.log(
|
|
568
|
-
`),
|
|
569
|
-
To configure database connection:`)),console.log(
|
|
570
|
-
`)),
|
|
604
|
+
`),console.log(It.bold("Supported Databases:")),console.log(` ${Object.values(G).map(({label:r})=>r).join(", ")}
|
|
605
|
+
`),console.log(It.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
|
|
606
|
+
`),console.log(It.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
|
|
607
|
+
`),Ql(It.green(`For more information, visit: ${os.SITE_DOCS_LINK}`))};y();Ht();ee();import{intro as au,note as su,outro as uo}from"@clack/prompts";import qe from"picocolors";He();var mo=async(r,e,t)=>{au(qe.inverse(" db-studio "));let n=t||Ze.VAR_NAME,a=null;if(e)a=e;else{let s=r?await St(r):await St();s?.[n]?a=s[n]:process.env[n]&&(a=process.env[n]??null)}a?uo(qe.green(`\u2713 Database connection configured (using ${n})`)):(su(qe.red(`\u2717 ${n} not found`),"Status"),console.log(qe.yellow(`
|
|
608
|
+
To configure database connection:`)),console.log(qe.dim(` \u2022 Supported databases: ${Object.values(G).map(({label:s})=>s).join(", ")}`)),console.log(qe.dim(` \u2022 Also via wire-compatible URLs: ${Object.keys(Un).map(s=>`${s}://`).join(", ")}`)),console.log(qe.dim(` \u2022 Add ${n} to your .env file or set it in process.env`)),console.log(qe.dim(" \u2022 Use -d flag: db-studio -d <url>")),console.log(qe.dim(" \u2022 Use -e flag: db-studio -e <path-to-env>")),console.log(qe.dim(` \u2022 Use -n flag: db-studio -n <var-name>
|
|
609
|
+
`)),uo(qe.yellow("\u26A0 No database connection configured")))};y();Zr();import{intro as iu,outro as cu}from"@clack/prompts";import po from"picocolors";var fo=()=>{iu(po.inverse(" db-studio ")),cu(po.green(`\u{1F680} db-studio v${dt.version}`))};var Ep=async()=>{let{env:r,port:e,databaseUrl:t,varName:n,open:a,status:s,help:o,version:i}=cs();o&&(ao(),process.exit(0)),i&&(fo(),process.exit(0)),s&&(await mo(r,t,n),process.exit(0)),bp(Sn.inverse(" db-studio "));let c=r?await St(r):await St();if(c)for(let[B,M]of Object.entries(c))process.env[B]===void 0&&(process.env[B]=M);let l=Number.parseInt(e??process.env.PORT??String(Ze.PORT),10),u=process.env.HOST,m=n||Ze.VAR_NAME,p=!!c?.[m],f=!!process.env[m],b=t||await ms(c,m),h=t?"Using database URL from --database-url":p?`Found ${m} in ${r??".env"}`:f?`Found ${m} in environment`:"Using database URL provided interactively";yr.success(h),process.env.DATABASE_URL=b;let{flushServerObservability:g,initServerObservability:S}=await Promise.resolve().then(()=>(Zt(),To));S();let{checkDatabaseConnection:w,getDatabaseConnectionDetails:A}=await Promise.resolve().then(()=>(Do(),Ao)),{type:D,name:R,destination:C}=A(b),_=Tp();_.start(`Connecting to ${R}...`);try{await w(D),_.stop(`Connected to ${R} at ${C}`)}catch(B){throw _.stop(`Could not connect to ${R} at ${C}`),B}let{createServer:O}=await Promise.resolve().then(()=>(Cc(),Sc)),{closeAllDbPools:k}=await Promise.resolve().then(()=>(it(),pa)),{app:x}=O(),v=async()=>{let B=new Promise(M=>setTimeout(M,5e3));await Promise.race([x.server?.stop(),B]),await Promise.race([Promise.allSettled([k(),g()]),B]),process.exit(0)};process.once("SIGINT",v),process.once("SIGTERM",v),x.listen({hostname:u,port:l});let $=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${l}`;if(yr.success(`Server listening at ${Sn.cyan($)}`),ds(a))try{await ps($),yr.success("Opened db-studio in your browser")}catch{yr.warn(`Could not open your browser. Visit ${Sn.cyan($)}`)}Rc(Sn.green("Ready"))};process.env.NODE_ENV!=="test"&&Ep().catch(r=>{let e=r instanceof Error?r.message:String(r);Rc(Sn.red(`Startup failed: ${ro(e)}`)),process.exit(1)});var dS=void 0;export{dS as default,Ep as main};
|
|
571
610
|
//# sourceMappingURL=index.js.map
|