db-studio 1.16.0 → 1.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/index.js +64 -64
  2. package/dist/index.js.map +1 -1
  3. package/dist/web-dist/assets/{_pathlessLayout-Boc5CMy6.js → _pathlessLayout-Dm9EQxZz.js} +1 -1
  4. package/dist/web-dist/assets/{_pathlessLayout-CR6og_FO.js → _pathlessLayout-KomQW7kv.js} +4 -4
  5. package/dist/web-dist/assets/{_queryId-B11-YnBQ.js → _queryId-Y0dZf-cC.js} +1 -1
  6. package/dist/web-dist/assets/{_table-DxQhMcry.js → _table-CzH4uICv.js} +1 -1
  7. package/dist/web-dist/assets/{_table-Bqn27t7B.js → _table-DvAv2WAN.js} +1 -1
  8. package/dist/web-dist/assets/{badge-CCWwBQqD.js → badge-D5EgvXjr.js} +1 -1
  9. package/dist/web-dist/assets/{browser-8cP9ndIh.js → browser-CmMj9Etg.js} +1 -1
  10. package/dist/web-dist/assets/{bundle-mjs-DB1RllIB.js → bundle-mjs-CoQqDXYI.js} +1 -1
  11. package/dist/web-dist/assets/{code-editor-BgChfnuO.js → code-editor-DdbJIkjN.js} +1 -1
  12. package/dist/web-dist/assets/{database.store-BQBwzxfV.js → database.store-CHdcWrDH.js} +10 -10
  13. package/dist/web-dist/assets/{dist-DkQ5_Uxh.js → dist-6oMMpbb8.js} +1 -1
  14. package/dist/web-dist/assets/editor.worker-BYfbSb3U.js +10621 -0
  15. package/dist/web-dist/assets/{format-cell-value-iKbN4Wqi.js → format-cell-value-Db6gUQtt.js} +1 -1
  16. package/dist/web-dist/assets/{highlighted-body-OFNGDK62-v8ygEbhn.js → highlighted-body-OFNGDK62-BSdYCCt8.js} +1 -1
  17. package/dist/web-dist/assets/{icons-BCT3bskt.js → icons-DhXVo5Bo.js} +1 -1
  18. package/dist/web-dist/assets/{index-UKp_x9Z2.js → index-CXM-VMxb.js} +10 -10
  19. package/dist/web-dist/assets/{indexes-B4-rFB3b.js → indexes-BaBT0iJv.js} +1 -1
  20. package/dist/web-dist/assets/{logs-BOXFja-k.js → logs-BNgg_Pdy.js} +1 -1
  21. package/dist/web-dist/assets/{mermaid-GHXKKRXX-DEXfBzpg.js → mermaid-GHXKKRXX-7XpYx0N7.js} +1 -1
  22. package/dist/web-dist/assets/{middleware-BW-pB9ic.js → middleware-BGupJOOn.js} +1 -1
  23. package/dist/web-dist/assets/{monaco-editor-BzOxyRit.js → monaco-editor-CjSWDgwd.js} +4 -4
  24. package/dist/web-dist/assets/{monitoring-BfsJUyIb.js → monitoring-BQqmb7Os.js} +1 -1
  25. package/dist/web-dist/assets/{overlay.store-F1O5kYfc.js → overlay.store-CIOj_XKm.js} +6 -6
  26. package/dist/web-dist/assets/{queries.store-BY0EJQVG.js → queries.store-g9a07xjm.js} +1 -1
  27. package/dist/web-dist/assets/{query-runner-Cf8qZvua.js → query-runner-CA0GllMK.js} +3 -3
  28. package/dist/web-dist/assets/{radix-ui-BgeXyBqe.js → radix-ui-Cct0OxHG.js} +1 -1
  29. package/dist/web-dist/assets/{react--smpiBOs.js → react-CsZsK598.js} +1 -1
  30. package/dist/web-dist/assets/{react-dom-DJiIHdcx.js → react-dom-CVM6YmrG.js} +1 -1
  31. package/dist/web-dist/assets/{redis-value-D-VAbClW.js → redis-value-IuKBQ6aR.js} +1 -1
  32. package/dist/web-dist/assets/{rolldown-runtime-aFZ5dRI8.js → rolldown-runtime-D_EvJRSK.js} +1 -1
  33. package/dist/web-dist/assets/{runner-DD-JnaQG.js → runner-DdyjNmVH.js} +1 -1
  34. package/dist/web-dist/assets/schema-CDY7Uyya.js +1 -0
  35. package/dist/web-dist/assets/{schema-D2srYuEZ.js → schema-E1zLqsI0.js} +1 -1
  36. package/dist/web-dist/assets/{table-D4qAO6ym.js → table-BhJJs1xo.js} +1 -1
  37. package/dist/web-dist/assets/{tanstack-BMrziknI.js → tanstack-Dwt_z01e.js} +1 -1
  38. package/dist/web-dist/assets/{use-database-engine-Dnkkyy1a.js → use-database-engine-D1BTDQpy.js} +1 -1
  39. package/dist/web-dist/assets/{visualizer-DKVyuUTU.js → visualizer-CeImbOqE.js} +1 -1
  40. package/dist/web-dist/index.html +18 -18
  41. package/package.json +1 -1
  42. package/dist/web-dist/assets/schema-C4Vx4FfH.js +0 -1
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- var Ji=Object.defineProperty;var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var Xt=(n,e)=>{for(var t in e)Ji(n,t,{get:e[t],enumerable:!0})};var h=S(()=>{"use strict";(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};n.SENTRY_RELEASE={id:"db-studio@1.16.0"}}catch{}})()});var Ia=S(()=>{"use strict";h()});var Ma=S(()=>{"use strict";h()});var ka=S(()=>{"use strict";h()});var va,xa,Qe,qa=S(()=>{"use strict";h();va=globalThis.process?.env,xa=va?.NODE_ENV,Qe={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:xa==="development",PROXY_URL:va?.DB_STUDIO_PROXY_URL??(xa==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var Ua=S(()=>{"use strict";h()});var Ba,rn=S(()=>{"use strict";h();Ba={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 Fa=S(()=>{"use strict";h()});var $t=S(()=>{"use strict";h();Ia();Ma();ka();qa();Ua();rn();Fa()});import{z as mt}from"zod";var x,dt,Pt,cl,ul,be,_e=S(()=>{"use strict";h();x=mt.object({db:mt.string("Database name is required")}),dt=["pg","mysql","mssql","mongodb","sqlite","redis","duckdb","oracle","clickhouse"],Pt=mt.enum(dt,{message:"Invalid database type"}),cl=x.extend({dbType:Pt}),ul=mt.object({dbType:Pt}),be=mt.object({tableName:mt.string("Table name is required")})});import{z as Be}from"zod";var xe,ml,dl,za=S(()=>{"use strict";h();_e();xe=Be.object({columnName:Be.string("Column name is required"),columnType:Be.string("Column type is required"),defaultValue:Be.string().optional(),isPrimaryKey:Be.boolean().default(!1),isNullable:Be.boolean().default(!1),isUnique:Be.boolean().default(!1),isIdentity:Be.boolean().default(!1),isArray:Be.boolean().default(!1)}),ml=be,dl=Be.object({db:x.shape.db,tableName:be.shape.tableName,columnName:xe.shape.columnName,columnType:xe.shape.columnType,defaultValue:xe.shape.defaultValue,isPrimaryKey:xe.shape.isPrimaryKey,isNullable:xe.shape.isNullable,isUnique:xe.shape.isUnique,isIdentity:xe.shape.isIdentity,isArray:xe.shape.isArray})});import{z as Lt}from"zod";var ln,Ga=S(()=>{"use strict";h();ln=Lt.object({tableName:Lt.string("Table name is required"),data:Lt.record(Lt.string("Column name is required"),Lt.any())})});import{z as pl}from"zod";var Qa,cn,Ja,un,mn=S(()=>{"use strict";h();Qa=["gemini","openai","anthropic","grok","openrouter"],cn=pl.enum(Qa),Ja=[{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"}]}],un=n=>Ja.find(e=>e.id===n)?.models[0]?.id??"gemini-3-flash-preview"});import{z as ve}from"zod";var dn,ge,fl,yl,er=S(()=>{"use strict";h();_e();dn=x.extend({cascade:ve.string().optional().transform(n=>n==="true")}),ge=ve.object({tableName:ve.string("Table name is required"),columnName:ve.string("Column name is required")}),fl=ve.object({db:x.shape.db,tableName:ge.shape.tableName,columnName:ge.shape.columnName,cascade:ve.boolean().optional()}),yl=ve.object({message:ve.string("Message is required"),tableName:ve.string("Table name is required"),columnName:ve.string("Column name is required"),deletedCount:ve.number("Deleted count is required").default(0)})});import{z as It}from"zod";var pt,hl,bl,Xa=S(()=>{"use strict";h();_e();er();pt=It.object({columnType:It.string("Column type is required"),isNullable:It.boolean(),defaultValue:It.string().nullable().optional()}),hl=ge,bl=It.object({db:x.shape.db,tableName:ge.shape.tableName,columnName:ge.shape.columnName,columnType:pt.shape.columnType,isNullable:pt.shape.isNullable,defaultValue:pt.shape.defaultValue})});var Za=S(()=>{"use strict";h()});import{z as ft}from"zod";var pn,eo=S(()=>{"use strict";h();pn=ft.object({tableName:ft.string().min(1,"Table name is required"),records:ft.array(ft.record(ft.string(),ft.any())).min(1,"At least one record is required")})});import{z as de}from"zod";var gl,Tl,fn,to=S(()=>{"use strict";h();mn();_e();gl=de.object({type:de.string(),content:de.string().optional()}).passthrough(),Tl=de.object({provider:cn.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(gl).optional()}).passthrough()),data:de.object({conversationId:de.string().optional(),db:x.shape.db,includeSchema:de.boolean().optional().default(!0)})}),fn=Tl.transform(n=>({...n,model:n.model??un(n.provider)}))});var ro=S(()=>{"use strict";h()});import{z as $e}from"zod";var El,no,M,wl,ao,Cl,yn=S(()=>{"use strict";h();El=["text","boolean","number","enum","json","date","array"],no=$e.enum(El),M={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},wl=["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"],ao=$e.enum(wl),Cl=$e.object({columnName:$e.string(),dataType:no,dataTypeLabel:ao,isNullable:$e.boolean(),columnDefault:$e.string().nullable(),isPrimaryKey:$e.boolean(),isForeignKey:$e.boolean(),referencedTable:$e.string().nullable(),referencedColumn:$e.string().nullable(),enumValues:$e.array($e.string()).nullable()})});function tr(n){let e=n?.toLowerCase().trim()||"";return e.includes("[]")||e==="date"||e==="time"||e==="time without time zone"||e.startsWith("time(")||e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")||e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?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 hn(n){if(!n)return b.text;let e=n.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 rr(n,e){let t=n?.toLowerCase().trim()||"",r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="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 bn(n,e){if(!n)return b.text;let t=n.toLowerCase().trim(),r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="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 nr(n){let e=n?.toLowerCase().trim()||"";return e==="tinyint"||e==="smallint"||e==="int"||e==="bigint"||e==="decimal"||e==="numeric"||e==="float"||e==="real"||e==="money"||e==="smallmoney"?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 gn(n){if(!n)return b.text;let e=n.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 ar(n){let e=n?.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 Tn(n){let e=n?.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 or(n){let e=n?.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 En(n){let e=n?.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 sr(n){let e=n?.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 wn(n){let e=n?.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 r=Number(t[1]);if(r<=4)return b.smallint;if(r<=10)return b.int;if(r<=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 yt(n){let e=n.trim();for(;;){let t=e.match(/^(?:Nullable|LowCardinality)\((.*)\)$/);if(!t?.[1])return e;e=t[1].trim()}}function ir(n){let e=yt(n);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 Cn(n){let e=yt(n);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,oo=S(()=>{"use strict";h();yn();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 pe}from"zod";var so,Rn,io,lo,Sn,co=S(()=>{"use strict";h();so=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],Rn=pe.enum(so),io=pe.object({columnName:pe.string("Column name is required"),columnType:pe.string("Column type is required"),defaultValue:pe.string().optional(),isPrimaryKey:pe.boolean().default(!1),isNullable:pe.boolean().default(!1),isUnique:pe.boolean().default(!1),isIdentity:pe.boolean().default(!1),isArray:pe.boolean().default(!1)}),lo=pe.object({columnName:pe.string("Column name is required"),referencedTable:pe.string("Referenced table is required"),referencedColumn:pe.string("Referenced column is required"),onUpdate:Rn.default("NO ACTION"),onDelete:Rn.default("NO ACTION")}),Sn=pe.object({tableName:pe.string("Table name is required"),fields:pe.array(io).min(1,"At least one field is required"),foreignKeys:pe.array(lo).optional()})});var Z,ht,uo=S(()=>{"use strict";h();_e();Z={pg:{label:"PostgreSQL",protocols:["postgres","postgresql","cockroachdb"],defaultPort:5432,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!0,rowMutation:!0},mysql:{label:"MySQL",protocols:["mysql","mysql2","mariadb","tidb"],defaultPort:3306,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},mssql:{label:"SQL Server",protocols:["mssql","sqlserver"],defaultPort:1433,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},mongodb:{label:"MongoDB",protocols:["mongodb","mongodb+srv"],defaultPort:27017,dataModel:"document",editorLanguage:"json",liveMode:!1,schemaSelector:!1,rowMutation:!0},sqlite:{label:"SQLite / libSQL",protocols:["sqlite","libsql"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},redis:{label:"Redis",protocols:["redis","rediss"],defaultPort:6379,dataModel:"key-value",editorLanguage:"plaintext",liveMode:!1,schemaSelector:!1,rowMutation:!0},duckdb:{label:"DuckDB",protocols:["duckdb"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},oracle:{label:"Oracle",protocols:["oracle"],defaultPort:1521,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},clickhouse:{label:"ClickHouse",protocols:["clickhouse","clickhouses"],defaultPort:8123,dataModel:"relational",editorLanguage:"pgsql",liveMode:!1,schemaSelector:!1,rowMutation:!1,rowMutationReason:"Use a SQL query to update or delete ClickHouse rows; sorting keys are not unique."}},ht=n=>dt.find(e=>Z[e].protocols.includes(n))});import{z as Te}from"zod";var mo,Rl,Sl,po=S(()=>{"use strict";h();_e();mo=Te.object({name:Te.string("Name is required"),size:Te.string("Size is required"),owner:Te.string("Owner is required"),encoding:Te.string("Encoding is required")}),Rl=Te.object({databases:Te.array(mo),dbType:Pt}),Sl=Te.object({version:Te.string("Version is required"),database:Te.string("Database is required"),user:Te.string("User is required"),host:Te.string("Host is required").nullable(),port:Te.number("Port is required").nullable(),active_connections:Te.coerce.number("Active connections is required"),max_connections:Te.coerce.number("Max connections is required")})});var fo=S(()=>{"use strict";h()});import{z as bt}from"zod";var lr,yo=S(()=>{"use strict";h();lr=bt.object({tableName:bt.string("Table name is required"),primaryKeys:bt.array(bt.object({columnName:bt.string("Column name is required"),value:bt.any()})).min(1,"At least one primary key is required")})});import{z as Al}from"zod";var An,ho=S(()=>{"use strict";h();_e();An=x.extend({cascade:Al.string().optional().transform(n=>n==="true")})});import{z as bo}from"zod";var Nn,go=S(()=>{"use strict";h();Nn=bo.object({query:bo.string("Query is required")})});import{z as Nl}from"zod";var To,Dn,Eo=S(()=>{"use strict";h();_e();To=["csv","xlsx","json"],Dn=x.extend({format:Nl.enum(To,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as T}from"zod";var cr,B,_n,On,Dl,$n,gt,_l,Ol,$l,Pl,Ll,Il,Ml,wo,kl,Pn,xl,vl,ql,Ul,Bl,Fl,Kl,Ln,jl,Hl,Wl,Vl,Yl,zl,Gl,Ql,Jl,Xl,Zl,ec,tc,rc,nc,In,Mn,ac,Co=S(()=>{"use strict";h();cr=T.enum(["string","hash","list","set","zset","stream","unknown"]),B=T.object({base64:T.string().max(16*1024*1024).refine(n=>/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/.test(n),"Invalid unpadded base64url value"),utf8:T.string().optional()}),_n=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:cr.exclude(["unknown"]).optional()}),On=T.object({key:B,type:cr,ttlMs:T.number().int(),memoryBytes:T.number().int().nonnegative().nullable()}),Dl=T.object({keys:T.array(On),nextCursor:T.string().nullable(),hasMore:T.boolean()}),$n=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")}),gt=T.object({key:T.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),_l=T.object({kind:T.literal("string"),value:B,truncated:T.boolean()}),Ol=T.object({kind:T.literal("hash"),entries:T.array(T.object({field:B,value:B}))}),$l=T.object({kind:T.literal("list"),entries:T.array(T.object({index:T.number().int(),value:B}))}),Pl=T.object({kind:T.literal("set"),members:T.array(B)}),Ll=T.object({kind:T.literal("zset"),entries:T.array(T.object({member:B,score:T.union([T.number(),T.literal("inf"),T.literal("-inf")])}))}),Il=T.object({kind:T.literal("stream"),entries:T.array(T.object({id:T.string(),fields:T.array(T.object({field:B,value:B}))}))}),Ml=T.object({kind:T.literal("unknown")}),wo=T.discriminatedUnion("kind",[_l,Ol,$l,Pl,Ll,Il,Ml]),kl=On.extend({length:T.number().int().nonnegative().nullable(),revision:T.string(),value:wo,nextCursor:T.string().nullable(),hasMore:T.boolean()}),Pn=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()}),xl=T.object({chunk:B,length:T.number().int().nonnegative(),nextOffset:T.number().int().nonnegative().nullable(),hasMore:T.boolean()}),vl=T.object({kind:T.literal("string"),value:B}),ql=T.object({kind:T.literal("hash"),entries:T.array(T.object({field:B,value:B})).min(1)}),Ul=T.object({kind:T.literal("list"),entries:T.array(B).min(1)}),Bl=T.object({kind:T.literal("set"),members:T.array(B).min(1)}),Fl=T.object({kind:T.literal("zset"),entries:T.array(T.object({member:B,score:T.number()})).min(1)}),Kl=T.object({kind:T.literal("stream"),id:T.string().default("*"),fields:T.array(T.object({field:B,value:B})).min(1)}),Ln=T.object({key:B,type:cr.exclude(["unknown"]),value:T.discriminatedUnion("kind",[vl,ql,Ul,Bl,Fl,Kl]),ttlMs:T.number().int().positive().nullable().default(null)}),jl=T.object({key:B,revision:T.string().nullable(),deleted:T.boolean()}),Hl=T.object({action:T.literal("rename"),newKey:B}),Wl=T.object({action:T.literal("setTtl"),ttlMs:T.number().int().positive().nullable()}),Vl=T.object({action:T.literal("setString"),value:B}),Yl=T.object({action:T.literal("upsertHash"),field:B,value:B}),zl=T.object({action:T.literal("deleteHash"),field:B}),Gl=T.object({action:T.literal("pushList"),side:T.enum(["left","right"]),value:B}),Ql=T.object({action:T.literal("setList"),index:T.number().int(),value:B}),Jl=T.object({action:T.literal("deleteList"),index:T.number().int()}),Xl=T.object({action:T.literal("addSet"),member:B}),Zl=T.object({action:T.literal("removeSet"),member:B}),ec=T.object({action:T.literal("upsertZset"),member:B,score:T.number()}),tc=T.object({action:T.literal("removeZset"),member:B}),rc=T.object({action:T.literal("appendStream"),id:T.string().default("*"),fields:T.array(T.object({field:B,value:B})).min(1)}),nc=T.object({action:T.literal("deleteStream"),id:T.string()}),In=T.object({expectedRevision:T.string(),force:T.boolean().default(!1),operation:T.discriminatedUnion("action",[Hl,Wl,Vl,Yl,zl,Gl,Ql,Jl,Xl,Zl,ec,tc,rc,nc])}),Mn=T.object({db:T.string(),expectedRevision:T.string(),force:T.stringbool().default(!1)}),ac=T.object({deleted:T.boolean()})});var Ro=S(()=>{"use strict";h()});import{z as kn}from"zod";var ur,oc,sc,So=S(()=>{"use strict";h();_e();er();ur=kn.object({newColumnName:kn.string("New column name is required")}),oc=ge,sc=kn.object({db:x.shape.db,tableName:ge.shape.tableName,columnName:ge.shape.columnName,newColumnName:ur.shape.newColumnName})});import{z as mr}from"zod";var Mt,ic,lc,Ao=S(()=>{"use strict";h();_e();Mt=mr.object({newTableName:mr.string("New table name is required").trim().min(1,"New table name is required"),schemaName:mr.string().trim().min(1).optional()}),ic=be,lc=mr.object({db:x.shape.db,tableName:be.shape.tableName,newTableName:Mt.shape.newTableName,schemaName:Mt.shape.schemaName})});import{z as G}from"zod";var cc,kt,uc,No,mc,xn,Do=S(()=>{"use strict";h();_e();cc=G.object({columnName:G.string(),operator:G.string(),value:G.string()}),kt=["asc","desc"],uc=G.object({columnName:G.string(),direction:G.enum(kt)}),No=G.object({limit:G.number(),total:G.number(),hasNextPage:G.boolean(),hasPreviousPage:G.boolean(),nextCursor:G.string().nullable(),prevCursor:G.string().nullable()}),mc=G.object({data:G.array(G.record(G.string(),G.unknown())),meta:No}),xn=G.object({db:x.shape.db,cursor:G.string().optional(),limit:G.string().optional().default("50").transform(Number),direction:G.enum(kt).optional().default(kt[0]),sort:G.string().optional().transform(n=>{if(!n)return"";try{let e=JSON.parse(n);return Array.isArray(e)?e:n}catch{return n}}),order:G.enum(kt).optional(),filters:G.string().optional().transform(n=>{if(!n)return[];try{return JSON.parse(n)}catch{return[]}})})});import{z as dr}from"zod";var dc,_o=S(()=>{"use strict";h();dc=dr.object({tableName:dr.string("Table name is required"),schemaName:dr.string().optional(),rowCount:dr.coerce.number("Row count is required")})});import{z as Oo}from"zod";var pc,$o=S(()=>{"use strict";h();pc=Oo.object({schema:Oo.string()})});import{z as Pe}from"zod";var vn,Po=S(()=>{"use strict";h();vn=Pe.object({tableName:Pe.string("Table name is required"),primaryKey:Pe.string("Primary key is required").default("id"),primaryKeys:Pe.array(Pe.string().min(1)).min(1).optional(),updates:Pe.array(Pe.object({rowData:Pe.record(Pe.string("Column name is required"),Pe.any()),columnName:Pe.string("Column name is required"),value:Pe.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var Lo={};Xt(Lo,{AI_PROVIDERS:()=>Qa,AI_PROVIDER_OPTIONS:()=>Ja,DATABASE_ENGINES:()=>Z,DATABASE_TYPES:()=>dt,DataTypes:()=>M,FOREIGN_KEY_ACTIONS:()=>so,FORMAT_TYPES:()=>To,StandardizedDataType:()=>b,addColumnParamSchema:()=>ml,addColumnParamsSchema:()=>dl,addColumnSchema:()=>xe,addRecordSchema:()=>ln,aiProviderSchema:()=>cn,alterColumnParamSchema:()=>hl,alterColumnParamsSchema:()=>bl,alterColumnSchema:()=>pt,bulkInsertRecordsSchema:()=>pn,chatSchema:()=>fn,columnInfoSchema:()=>Cl,connectionInfoSchema:()=>Sl,createKeySchema:()=>Ln,createTableSchema:()=>Sn,currentDatabaseSchema:()=>cl,dataTypesSchema:()=>no,databaseInfoSchema:()=>mo,databaseListSchema:()=>Rl,databaseSchema:()=>x,databaseTypeParamSchema:()=>ul,databaseTypeSchema:()=>Pt,dbTypeFromProtocol:()=>ht,deleteColumnParamSchema:()=>ge,deleteColumnParamsSchema:()=>fl,deleteColumnQuerySchema:()=>dn,deleteColumnSuccessResponseSchema:()=>yl,deleteKeyQuerySchema:()=>Mn,deleteKeyResultSchema:()=>ac,deleteRecordSchema:()=>lr,deleteTableQuerySchema:()=>An,encodedRedisValueSchema:()=>B,executeQuerySchema:()=>Nn,exportTableSchema:()=>Dn,fieldDataSchema:()=>io,filterSchema:()=>cc,foreignKeyActionSchema:()=>Rn,foreignKeyDataSchema:()=>lo,getDefaultAiModel:()=>un,keyActionSchema:()=>In,keyDetailsQuerySchema:()=>$n,keyDetailsResultSchema:()=>kl,keyParamSchema:()=>gt,keyRawQuerySchema:()=>Pn,keyRawResultSchema:()=>xl,keyScanQuerySchema:()=>_n,keyScanResultSchema:()=>Dl,keyWriteResultSchema:()=>jl,mapClickhouseToDataType:()=>ir,mapDuckdbToDataType:()=>or,mapMssqlToDataType:()=>nr,mapMysqlToDataType:()=>rr,mapOracleToDataType:()=>sr,mapPostgresToDataType:()=>tr,mapSqliteToDataType:()=>ar,redisKeySummarySchema:()=>On,redisKeyTypeSchema:()=>cr,redisKeyValueSchema:()=>wo,renameColumnParamSchema:()=>oc,renameColumnParamsSchema:()=>sc,renameColumnSchema:()=>ur,renameTableParamSchema:()=>ic,renameTableParamsSchema:()=>lc,renameTableSchema:()=>Mt,sortDirections:()=>kt,sortSchema:()=>uc,standardizeClickhouseDataTypeLabel:()=>Cn,standardizeDataTypeLabel:()=>hn,standardizeDuckdbDataTypeLabel:()=>En,standardizeMssqlDataTypeLabel:()=>gn,standardizeMysqlDataTypeLabel:()=>bn,standardizeOracleDataTypeLabel:()=>wn,standardizeSqliteDataTypeLabel:()=>Tn,standardizedDataTypeSchema:()=>ao,tableDataMetaSchema:()=>No,tableDataQuerySchema:()=>xn,tableDataResultSchema:()=>mc,tableInfoSchema:()=>dc,tableNameSchema:()=>be,tableSchemaResultSchema:()=>pc,unwrapClickhouseType:()=>yt,updateRecordsSchema:()=>vn});var ne=S(()=>{"use strict";h();za();Ga();mn();Xa();Za();eo();to();ro();oo();yn();co();_e();uo();po();fo();er();yo();ho();go();Eo();Co();Ro();So();Ao();Do();_o();$o();Po()});function Re(n=process.env.DATABASE_URL){if(!n)return{host:"localhost",port:5432};try{let e=new URL(n);return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||Tc(e)}}catch(e){return console.error("Failed to parse DATABASE_URL:",e),{host:"localhost",port:5432}}}var pr,Tc,ko,Fe=S(()=>{"use strict";h();ne();pr={cockroachdb:{driverScheme:"postgresql",defaultPort:26257},mariadb:{driverScheme:"mysql",defaultPort:3306},tidb:{driverScheme:"mysql",defaultPort:4e3}},Tc=n=>{let e=n.protocol.replace(":",""),t=ht(e);return pr[e]?.defaultPort??(t&&Z[t].defaultPort)??5432},ko=n=>{let e=new URL(n),t=pr[e.protocol.replace(":","")];return t?(e.port||=String(t.defaultPort),e.protocol=t.driverScheme,e.toString()):n}});var ot,qn=S(()=>{ot={name:"db-studio",type:"module",version:"1.16.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"},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","@hono/node-server":"^2.0.0","@hono/zod-validator":"^0.9.0","@libsql/client":"^0.18.0","@sentry/node":"^10.73.0",commander:"^15.0.0",dotenv:"^18.0.0",hono:"^4.10.4",ioredis:"^6.0.0",mongodb:"^7.1.1",mssql:"^12.2.0",mysql2:"^3.18.2",open:"^11.0.0",oracledb:"^7.0.1",pg:"^8.13.1",picocolors:"^1.1.1","posthog-node":"^5.20.0",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@db-studio/shared":"workspace:*","@sentry/esbuild-plugin":"^5.4.0","@types/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",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^7.0.2",vitest:"^5.0.0"}}});var Vo={};Xt(Vo,{captureInstallationActive:()=>jn,captureServerError:()=>Hn,captureServerEvent:()=>gr,databaseTypeForRequest:()=>Kn,durationBucket:()=>Bn,getTelemetryConfig:()=>hr,initServerObservability:()=>Wo,isTelemetryEnabled:()=>Ct,operationForRequest:()=>xt,outcomeForStatus:()=>Fn,resetTelemetryId:()=>Un,setTelemetryEnabled:()=>br,startServerSpan:()=>Wn,writeOperationalLog:()=>Vn});import{randomUUID as Fo}from"crypto";import{existsSync as Ac,mkdirSync as Nc,readFileSync as Dc,writeFileSync as _c}from"fs";import{homedir as Bo,platform as Oc}from"os";import fr from"path";import*as Le from"@sentry/node";import{HTTPException as Ko}from"hono/http-exception";import{PostHog as $c}from"posthog-node";var Pc,jo,yr,Lc,Ic,Ze,Et,Mc,kc,wt,Ct,hr,br,Un,Bn,Fn,Ho,xt,Kn,Wo,gr,jn,xc,vc,qc,Hn,Wn,Vn,vt=S(()=>{"use strict";h();ne();qn();Pc=()=>process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development",jo=()=>{let n=process.env.DB_STUDIO_DATA_DIR??process.env.XDG_STATE_HOME??(process.platform==="win32"?process.env.LOCALAPPDATA:fr.join(Bo(),".local","state"));return fr.join(n||fr.join(Bo(),".db-studio"),"db-studio","telemetry.json")},yr=n=>{try{let e=jo();Nc(fr.dirname(e),{recursive:!0}),_c(e,JSON.stringify(n),{encoding:"utf8",mode:384})}catch{}},Lc=()=>({installationId:Fo(),enabled:!0}),Ic=()=>{let n=jo();try{if(Ac(n)){let t=JSON.parse(Dc(n,"utf8"));if(typeof t.installationId=="string"&&typeof t.enabled=="boolean")return{installationId:t.installationId,enabled:t.enabled,lastActiveAt:typeof t.lastActiveAt=="string"?t.lastActiveAt:void 0}}}catch{}let e=Lc();return yr(e),e},Mc="https://a1e890d1105f1f27fcb1dbead71c30dd@o4509725125181440.ingest.de.sentry.io/4512040493383760",kc="phc_nxaQk54MWAehmL72J4gjVbrQCpbSTedMyHn3PvFxAhkd",wt=()=>Ze??=Ic(),Ct=()=>!Pc()&&process.env.DB_STUDIO_TELEMETRY!=="0"&&wt().enabled,hr=()=>({enabled:Ct(),installationId:wt().installationId,appVersion:ot.version}),br=n=>{Ze={...wt(),enabled:n},yr(Ze),n?(Et?.enable(),Wo()):(Et?.disable(),Le.close(500))},Un=()=>(Ze={...wt(),installationId:Fo(),lastActiveAt:void 0},yr(Ze),Ze.installationId),Bn=n=>n<100?"under_100ms":n<1e3?"100ms_1s":n<5e3?"1s_5s":"over_5s",Fn=n=>n>=500?"server_error":n>=400?"client_error":"success",Ho=new RegExp(`^/api/(${dt.join("|")})(?=/|$)`),xt=(n,e)=>{let t=e.replace(Ho,"/api"),a=[[/^\/api\/databases(?:\/|$)/,"databases"],[/^\/api\/tables(?:\/|$)/,"tables"],[/^\/api\/records(?:\/|$)/,"records"],[/^\/api\/query(?:\/|$)/,"query"],[/^\/api\/keys(?:\/|$)/,"keys"],[/^\/api\/chat(?:\/|$)/,"chat"]].find(([o])=>o.test(t))?.[1]??"other";return`${n.toLowerCase()}_${a}`},Kn=n=>n.match(Ho)?.[1],Wo=()=>{if(!Ct())return;let n=process.env.DB_STUDIO_SENTRY_DSN??Mc;n&&(!Le.isInitialized()||Le.getClient()?.getOptions().enabled===!1)&&Le.init({dsn:n,environment:process.env.NODE_ENV??"production",release:`db-studio@${ot.version}`,tracesSampleRate:.1,sendDefaultPii:!1,defaultIntegrations:!1,beforeSend(t){return delete t.request,delete t.user,delete t.breadcrumbs,t},beforeSendSpan(t){return{...t,data:Object.fromEntries(Object.entries(t.data??{}).filter(([r])=>r.startsWith("db_studio.")))}}});let e=process.env.DB_STUDIO_POSTHOG_KEY??kc;e&&!Et&&(Et=new $c(e,{host:process.env.DB_STUDIO_POSTHOG_HOST??"https://eu.i.posthog.com",flushAt:20,flushInterval:1e4,requestTimeout:2e3}))},gr=n=>{!Ct()||!Et||Et.capture({distinctId:wt().installationId,event:n.event,properties:{...n.properties,source:"server",app_version:ot.version,$geoip_disable:!1}})},jn=()=>{if(!Ct())return;let n=wt(),e=n.lastActiveAt?Date.parse(n.lastActiveAt):0;Date.now()-e<864e5||(Ze={...n,lastActiveAt:new Date().toISOString()},yr(Ze),gr({event:"installation_active",properties:{runtime:`node-${process.versions.node.split(".")[0]}`,os:Oc()}}))},xc=n=>{let e=n instanceof Ko?"HTTPException":n instanceof Error?n.name:"Error";return/^[A-Za-z][A-Za-z0-9]{0,49}$/.test(e)?e:"Error"},vc=n=>{if(!(n instanceof Error))return;let{code:e,errno:t}=n;if(typeof e=="string"&&/^[A-Z0-9_]{2,32}$/.test(e))return e;if(typeof t=="number"&&Number.isSafeInteger(t))return String(t)},qc=(n,e)=>{let t=new Error("Server operation failed");if(t.name=e,n instanceof Error&&n.stack){let r=n.stack.split(`
3
- `).slice(1).filter(a=>/^\s*at\s/.test(a));t.stack=[`${e}: Server operation failed`,...r].join(`
4
- `)}return t},Hn=(n,{operation:e,status:t,dbType:r})=>{if(!Ct()||t<500)return;let a=n instanceof Ko&&n.cause?n.cause:n,o=xc(a),s=vc(a);Le.captureException(qc(a,o),{tags:{operation:e,source:"server",release:ot.version,status:String(t),...r?{db_type:r}:{},error_type:o,...s?{error_code:s}:{}},fingerprint:[e,String(t),o,s??"unknown"]})},Wn=(n,e,t)=>Le.startSpan({name:n,op:"http.server",attributes:{"db_studio.operation":n,...e?{"db_studio.db_type":e}:{}}},t),Vn=(n,e,t)=>{let r=Object.fromEntries(Object.entries(t).filter(([,a])=>a!==void 0));process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:n,event:e,...r})}
5
- `)}});import{resolve as Uc}from"path";import{pathToFileURL as Bc}from"url";import{ClickHouseLogLevel as Fc,createClient as Kc}from"@clickhouse/client";import{DuckDBInstance as jc}from"@duckdb/node-api";import{createClient as Hc}from"@libsql/client";import{Redis as Wc}from"ioredis";import{MongoClient as Vc,ObjectId as Yn}from"mongodb";import Yc from"mssql";import{createPool as zc}from"mysql2/promise";import Gc from"oracledb";import{Pool as Yo}from"pg";var zn,Se,Tr,Er,wr,Cr,et,Rr,Sr,Ar,Nr,Dr,zo,_r,Go,Qo,Or,$r,st=S(()=>{"use strict";h();ne();Fe();zn=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)),console.error(`\u274C Database configuration error: ${this.initError.message}`)}}detectDbType(e){let t=e.protocol.replace(":",""),r=ht(t);if(r)return r;let a=Object.values(Z).map(({label:o,protocols:s})=>`${o} (${s.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=ht(e.split("://")[0]);if(t&&Z[t].defaultPort===null){this.baseConfig={url:e,host:"localhost",port:0,user:"",password:"",dbType:t};return}try{let r=ko(e),a=new URL(r),o=this.detectDbType(a);this.baseConfig={url:r,host:a.hostname,port:Number.parseInt(a.port,10)||(Z[o].defaultPort??0),user:a.username,password:a.password,dbType:o}}catch(r){throw new Error(r instanceof Error?r.message:String(r))}}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(Z[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:// or libsql:// connection");let{url:e}=this.baseConfig;return this.sqliteClient??=this.openSqliteClient(e).catch(t=>{throw this.sqliteClient=null,t}),this.sqliteClient}async openSqliteClient(e){let t=e.startsWith("sqlite://")?e.slice(9):null,r=t===null?e:t===":memory:"?t:Bc(Uc(t)).href,a=Hc({url:r,intMode:"bigint"});return a.protocol==="file"&&(await a.execute("PRAGMA journal_mode = WAL"),await a.execute("PRAGMA foreign_keys = ON")),a}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 t=await jc.create(e,{checkpoint_threshold:"0b"});return{instance:t,connection:await t.connect()}}catch(t){this.duckdb=null;let r=t instanceof Error?t.message:String(t);throw r.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. (${r})`):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:r,user:a,password:o}=this.baseConfig,s=decodeURIComponent(new URL(e).pathname.slice(1));return this.oraclePool??=Gc.createPool({user:decodeURIComponent(a),password:decodeURIComponent(o),connectString:`${t}:${r}/${s}`,poolMin:0,poolMax:10,connectTimeout:5,sessionCallback:(i,l,c)=>{i.execute("ALTER SESSION SET TIME_ZONE = '+00:00'").then(()=>i.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(()=>c(),c)}}).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)}getPgPool(e){let t=this.buildConnectionString(e);if(!this.pgPools.has(t)){let r={connectionString:t,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:2e3},a=new Yo(r);a.on("connect",o=>{o.query(`SELECT set_config(
2
+ var sl=Object.defineProperty;var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var nr=(n,e)=>{for(var t in e)sl(n,t,{get:e[t],enumerable:!0})};var h=S(()=>{"use strict";(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};n.SENTRY_RELEASE={id:"db-studio@1.16.1"}}catch{}})()});var va=S(()=>{"use strict";h()});var qa=S(()=>{"use strict";h()});var Ua=S(()=>{"use strict";h()});var Fa,Ba,Xe,Ka=S(()=>{"use strict";h();Fa=globalThis.process?.env,Ba=Fa?.NODE_ENV,Xe={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"https://api.db-studio.localhost",API_PREFIX:"/api",IS_DEV:Ba==="development",PROXY_URL:Fa?.DB_STUDIO_PROXY_URL??(Ba==="development"?"https://proxy.db-studio.localhost":"https://db-studio-proxy.husamql3.workers.dev")}});var ja=S(()=>{"use strict";h()});var Ha,ln=S(()=>{"use strict";h();Ha={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 Wa=S(()=>{"use strict";h()});var kt=S(()=>{"use strict";h();va();qa();Ua();Ka();ja();ln();Wa()});import{z as yt}from"zod";var x,ht,xt,gl,Tl,Te,$e=S(()=>{"use strict";h();x=yt.object({db:yt.string("Database name is required")}),ht=["pg","mysql","mssql","mongodb","sqlite","redis","duckdb","oracle","clickhouse"],xt=yt.enum(ht,{message:"Invalid database type"}),gl=x.extend({dbType:xt}),Tl=yt.object({dbType:xt}),Te=yt.object({tableName:yt.string("Table name is required")})});import{z as Ke}from"zod";var qe,El,wl,Xa=S(()=>{"use strict";h();$e();qe=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)}),El=Te,wl=Ke.object({db:x.shape.db,tableName:Te.shape.tableName,columnName:qe.shape.columnName,columnType:qe.shape.columnType,defaultValue:qe.shape.defaultValue,isPrimaryKey:qe.shape.isPrimaryKey,isNullable:qe.shape.isNullable,isUnique:qe.shape.isUnique,isIdentity:qe.shape.isIdentity,isArray:qe.shape.isArray})});import{z as vt}from"zod";var pn,Za=S(()=>{"use strict";h();pn=vt.object({tableName:vt.string("Table name is required"),data:vt.record(vt.string("Column name is required"),vt.any())})});import{z as Cl}from"zod";var eo,fn,to,yn,hn=S(()=>{"use strict";h();eo=["gemini","openai","anthropic","grok","openrouter"],fn=Cl.enum(eo),to=[{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"}]}],yn=n=>to.find(e=>e.id===n)?.models[0]?.id??"gemini-3-flash-preview"});import{z as Ue}from"zod";var bn,Ee,Rl,Sl,or=S(()=>{"use strict";h();$e();bn=x.extend({cascade:Ue.string().optional().transform(n=>n==="true")}),Ee=Ue.object({tableName:Ue.string("Table name is required"),columnName:Ue.string("Column name is required")}),Rl=Ue.object({db:x.shape.db,tableName:Ee.shape.tableName,columnName:Ee.shape.columnName,cascade:Ue.boolean().optional()}),Sl=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 qt}from"zod";var bt,Al,Nl,ro=S(()=>{"use strict";h();$e();or();bt=qt.object({columnType:qt.string("Column type is required"),isNullable:qt.boolean(),defaultValue:qt.string().nullable().optional()}),Al=Ee,Nl=qt.object({db:x.shape.db,tableName:Ee.shape.tableName,columnName:Ee.shape.columnName,columnType:bt.shape.columnType,isNullable:bt.shape.isNullable,defaultValue:bt.shape.defaultValue})});var no=S(()=>{"use strict";h()});import{z as gt}from"zod";var gn,ao=S(()=>{"use strict";h();gn=gt.object({tableName:gt.string().min(1,"Table name is required"),records:gt.array(gt.record(gt.string(),gt.any())).min(1,"At least one record is required")})});import{z as fe}from"zod";var Dl,_l,Tn,oo=S(()=>{"use strict";h();hn();$e();Dl=fe.object({type:fe.string(),content:fe.string().optional()}).passthrough(),_l=fe.object({provider:fn.optional().default("gemini"),model:fe.string().min(1).optional(),messages:fe.array(fe.object({id:fe.string(),role:fe.enum(["user","assistant","system","tool","reasoning"]),content:fe.union([fe.string(),fe.null(),fe.array(fe.unknown())]).optional(),parts:fe.array(Dl).optional()}).passthrough()),data:fe.object({conversationId:fe.string().optional(),db:x.shape.db,includeSchema:fe.boolean().optional().default(!0)})}),Tn=_l.transform(n=>({...n,model:n.model??yn(n.provider)}))});var so=S(()=>{"use strict";h()});import{z as Ie}from"zod";var Ol,io,M,$l,lo,Pl,En=S(()=>{"use strict";h();Ol=["text","boolean","number","enum","json","date","array"],io=Ie.enum(Ol),M={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},$l=["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"],lo=Ie.enum($l),Pl=Ie.object({columnName:Ie.string(),dataType:io,dataTypeLabel:lo,isNullable:Ie.boolean(),columnDefault:Ie.string().nullable(),isPrimaryKey:Ie.boolean(),isForeignKey:Ie.boolean(),referencedTable:Ie.string().nullable(),referencedColumn:Ie.string().nullable(),enumValues:Ie.array(Ie.string()).nullable()})});function sr(n){let e=n?.toLowerCase().trim()||"";return e.includes("[]")||e==="date"||e==="time"||e==="time without time zone"||e.startsWith("time(")||e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")||e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?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 wn(n){if(!n)return b.text;let e=n.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 ir(n,e){let t=n?.toLowerCase().trim()||"",r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="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 Cn(n,e){if(!n)return b.text;let t=n.toLowerCase().trim(),r=e?.toLowerCase().trim()||"";return t==="tinyint"&&r==="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 lr(n){let e=n?.toLowerCase().trim()||"";return e==="tinyint"||e==="smallint"||e==="int"||e==="bigint"||e==="decimal"||e==="numeric"||e==="float"||e==="real"||e==="money"||e==="smallmoney"?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 Rn(n){if(!n)return b.text;let e=n.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 cr(n){let e=n?.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 Sn(n){let e=n?.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 ur(n){let e=n?.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 An(n){let e=n?.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 mr(n){let e=n?.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 Nn(n){let e=n?.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 r=Number(t[1]);if(r<=4)return b.smallint;if(r<=10)return b.int;if(r<=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 Tt(n){let e=n.trim();for(;;){let t=e.match(/^(?:Nullable|LowCardinality)\((.*)\)$/);if(!t?.[1])return e;e=t[1].trim()}}function dr(n){let e=Tt(n);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 Dn(n){let e=Tt(n);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,co=S(()=>{"use strict";h();En();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 ye}from"zod";var uo,_n,mo,po,On,fo=S(()=>{"use strict";h();uo=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],_n=ye.enum(uo),mo=ye.object({columnName:ye.string("Column name is required"),columnType:ye.string("Column type is required"),defaultValue:ye.string().optional(),isPrimaryKey:ye.boolean().default(!1),isNullable:ye.boolean().default(!1),isUnique:ye.boolean().default(!1),isIdentity:ye.boolean().default(!1),isArray:ye.boolean().default(!1)}),po=ye.object({columnName:ye.string("Column name is required"),referencedTable:ye.string("Referenced table is required"),referencedColumn:ye.string("Referenced column is required"),onUpdate:_n.default("NO ACTION"),onDelete:_n.default("NO ACTION")}),On=ye.object({tableName:ye.string("Table name is required"),fields:ye.array(mo).min(1,"At least one field is required"),foreignKeys:ye.array(po).optional()})});var ee,Et,yo=S(()=>{"use strict";h();$e();ee={pg:{label:"PostgreSQL",protocols:["postgres","postgresql","cockroachdb"],defaultPort:5432,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!0,rowMutation:!0},mysql:{label:"MySQL",protocols:["mysql","mysql2","mariadb","tidb"],defaultPort:3306,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},mssql:{label:"SQL Server",protocols:["mssql","sqlserver"],defaultPort:1433,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},mongodb:{label:"MongoDB",protocols:["mongodb","mongodb+srv"],defaultPort:27017,dataModel:"document",editorLanguage:"json",liveMode:!1,schemaSelector:!1,rowMutation:!0},sqlite:{label:"SQLite / libSQL",protocols:["sqlite","libsql"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},redis:{label:"Redis",protocols:["redis","rediss"],defaultPort:6379,dataModel:"key-value",editorLanguage:"plaintext",liveMode:!1,schemaSelector:!1,rowMutation:!0},duckdb:{label:"DuckDB",protocols:["duckdb"],defaultPort:null,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},oracle:{label:"Oracle",protocols:["oracle"],defaultPort:1521,dataModel:"relational",editorLanguage:"pgsql",liveMode:!0,schemaSelector:!1,rowMutation:!0},clickhouse:{label:"ClickHouse",protocols:["clickhouse","clickhouses"],defaultPort:8123,dataModel:"relational",editorLanguage:"pgsql",liveMode:!1,schemaSelector:!1,rowMutation:!1,rowMutationReason:"Use a SQL query to update or delete ClickHouse rows; sorting keys are not unique."}},Et=n=>ht.find(e=>ee[e].protocols.includes(n))});import{z as we}from"zod";var ho,Il,Ll,bo=S(()=>{"use strict";h();$e();ho=we.object({name:we.string("Name is required"),size:we.string("Size is required"),owner:we.string("Owner is required"),encoding:we.string("Encoding is required")}),Il=we.object({databases:we.array(ho),dbType:xt}),Ll=we.object({version:we.string("Version is required"),database:we.string("Database is required"),user:we.string("User is required"),host:we.string("Host is required").nullable(),port:we.number("Port is required").nullable(),active_connections:we.coerce.number("Active connections is required"),max_connections:we.coerce.number("Max connections is required")})});var go=S(()=>{"use strict";h()});import{z as wt}from"zod";var pr,To=S(()=>{"use strict";h();pr=wt.object({tableName:wt.string("Table name is required"),primaryKeys:wt.array(wt.object({columnName:wt.string("Column name is required"),value:wt.any()})).min(1,"At least one primary key is required")})});import{z as Ml}from"zod";var $n,Eo=S(()=>{"use strict";h();$e();$n=x.extend({cascade:Ml.string().optional().transform(n=>n==="true")})});import{z as wo}from"zod";var Pn,Co=S(()=>{"use strict";h();Pn=wo.object({query:wo.string("Query is required")})});import{z as kl}from"zod";var Ro,In,So=S(()=>{"use strict";h();$e();Ro=["csv","xlsx","json"],In=x.extend({format:kl.enum(Ro,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});import{z as T}from"zod";var fr,B,Ln,Mn,xl,kn,Ct,vl,ql,Ul,Bl,Fl,Kl,jl,Ao,Hl,xn,Wl,Vl,Yl,zl,Gl,Ql,Jl,vn,Xl,Zl,ec,tc,rc,nc,ac,oc,sc,ic,lc,cc,uc,mc,dc,qn,Un,pc,No=S(()=>{"use strict";h();fr=T.enum(["string","hash","list","set","zset","stream","unknown"]),B=T.object({base64:T.string().max(16*1024*1024).refine(n=>/^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/.test(n),"Invalid unpadded base64url value"),utf8:T.string().optional()}),Ln=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:fr.exclude(["unknown"]).optional()}),Mn=T.object({key:B,type:fr,ttlMs:T.number().int(),memoryBytes:T.number().int().nonnegative().nullable()}),xl=T.object({keys:T.array(Mn),nextCursor:T.string().nullable(),hasMore:T.boolean()}),kn=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")}),Ct=T.object({key:T.string().min(1).max(16*1024).regex(/^[A-Za-z0-9_-]+$/)}),vl=T.object({kind:T.literal("string"),value:B,truncated:T.boolean()}),ql=T.object({kind:T.literal("hash"),entries:T.array(T.object({field:B,value:B}))}),Ul=T.object({kind:T.literal("list"),entries:T.array(T.object({index:T.number().int(),value:B}))}),Bl=T.object({kind:T.literal("set"),members:T.array(B)}),Fl=T.object({kind:T.literal("zset"),entries:T.array(T.object({member:B,score:T.union([T.number(),T.literal("inf"),T.literal("-inf")])}))}),Kl=T.object({kind:T.literal("stream"),entries:T.array(T.object({id:T.string(),fields:T.array(T.object({field:B,value:B}))}))}),jl=T.object({kind:T.literal("unknown")}),Ao=T.discriminatedUnion("kind",[vl,ql,Ul,Bl,Fl,Kl,jl]),Hl=Mn.extend({length:T.number().int().nonnegative().nullable(),revision:T.string(),value:Ao,nextCursor:T.string().nullable(),hasMore:T.boolean()}),xn=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()}),Wl=T.object({chunk:B,length:T.number().int().nonnegative(),nextOffset:T.number().int().nonnegative().nullable(),hasMore:T.boolean()}),Vl=T.object({kind:T.literal("string"),value:B}),Yl=T.object({kind:T.literal("hash"),entries:T.array(T.object({field:B,value:B})).min(1)}),zl=T.object({kind:T.literal("list"),entries:T.array(B).min(1)}),Gl=T.object({kind:T.literal("set"),members:T.array(B).min(1)}),Ql=T.object({kind:T.literal("zset"),entries:T.array(T.object({member:B,score:T.number()})).min(1)}),Jl=T.object({kind:T.literal("stream"),id:T.string().default("*"),fields:T.array(T.object({field:B,value:B})).min(1)}),vn=T.object({key:B,type:fr.exclude(["unknown"]),value:T.discriminatedUnion("kind",[Vl,Yl,zl,Gl,Ql,Jl]),ttlMs:T.number().int().positive().nullable().default(null)}),Xl=T.object({key:B,revision:T.string().nullable(),deleted:T.boolean()}),Zl=T.object({action:T.literal("rename"),newKey:B}),ec=T.object({action:T.literal("setTtl"),ttlMs:T.number().int().positive().nullable()}),tc=T.object({action:T.literal("setString"),value:B}),rc=T.object({action:T.literal("upsertHash"),field:B,value:B}),nc=T.object({action:T.literal("deleteHash"),field:B}),ac=T.object({action:T.literal("pushList"),side:T.enum(["left","right"]),value:B}),oc=T.object({action:T.literal("setList"),index:T.number().int(),value:B}),sc=T.object({action:T.literal("deleteList"),index:T.number().int()}),ic=T.object({action:T.literal("addSet"),member:B}),lc=T.object({action:T.literal("removeSet"),member:B}),cc=T.object({action:T.literal("upsertZset"),member:B,score:T.number()}),uc=T.object({action:T.literal("removeZset"),member:B}),mc=T.object({action:T.literal("appendStream"),id:T.string().default("*"),fields:T.array(T.object({field:B,value:B})).min(1)}),dc=T.object({action:T.literal("deleteStream"),id:T.string()}),qn=T.object({expectedRevision:T.string(),force:T.boolean().default(!1),operation:T.discriminatedUnion("action",[Zl,ec,tc,rc,nc,ac,oc,sc,ic,lc,cc,uc,mc,dc])}),Un=T.object({db:T.string(),expectedRevision:T.string(),force:T.stringbool().default(!1)}),pc=T.object({deleted:T.boolean()})});var Do=S(()=>{"use strict";h()});import{z as Bn}from"zod";var yr,fc,yc,_o=S(()=>{"use strict";h();$e();or();yr=Bn.object({newColumnName:Bn.string("New column name is required")}),fc=Ee,yc=Bn.object({db:x.shape.db,tableName:Ee.shape.tableName,columnName:Ee.shape.columnName,newColumnName:yr.shape.newColumnName})});import{z as hr}from"zod";var Ut,hc,bc,Oo=S(()=>{"use strict";h();$e();Ut=hr.object({newTableName:hr.string("New table name is required").trim().min(1,"New table name is required"),schemaName:hr.string().trim().min(1).optional()}),hc=Te,bc=hr.object({db:x.shape.db,tableName:Te.shape.tableName,newTableName:Ut.shape.newTableName,schemaName:Ut.shape.schemaName})});import{z as G}from"zod";var gc,Bt,Tc,$o,Ec,Fn,Po=S(()=>{"use strict";h();$e();gc=G.object({columnName:G.string(),operator:G.string(),value:G.string()}),Bt=["asc","desc"],Tc=G.object({columnName:G.string(),direction:G.enum(Bt)}),$o=G.object({limit:G.number(),total:G.number(),hasNextPage:G.boolean(),hasPreviousPage:G.boolean(),nextCursor:G.string().nullable(),prevCursor:G.string().nullable()}),Ec=G.object({data:G.array(G.record(G.string(),G.unknown())),meta:$o}),Fn=G.object({db:x.shape.db,cursor:G.string().optional(),limit:G.string().optional().default("50").transform(Number),direction:G.enum(Bt).optional().default(Bt[0]),sort:G.string().optional().transform(n=>{if(!n)return"";try{let e=JSON.parse(n);return Array.isArray(e)?e:n}catch{return n}}),order:G.enum(Bt).optional(),filters:G.string().optional().transform(n=>{if(!n)return[];try{return JSON.parse(n)}catch{return[]}})})});import{z as br}from"zod";var wc,Io=S(()=>{"use strict";h();wc=br.object({tableName:br.string("Table name is required"),schemaName:br.string().optional(),rowCount:br.coerce.number("Row count is required")})});import{z as Lo}from"zod";var Cc,Mo=S(()=>{"use strict";h();Cc=Lo.object({schema:Lo.string()})});import{z as Le}from"zod";var Kn,ko=S(()=>{"use strict";h();Kn=Le.object({tableName:Le.string("Table name is required"),primaryKey:Le.string("Primary key is required").default("id"),primaryKeys:Le.array(Le.string().min(1)).min(1).optional(),updates:Le.array(Le.object({rowData:Le.record(Le.string("Column name is required"),Le.any()),columnName:Le.string("Column name is required"),value:Le.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var xo={};nr(xo,{AI_PROVIDERS:()=>eo,AI_PROVIDER_OPTIONS:()=>to,DATABASE_ENGINES:()=>ee,DATABASE_TYPES:()=>ht,DataTypes:()=>M,FOREIGN_KEY_ACTIONS:()=>uo,FORMAT_TYPES:()=>Ro,StandardizedDataType:()=>b,addColumnParamSchema:()=>El,addColumnParamsSchema:()=>wl,addColumnSchema:()=>qe,addRecordSchema:()=>pn,aiProviderSchema:()=>fn,alterColumnParamSchema:()=>Al,alterColumnParamsSchema:()=>Nl,alterColumnSchema:()=>bt,bulkInsertRecordsSchema:()=>gn,chatSchema:()=>Tn,columnInfoSchema:()=>Pl,connectionInfoSchema:()=>Ll,createKeySchema:()=>vn,createTableSchema:()=>On,currentDatabaseSchema:()=>gl,dataTypesSchema:()=>io,databaseInfoSchema:()=>ho,databaseListSchema:()=>Il,databaseSchema:()=>x,databaseTypeParamSchema:()=>Tl,databaseTypeSchema:()=>xt,dbTypeFromProtocol:()=>Et,deleteColumnParamSchema:()=>Ee,deleteColumnParamsSchema:()=>Rl,deleteColumnQuerySchema:()=>bn,deleteColumnSuccessResponseSchema:()=>Sl,deleteKeyQuerySchema:()=>Un,deleteKeyResultSchema:()=>pc,deleteRecordSchema:()=>pr,deleteTableQuerySchema:()=>$n,encodedRedisValueSchema:()=>B,executeQuerySchema:()=>Pn,exportTableSchema:()=>In,fieldDataSchema:()=>mo,filterSchema:()=>gc,foreignKeyActionSchema:()=>_n,foreignKeyDataSchema:()=>po,getDefaultAiModel:()=>yn,keyActionSchema:()=>qn,keyDetailsQuerySchema:()=>kn,keyDetailsResultSchema:()=>Hl,keyParamSchema:()=>Ct,keyRawQuerySchema:()=>xn,keyRawResultSchema:()=>Wl,keyScanQuerySchema:()=>Ln,keyScanResultSchema:()=>xl,keyWriteResultSchema:()=>Xl,mapClickhouseToDataType:()=>dr,mapDuckdbToDataType:()=>ur,mapMssqlToDataType:()=>lr,mapMysqlToDataType:()=>ir,mapOracleToDataType:()=>mr,mapPostgresToDataType:()=>sr,mapSqliteToDataType:()=>cr,redisKeySummarySchema:()=>Mn,redisKeyTypeSchema:()=>fr,redisKeyValueSchema:()=>Ao,renameColumnParamSchema:()=>fc,renameColumnParamsSchema:()=>yc,renameColumnSchema:()=>yr,renameTableParamSchema:()=>hc,renameTableParamsSchema:()=>bc,renameTableSchema:()=>Ut,sortDirections:()=>Bt,sortSchema:()=>Tc,standardizeClickhouseDataTypeLabel:()=>Dn,standardizeDataTypeLabel:()=>wn,standardizeDuckdbDataTypeLabel:()=>An,standardizeMssqlDataTypeLabel:()=>Rn,standardizeMysqlDataTypeLabel:()=>Cn,standardizeOracleDataTypeLabel:()=>Nn,standardizeSqliteDataTypeLabel:()=>Sn,standardizedDataTypeSchema:()=>lo,tableDataMetaSchema:()=>$o,tableDataQuerySchema:()=>Fn,tableDataResultSchema:()=>Ec,tableInfoSchema:()=>wc,tableNameSchema:()=>Te,tableSchemaResultSchema:()=>Cc,unwrapClickhouseType:()=>Tt,updateRecordsSchema:()=>Kn});var ae=S(()=>{"use strict";h();Xa();Za();hn();ro();no();ao();oo();so();co();En();fo();$e();yo();bo();go();or();To();Eo();Co();So();No();Do();_o();Oo();Po();Io();Mo();ko()});import{AsyncLocalStorage as _c}from"async_hooks";import{randomUUID as Uo}from"crypto";import{HTTPException as Bo}from"hono/http-exception";var Oc,$c,jn,Fo,Ko,lt,Pc,Ic,Lc,jo,Hn,le,Q,Ze=S(()=>{"use strict";h();Oc=Uo(),$c=/^[A-Za-z0-9_-]{8,64}$/,jn=new _c,Fo=n=>n&&$c.test(n)?n:Uo(),Ko=(n,e)=>jn.run(n,e),lt=()=>jn.getStore()?.requestId,Pc=n=>{let e=n instanceof Bo?"HTTPException":n instanceof Error?n.name:"Error";return/^[A-Za-z][A-Za-z0-9]{0,49}$/.test(e)?e:"Error"},Ic=/^[A-Z0-9_-]{2,32}$/,Lc=[[/^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"]],jo=n=>{if(!(n instanceof Error))return;let{code:e,errno:t,number:r,cause:a}=n;return typeof r=="number"&&Number.isSafeInteger(r)?String(r):typeof e=="string"&&Ic.test(e)?e:typeof e=="number"&&Number.isSafeInteger(e)?String(e):typeof t=="number"&&Number.isSafeInteger(t)?String(t):n.name==="ReplyError"?n.message.match(/^[A-Z]{3,32}(?= |$)/)?.[0]:Lc.find(([o])=>o.test(n.message))?.[1]??jo(a)},Hn=n=>n instanceof Bo&&n.cause?n.cause:n,le=n=>{let e=Hn(n);return{error_type:Pc(e),error_code:jo(e)}},Q=(n,e,t={})=>{let r=jn.getStore();process.stderr.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:n,event:e,instance_id:Oc,request_id:r?.requestId,operation:r?.operation,db_type:r?.dbType,...t})}
3
+ `)}});function Ae(n=process.env.DATABASE_URL){if(!n)return{host:"localhost",port:5432};try{let e=new URL(n);return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||Mc(e)}}catch(e){return Q("error","database_url_unparseable",le(e)),{host:"localhost",port:5432}}}var gr,Mc,Ho,je=S(()=>{"use strict";h();ae();Ze();gr={cockroachdb:{driverScheme:"postgresql",defaultPort:26257},mariadb:{driverScheme:"mysql",defaultPort:3306},tidb:{driverScheme:"mysql",defaultPort:4e3}},Mc=n=>{let e=n.protocol.replace(":",""),t=Et(e);return gr[e]?.defaultPort??(t&&ee[t].defaultPort)??5432},Ho=n=>{let e=new URL(n),t=gr[e.protocol.replace(":","")];return t?(e.port||=String(t.defaultPort),e.protocol=t.driverScheme,e.toString()):n}});var ct,Wn=S(()=>{ct={name:"db-studio",type:"module",version:"1.16.1",description:"Modern database client for PostgreSQL with spreadsheet-like grid, AI-powered SQL assistance, ER diagrams, fast data browsing and editing. CLI tool, upcoming desktop & web versions.",keywords:["database client","database gui","database browser","sql client","sql editor","query tool","table editor","data editor","postgres","postgresql","postgresql client","postgresql gui","pgadmin alternative","mysql","mysql client","ai sql","er diagram","database management","database studio"],author:"H\xFCsam \u{1F951} <husam@ql3.dev>",homepage:"https://dbstudio.sh",repository:{type:"git",url:"git+https://github.com/husamql3/db-studio.git"},bugs:{url:"https://github.com/husamql3/db-studio/issues"},license:"Apache-2.0",bin:{"db-studio":"./dist/index.js"},files:["dist"],scripts:{dev:"portless run","dev:app":"NODE_ENV=development tsx watch src/index.ts",build:"tsup --minify",prepack:"cd ../web && bun run build && cd ../server && bun run build",start:`sh -c 'APP_PORT=\${PORT:-3333}; portless proxy start >/dev/null && portless alias db-studio "$APP_PORT" --force >/dev/null && HOST=127.0.0.1 PORT="$APP_PORT" DB_STUDIO_SERVER_URL=https://db-studio.localhost node dist/index.js'`,format:"biome check --write --unsafe",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage",e2e:"tsx e2e/contract.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","@hono/node-server":"^2.0.0","@hono/zod-validator":"^0.9.0","@libsql/client":"^0.18.0","@sentry/node":"^10.73.0",commander:"^15.0.0",dotenv:"^18.0.0",hono:"^4.10.4",ioredis:"^6.0.0",mongodb:"^7.1.1",mssql:"^12.2.0",mysql2:"^3.18.2",open:"^11.0.0",oracledb:"^7.0.1",pg:"^8.13.1",picocolors:"^1.1.1","posthog-node":"^5.20.0",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@db-studio/shared":"workspace:*","@sentry/esbuild-plugin":"^5.4.0","@types/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",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^7.0.2",vitest:"^5.0.0"}}});var es={};nr(es,{captureInstallationActive:()=>Gn,captureServerError:()=>Qn,captureServerEvent:()=>Rr,databaseTypeForRequest:()=>Ft,durationBucket:()=>Yn,getTelemetryConfig:()=>wr,initServerObservability:()=>Zo,isTelemetryEnabled:()=>Nt,operationForRequest:()=>Dt,outcomeForStatus:()=>zn,resetTelemetryId:()=>Vn,setTelemetryEnabled:()=>Cr,startServerSpan:()=>Jn});import{randomUUID as Qo}from"crypto";import{existsSync as Bc,mkdirSync as Fc,readFileSync as Kc,writeFileSync as jc}from"fs";import{homedir as Go,platform as Hc}from"os";import Tr from"path";import*as Me from"@sentry/node";import{PostHog as Wc}from"posthog-node";var Vc,Jo,Er,Yc,zc,rt,St,Gc,Qc,At,Nt,wr,Cr,Vn,Yn,zn,Xo,Dt,Ft,Zo,Rr,Gn,Jc,Qn,Jn,Kt=S(()=>{"use strict";h();ae();Ze();Wn();Vc=()=>process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development",Jo=()=>{let n=process.env.DB_STUDIO_DATA_DIR??process.env.XDG_STATE_HOME??(process.platform==="win32"?process.env.LOCALAPPDATA:Tr.join(Go(),".local","state"));return Tr.join(n||Tr.join(Go(),".db-studio"),"db-studio","telemetry.json")},Er=n=>{try{let e=Jo();Fc(Tr.dirname(e),{recursive:!0}),jc(e,JSON.stringify(n),{encoding:"utf8",mode:384})}catch{}},Yc=()=>({installationId:Qo(),enabled:!0}),zc=()=>{let n=Jo();try{if(Bc(n)){let t=JSON.parse(Kc(n,"utf8"));if(typeof t.installationId=="string"&&typeof t.enabled=="boolean")return{installationId:t.installationId,enabled:t.enabled,lastActiveAt:typeof t.lastActiveAt=="string"?t.lastActiveAt:void 0}}}catch{}let e=Yc();return Er(e),e},Gc="https://a1e890d1105f1f27fcb1dbead71c30dd@o4509725125181440.ingest.de.sentry.io/4512040493383760",Qc="phc_nxaQk54MWAehmL72J4gjVbrQCpbSTedMyHn3PvFxAhkd",At=()=>rt??=zc(),Nt=()=>!Vc()&&process.env.DB_STUDIO_TELEMETRY!=="0"&&At().enabled,wr=()=>({enabled:Nt(),installationId:At().installationId,appVersion:ct.version}),Cr=n=>{rt={...At(),enabled:n},Er(rt),n?(St?.enable(),Zo()):(St?.disable(),Me.close(500))},Vn=()=>(rt={...At(),installationId:Qo(),lastActiveAt:void 0},Er(rt),rt.installationId),Yn=n=>n<100?"under_100ms":n<1e3?"100ms_1s":n<5e3?"1s_5s":"over_5s",zn=n=>n>=500?"server_error":n>=400?"client_error":"success",Xo=new RegExp(`^/api/(${ht.join("|")})(?=/|$)`),Dt=(n,e)=>{let t=e.replace(Xo,"/api"),a=[[/^\/api\/databases(?:\/|$)/,"databases"],[/^\/api\/tables(?:\/|$)/,"tables"],[/^\/api\/records(?:\/|$)/,"records"],[/^\/api\/query(?:\/|$)/,"query"],[/^\/api\/keys(?:\/|$)/,"keys"],[/^\/api\/chat(?:\/|$)/,"chat"]].find(([o])=>o.test(t))?.[1]??"other";return`${n.toLowerCase()}_${a}`},Ft=n=>n.match(Xo)?.[1],Zo=()=>{if(!Nt())return;let n=process.env.DB_STUDIO_SENTRY_DSN??Gc;n&&(!Me.isInitialized()||Me.getClient()?.getOptions().enabled===!1)&&Me.init({dsn:n,environment:process.env.NODE_ENV??"production",release:`db-studio@${ct.version}`,tracesSampleRate:.1,sendDefaultPii:!1,defaultIntegrations:!1,beforeSend(t){return delete t.request,delete t.user,delete t.breadcrumbs,delete t.server_name,t},beforeSendSpan(t){return{...t,data:Object.fromEntries(Object.entries(t.data??{}).filter(([r])=>r.startsWith("db_studio.")))}}});let e=process.env.DB_STUDIO_POSTHOG_KEY??Qc;e&&!St&&(St=new Wc(e,{host:process.env.DB_STUDIO_POSTHOG_HOST??"https://eu.i.posthog.com",flushAt:20,flushInterval:1e4,requestTimeout:2e3}))},Rr=n=>{!Nt()||!St||St.capture({distinctId:At().installationId,event:n.event,properties:{...n.properties,source:"server",app_version:ct.version,$geoip_disable:!1}})},Gn=()=>{if(!Nt())return;let n=At(),e=n.lastActiveAt?Date.parse(n.lastActiveAt):0;Date.now()-e<864e5||(rt={...n,lastActiveAt:new Date().toISOString()},Er(rt),Rr({event:"installation_active",properties:{runtime:`node-${process.versions.node.split(".")[0]}`,os:Hc()}}))},Jc=(n,e,t)=>{let r=new Error(t);if(r.name=e,n instanceof Error&&n.stack){let a=n.stack.split(`
4
+ `).slice(1).filter(o=>/^\s*at\s/.test(o));r.stack=[`${e}: ${t}`,...a].join(`
5
+ `)}return r},Qn=(n,{operation:e,status:t,dbType:r})=>{if(!Nt()||t<500)return;let{error_type:a,error_code:o}=le(n),s=lt(),i=`${e} failed with ${t}${o?` ${o}`:""}`;Me.captureException(Jc(Hn(n),a,i),{tags:{operation:e,source:"server",release:ct.version,status:String(t),...r?{db_type:r}:{},error_type:a,...o?{error_code:o}:{},...s?{request_id:s}:{}},fingerprint:[e,String(t),a,o??"unknown"]})},Jn=(n,e,t)=>Me.startSpan({name:n,op:"http.server",attributes:{"db_studio.operation":n,...e?{"db_studio.db_type":e}:{}}},t)});import{resolve as Xc}from"path";import{pathToFileURL as Zc}from"url";import{ClickHouseLogLevel as eu,createClient as tu}from"@clickhouse/client";import{DuckDBInstance as ru}from"@duckdb/node-api";import{createClient as nu}from"@libsql/client";import{Redis as au}from"ioredis";import{MongoClient as ou,ObjectId as Xn}from"mongodb";import su from"mssql";import{createPool as iu}from"mysql2/promise";import lu from"oracledb";import{Pool as ts}from"pg";var Zn,Ne,Sr,Ar,Nr,Dr,nt,_r,Or,$r,Pr,Ir,rs,Lr,ns,as,Mr,kr,ut=S(()=>{"use strict";h();ae();Ze();je();Zn=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(":",""),r=Et(t);if(r)return r;let a=Object.values(ee).map(({label:o,protocols:s})=>`${o} (${s.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=Et(e.split("://")[0]);if(t&&ee[t].defaultPort===null){this.baseConfig={url:e,host:"localhost",port:0,user:"",password:"",dbType:t};return}try{let r=Ho(e),a=new URL(r),o=this.detectDbType(a);this.baseConfig={url:r,host:a.hostname,port:Number.parseInt(a.port,10)||(ee[o].defaultPort??0),user:a.username,password:a.password,dbType:o}}catch(r){throw new Error(r instanceof Error?r.message:String(r))}}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(ee[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:// or libsql:// connection");let{url:e}=this.baseConfig;return this.sqliteClient??=this.openSqliteClient(e).catch(t=>{throw this.sqliteClient=null,t}),this.sqliteClient}async openSqliteClient(e){let t=e.startsWith("sqlite://")?e.slice(9):null,r=t===null?e:t===":memory:"?t:Zc(Xc(t)).href,a=nu({url:r,intMode:"bigint"});return a.protocol==="file"&&(await a.execute("PRAGMA journal_mode = WAL"),await a.execute("PRAGMA foreign_keys = ON")),a}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 t=await ru.create(e,{checkpoint_threshold:"0b"});return{instance:t,connection:await t.connect()}}catch(t){this.duckdb=null;let r=t instanceof Error?t.message:String(t);throw r.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. (${r})`):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:r,user:a,password:o}=this.baseConfig,s=decodeURIComponent(new URL(e).pathname.slice(1));return this.oraclePool??=lu.createPool({user:decodeURIComponent(a),password:decodeURIComponent(o),connectString:`${t}:${r}/${s}`,poolMin:0,poolMax:10,connectTimeout:5,sessionCallback:(i,l,c)=>{i.execute("ALTER SESSION SET TIME_ZONE = '+00:00'").then(()=>i.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(()=>c(),c)}}).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)}getPgPool(e){let t=this.buildConnectionString(e);if(!this.pgPools.has(t)){let r={connectionString:t,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:2e3},a=new ts(r);a.on("connect",o=>{o.query(`SELECT set_config(
6
6
  'search_path',
7
7
  COALESCE(
8
8
  'public, ' || string_agg(quote_ident(nspname), ', ' ORDER BY nspname),
@@ -13,7 +13,7 @@ var Ji=Object.defineProperty;var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var Xt=(n,e)=>{f
13
13
  FROM pg_namespace
14
14
  WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'public', 'crdb_internal', 'pg_extension')
15
15
  AND nspname NOT LIKE 'pg_toast%'
16
- AND nspname NOT LIKE 'pg_temp%';`).catch(s=>{console.error(`Failed to widen search_path for "${t}":`,s.message)})}),a.on("error",o=>{console.error(`Unexpected error on PostgreSQL pool for "${t}":`,o.message)}),this.pgPools.set(t,a)}return this.pgPools.get(t)??new Yo({connectionString:t})}getMysqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mysqlPools.has(t)){let a=new URL(t).pathname.slice(1),o=zc({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(t,o)}return this.mysqlPools.get(t)}async getMssqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mssqlPools.has(t)){let a=new URL(t).pathname.slice(1),o={server:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},s=await new Yc.ConnectionPool(o).connect();s.on("error",i=>{console.error(`Unexpected error on SQL Server pool for "${t}":`,i.message)}),this.mssqlPools.set(t,s)}return this.mssqlPools.get(t)}getClickhouseClient(e){let t=new URL(this.buildConnectionString(e)),r=decodeURIComponent(t.pathname.slice(1))||"default",a=this.clickhouseClients.get(r);if(a)return a;let o=t.protocol==="clickhouses:",s=Kc({url:`${o?"https":"http"}://${t.hostname}:${t.port||(o?8443:8123)}`,username:decodeURIComponent(t.username)||"default",password:decodeURIComponent(t.password),database:r,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:Fc.OFF}});return this.clickhouseClients.set(r,s),s}getPool(e){return this.getPgPool(e)}async closePgPool(e){let t=this.pgPools.get(e);t&&(await t.end(),this.pgPools.delete(e),console.log(`Closed PostgreSQL connection pool for: ${e}`))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e),console.log(`Closed MySQL connection pool for: ${e}`))}async closeMssqlPool(e){let t=this.mssqlPools.get(e);t&&(await t.close(),this.mssqlPools.delete(e),console.log(`Closed SQL Server connection pool for: ${e}`))}async closePool(e){if(this.baseConfig?.dbType==="sqlite"&&e===this.baseConfig.url){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 Vc(this.baseConfig.url);try{await e.connect(),this.mongoClient=e}catch(t){try{await e.close()}catch{}throw t}}return this.mongoClient}getMongoDbName(){if(!this.baseConfig)throw new Error("Base configuration not initialized");let e=new URL(this.baseConfig.url).pathname.replace(/^\/+|\/+$/g,"");try{return decodeURIComponent(e)||"admin"}catch{return e||"admin"}}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType!=="redis")throw new Error("DATABASE_URL is not a redis:// connection");let t=e??this.getRedisDefaultDb(),r=this.redisClients.get(t);if(r)return r;let a=new URL(this.baseConfig.url),o={host:this.baseConfig.host,port:this.baseConfig.port,db:t,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};this.baseConfig.user&&(o.username=decodeURIComponent(this.baseConfig.user)),this.baseConfig.password&&(o.password=decodeURIComponent(this.baseConfig.password)),a.protocol==="rediss:"&&(o.tls={});let s=new Wc(o);try{if(await s.connect(),!this.redisClusterChecked){let i=await s.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(i))throw await s.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let l=i.match(/^redis_version:([^\r\n]+)/m)?.[1],[c=0,u=0]=l?.split(".").map(Number)??[];if(c<6||c===6&&u<2)throw await s.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${l??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(i){throw await s.quit().catch(()=>{}),i}return this.redisClients.set(t,s),s}async getIsolatedRedisClient(e){let t=(await this.getRedisClient(e)).duplicate();return await t.connect(),t}getRedisDefaultDb(){if(!this.baseConfig)return 0;try{let t=new URL(this.baseConfig.url).pathname.replace(/^\//,"");if(!t)return 0;let r=Number.parseInt(t,10);return Number.isFinite(r)?r:0}catch{return 0}}async closeAll(){let e=Array.from(this.pgPools.entries()).map(async([o,s])=>{await s.end(),console.log(`Closed PostgreSQL pool for: ${o}`)}),t=Array.from(this.mysqlPools.entries()).map(async([o,s])=>{await s.end(),console.log(`Closed MySQL pool for: ${o}`)}),r=Array.from(this.mssqlPools.entries()).map(async([o,s])=>{await s.close(),console.log(`Closed SQL Server pool for: ${o}`)});await Promise.all([...e,...t,...r]),this.pgPools.clear(),this.mysqlPools.clear(),this.mssqlPools.clear(),this.mongoClient&&(await this.mongoClient.close(),this.mongoClient=null),await this.closeSqliteClient(),await this.closeDuckdb(),await this.closeOraclePool();let a=Array.from(this.redisClients.entries()).map(async([o,s])=>{await s.quit().catch(()=>{}),console.log(`Closed Redis client for db=${o}`)});await Promise.all(a),this.redisClients.clear(),this.redisClusterChecked=!1,await Promise.all(Array.from(this.clickhouseClients.values()).map(o=>o.close())),this.clickhouseClients.clear()}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys()),...Array.from(this.mssqlPools.keys())]}},Se=new zn,Tr=n=>Se.getPgPool(n),Er=n=>Se.getMysqlPool(n),wr=async n=>Se.getMssqlPool(n),Cr=n=>Se.getClickhouseClient(n),et=()=>Se.getDbType(),Rr=()=>Se.getSqliteClient(),Sr=n=>Se.withDuckdbConnection(n),Ar=()=>Se.getOraclePool(),Nr=()=>Se.getMongoClient(),Dr=()=>Se.getMongoDbName(),zo=n=>Se.getMongoDb(n),_r=n=>Se.getRedisClient(n),Go=n=>Se.getIsolatedRedisClient(n),Qo=()=>Se.getRedisDefaultDb(),Or=n=>typeof n=="string"&&Yn.isValid(n),$r=n=>typeof n=="string"&&Yn.isValid(n)?new Yn(n):n});var Jo={};Xt(Jo,{checkDatabaseConnection:()=>Zc,getDatabaseConnectionDetails:()=>Xc});var Jc,Gn,Xc,Zc,Xo=S(()=>{"use strict";h();ne();st();Fe();Jc=2e3,Gn=async n=>{let e;try{return await Promise.race([n,new Promise((t,r)=>{e=setTimeout(()=>r(new Error("Database startup check timed out")),Jc)})])}finally{e&&clearTimeout(e)}},Xc=n=>{let e=et(),{label:t,defaultPort:r}=Z[e];if(n.startsWith("sqlite://"))return{type:e,name:t,destination:"local file"};if(r===null)return{type:e,name:t,destination:new URL(n).host};let{host:a,port:o}=Re(n);return{type:e,name:t,destination:`${a}:${o}`}},Zc=async n=>{switch(n){case"pg":await Gn(Tr().query("SELECT 1"));return;case"mysql":await Er().query("SELECT 1");return;case"mssql":await(await wr()).request().query("SELECT 1");return;case"mongodb":{await(await Nr()).db(Dr()).command({ping:1});return}case"sqlite":await Gn(Rr().then(e=>e.execute("SELECT 1")));return;case"redis":await(await _r()).ping();return;case"duckdb":await Sr(e=>e.run("SELECT 1"));return;case"oracle":{let e=await(await Ar()).getConnection();await e.execute("SELECT 1 FROM dual").finally(()=>e.close());return}case"clickhouse":await Gn(Cr().query({query:"SELECT 1"}))}}});import{HTTPException as Zo}from"hono/http-exception";function F(n){return he.get(n)}function it(n,e){if(!eu(n))throw new Zo(400,{message:`Key browsing is not supported for database type: "${e}"`});return n}var Qn,he,eu,Je=S(()=>{"use strict";h();Qn=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new Zo(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 Qn;eu=n=>"scanKeys"in n&&typeof n.scanKeys=="function"});import{HTTPException as Ke}from"hono/http-exception";import{DatabaseError as tu}from"pg";function ie(n){throw new Ke(501,{message:`${n} is not implemented for this database type`})}var oe,je=S(()=>{"use strict";h();oe=class{assertDeletableKey(e){if(e.length>1)throw new Ke(400,{message:"Deleting rows from tables with a composite primary key is not supported yet."})}wrapError(e){if(e instanceof Ke)return e;if(e instanceof Error){let t=e,r=t.code??e.cause?.code;return r==="ECONNREFUSED"||r==="ENOTFOUND"||r==="ETIMEDOUT"||r==="ER_ACCESS_DENIED_ERROR"||r==="ER_BAD_HOST_ERROR"||r==="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 tu&&e.code?.startsWith("08")?new Ke(503,{message:e.message,cause:e}):new Ke(500,{message:e.message,cause:e})}return new Ke(500,{message:"Internal server error",cause:e})}resolveKeyColumns(e){return e.primaryKeys?.length?e.primaryKeys:[e.primaryKey]}assertWholeKey(e,t){let r=e.filter(a=>!t.includes(a));if(r.length>0)throw new Ke(400,{message:`Updates must match on every primary key column; missing: ${r.join(", ")}`})}groupUpdatesByKey(e,t){let r=new Map;for(let a of e.updates){let o=t.map(l=>{let c=a.rowData[l];if(c==null)throw new Ke(400,{message:`Primary key "${l}" not found in row data.`});return c}),s=JSON.stringify(o.map(l=>String(l))),i=r.get(s)??{keyValues:o,rowUpdates:[]};i.rowUpdates.push({columnName:a.columnName,value:a.value}),r.set(s,i)}return[...r.values()]}orderTerms(e=[],t,r){let a=typeof e=="string"?e?[{columnName:e,direction:t}]:[]:e,o=a[0]?.direction??t;return[...a.map(s=>({column:s.columnName,direction:s.direction})),...r.filter(s=>!a.some(i=>i.columnName===s)).map(s=>({column:s,direction:o}))]}describeKey(e,t){return e.map((r,a)=>`${r} = ${t[a]}`).join(", ")}assertDifferentTableName(e,t){if(e===t)throw new Ke(400,{message:`New table name must be different from "${e}"`})}encodeCursor(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}decodeCursor(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}normalizeRow(e){let t={};for(let[r,a]of Object.entries(e))t[r]=a;return t}async getTableData(e){try{let{db:t,limit:r=50,direction:a="asc"}=e,o=this.buildTableDataQuery(e),s=await this.runQuery(t,o.countSql,o.countValues),i=Number(s[0]?.total??0),l=await this.runQuery(t,o.sql,o.values),c=l.length>r;c&&(l=l.slice(0,r));let u=this.normalizeRows(l);a==="desc"&&(u=u.reverse());let{nextCursor:m,prevCursor:p}=this.buildCursors(e,u,c);return{data:u,meta:{limit:r,total:i,hasNextPage:a==="asc"?c:!!e.cursor,hasPreviousPage:a==="asc"?!!e.cursor:c,nextCursor:m,prevCursor:p}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=`SELECT * FROM ${this.quoteIdentifier(e)}`,a=await this.runQuery(t,r,[]);if(!a||a.length===0)throw new Ke(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(a[0]),rows:a}}catch(r){throw this.wrapError(r)}}getDatabasesList(){return ie("getDatabasesList")}getCurrentDatabase(){return ie("getCurrentDatabase")}getDatabaseConnectionInfo(){return ie("getDatabaseConnectionInfo")}getTablesList(e){return ie("getTablesList")}createTable(e){return ie("createTable")}deleteTable(e){return ie("deleteTable")}renameTable(e){return ie("renameTable")}getTableSchema(e){return ie("getTableSchema")}getTableColumns(e){return ie("getTableColumns")}addColumn(e){return ie("addColumn")}deleteColumn(e){return ie("deleteColumn")}alterColumn(e){return ie("alterColumn")}renameColumn(e){return ie("renameColumn")}addRecord(e){return ie("addRecord")}updateRecords(e){return ie("updateRecords")}deleteRecords(e){return ie("deleteRecords")}forceDeleteRecords(e){return ie("forceDeleteRecords")}bulkInsertRecords(e){return ie("bulkInsertRecords")}executeQuery(e){return ie("executeQuery")}}});var re,J,Q,ae,Jn,Xn,Zn,Pr,fe,Ae,Lr,lt,qt,He=S(()=>{"use strict";h();st();re=n=>Tr(n),J=n=>Er(n),Q=n=>wr(n),ae=()=>Rr(),Jn=n=>Sr(n),Xn=()=>Ar(),Zn=()=>Nr(),Pr=()=>Dr(),fe=n=>zo(n),Ae=n=>_r(n),Lr=n=>Go(n),lt=()=>Qo(),qt=n=>Cr(n)});function es(n){let e=[],t=[],r=a=>(t.push(a),`{p${t.length-1}:String}`);for(let{columnName:a,operator:o,value:s}of n){let i=ea(a);switch(o){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${i} ${o} ${r(s)}`);break;case"is":e.push(s.toLowerCase()==="null"?`${i} IS NULL`:`${i} = ${r(s)}`);break;case"is not":e.push(s.toLowerCase()==="null"?`${i} IS NOT NULL`:`${i} != ${r(s)}`);break;case"like":e.push(`toString(${i}) LIKE ${r(s)}`);break;case"not like":e.push(`toString(${i}) NOT LIKE ${r(s)}`);break;case"ilike":e.push(`toString(${i}) ILIKE ${r(s)}`);break;case"not ilike":e.push(`toString(${i}) NOT ILIKE ${r(s)}`);break}}return{clause:e.length?`WHERE ${e.join(" AND ")}`:"",values:t}}function ts(n,e,t){let r=Array.isArray(n)?n:n?[{columnName:n,direction:e}]:[],a=(r[0]?.direction??e).toUpperCase(),o=[...r.map(s=>`${ea(s.columnName)} ${s.direction.toUpperCase()}`),...t.map(s=>`${s} ${a}`)];return o.length?`ORDER BY ${o.join(", ")}`:""}function ru(n,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"}[n.toLowerCase().trim()]??n.trim();return e?`Array(${a})`:a}function Ir(n,e){let t=ea(n.columnName);if(n.isIdentity||/serial/i.test(n.columnType))return`${t} UInt64 DEFAULT generateSnowflakeID()`;let r=ru(n.columnType,n.isArray??!1,e),a=n.isNullable&&!n.isPrimaryKey&&!n.isArray,o=`${t} ${a?`Nullable(${r})`:r}`,s=n.defaultValue?.trim();return s&&(o+=` DEFAULT ${nu[s.toLowerCase()]??s}`),o}var se,ea,nu,rs=S(()=>{"use strict";h();se=n=>`\`${n.replaceAll("\\","\\\\").replaceAll("`","\\`")}\``,ea=se;nu={"now()":"now()",current_timestamp:"now()","current_timestamp()":"now()",current_date:"today()","gen_random_uuid()":"generateUUIDv4()","uuid_generate_v4()":"generateUUIDv4()"}});import{HTTPException as le}from"hono/http-exception";var au,ns,ou,Mr,as=S(()=>{"use strict";h();ne();je();He();Fe();rs();au={mutations_sync:"2"},ns=n=>/^(LowCardinality\()?Nullable\(/.test(n),ou=(n,e)=>{if(n==null)return null;let t=yt(e);if(n===""&&t!=="String"&&!t.startsWith("FixedString"))return null;if(n instanceof Date)return n.toISOString();if(t==="Bool"&&typeof n=="string")return["true","t","1","yes","on"].includes(n.trim().toLowerCase());if(typeof n=="string"&&(t.startsWith("JSON")||t.startsWith("Array(")||t.startsWith("Map(")))try{return JSON.parse(n)}catch{throw new le(400,{message:`Invalid ${t} value: ${n}`})}return typeof n=="object"&&t==="String"?JSON.stringify(n):n},Mr=class extends oe{serverVersion=null;async runQuery(e,t,r){let a=Object.fromEntries(r.map((o,s)=>[`p${s}`,o]));return await this.select(e,t,a)}quoteIdentifier(e){return se(e)}mapToUniversalType(e){return ir(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,r){let{cursor:a,limit:o=50}=e,s=a?this.decodeOffsetCursor(a):0;return{nextCursor:r?this.makeCursor(s+o):null,prevCursor:s>0?this.makeCursor(Math.max(0,s-o)):null}}async getTableData(e){try{let{db:t,tableName:r,limit:a=50,cursor:o}=e,s=await this.getTable(t,r),i=s.sorting_key?[`(${s.sorting_key})`]:[];s.engine.endsWith("MergeTree")&&i.push("_part","_part_offset");let l=this.buildPageQuery(e,i),[c,u]=await Promise.all([this.runQuery(t,l.countSql,l.countValues),this.runQuery(t,l.sql,l.values)]),m=u.length>a,p=this.normalizeRows(m?u.slice(0,a):u),d=o?this.decodeOffsetCursor(o):0;return{data:p,meta:{limit:a,total:Number(c[0]?.total??0),hasNextPage:m,hasPreviousPage:d>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
16
+ AND nspname NOT LIKE 'pg_temp%';`).catch(s=>{Q("warn","db_search_path_widen_failed",{db_type:"pg",...le(s)})})}),a.on("error",o=>{Q("error","db_pool_error",{db_type:"pg",...le(o)})}),this.pgPools.set(t,a)}return this.pgPools.get(t)??new ts({connectionString:t})}getMysqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mysqlPools.has(t)){let a=new URL(t).pathname.slice(1),o=iu({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(t,o)}return this.mysqlPools.get(t)}async getMssqlPool(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");let t=this.buildConnectionString(e);if(!this.mssqlPools.has(t)){let a=new URL(t).pathname.slice(1),o={server:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:a||void 0,options:{encrypt:!1,trustServerCertificate:!0,enableArithAbort:!0,connectTimeout:2e3},pool:{max:10,min:0,idleTimeoutMillis:3e4}},s=await new su.ConnectionPool(o).connect();s.on("error",i=>{Q("error","db_pool_error",{db_type:"mssql",...le(i)})}),this.mssqlPools.set(t,s)}return this.mssqlPools.get(t)}getClickhouseClient(e){let t=new URL(this.buildConnectionString(e)),r=decodeURIComponent(t.pathname.slice(1))||"default",a=this.clickhouseClients.get(r);if(a)return a;let o=t.protocol==="clickhouses:",s=tu({url:`${o?"https":"http"}://${t.hostname}:${t.port||(o?8443:8123)}`,username:decodeURIComponent(t.username)||"default",password:decodeURIComponent(t.password),database:r,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:eu.OFF}});return this.clickhouseClients.set(r,s),s}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 e=new ou(this.baseConfig.url);try{await e.connect(),this.mongoClient=e}catch(t){try{await e.close()}catch{}throw t}}return this.mongoClient}getMongoDbName(){if(!this.baseConfig)throw new Error("Base configuration not initialized");let e=new URL(this.baseConfig.url).pathname.replace(/^\/+|\/+$/g,"");try{return decodeURIComponent(e)||"admin"}catch{return e||"admin"}}async getMongoDb(e){return(await this.getMongoClient()).db(e??this.getMongoDbName())}async getRedisClient(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(this.baseConfig.dbType!=="redis")throw new Error("DATABASE_URL is not a redis:// connection");let t=e??this.getRedisDefaultDb(),r=this.redisClients.get(t);if(r)return r;let a=new URL(this.baseConfig.url),o={host:this.baseConfig.host,port:this.baseConfig.port,db:t,lazyConnect:!0,maxRetriesPerRequest:1,enableReadyCheck:!0,connectTimeout:2e3};this.baseConfig.user&&(o.username=decodeURIComponent(this.baseConfig.user)),this.baseConfig.password&&(o.password=decodeURIComponent(this.baseConfig.password)),a.protocol==="rediss:"&&(o.tls={});let s=new au(o);try{if(await s.connect(),!this.redisClusterChecked){let i=await s.info("server");if(/^redis_mode:(cluster|sentinel)\b/m.test(i))throw await s.quit().catch(()=>{}),new Error("Redis cluster and Sentinel modes are not supported. Use a standalone redis:// connection.");let l=i.match(/^redis_version:([^\r\n]+)/m)?.[1],[c=0,u=0]=l?.split(".").map(Number)??[];if(c<6||c===6&&u<2)throw await s.quit().catch(()=>{}),new Error(`Redis 6.2 or newer is required. Connected server reports ${l??"an unknown version"}.`);this.redisClusterChecked=!0}}catch(i){throw await s.quit().catch(()=>{}),i}return this.redisClients.set(t,s),s}async getIsolatedRedisClient(e){let t=(await this.getRedisClient(e)).duplicate();return await t.connect(),t}getRedisDefaultDb(){if(!this.baseConfig)return 0;try{let t=new URL(this.baseConfig.url).pathname.replace(/^\//,"");if(!t)return 0;let r=Number.parseInt(t,10);return Number.isFinite(r)?r:0}catch{return 0}}async closeAll(){let e=Array.from(this.pgPools.values()).map(async o=>{await o.end(),Q("info","db_pool_closed",{db_type:"pg"})}),t=Array.from(this.mysqlPools.values()).map(async o=>{await o.end(),Q("info","db_pool_closed",{db_type:"mysql"})}),r=Array.from(this.mssqlPools.values()).map(async o=>{await o.close(),Q("info","db_pool_closed",{db_type:"mssql"})});await Promise.all([...e,...t,...r]),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 o=>{await o.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(o=>o.close())),this.clickhouseClients.clear()}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys()),...Array.from(this.mssqlPools.keys())]}},Ne=new Zn,Sr=n=>Ne.getPgPool(n),Ar=n=>Ne.getMysqlPool(n),Nr=async n=>Ne.getMssqlPool(n),Dr=n=>Ne.getClickhouseClient(n),nt=()=>Ne.getDbType(),_r=()=>Ne.getSqliteClient(),Or=n=>Ne.withDuckdbConnection(n),$r=()=>Ne.getOraclePool(),Pr=()=>Ne.getMongoClient(),Ir=()=>Ne.getMongoDbName(),rs=n=>Ne.getMongoDb(n),Lr=n=>Ne.getRedisClient(n),ns=n=>Ne.getIsolatedRedisClient(n),as=()=>Ne.getRedisDefaultDb(),Mr=n=>typeof n=="string"&&Xn.isValid(n),kr=n=>typeof n=="string"&&Xn.isValid(n)?new Xn(n):n});var os={};nr(os,{checkDatabaseConnection:()=>du,getDatabaseConnectionDetails:()=>mu});var uu,ea,mu,du,ss=S(()=>{"use strict";h();ae();ut();je();uu=2e3,ea=async n=>{let e;try{return await Promise.race([n,new Promise((t,r)=>{e=setTimeout(()=>r(new Error("Database startup check timed out")),uu)})])}finally{e&&clearTimeout(e)}},mu=n=>{let e=nt(),{label:t,defaultPort:r}=ee[e];if(n.startsWith("sqlite://"))return{type:e,name:t,destination:"local file"};if(r===null)return{type:e,name:t,destination:new URL(n).host};let{host:a,port:o}=Ae(n);return{type:e,name:t,destination:`${a}:${o}`}},du=async n=>{switch(n){case"pg":await ea(Sr().query("SELECT 1"));return;case"mysql":await Ar().query("SELECT 1");return;case"mssql":await(await Nr()).request().query("SELECT 1");return;case"mongodb":{await(await Pr()).db(Ir()).command({ping:1});return}case"sqlite":await ea(_r().then(e=>e.execute("SELECT 1")));return;case"redis":await(await Lr()).ping();return;case"duckdb":await Or(e=>e.run("SELECT 1"));return;case"oracle":{let e=await(await $r()).getConnection();await e.execute("SELECT 1 FROM dual").finally(()=>e.close());return}case"clickhouse":await ea(Dr().query({query:"SELECT 1"}))}}});import{HTTPException as is}from"hono/http-exception";function F(n){return ge.get(n)}function mt(n,e){if(!pu(n))throw new is(400,{message:`Key browsing is not supported for database type: "${e}"`});return n}var ta,ge,pu,et=S(()=>{"use strict";h();ta=class{adapters=new Map;register(e,t){this.adapters.set(e,t)}get(e){let t=this.adapters.get(e);if(!t)throw new is(400,{message:`Unsupported database type: "${e}". Supported types: ${this.getSupportedTypes().join(", ")}`});return t}has(e){return this.adapters.has(e)}getSupportedTypes(){return[...this.adapters.keys()]}},ge=new ta;pu=n=>"scanKeys"in n&&typeof n.scanKeys=="function"});import{HTTPException as He}from"hono/http-exception";import{DatabaseError as fu}from"pg";function ce(n){throw new He(501,{message:`${n} is not implemented for this database type`})}var se,We=S(()=>{"use strict";h();se=class{assertDeletableKey(e){if(e.length>1)throw new He(400,{message:"Deleting rows from tables with a composite primary key is not supported yet."})}wrapError(e){if(e instanceof He)return e;if(e instanceof Error){let t=e,r=t.code??e.cause?.code;return r==="ECONNREFUSED"||r==="ENOTFOUND"||r==="ETIMEDOUT"||r==="ER_ACCESS_DENIED_ERROR"||r==="ER_BAD_HOST_ERROR"||r==="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 fu&&e.code?.startsWith("08")?new He(503,{message:e.message,cause:e}):new He(500,{message:e.message,cause:e})}return new He(500,{message:"Internal server error",cause:e})}resolveKeyColumns(e){return e.primaryKeys?.length?e.primaryKeys:[e.primaryKey]}assertWholeKey(e,t){let r=e.filter(a=>!t.includes(a));if(r.length>0)throw new He(400,{message:`Updates must match on every primary key column; missing: ${r.join(", ")}`})}groupUpdatesByKey(e,t){let r=new Map;for(let a of e.updates){let o=t.map(l=>{let c=a.rowData[l];if(c==null)throw new He(400,{message:`Primary key "${l}" not found in row data.`});return c}),s=JSON.stringify(o.map(l=>String(l))),i=r.get(s)??{keyValues:o,rowUpdates:[]};i.rowUpdates.push({columnName:a.columnName,value:a.value}),r.set(s,i)}return[...r.values()]}orderTerms(e=[],t,r){let a=typeof e=="string"?e?[{columnName:e,direction:t}]:[]:e,o=a[0]?.direction??t;return[...a.map(s=>({column:s.columnName,direction:s.direction})),...r.filter(s=>!a.some(i=>i.columnName===s)).map(s=>({column:s,direction:o}))]}describeKey(e,t){return e.map((r,a)=>`${r} = ${t[a]}`).join(", ")}assertDifferentTableName(e,t){if(e===t)throw new He(400,{message:`New table name must be different from "${e}"`})}encodeCursor(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}decodeCursor(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf-8"))}catch{return null}}normalizeRow(e){let t={};for(let[r,a]of Object.entries(e))t[r]=a;return t}async getTableData(e){try{let{db:t,limit:r=50,direction:a="asc"}=e,o=this.buildTableDataQuery(e),s=await this.runQuery(t,o.countSql,o.countValues),i=Number(s[0]?.total??0),l=await this.runQuery(t,o.sql,o.values),c=l.length>r;c&&(l=l.slice(0,r));let u=this.normalizeRows(l);a==="desc"&&(u=u.reverse());let{nextCursor:m,prevCursor:p}=this.buildCursors(e,u,c);return{data:u,meta:{limit:r,total:i,hasNextPage:a==="asc"?c:!!e.cursor,hasPreviousPage:a==="asc"?!!e.cursor:c,nextCursor:m,prevCursor:p}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=`SELECT * FROM ${this.quoteIdentifier(e)}`,a=await this.runQuery(t,r,[]);if(!a||a.length===0)throw new He(404,{message:`Table "${e}" does not exist or has no data`});return{cols:Object.keys(a[0]),rows:a}}catch(r){throw this.wrapError(r)}}getDatabasesList(){return ce("getDatabasesList")}getCurrentDatabase(){return ce("getCurrentDatabase")}getDatabaseConnectionInfo(){return ce("getDatabaseConnectionInfo")}getTablesList(e){return ce("getTablesList")}createTable(e){return ce("createTable")}deleteTable(e){return ce("deleteTable")}renameTable(e){return ce("renameTable")}getTableSchema(e){return ce("getTableSchema")}getTableColumns(e){return ce("getTableColumns")}addColumn(e){return ce("addColumn")}deleteColumn(e){return ce("deleteColumn")}alterColumn(e){return ce("alterColumn")}renameColumn(e){return ce("renameColumn")}addRecord(e){return ce("addRecord")}updateRecords(e){return ce("updateRecords")}deleteRecords(e){return ce("deleteRecords")}forceDeleteRecords(e){return ce("forceDeleteRecords")}bulkInsertRecords(e){return ce("bulkInsertRecords")}executeQuery(e){return ce("executeQuery")}}});var ne,X,J,oe,ra,na,aa,xr,he,De,vr,dt,jt,Ve=S(()=>{"use strict";h();ut();ne=n=>Sr(n),X=n=>Ar(n),J=n=>Nr(n),oe=()=>_r(),ra=n=>Or(n),na=()=>$r(),aa=()=>Pr(),xr=()=>Ir(),he=n=>rs(n),De=n=>Lr(n),vr=n=>ns(n),dt=()=>as(),jt=n=>Dr(n)});function ls(n){let e=[],t=[],r=a=>(t.push(a),`{p${t.length-1}:String}`);for(let{columnName:a,operator:o,value:s}of n){let i=oa(a);switch(o){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${i} ${o} ${r(s)}`);break;case"is":e.push(s.toLowerCase()==="null"?`${i} IS NULL`:`${i} = ${r(s)}`);break;case"is not":e.push(s.toLowerCase()==="null"?`${i} IS NOT NULL`:`${i} != ${r(s)}`);break;case"like":e.push(`toString(${i}) LIKE ${r(s)}`);break;case"not like":e.push(`toString(${i}) NOT LIKE ${r(s)}`);break;case"ilike":e.push(`toString(${i}) ILIKE ${r(s)}`);break;case"not ilike":e.push(`toString(${i}) NOT ILIKE ${r(s)}`);break}}return{clause:e.length?`WHERE ${e.join(" AND ")}`:"",values:t}}function cs(n,e,t){let r=Array.isArray(n)?n:n?[{columnName:n,direction:e}]:[],a=(r[0]?.direction??e).toUpperCase(),o=[...r.map(s=>`${oa(s.columnName)} ${s.direction.toUpperCase()}`),...t.map(s=>`${s} ${a}`)];return o.length?`ORDER BY ${o.join(", ")}`:""}function yu(n,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"}[n.toLowerCase().trim()]??n.trim();return e?`Array(${a})`:a}function qr(n,e){let t=oa(n.columnName);if(n.isIdentity||/serial/i.test(n.columnType))return`${t} UInt64 DEFAULT generateSnowflakeID()`;let r=yu(n.columnType,n.isArray??!1,e),a=n.isNullable&&!n.isPrimaryKey&&!n.isArray,o=`${t} ${a?`Nullable(${r})`:r}`,s=n.defaultValue?.trim();return s&&(o+=` DEFAULT ${hu[s.toLowerCase()]??s}`),o}var ie,oa,hu,us=S(()=>{"use strict";h();ie=n=>`\`${n.replaceAll("\\","\\\\").replaceAll("`","\\`")}\``,oa=ie;hu={"now()":"now()",current_timestamp:"now()","current_timestamp()":"now()",current_date:"today()","gen_random_uuid()":"generateUUIDv4()","uuid_generate_v4()":"generateUUIDv4()"}});import{HTTPException as ue}from"hono/http-exception";var bu,ms,gu,Ur,ds=S(()=>{"use strict";h();ae();We();Ve();je();us();bu={mutations_sync:"2"},ms=n=>/^(LowCardinality\()?Nullable\(/.test(n),gu=(n,e)=>{if(n==null)return null;let t=Tt(e);if(n===""&&t!=="String"&&!t.startsWith("FixedString"))return null;if(n instanceof Date)return n.toISOString();if(t==="Bool"&&typeof n=="string")return["true","t","1","yes","on"].includes(n.trim().toLowerCase());if(typeof n=="string"&&(t.startsWith("JSON")||t.startsWith("Array(")||t.startsWith("Map(")))try{return JSON.parse(n)}catch{throw new ue(400,{message:`Invalid ${t} value: ${n}`})}return typeof n=="object"&&t==="String"?JSON.stringify(n):n},Ur=class extends se{serverVersion=null;async runQuery(e,t,r){let a=Object.fromEntries(r.map((o,s)=>[`p${s}`,o]));return await this.select(e,t,a)}quoteIdentifier(e){return ie(e)}mapToUniversalType(e){return dr(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,r){let{cursor:a,limit:o=50}=e,s=a?this.decodeOffsetCursor(a):0;return{nextCursor:r?this.makeCursor(s+o):null,prevCursor:s>0?this.makeCursor(Math.max(0,s-o)):null}}async getTableData(e){try{let{db:t,tableName:r,limit:a=50,cursor:o}=e,s=await this.getTable(t,r),i=s.sorting_key?[`(${s.sorting_key})`]:[];s.engine.endsWith("MergeTree")&&i.push("_part","_part_offset");let l=this.buildPageQuery(e,i),[c,u]=await Promise.all([this.runQuery(t,l.countSql,l.countValues),this.runQuery(t,l.sql,l.values)]),m=u.length>a,p=this.normalizeRows(m?u.slice(0,a):u),d=o?this.decodeOffsetCursor(o):0;return{data:p,meta:{limit:a,total:Number(c[0]?.total??0),hasNextPage:m,hasPreviousPage:d>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,13 @@ var Ji=Object.defineProperty;var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var Xt=(n,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 le(500,{message:"No connection information returned"});let{host:t,port:r}=Re();return{host:t,port:r,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
27
+ (SELECT value FROM system.server_settings WHERE name = 'max_connections') AS max_connections`);if(!e)throw new ue(500,{message:"No connection information returned"});let{host:t,port:r}=Ae();return{host:t,port:r,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(r=>({tableName:r.tableName,rowCount:Number(r.rowCount??0)}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e;if(o?.length)throw new le(400,{message:"ClickHouse does not support foreign keys"});let s=a.find(i=>i.isUnique&&!i.isPrimaryKey);if(s)throw new le(400,{message:`ClickHouse does not enforce UNIQUE constraints; clear "Unique" on "${s.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 le(400,{message:"Auto-generated ids need ClickHouse 24.6 or newer (generateSnowflakeID)"});let l=a.map(u=>Ir(u,i)),c=a.filter(u=>u.isPrimaryKey).map(u=>se(u.columnName));await this.command(t,`CREATE TABLE ${se(r)} (${l.join(", ")}) ENGINE = MergeTree ORDER BY ${c.length?`(${c.join(", ")})`:"tuple()"}`)}catch(i){throw this.wrapError(i)}}async deleteTable({tableName:e,db:t}){try{await this.getTable(t,e);let[r]=await this.select(t,`SELECT count() AS total FROM ${se(e)}`);return await this.command(t,`DROP TABLE ${se(e)}`),{deletedCount:Number(r?.total??0),fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async renameTable({tableName:e,newTableName:t,db:r}){this.assertDifferentTableName(e,t);try{if(await this.getTable(r,e),await this.findTable(r,t))throw new le(409,{message:`Table "${t}" already exists`});await this.command(r,`RENAME TABLE ${se(e)} TO ${se(t)}`)}catch(a){throw this.wrapError(a)}}async getTableSchema({tableName:e,db:t}){try{await this.getTable(t,e);let[r]=await this.select(t,`SHOW CREATE TABLE ${se(e)}`);return r?.statement??""}catch(r){throw this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{return await this.getTable(t,e),(await this.getColumns(t,e)).map(a=>({columnName:a.name,dataType:ir(a.type),dataTypeLabel:Cn(a.type),isNullable:ns(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(yt(a.type))?[...a.type.matchAll(/'((?:[^'\\]|\\.)*)'\s*=/g)].map(o=>o[1]??""):null}))}catch(r){throw this.wrapError(r)}}async addColumn(e){let{tableName:t,columnName:r,db:a}=e;if(e.isUnique)throw new le(400,{message:"ClickHouse does not enforce UNIQUE constraints"});try{if(await this.getTable(a,t),(await this.getColumns(a,t)).some(i=>i.name===r))throw new le(409,{message:`Column "${r}" already exists in table "${t}"`});let s=Ir({...e,isPrimaryKey:!1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${se(t)} ADD COLUMN ${s}`)}catch(o){throw this.wrapError(o)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{if((await this.getColumn(r,e,t)).is_in_sorting_key)throw new le(400,{message:`"${t}" is part of the sorting key and cannot be dropped`});return await this.command(r,`ALTER TABLE ${se(e)} DROP COLUMN ${se(t)}`),{deletedCount:1}}catch(a){throw this.wrapError(a)}}async alterColumn(e){let{tableName:t,columnName:r,db:a}=e;try{let o=await this.getColumn(a,t,r),s=Ir({...e,columnName:r,isPrimaryKey:o.is_in_sorting_key===1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${se(t)} MODIFY COLUMN ${s}`)}catch(o){throw this.wrapError(o)}}async renameColumn({tableName:e,columnName:t,newColumnName:r,db:a}){try{if(await this.getColumn(a,e,t),(await this.getColumns(a,e)).some(s=>s.name===r))throw new le(409,{message:`Column "${r}" already exists in table "${e}"`});await this.command(a,`ALTER TABLE ${se(e)} RENAME COLUMN ${se(t)} TO ${se(r)}`)}catch(o){throw this.wrapError(o)}}async addRecord({db:e,params:t}){if(!Object.keys(t.data).length)throw new le(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:r}){if(!t?.length)throw new le(400,{message:"At least one record is required"});return await this.insertRows(r,e,t),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}async updateRecords(e){throw new le(400,{message:Z.clickhouse.rowMutationReason})}async deleteRecords(e){throw new le(400,{message:Z.clickhouse.rowMutationReason})}async forceDeleteRecords(e){throw new le(400,{message:Z.clickhouse.rowMutationReason})}async executeQuery({query:e,db:t}){let r=e.trim().replace(/;+\s*$/,"");if(!r)throw new le(400,{message:"Query is required"});let a=performance.now();try{let o=qt(t),s=r.replace(/^(\s*(--[^\n]*\n|\/\*[\s\S]*?\*\/))*/,"").match(/^\s*(\w+)/)?.[1]?.toUpperCase();if(s&&["SELECT","WITH","SHOW","DESC","DESCRIBE","EXPLAIN","EXISTS"].includes(s)){let c=await o.query({query:r,format:"JSON"}),{meta:u=[],data:m}=await c.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 o.command({query:r,clickhouse_settings:au}),l=Number(i?.written_rows??0);return{columns:[],rows:[],rowCount:l,duration:performance.now()-a,message:`OK (${l} rows affected)`}}catch(o){throw this.wrapError(o)}}async select(e,t,r={}){return(await qt(e).query({query:t,query_params:r,format:"JSONEachRow"})).json()}async command(e,t,r={},a={}){await qt(e).command({query:t,query_params:r,clickhouse_settings:a})}buildPageQuery(e,t){let{tableName:r,filters:a=[],sort:o=[],order:s="asc",limit:i=50,cursor:l}=e,{clause:c,values:u}=es(a),m=ts(o,s,t),p=l?this.decodeOffsetCursor(l):0,d=u.length;return{sql:`SELECT * FROM ${se(r)} ${c} ${m} LIMIT {p${d+1}:UInt64} OFFSET {p${d}:UInt64}`,values:[...u,p,i+1],countSql:`SELECT count() AS total FROM ${se(r)} ${c}`,countValues:u}}async findTable(e,t){let[r]=await this.select(e,"SELECT engine, sorting_key FROM system.tables WHERE database = currentDatabase() AND name = {table:String}",{table:t});return r}async getTable(e,t){let r=await this.findTable(e,t);if(!r)throw new le(404,{message:`Table "${t}" does not exist`});return r}getColumns(e,t){return this.select(e,`SELECT name, type, default_expression, is_in_sorting_key
30
+ ORDER BY name`)).map(r=>({tableName:r.tableName,rowCount:Number(r.rowCount??0)}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e;if(o?.length)throw new ue(400,{message:"ClickHouse does not support foreign keys"});let s=a.find(i=>i.isUnique&&!i.isPrimaryKey);if(s)throw new ue(400,{message:`ClickHouse does not enforce UNIQUE constraints; clear "Unique" on "${s.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 ue(400,{message:"Auto-generated ids need ClickHouse 24.6 or newer (generateSnowflakeID)"});let l=a.map(u=>qr(u,i)),c=a.filter(u=>u.isPrimaryKey).map(u=>ie(u.columnName));await this.command(t,`CREATE TABLE ${ie(r)} (${l.join(", ")}) ENGINE = MergeTree ORDER BY ${c.length?`(${c.join(", ")})`:"tuple()"}`)}catch(i){throw this.wrapError(i)}}async deleteTable({tableName:e,db:t}){try{await this.getTable(t,e);let[r]=await this.select(t,`SELECT count() AS total FROM ${ie(e)}`);return await this.command(t,`DROP TABLE ${ie(e)}`),{deletedCount:Number(r?.total??0),fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async renameTable({tableName:e,newTableName:t,db:r}){this.assertDifferentTableName(e,t);try{if(await this.getTable(r,e),await this.findTable(r,t))throw new ue(409,{message:`Table "${t}" already exists`});await this.command(r,`RENAME TABLE ${ie(e)} TO ${ie(t)}`)}catch(a){throw this.wrapError(a)}}async getTableSchema({tableName:e,db:t}){try{await this.getTable(t,e);let[r]=await this.select(t,`SHOW CREATE TABLE ${ie(e)}`);return r?.statement??""}catch(r){throw this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{return await this.getTable(t,e),(await this.getColumns(t,e)).map(a=>({columnName:a.name,dataType:dr(a.type),dataTypeLabel:Dn(a.type),isNullable:ms(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(Tt(a.type))?[...a.type.matchAll(/'((?:[^'\\]|\\.)*)'\s*=/g)].map(o=>o[1]??""):null}))}catch(r){throw this.wrapError(r)}}async addColumn(e){let{tableName:t,columnName:r,db:a}=e;if(e.isUnique)throw new ue(400,{message:"ClickHouse does not enforce UNIQUE constraints"});try{if(await this.getTable(a,t),(await this.getColumns(a,t)).some(i=>i.name===r))throw new ue(409,{message:`Column "${r}" already exists in table "${t}"`});let s=qr({...e,isPrimaryKey:!1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${ie(t)} ADD COLUMN ${s}`)}catch(o){throw this.wrapError(o)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{if((await this.getColumn(r,e,t)).is_in_sorting_key)throw new ue(400,{message:`"${t}" is part of the sorting key and cannot be dropped`});return await this.command(r,`ALTER TABLE ${ie(e)} DROP COLUMN ${ie(t)}`),{deletedCount:1}}catch(a){throw this.wrapError(a)}}async alterColumn(e){let{tableName:t,columnName:r,db:a}=e;try{let o=await this.getColumn(a,t,r),s=qr({...e,columnName:r,isPrimaryKey:o.is_in_sorting_key===1},await this.isAtLeast(a,25,3));await this.command(a,`ALTER TABLE ${ie(t)} MODIFY COLUMN ${s}`)}catch(o){throw this.wrapError(o)}}async renameColumn({tableName:e,columnName:t,newColumnName:r,db:a}){try{if(await this.getColumn(a,e,t),(await this.getColumns(a,e)).some(s=>s.name===r))throw new ue(409,{message:`Column "${r}" already exists in table "${e}"`});await this.command(a,`ALTER TABLE ${ie(e)} RENAME COLUMN ${ie(t)} TO ${ie(r)}`)}catch(o){throw this.wrapError(o)}}async addRecord({db:e,params:t}){if(!Object.keys(t.data).length)throw new ue(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:r}){if(!t?.length)throw new ue(400,{message:"At least one record is required"});return await this.insertRows(r,e,t),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}async updateRecords(e){throw new ue(400,{message:ee.clickhouse.rowMutationReason})}async deleteRecords(e){throw new ue(400,{message:ee.clickhouse.rowMutationReason})}async forceDeleteRecords(e){throw new ue(400,{message:ee.clickhouse.rowMutationReason})}async executeQuery({query:e,db:t}){let r=e.trim().replace(/;+\s*$/,"");if(!r)throw new ue(400,{message:"Query is required"});let a=performance.now();try{let o=jt(t),s=r.replace(/^(\s*(--[^\n]*\n|\/\*[\s\S]*?\*\/))*/,"").match(/^\s*(\w+)/)?.[1]?.toUpperCase();if(s&&["SELECT","WITH","SHOW","DESC","DESCRIBE","EXPLAIN","EXISTS"].includes(s)){let c=await o.query({query:r,format:"JSON"}),{meta:u=[],data:m}=await c.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 o.command({query:r,clickhouse_settings:bu}),l=Number(i?.written_rows??0);return{columns:[],rows:[],rowCount:l,duration:performance.now()-a,message:`OK (${l} rows affected)`}}catch(o){throw this.wrapError(o)}}async select(e,t,r={}){return(await jt(e).query({query:t,query_params:r,format:"JSONEachRow"})).json()}async command(e,t,r={},a={}){await jt(e).command({query:t,query_params:r,clickhouse_settings:a})}buildPageQuery(e,t){let{tableName:r,filters:a=[],sort:o=[],order:s="asc",limit:i=50,cursor:l}=e,{clause:c,values:u}=ls(a),m=cs(o,s,t),p=l?this.decodeOffsetCursor(l):0,d=u.length;return{sql:`SELECT * FROM ${ie(r)} ${c} ${m} LIMIT {p${d+1}:UInt64} OFFSET {p${d}:UInt64}`,values:[...u,p,i+1],countSql:`SELECT count() AS total FROM ${ie(r)} ${c}`,countValues:u}}async findTable(e,t){let[r]=await this.select(e,"SELECT engine, sorting_key FROM system.tables WHERE database = currentDatabase() AND name = {table:String}",{table:t});return r}async getTable(e,t){let r=await this.findTable(e,t);if(!r)throw new ue(404,{message:`Table "${t}" does not exist`});return r}getColumns(e,t){return this.select(e,`SELECT name, type, default_expression, is_in_sorting_key
31
31
  FROM system.columns
32
32
  WHERE database = currentDatabase() AND table = {table:String}
33
- ORDER BY position`,{table:t})}async getColumn(e,t,r){await this.getTable(e,t);let a=(await this.getColumns(e,t)).find(o=>o.name===r);if(!a)throw new le(404,{message:`Column "${r}" does not exist in table "${t}"`});return a}async insertRows(e,t,r){try{await this.getTable(e,t);let a=new Map((await this.getColumns(e,t)).map(s=>[s.name,s.type])),o=r.map(s=>Object.fromEntries(Object.entries(s).flatMap(([i,l])=>{let c=a.get(i);if(!c)throw new le(400,{message:`Column "${i}" does not exist in table "${t}"`});let u=ou(l,c);return u===null&&!ns(c)?[]:[[i,u]]})));await qt(e).insert({table:se(t),values:o,format:"JSONEachRow",clickhouse_settings:{date_time_input_format:"best_effort"}})}catch(a){throw this.wrapError(a)}}async isAtLeast(e,t,r){if(!this.serverVersion){let[s]=await this.select(e,"SELECT version() AS version");this.serverVersion=(s?.version??"0.0").split(".").map(Number)}let[a=0,o=0]=this.serverVersion;return a>t||a===t&&o>=r}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){return Number(this.decodeCursor(e)?.values._offset??0)}}});function os(n){let e=[],t=[];for(let r of n){let a=L(r.columnName),o=r.value.toLowerCase()==="null";switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":o?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":o?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":case"not like":case"ilike":case"not ilike":e.push(`CAST(${a} AS VARCHAR) ${r.operator.toUpperCase()} ?`),t.push(r.value);break}}return{conditions:e,values:t}}function ls(n,e,t){let r=[],a=[],o=[],s=[];for(let i of n){let l=L(i.column),c=e[i.column]??null,{descending:u,nullsLast:m}=ss(i,t),p=c===null?m?null:`${l} IS NOT NULL`:`${l} ${u?"<":">"} ?${m?` OR ${l} IS NULL`:""}`;p&&(r.push(`(${[...o,`(${p})`].join(" AND ")})`),a.push(...s,...c===null?[]:[c])),c===null?o.push(`${l} IS NULL`):(o.push(`${l} = ?`),s.push(c))}return{clause:r.length?`(${r.join(" OR ")})`:"FALSE",values:a}}function kr(n,e){let t=n.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]??n.toUpperCase();return e?`${a}[]`:a}var L,ta,ss,is,su,ra,cs=S(()=>{"use strict";h();L=n=>`"${n.replaceAll('"','""')}"`,ta=n=>n.length?`WHERE ${n.join(" AND ")}`:"";ss=(n,e)=>({descending:n.direction==="desc"!==e,nullsLast:!e}),is=(n,e=!1)=>`ORDER BY ${n.map(t=>{let{descending:r,nullsLast:a}=ss(t,e);return`${L(t.column)} ${r?"DESC":"ASC"} NULLS ${a?"LAST":"FIRST"}`}).join(", ")}`;su=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),ra=n=>su.has(n.toLowerCase().trim())});import{statSync as iu}from"fs";import{DuckDBTypeId as xr,ResultReturnType as us,StatementType as lu}from"@duckdb/node-api";import{HTTPException as ce}from"hono/http-exception";var Ut,cu,ms,aa,Ee,na,Bt,vr,uu,mu,du,pu,qr,ds=S(()=>{"use strict";h();ne();je();He();cs();Ut="database_name = current_database() AND schema_name = current_schema()",cu=new Set([xr.BIGINT,xr.UBIGINT,xr.HUGEINT,xr.UHUGEINT]),ms=n=>{let e=n.columnTypes(),t=n.columnNames().filter((a,o)=>cu.has(e[o].typeId)),r=n.getRowObjectsJson();for(let a of r)for(let o of t){let s=a[o];typeof s=="string"&&Number.isSafeInteger(Number(s))&&(a[o]=Number(s))}return r},aa=n=>n==null?null:typeof n=="string"||typeof n=="number"||typeof n=="boolean"||typeof n=="bigint"?n:n instanceof Date?n.toISOString():JSON.stringify(n),Ee=async(n,e,t=[])=>ms(await n.runAndReadAll(e,t.map(aa))),na=async(n,e,t=[])=>(await n.runAndReadAll(e,t.map(aa))).rowsChanged,Bt=async(n,e)=>{await n.run("BEGIN TRANSACTION");try{let t=await e();return await n.run("COMMIT"),t}catch(t){throw await n.run("ROLLBACK").catch(()=>{}),t}},vr=n=>n.map(()=>"?").join(", "),uu=n=>n.columns.map((e,t)=>`c.${L(e)} = p.${L(n.referencedColumns[t])}`).join(" AND "),mu=n=>n.flatMap(e=>[...(e.column_default??"").matchAll(/nextval\('([^']+)'\)/g)].map(t=>t[1])),du=[["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."]],pu=new Set(["CASCADE","SET NULL","SET DEFAULT"]),qr=class extends oe{async runQuery(e,t,r){return Jn(a=>Ee(a,t,r))}quoteIdentifier(e){return L(e)}mapToUniversalType(e){return or(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=du.find(([r])=>e.message.includes(r));if(t)return new ce(400,{message:`${t[1]} (${e.message})`,cause:e})}return super.wrapError(e)}withConnection(e){return Jn(e).catch(t=>{throw this.wrapError(t)})}async getTableData(e){let{tableName:t,limit:r=50,direction:a="asc",sort:o=[],order:s="asc",cursor:i,filters:l=[]}=e;return this.withConnection(async c=>{await this.requireColumns(c,t);let u=await this.primaryKey(c,t),m=this.orderTerms(o,s,u.length?u:["rowid"]),p=a==="desc",d=os(l),f=i?this.decodeCursor(i):null,y=f?ls(m,f.values,p):null,g=is(m,p),w=u.length?"*":"*, rowid",C=ta(y?[...d.conditions,y.clause]:d.conditions),[N]=await Ee(c,`SELECT COUNT(*) AS total FROM ${L(t)} ${ta(d.conditions)}`,d.values),A=await Ee(c,`SELECT ${w} FROM ${L(t)} ${C} ${g} LIMIT ?`,[...d.values,...y?.values??[],r+1]),E=A.length>r,R=A.slice(0,r);p&&R.reverse();let D=te=>this.encodeCursor({values:Object.fromEntries(m.map(V=>[V.column,te[V.column]])),sortColumns:m.map(V=>V.column)}),$=R[0],q=R.at(-1),P=p?!!i:E,U=p?E:!!i;return{data:R.map(te=>{if(u.length)return this.normalizeRow(te);let{rowid:V,...k}=te;return this.normalizeRow(k)}),meta:{limit:r,total:Number(N?.total??0),hasNextPage:P,hasPreviousPage:U,nextCursor:P&&q?D(q):null,prevCursor:U&&$?D($):null}}})}async getDatabasesList(){return this.withConnection(async e=>(await Ee(e,"SELECT database_name, path FROM duckdb_databases() WHERE database_name = current_database()")).map(r=>({name:r.database_name,size:this.getFileSize(r.path),owner:"",encoding:"UTF-8"})))}async getCurrentDatabase(){return this.withConnection(async e=>{let[t]=await Ee(e,"SELECT current_database() AS db");return{db:t.db}})}async getDatabaseConnectionInfo(){return this.withConnection(async e=>{let[t]=await Ee(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 r=await Ee(t,`SELECT table_name FROM duckdb_tables() WHERE ${Ut} AND NOT temporary ORDER BY table_name`),a=[];for(let{table_name:o}of r){let[s]=await Ee(t,`SELECT COUNT(*) AS count FROM ${L(o)}`);a.push({tableName:o,rowCount:Number(s?.count??0)})}return a})}async createTable({tableData:e}){let{tableName:t,fields:r,foreignKeys:a=[]}=e;for(let c of a){let u=[c.onUpdate,c.onDelete].find(m=>pu.has(m));if(u)throw new ce(400,{message:`DuckDB foreign keys do not support ${u} (on "${c.columnName}"). Use NO ACTION or RESTRICT.`})}let o=[],s=r.filter(c=>c.isPrimaryKey).map(c=>c.columnName),i=r.map(c=>{let u=`${L(c.columnName)} ${kr(c.columnType,c.isArray)}`;if(s.length===1&&c.isPrimaryKey&&(u+=" PRIMARY KEY"),c.isUnique&&!c.isPrimaryKey&&(u+=" UNIQUE"),!c.isNullable&&!c.isPrimaryKey&&(u+=" NOT NULL"),c.isIdentity||ra(c.columnType)){let m=`${t}_${c.columnName}_seq`;o.push(m),u+=` DEFAULT nextval('${m.replaceAll("'","''")}')`}else c.defaultValue?.trim()&&(u+=` DEFAULT ${c.defaultValue.trim()}`);return u});s.length>1&&i.push(`PRIMARY KEY (${s.map(L).join(", ")})`);let l=a.map(c=>`FOREIGN KEY (${L(c.columnName)}) REFERENCES ${L(c.referencedTable)} (${L(c.referencedColumn)}) ON UPDATE ${c.onUpdate} ON DELETE ${c.onDelete}`);await this.withConnection(c=>Bt(c,async()=>{for(let u of o)await c.run(`CREATE SEQUENCE ${L(u)}`);await c.run(`CREATE TABLE ${L(t)} (${[...i,...l].join(", ")})`)}))}async deleteTable({tableName:e,cascade:t}){return this.withConnection(async r=>{let a=await this.requireColumns(r,e),o=(await this.foreignKeys(r,"referenced_table",e)).filter(i=>i.table!==e);if(o.length){if(t)throw new ce(400,{message:`DuckDB cannot drop "${e}" while ${[...new Set(o.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(r,o)}}let[s]=await Ee(r,`SELECT COUNT(*) AS count FROM ${L(e)}`);await r.run(`DROP TABLE ${L(e)}`);for(let i of mu(a))await r.run(`DROP SEQUENCE IF EXISTS ${L(i)}`).catch(()=>{});return{deletedCount:Number(s?.count??0),fkViolation:!1,relatedRecords:[]}})}async renameTable({tableName:e,newTableName:t}){this.assertDifferentTableName(e,t),await this.withConnection(async r=>{if(await this.requireColumns(r,e),(await this.columns(r,t)).length)throw new ce(409,{message:`Table "${t}" already exists`});await r.run(`ALTER TABLE ${L(e)} RENAME TO ${L(t)}`)})}async getTableSchema({tableName:e}){return this.withConnection(async t=>{let[r]=await Ee(t,`SELECT sql FROM duckdb_tables() WHERE ${Ut} AND table_name = ?`,[e]);if(!r)throw new ce(404,{message:`Table "${e}" does not exist`});return r.sql})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let r=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),o=new Map((await this.foreignKeys(t,"table_name",e)).flatMap(s=>s.columns.map((i,l)=>[i,{table:s.referencedTable,column:s.referencedColumns[l]}])));return r.map(s=>{let i=o.get(s.column_name),l=a.has(s.column_name);return{columnName:s.column_name,dataType:or(s.data_type),dataTypeLabel:En(s.data_type),isNullable:s.is_nullable&&!l,columnDefault:s.column_default,isPrimaryKey:l,isForeignKey:!!i,referencedTable:i?.table??null,referencedColumn:i?.column??null,enumValues:s.data_type.startsWith("ENUM(")?[...s.data_type.matchAll(/'((?:[^']|'')*)'/g)].map(c=>c[1].replaceAll("''","'")):null}})})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isNullable:s,isUnique:i,isPrimaryKey:l}=e;if(i||l)throw new ce(400,{message:`DuckDB cannot add a ${l?"PRIMARY KEY":"UNIQUE"} column to an existing table. Add the column without it, or recreate the table.`});let c=e.isIdentity||ra(a)?`${t}_${r}_seq`:null,u=`${L(r)} ${kr(a,e.isArray)}`;c?u+=` DEFAULT nextval('${c.replaceAll("'","''")}')`:o?.trim()&&(u+=` DEFAULT ${o.trim()}`),await this.withConnection(async m=>{if((await this.requireColumns(m,t)).some(d=>d.column_name===r))throw new ce(409,{message:`Column "${r}" already exists in table "${t}"`});await Bt(m,async()=>{c&&await m.run(`CREATE SEQUENCE ${L(c)}`),await m.run(`ALTER TABLE ${L(t)} ADD COLUMN ${u}`),s||await m.run(`ALTER TABLE ${L(t)} ALTER COLUMN ${L(r)} SET NOT NULL`).catch(d=>{throw String(d).includes("NOT NULL constraint failed")?new ce(400,{message:`Column "${r}" needs a default value to be NOT NULL, because "${t}" already has rows.`}):d})})})}async deleteColumn({tableName:e,columnName:t}){return await this.withConnection(async r=>{await this.requireColumn(r,e,t),await r.run(`ALTER TABLE ${L(e)} DROP COLUMN ${L(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s}=e,i=`ALTER TABLE ${L(t)} ALTER COLUMN ${L(r)}`;await this.withConnection(async l=>{await this.requireColumn(l,t,r),await Bt(l,async()=>{await l.run(`${i} TYPE ${kr(a,!1)}`),await l.run(`${i} ${o?"DROP":"SET"} NOT NULL`),await l.run(s?.trim()?`${i} SET DEFAULT ${s.trim()}`:`${i} DROP DEFAULT`)})})}async renameColumn({tableName:e,columnName:t,newColumnName:r}){await this.withConnection(async a=>{if((await this.requireColumn(a,e,t)).some(s=>s.column_name===r))throw new ce(409,{message:`Column "${r}" already exists in table "${e}"`});await a.run(`ALTER TABLE ${L(e)} RENAME COLUMN ${L(t)} TO ${L(r)}`)})}async addRecord({params:e}){let{tableName:t,data:r}=e,a=Object.keys(r);if(!a.length)throw new ce(400,{message:"No data provided for insert"});return{insertedCount:await this.withConnection(s=>na(s,`INSERT INTO ${L(t)} (${a.map(L).join(", ")}) VALUES (${vr(a)})`,Object.values(r)))}}async updateRecords({params:e}){let{tableName:t}=e,r=this.resolveKeyColumns(e),a=this.groupUpdatesByKey(e,r);return{updatedCount:await this.withConnection(s=>Bt(s,async()=>{this.assertWholeKey(await this.primaryKey(s,t),r);let i=0;for(let{keyValues:l,rowUpdates:c}of a){let u=await na(s,`UPDATE ${L(t)} SET ${c.map(m=>`${L(m.columnName)} = ?`).join(", ")} WHERE ${r.map(m=>`${L(m)} = ?`).join(" AND ")}`,[...c.map(m=>m.value),...l]);if(u===0)throw new ce(404,{message:`Record with ${this.describeKey(r,l)} not found in table "${t}"`});i+=u}return i}))}}async deleteRecords({tableName:e,primaryKeys:t}){let r=t[0]?.columnName;if(!r)throw new ce(400,{message:"Primary key column name is required"});let a=t.map(o=>o.value);return this.withConnection(async o=>{this.assertDeletableKey(await this.primaryKey(o,e));try{return{deletedCount:await na(o,`DELETE FROM ${L(e)} WHERE ${L(r)} IN (${vr(a)})`,a),fkViolation:!1,relatedRecords:[]}}catch(s){if(!(s instanceof Error)||!s.message.includes("Violates foreign key constraint"))throw s;let i=[];for(let l of await this.foreignKeys(o,"referenced_table",e)){let c=await Ee(o,`SELECT c.* FROM ${L(l.table)} c JOIN ${L(e)} p ON ${uu(l)} WHERE p.${L(r)} IN (${vr(a)}) LIMIT 100`,a);c.length&&i.push({tableName:l.table,columnName:l.columns.join(", "),constraintName:l.constraintName,records:c})}return{deletedCount:0,fkViolation:!0,relatedRecords:i}}})}async forceDeleteRecords(e){let t=await this.deleteRecords(e);if(t.fkViolation)throw new ce(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 ce(400,{message:"At least one record is required"});let r=Object.keys(t[0]),a=await this.withConnection(o=>Bt(o,async()=>{let s=await o.prepare(`INSERT INTO ${L(e)} (${r.map(L).join(", ")}) VALUES (${vr(r)})`);for(let i of t)s.bind(r.map(l=>aa(i[l]))),await s.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 ce(400,{message:"Query is required"});return this.withConnection(async t=>{let r=performance.now(),a=await t.extractStatements(e);if(a.count!==1)throw new ce(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let o=await a.prepare(0);try{if(o.statementType===lu.TRANSACTION)throw new ce(400,{message:"Transactions cannot span query-runner requests. BEGIN, COMMIT, and ROLLBACK are not supported."});let s=await o.runAndReadAll(),i=performance.now()-r;if(s.returnType===us.CHANGED_ROWS)return{columns:[],rows:[],rowCount:s.rowsChanged,duration:i,message:`OK (${s.rowsChanged} rows affected)`};if(s.returnType===us.NOTHING)return{columns:[],rows:[],rowCount:0,duration:i,message:"OK"};let l=ms(s);return{columns:s.columnNames(),rows:l,rowCount:l.length,duration:i,message:l.length===0?"OK":void 0}}finally{o.destroySync()}})}getFileSize(e){if(!e)return"in-memory";try{let t=iu(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 Ee(e,`SELECT column_name, data_type, is_nullable, column_default FROM duckdb_columns() WHERE ${Ut} AND table_name = ? ORDER BY column_index`,[t])}async requireColumns(e,t){let r=await this.columns(e,t);if(!r.length)throw new ce(404,{message:`Table "${t}" does not exist`});return r}async requireColumn(e,t,r){let a=await this.requireColumns(e,t);if(!a.some(o=>o.column_name===r))throw new ce(404,{message:`Column "${r}" does not exist in table "${t}"`});return a}async primaryKey(e,t){let[r]=await Ee(e,`SELECT constraint_column_names AS columns FROM duckdb_constraints() WHERE ${Ut} AND table_name = ? AND constraint_type = 'PRIMARY KEY'`,[t]);return r?.columns??[]}async foreignKeys(e,t,r){return Ee(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 ${Ut} AND constraint_type = 'FOREIGN KEY' AND ${t} = ?`,[r])}async sampleReferencingRows(e,t){let r=[];for(let a of t){let o=await Ee(e,`SELECT * FROM ${L(a.table)} WHERE ${a.columns.map(s=>`${L(s)} IS NOT NULL`).join(" AND ")} LIMIT 100`);o.length&&r.push({tableName:a.table,columnName:a.columns.join(", "),constraintName:a.constraintName,records:o})}return r}}});var fu,ps,fs=S(()=>{"use strict";h();fu=new Set(["admin","config","local"]),ps=(n,e)=>{let t=n.filter(r=>!fu.has(r.name)||r.name===e);return!e||t.some(r=>r.name===e)?t:[...t,{name:e,sizeOnDisk:0}]}});function ys(n){if(!n||n.length===0)return{};let e=[];for(let t of n){let r=t.columnName,a=yu(t.value),o=t.operator.toLowerCase();if(r)switch(o){case"=":e.push({[r]:a});break;case"!=":e.push({[r]:{$ne:a}});break;case">":e.push({[r]:{$gt:a}});break;case">=":e.push({[r]:{$gte:a}});break;case"<":e.push({[r]:{$lt:a}});break;case"<=":e.push({[r]:{$lte:a}});break;case"is":e.push({[r]:a});break;case"is not":e.push({[r]:{$ne:a}});break;case"like":e.push({[r]:{$regex:Ur(String(a)),$options:""}});break;case"not like":e.push({[r]:{$not:{$regex:Ur(String(a)),$options:""}}});break;case"ilike":e.push({[r]:{$regex:Ur(String(a)),$options:"i"}});break;case"not ilike":e.push({[r]:{$not:{$regex:Ur(String(a)),$options:"i"}}});break;default:e.push({[r]:a});break}}return e.length?{$and:e}:{}}function oa(n,e){return n?Array.isArray(n)?n.length===0?{_id:1}:Object.fromEntries(n.map(t=>[t.columnName,t.direction==="desc"?-1:1])):typeof n=="string"&&n.length>0?{[n]:e==="desc"?-1:1}:{_id:1}:{_id:1}}function sa(n){return Buffer.from(JSON.stringify({offset:n})).toString("base64url")}function hs(n){if(!n)return 0;try{let e=JSON.parse(Buffer.from(n,"base64url").toString("utf-8"));return typeof e.offset=="number"?e.offset:0}catch{return 0}}var Ur,yu,bs=S(()=>{"use strict";h();st();Ur=n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),yu=n=>{let e=n.trim();if(e==="null")return null;if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return!Number.isNaN(t)&&e!==""?t:Or(e)?$r(e):e}});import{HTTPException as j}from"hono/http-exception";var ia,Rt,hu,bu,gs,Ft,gu,Ts,Tu,Eu,wu,St,Br,Es=S(()=>{"use strict";h();je();He();st();fs();Fe();bs();ia=n=>n instanceof Date?n.toISOString():typeof n=="bigint"?n.toString():n&&typeof n=="object"?"_bsontype"in n&&n._bsontype==="ObjectId"?n.toHexString():Array.isArray(n)?n.map(e=>ia(e)):Object.fromEntries(Object.entries(n).map(([e,t])=>[e,ia(t)])):n,Rt=n=>ia(n),hu=n=>n instanceof Date?"date":n&&typeof n=="object"?Array.isArray(n)?"array":"_bsontype"in n?"text":"json":typeof n=="boolean"?"boolean":typeof n=="number"||typeof n=="bigint"?"number":"text",bu=n=>{switch(n){case"number":return"numeric";case"boolean":return"boolean";case"json":return"json";case"date":return"date";case"array":return"array";case"enum":return"enum";default:return"text"}},gs=n=>typeof n=="string"&&Or(n),Ft=n=>$r(n),gu=n=>{if(!Number.isFinite(n))return"n/a";let e=["B","KB","MB","GB","TB"],t=n,r=0;for(;t>=1024&&r<e.length-1;)t/=1024,r++;return`${t.toFixed(1)} ${e[r]}`},Ts=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),Tu=n=>{let e=n.trim();if(Ts.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},Eu=n=>{if(n==null)return"null";if(n instanceof Date)return"date";if(typeof n=="boolean")return"bool";if(typeof n=="number")return Number.isInteger(n)?"int":"double";if(typeof n=="bigint")return"long";if(Array.isArray(n))return"array";if(typeof n=="object"){let e=n._bsontype;return e==="ObjectId"?"objectId":e==="Decimal128"?"decimal":e==="Binary"?"binData":e==="Timestamp"?"timestamp":e?e.toLowerCase():"object"}return"string"},wu=(n,e)=>{if(n!=null&&n.trim()!=="")try{return JSON.parse(n)}catch{return n}switch(e){case"string":return"";case"int":case"long":case"double":case"decimal":return 0;case"bool":return!1;case"array":return[];case"object":return{};case"date":return new Date;default:return null}},St=n=>{if(n._id&&typeof n._id=="string")return{...n,_id:Ft(n._id)};if(n._id&&typeof n._id=="object"){let e=n._id;if(Array.isArray(e.$in))return{...n,_id:{...e,$in:e.$in.map(t=>typeof t=="string"?Ft(t):t)}};if(Array.isArray(e.$nin))return{...n,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?Ft(t):t)}}}return n},Br=class extends oe{runQuery(){throw new j(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new j(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(Rt(t)))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"int":case"long":case"double":case"decimal":return"number";case"bool":return"boolean";case"date":return"date";case"array":return"array";case"object":return"json";default:return"text"}}mapFromUniversalType(e){switch(e){case"number":return"double";case"boolean":return"bool";case"date":return"date";case"array":return"array";case"json":return"object";default:return"string"}}wrapError(e){if(e instanceof j)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new j(503,{message:e.message,cause:e})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:r,cursor:a,limit:o,direction:s="asc",sort:i,order:l,filters:c}=e,m=(await fe(r)).collection(t),p=ys(c??[]),d=oa(i??"",l),f=o&&o>0?o:50,y=hs(a),g=Number.isFinite(y)&&y>=0?y:0,w=s==="desc"?Math.max(g-f,0):g,[C,N]=await Promise.all([m.countDocuments(p),m.find(p).sort(d).skip(w).limit(f).toArray()]),A=N.map(D=>Rt(D)),E=w+f,R=Math.max(w-f,0);return{data:A,meta:{limit:f,total:C,hasNextPage:E<C,hasPreviousPage:w>0,nextCursor:E<C?sa(E):null,prevCursor:w>0?sa(R):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let s=(await(await fe(t)).collection(e).find({}).limit(1e4).toArray()).map(l=>Rt(l));return{cols:Array.from(new Set(s.flatMap(l=>Object.keys(l)))),rows:s}}catch(r){throw this.wrapError(r)}}async getDatabasesList(){try{let a=(await(await Zn()).db().admin().listDatabases()).databases??[];if(!a[0])throw new j(500,{message:"No databases returned from MongoDB"});return ps(a,Pr()).map(o=>({name:o.name,size:gu(o.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:Pr()}}async getDatabaseConnectionInfo(){try{let t=(await Zn()).db().admin(),r=Re(),a={};try{a=await t.serverStatus()}catch(o){console.warn("Failed to read MongoDB serverStatus:",o)}return{host:r.host,port:r.port,user:"n/a",database:Pr(),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 fe(e),r=await t.listCollections().toArray(),a=[];for(let o of r){let s=await t.collection(o.name).estimatedDocumentCount();a.push({tableName:o.name,rowCount:s})}return a}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){try{let r=e?.tableName??"",a=await fe(t);if((await a.listCollections({name:r}).toArray()).length>0)throw new j(400,{message:`Collection "${r}" already exists`});let s=e?.fields??[];if(s.length===0){await a.createCollection(r);return}let i={},l=[];for(let c of s){let u=Tu(c.columnType);if(!Ts.has(u))throw new j(400,{message:`Unsupported MongoDB BSON type "${c.columnType}" for field "${c.columnName}"`});c.isArray?i[c.columnName]={bsonType:"array",...u!=="array"?{items:{bsonType:u}}:{}}:i[c.columnName]={bsonType:u},c.isNullable||l.push(c.columnName)}await a.createCollection(r,{validator:{$jsonSchema:{bsonType:"object",required:l,properties:i,additionalProperties:!0}},validationAction:"error"})}catch(r){throw this.wrapError(r)}}async deleteTable({tableName:e,db:t}){try{let a=(await fe(t)).collection(e),o=await a.estimatedDocumentCount();return await a.drop(),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async renameTable(e){try{let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=await fe(a);if((await o.listCollections({name:t}).toArray()).length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if((await o.listCollections({name:r}).toArray()).length>0)throw new j(409,{message:`Collection "${r}" already exists`});await o.collection(t).rename(r)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){try{let r=await fe(t);if((await r.listCollections({name:e}).toArray()).length===0)throw new j(404,{message:`Collection "${e}" does not exist`});let o=r.collection(e),s=await o.find({}).limit(200).toArray(),i=await o.estimatedDocumentCount(),l=new Map,c=new Map;for(let d of s)for(let[f,y]of Object.entries(d)){let g=Eu(y);l.has(f)||(l.set(f,new Set),c.set(f,0)),l.get(f)?.add(g),c.set(f,(c.get(f)??0)+1)}let u={},m=[];for(let[d,f]of l.entries()){let y=c.get(d)??0,g=Array.from(f).filter(C=>C!=="null"),w=f.has("null")||y<s.length;y===s.length&&s.length>0&&!w&&m.push(d),u[d]=g.length===1?{bsonType:w?[g[0],"null"]:g[0]}:{bsonType:w?[...g,"null"]:g}}let p={collection:e,estimatedDocumentCount:i,sampledDocuments:s.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(p,null,2)}catch(r){throw this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let o=await(await fe(t)).collection(e).find({}).limit(200).toArray(),s=o.length,i=new Map,l=(c,u)=>{let m=hu(u);if(!i.has(c))i.set(c,{types:new Set([m]),nullable:!1,presentCount:1});else{let p=i.get(c);p.types.add(m),p.presentCount+=1}};for(let c of o)for(let[u,m]of Object.entries(c)){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}l(u,m)}if(s>0)for(let c of i.values())c.presentCount<s&&(c.nullable=!0);return i.has("_id")||i.set("_id",{types:new Set(["text"]),nullable:!1,presentCount:s}),Array.from(i.entries()).map(([c,u])=>{let m=u.types.values().next().value??"text";return{columnName:c,dataType:m,dataTypeLabel:bu(m),isNullable:u.nullable,columnDefault:null,isPrimaryKey:c==="_id",isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}})}catch(r){throw this.wrapError(r)}}async addColumn(e){try{let{tableName:t,columnName:r,columnType:a,defaultValue:o,isNullable:s,db:i}=e,l=await fe(i),c=await l.listCollections({name:t}).toArray();if(c.length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(await l.collection(t).findOne({[r]:{$exists:!0}}))throw new j(409,{message:`Field "${r}" already exists in collection "${t}"`});let m=wu(o,a);await l.collection(t).updateMany({},{$set:{[r]:m}});let d=c[0].options?.validator?.$jsonSchema??{},f={...d.properties??{},[r]:{bsonType:s?[a,"null"]:a}},y=[...d.required??[]];!s&&!y.includes(r)&&y.push(r),await l.command({collMod:t,validator:{$jsonSchema:{...d,bsonType:"object",properties:f,...y.length>0?{required:y}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{return{deletedCount:(await(await fe(r)).collection(e).updateMany({},{$unset:{[t]:""}})).modifiedCount}}catch(a){throw this.wrapError(a)}}async alterColumn(e){try{let{tableName:t,columnName:r,columnType:a,isNullable:o,db:s}=e,i=await fe(s),l=await i.listCollections({name:t}).toArray();if(l.length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new j(400,{message:'Cannot alter the "_id" field'});let u=l[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},p=[...u.required??[]];m[r]={bsonType:o?[a,"null"]:a};let d=p.indexOf(r);!o&&d===-1?p.push(r):o&&d!==-1&&p.splice(d,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:r,newColumnName:a,db:o}=e,s=await fe(o);if((await s.listCollections({name:t}).toArray()).length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new j(400,{message:'Cannot rename the "_id" field'});if(!await s.collection(t).findOne({[r]:{$exists:!0}}))throw new j(404,{message:`Field "${r}" does not exist in collection "${t}"`});if(await s.collection(t).findOne({[a]:{$exists:!0}}))throw new j(409,{message:`Field "${a}" already exists in collection "${t}"`});await s.collection(t).updateMany({[r]:{$exists:!0}},{$rename:{[r]:a}})}catch(t){throw this.wrapError(t)}}async addRecord({db:e,params:t}){try{let{tableName:r,data:a}=t,s=(await fe(e)).collection(r),i=Rt(a);if((i._id===""||i._id===null)&&delete i._id,!(await s.insertOne(i)).insertedId)throw new j(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r}=t,o=(await fe(e)).collection(r),s=0,i=this.resolveKeyColumns(t).map(c=>c||"_id"),l=this.groupUpdatesByKey({...t,primaryKeys:i},i);for(let{keyValues:c,rowUpdates:u}of l){if(u.some(f=>f.columnName==="_id"))throw new j(400,{message:'The "_id" field is immutable and cannot be updated.'});let m={};for(let f of u)m[f.columnName]=f.value;let p={};i.forEach((f,y)=>{let g=c[y];p[f]=f==="_id"&&gs(g)?Ft(g):g});let d=await o.updateOne(p,{$set:m});if(d.matchedCount===0)throw new j(404,{message:`Record with ${this.describeKey(i,c)} not found in "${r}"`});s+=d.modifiedCount}return{updatedCount:s}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:a}=e,s=(await fe(a)).collection(t),i=r[0]?.columnName??"_id",l=r.map(u=>i==="_id"&&gs(u.value)?Ft(u.value):u.value);return{deletedCount:(await s.deleteMany({[i]:{$in:l}})).deletedCount??0,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:r,db:a}=e;if(!r||r.length===0)throw new j(400,{message:"At least one record is required"});let s=(await fe(a)).collection(t),i=r.map(c=>{let u=Rt(c);return(u._id===""||u._id===null)&&delete u._id,u}),l=await s.insertMany(i,{ordered:!1});return{success:!0,message:`Successfully inserted ${l.insertedCount} record${l.insertedCount!==1?"s":""}`,successCount:l.insertedCount,failureCount:r.length-l.insertedCount}}catch(t){throw this.wrapError(t)}}async executeQuery({query:e,db:t}){try{if(!e?.trim())throw new j(400,{message:"Query is required"});let r;try{r=JSON.parse(e)}catch{throw new j(400,{message:"Mongo query must be valid JSON"})}if(!r.collection||!r.operation)throw new j(400,{message:"Mongo query must include collection and operation"});let o=(await fe(t)).collection(r.collection),s=performance.now(),i=[],l=0,c;switch(r.operation){case"find":{let d=St(r.filter??{}),f=o.find(d,r.options??{});f.sort(r.sort??oa("",void 0)),r.skip&&f.skip(r.skip),r.limit&&f.limit(r.limit),i=await f.toArray(),l=i.length;break}case"aggregate":{i=await o.aggregate(r.pipeline??[],r.options??{}).toArray(),l=i.length;break}case"insertOne":{let d=r.document;if(!d)throw new j(400,{message:"document is required"});l=(await o.insertOne(d)).insertedId?1:0,c="OK";break}case"insertMany":{let d=r.document;if(!Array.isArray(d))throw new j(400,{message:"document array is required"});l=(await o.insertMany(d)).insertedCount??0,c="OK";break}case"updateOne":{let d=St(r.filter??{});if(!r.update)throw new j(400,{message:"update is required"});let f=await o.updateOne(d,r.update,r.options??{});l=f.matchedCount??0,c=`OK (${f.modifiedCount??0} modified)`;break}case"updateMany":{let d=St(r.filter??{});if(!r.update)throw new j(400,{message:"update is required"});let f=await o.updateMany(d,r.update,r.options??{});l=f.matchedCount??0,c=`OK (${f.modifiedCount??0} modified)`;break}case"deleteOne":{let d=St(r.filter??{});l=(await o.deleteOne(d,r.options??{})).deletedCount??0,c="OK";break}case"deleteMany":{let d=St(r.filter??{});l=(await o.deleteMany(d,r.options??{})).deletedCount??0,c="OK";break}case"count":{let d=St(r.filter??{});l=await o.countDocuments(d),i=[{count:l}],c="OK";break}default:throw new j(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-s,m=i.map(d=>Rt(d));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:l,duration:u,message:c}}catch(r){throw this.wrapError(r)}}}});function la(n,e=0){if(n.length===0)return{clause:"",values:[],nextIdx:e};let t=[],r=[],a=e;for(let o of n){let s=`[${o.columnName}]`;switch(o.operator){case"=":case"!=":case">":case">=":case"<":case"<=":t.push(`${s} ${o.operator} @p${a}`),r.push(o.value),a++;break;case"is":o.value.toLowerCase()==="null"?t.push(`${s} IS NULL`):(t.push(`${s} = @p${a}`),r.push(o.value),a++);break;case"is not":o.value.toLowerCase()==="null"?t.push(`${s} IS NOT NULL`):(t.push(`${s} != @p${a}`),r.push(o.value),a++);break;case"like":case"ilike":t.push(`${s} LIKE @p${a}`),r.push(o.value),a++;break;case"not like":case"not ilike":t.push(`${s} NOT LIKE @p${a}`),r.push(o.value),a++;break;default:break}}return t.length===0?{clause:"",values:[],nextIdx:e}:{clause:`WHERE ${t.join(" AND ")}`,values:r,nextIdx:a}}function ca(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(t=>`[${t.columnName}] ${t.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY [${n}] ${e?.toUpperCase()||"ASC"}`:""}function ws(n,e,t){let r=ca(n,e),a=Array.isArray(n)?n.map(i=>i.columnName):[n],o=(Array.isArray(n)?n[0]?.direction??e:e).toUpperCase(),s=t.filter(i=>!a.includes(i)).map(i=>`[${i}] ${o}`).join(", ");return s?r?`${r}, ${s}`:`ORDER BY ${s}`:r||"ORDER BY (SELECT NULL)"}function ua(n,e){if(e)return"NVARCHAR(MAX)";let t=n.toLowerCase().trim();return{serial:"INT IDENTITY(1,1)",serial4:"INT IDENTITY(1,1)",bigserial:"BIGINT IDENTITY(1,1)",serial8:"BIGINT IDENTITY(1,1)",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",tinyint:"TINYINT",numeric:"NUMERIC",decimal:"DECIMAL",real:"REAL",float4:"REAL",float:"FLOAT","double precision":"FLOAT",float8:"FLOAT",money:"MONEY",boolean:"BIT",bool:"BIT",text:"NVARCHAR(MAX)",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"UNIQUEIDENTIFIER",json:"NVARCHAR(MAX)",jsonb:"NVARCHAR(MAX)",xml:"XML",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME2","timestamp without time zone":"DATETIME2","timestamp with time zone":"DATETIMEOFFSET",timestamptz:"DATETIMEOFFSET",interval:"VARCHAR(255)",bytea:"VARBINARY(MAX)",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)"}[t]||n.toUpperCase()}function ma(n,e){let t=n.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("newid()")?e.toUpperCase().includes("UNIQUEIDENTIFIER")?"NEWID()":null:t.includes("getdate")||t.includes("current_timestamp")?"GETDATE()":n.trim():t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":n.trim()}function Cs(n,e={}){let t=ua(n.columnType,n.isArray??!1),r=`[${n.columnName}] ${t}`;if(n.isIdentity&&!t.includes("IDENTITY")&&(r+=" IDENTITY(1,1)"),!n.isNullable&&!n.isPrimaryKey&&(r+=" NOT NULL"),n.defaultValue?.trim()&&!t.includes("IDENTITY")){let a=ma(n.defaultValue,t);a!==null&&(r+=` DEFAULT ${a}`)}return e.includeUnique&&n.isUnique&&!n.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&n.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var Rs=S(()=>{"use strict";h()});import{HTTPException as Y}from"hono/http-exception";var Cu,Ru,Fr,Ss=S(()=>{"use strict";h();ne();je();He();Fe();Rs();Cu=547,Ru=3726,Fr=class extends oe{async runQuery(e,t,r){let o=(await Q(e)).request();return r.forEach((i,l)=>{o.input(`p${l}`,i)}),(await o.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return nr(e)}mapFromUniversalType(e){return{text:"NVARCHAR(MAX)",number:"INT",boolean:"BIT",json:"NVARCHAR(MAX)",date:"DATETIME2",array:"NVARCHAR(MAX)",enum:"NVARCHAR(255)"}[e]??"NVARCHAR(MAX)"}buildTableDataQuery(e){let{tableName:t,filters:r=[],sort:a=[],order:o="asc",limit:s=50,cursor:i}=e,{clause:l,values:c,nextIdx:u}=la(r,0),m=ca(a,o)||"ORDER BY (SELECT NULL)",p=i?this.decodeOffsetCursor(i):0,d=`SELECT * FROM [${t}] ${l} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,f=[...c,p,s+1],y=`SELECT COUNT(*) as total FROM [${t}] ${l}`;return{sql:d,values:f,countSql:y,countValues:c}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){let{cursor:a,limit:o=50}=e,s=a?this.decodeOffsetCursor(a):0;return{nextCursor:r?this.makeCursor(s+o):null,prevCursor:s>0?this.makeCursor(Math.max(0,s-o)):null}}async getTableData(e){try{let{tableName:t,db:r,limit:a=50,sort:o=[],order:s="asc",cursor:i,filters:l=[]}=e,c=await Q(r),u=await this.getPrimaryKeyColumns(c,t),m=i?this.decodeOffsetCursor(i):0,{clause:p,values:d,nextIdx:f}=la(l,0),y=ws(o,s,u),g=c.request();d.forEach((D,$)=>{g.input(`p${$}`,D)});let w=await g.query(`SELECT COUNT(*) as total FROM [${t}] ${p}`),C=Number(w.recordset[0]?.total??0),N=c.request();d.forEach((D,$)=>{N.input(`p${$}`,D)}),N.input(`p${f}`,m),N.input(`p${f+1}`,a+1);let E=(await N.query(`SELECT * FROM [${t}] ${p} ${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 Q()).request().query(`
33
+ ORDER BY position`,{table:t})}async getColumn(e,t,r){await this.getTable(e,t);let a=(await this.getColumns(e,t)).find(o=>o.name===r);if(!a)throw new ue(404,{message:`Column "${r}" does not exist in table "${t}"`});return a}async insertRows(e,t,r){try{await this.getTable(e,t);let a=new Map((await this.getColumns(e,t)).map(s=>[s.name,s.type])),o=r.map(s=>Object.fromEntries(Object.entries(s).flatMap(([i,l])=>{let c=a.get(i);if(!c)throw new ue(400,{message:`Column "${i}" does not exist in table "${t}"`});let u=gu(l,c);return u===null&&!ms(c)?[]:[[i,u]]})));await jt(e).insert({table:ie(t),values:o,format:"JSONEachRow",clickhouse_settings:{date_time_input_format:"best_effort"}})}catch(a){throw this.wrapError(a)}}async isAtLeast(e,t,r){if(!this.serverVersion){let[s]=await this.select(e,"SELECT version() AS version");this.serverVersion=(s?.version??"0.0").split(".").map(Number)}let[a=0,o=0]=this.serverVersion;return a>t||a===t&&o>=r}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){return Number(this.decodeCursor(e)?.values._offset??0)}}});function ps(n){let e=[],t=[];for(let r of n){let a=I(r.columnName),o=r.value.toLowerCase()==="null";switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":o?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":o?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":case"not like":case"ilike":case"not ilike":e.push(`CAST(${a} AS VARCHAR) ${r.operator.toUpperCase()} ?`),t.push(r.value);break}}return{conditions:e,values:t}}function hs(n,e,t){let r=[],a=[],o=[],s=[];for(let i of n){let l=I(i.column),c=e[i.column]??null,{descending:u,nullsLast:m}=fs(i,t),p=c===null?m?null:`${l} IS NOT NULL`:`${l} ${u?"<":">"} ?${m?` OR ${l} IS NULL`:""}`;p&&(r.push(`(${[...o,`(${p})`].join(" AND ")})`),a.push(...s,...c===null?[]:[c])),c===null?o.push(`${l} IS NULL`):(o.push(`${l} = ?`),s.push(c))}return{clause:r.length?`(${r.join(" OR ")})`:"FALSE",values:a}}function Br(n,e){let t=n.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]??n.toUpperCase();return e?`${a}[]`:a}var I,sa,fs,ys,Tu,ia,bs=S(()=>{"use strict";h();I=n=>`"${n.replaceAll('"','""')}"`,sa=n=>n.length?`WHERE ${n.join(" AND ")}`:"";fs=(n,e)=>({descending:n.direction==="desc"!==e,nullsLast:!e}),ys=(n,e=!1)=>`ORDER BY ${n.map(t=>{let{descending:r,nullsLast:a}=fs(t,e);return`${I(t.column)} ${r?"DESC":"ASC"} NULLS ${a?"LAST":"FIRST"}`}).join(", ")}`;Tu=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),ia=n=>Tu.has(n.toLowerCase().trim())});import{statSync as Eu}from"fs";import{DuckDBTypeId as Fr,ResultReturnType as gs,StatementType as wu}from"@duckdb/node-api";import{HTTPException as me}from"hono/http-exception";var Ht,Cu,Ts,ca,Ce,la,Wt,Kr,Ru,Su,Au,Nu,jr,Es=S(()=>{"use strict";h();ae();We();Ve();bs();Ht="database_name = current_database() AND schema_name = current_schema()",Cu=new Set([Fr.BIGINT,Fr.UBIGINT,Fr.HUGEINT,Fr.UHUGEINT]),Ts=n=>{let e=n.columnTypes(),t=n.columnNames().filter((a,o)=>Cu.has(e[o].typeId)),r=n.getRowObjectsJson();for(let a of r)for(let o of t){let s=a[o];typeof s=="string"&&Number.isSafeInteger(Number(s))&&(a[o]=Number(s))}return r},ca=n=>n==null?null:typeof n=="string"||typeof n=="number"||typeof n=="boolean"||typeof n=="bigint"?n:n instanceof Date?n.toISOString():JSON.stringify(n),Ce=async(n,e,t=[])=>Ts(await n.runAndReadAll(e,t.map(ca))),la=async(n,e,t=[])=>(await n.runAndReadAll(e,t.map(ca))).rowsChanged,Wt=async(n,e)=>{await n.run("BEGIN TRANSACTION");try{let t=await e();return await n.run("COMMIT"),t}catch(t){throw await n.run("ROLLBACK").catch(()=>{}),t}},Kr=n=>n.map(()=>"?").join(", "),Ru=n=>n.columns.map((e,t)=>`c.${I(e)} = p.${I(n.referencedColumns[t])}`).join(" AND "),Su=n=>n.flatMap(e=>[...(e.column_default??"").matchAll(/nextval\('([^']+)'\)/g)].map(t=>t[1])),Au=[["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."]],Nu=new Set(["CASCADE","SET NULL","SET DEFAULT"]),jr=class extends se{async runQuery(e,t,r){return ra(a=>Ce(a,t,r))}quoteIdentifier(e){return I(e)}mapToUniversalType(e){return ur(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=Au.find(([r])=>e.message.includes(r));if(t)return new me(400,{message:`${t[1]} (${e.message})`,cause:e})}return super.wrapError(e)}withConnection(e){return ra(e).catch(t=>{throw this.wrapError(t)})}async getTableData(e){let{tableName:t,limit:r=50,direction:a="asc",sort:o=[],order:s="asc",cursor:i,filters:l=[]}=e;return this.withConnection(async c=>{await this.requireColumns(c,t);let u=await this.primaryKey(c,t),m=this.orderTerms(o,s,u.length?u:["rowid"]),p=a==="desc",d=ps(l),f=i?this.decodeCursor(i):null,y=f?hs(m,f.values,p):null,g=ys(m,p),w=u.length?"*":"*, rowid",C=sa(y?[...d.conditions,y.clause]:d.conditions),[N]=await Ce(c,`SELECT COUNT(*) AS total FROM ${I(t)} ${sa(d.conditions)}`,d.values),A=await Ce(c,`SELECT ${w} FROM ${I(t)} ${C} ${g} LIMIT ?`,[...d.values,...y?.values??[],r+1]),E=A.length>r,R=A.slice(0,r);p&&R.reverse();let D=re=>this.encodeCursor({values:Object.fromEntries(m.map(V=>[V.column,re[V.column]])),sortColumns:m.map(V=>V.column)}),$=R[0],q=R.at(-1),P=p?!!i:E,U=p?E:!!i;return{data:R.map(re=>{if(u.length)return this.normalizeRow(re);let{rowid:V,...k}=re;return this.normalizeRow(k)}),meta:{limit:r,total:Number(N?.total??0),hasNextPage:P,hasPreviousPage:U,nextCursor:P&&q?D(q):null,prevCursor:U&&$?D($):null}}})}async getDatabasesList(){return this.withConnection(async e=>(await Ce(e,"SELECT database_name, path FROM duckdb_databases() WHERE database_name = current_database()")).map(r=>({name:r.database_name,size:this.getFileSize(r.path),owner:"",encoding:"UTF-8"})))}async getCurrentDatabase(){return this.withConnection(async e=>{let[t]=await Ce(e,"SELECT current_database() AS db");return{db:t.db}})}async getDatabaseConnectionInfo(){return this.withConnection(async e=>{let[t]=await Ce(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 r=await Ce(t,`SELECT table_name FROM duckdb_tables() WHERE ${Ht} AND NOT temporary ORDER BY table_name`),a=[];for(let{table_name:o}of r){let[s]=await Ce(t,`SELECT COUNT(*) AS count FROM ${I(o)}`);a.push({tableName:o,rowCount:Number(s?.count??0)})}return a})}async createTable({tableData:e}){let{tableName:t,fields:r,foreignKeys:a=[]}=e;for(let c of a){let u=[c.onUpdate,c.onDelete].find(m=>Nu.has(m));if(u)throw new me(400,{message:`DuckDB foreign keys do not support ${u} (on "${c.columnName}"). Use NO ACTION or RESTRICT.`})}let o=[],s=r.filter(c=>c.isPrimaryKey).map(c=>c.columnName),i=r.map(c=>{let u=`${I(c.columnName)} ${Br(c.columnType,c.isArray)}`;if(s.length===1&&c.isPrimaryKey&&(u+=" PRIMARY KEY"),c.isUnique&&!c.isPrimaryKey&&(u+=" UNIQUE"),!c.isNullable&&!c.isPrimaryKey&&(u+=" NOT NULL"),c.isIdentity||ia(c.columnType)){let m=`${t}_${c.columnName}_seq`;o.push(m),u+=` DEFAULT nextval('${m.replaceAll("'","''")}')`}else c.defaultValue?.trim()&&(u+=` DEFAULT ${c.defaultValue.trim()}`);return u});s.length>1&&i.push(`PRIMARY KEY (${s.map(I).join(", ")})`);let l=a.map(c=>`FOREIGN KEY (${I(c.columnName)}) REFERENCES ${I(c.referencedTable)} (${I(c.referencedColumn)}) ON UPDATE ${c.onUpdate} ON DELETE ${c.onDelete}`);await this.withConnection(c=>Wt(c,async()=>{for(let u of o)await c.run(`CREATE SEQUENCE ${I(u)}`);await c.run(`CREATE TABLE ${I(t)} (${[...i,...l].join(", ")})`)}))}async deleteTable({tableName:e,cascade:t}){return this.withConnection(async r=>{let a=await this.requireColumns(r,e),o=(await this.foreignKeys(r,"referenced_table",e)).filter(i=>i.table!==e);if(o.length){if(t)throw new me(400,{message:`DuckDB cannot drop "${e}" while ${[...new Set(o.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(r,o)}}let[s]=await Ce(r,`SELECT COUNT(*) AS count FROM ${I(e)}`);await r.run(`DROP TABLE ${I(e)}`);for(let i of Su(a))await r.run(`DROP SEQUENCE IF EXISTS ${I(i)}`).catch(()=>{});return{deletedCount:Number(s?.count??0),fkViolation:!1,relatedRecords:[]}})}async renameTable({tableName:e,newTableName:t}){this.assertDifferentTableName(e,t),await this.withConnection(async r=>{if(await this.requireColumns(r,e),(await this.columns(r,t)).length)throw new me(409,{message:`Table "${t}" already exists`});await r.run(`ALTER TABLE ${I(e)} RENAME TO ${I(t)}`)})}async getTableSchema({tableName:e}){return this.withConnection(async t=>{let[r]=await Ce(t,`SELECT sql FROM duckdb_tables() WHERE ${Ht} AND table_name = ?`,[e]);if(!r)throw new me(404,{message:`Table "${e}" does not exist`});return r.sql})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let r=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),o=new Map((await this.foreignKeys(t,"table_name",e)).flatMap(s=>s.columns.map((i,l)=>[i,{table:s.referencedTable,column:s.referencedColumns[l]}])));return r.map(s=>{let i=o.get(s.column_name),l=a.has(s.column_name);return{columnName:s.column_name,dataType:ur(s.data_type),dataTypeLabel:An(s.data_type),isNullable:s.is_nullable&&!l,columnDefault:s.column_default,isPrimaryKey:l,isForeignKey:!!i,referencedTable:i?.table??null,referencedColumn:i?.column??null,enumValues:s.data_type.startsWith("ENUM(")?[...s.data_type.matchAll(/'((?:[^']|'')*)'/g)].map(c=>c[1].replaceAll("''","'")):null}})})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isNullable:s,isUnique:i,isPrimaryKey:l}=e;if(i||l)throw new me(400,{message:`DuckDB cannot add a ${l?"PRIMARY KEY":"UNIQUE"} column to an existing table. Add the column without it, or recreate the table.`});let c=e.isIdentity||ia(a)?`${t}_${r}_seq`:null,u=`${I(r)} ${Br(a,e.isArray)}`;c?u+=` DEFAULT nextval('${c.replaceAll("'","''")}')`:o?.trim()&&(u+=` DEFAULT ${o.trim()}`),await this.withConnection(async m=>{if((await this.requireColumns(m,t)).some(d=>d.column_name===r))throw new me(409,{message:`Column "${r}" already exists in table "${t}"`});await Wt(m,async()=>{c&&await m.run(`CREATE SEQUENCE ${I(c)}`),await m.run(`ALTER TABLE ${I(t)} ADD COLUMN ${u}`),s||await m.run(`ALTER TABLE ${I(t)} ALTER COLUMN ${I(r)} SET NOT NULL`).catch(d=>{throw String(d).includes("NOT NULL constraint failed")?new me(400,{message:`Column "${r}" needs a default value to be NOT NULL, because "${t}" already has rows.`}):d})})})}async deleteColumn({tableName:e,columnName:t}){return await this.withConnection(async r=>{await this.requireColumn(r,e,t),await r.run(`ALTER TABLE ${I(e)} DROP COLUMN ${I(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s}=e,i=`ALTER TABLE ${I(t)} ALTER COLUMN ${I(r)}`;await this.withConnection(async l=>{await this.requireColumn(l,t,r),await Wt(l,async()=>{await l.run(`${i} TYPE ${Br(a,!1)}`),await l.run(`${i} ${o?"DROP":"SET"} NOT NULL`),await l.run(s?.trim()?`${i} SET DEFAULT ${s.trim()}`:`${i} DROP DEFAULT`)})})}async renameColumn({tableName:e,columnName:t,newColumnName:r}){await this.withConnection(async a=>{if((await this.requireColumn(a,e,t)).some(s=>s.column_name===r))throw new me(409,{message:`Column "${r}" already exists in table "${e}"`});await a.run(`ALTER TABLE ${I(e)} RENAME COLUMN ${I(t)} TO ${I(r)}`)})}async addRecord({params:e}){let{tableName:t,data:r}=e,a=Object.keys(r);if(!a.length)throw new me(400,{message:"No data provided for insert"});return{insertedCount:await this.withConnection(s=>la(s,`INSERT INTO ${I(t)} (${a.map(I).join(", ")}) VALUES (${Kr(a)})`,Object.values(r)))}}async updateRecords({params:e}){let{tableName:t}=e,r=this.resolveKeyColumns(e),a=this.groupUpdatesByKey(e,r);return{updatedCount:await this.withConnection(s=>Wt(s,async()=>{this.assertWholeKey(await this.primaryKey(s,t),r);let i=0;for(let{keyValues:l,rowUpdates:c}of a){let u=await la(s,`UPDATE ${I(t)} SET ${c.map(m=>`${I(m.columnName)} = ?`).join(", ")} WHERE ${r.map(m=>`${I(m)} = ?`).join(" AND ")}`,[...c.map(m=>m.value),...l]);if(u===0)throw new me(404,{message:`Record with ${this.describeKey(r,l)} not found in table "${t}"`});i+=u}return i}))}}async deleteRecords({tableName:e,primaryKeys:t}){let r=t[0]?.columnName;if(!r)throw new me(400,{message:"Primary key column name is required"});let a=t.map(o=>o.value);return this.withConnection(async o=>{this.assertDeletableKey(await this.primaryKey(o,e));try{return{deletedCount:await la(o,`DELETE FROM ${I(e)} WHERE ${I(r)} IN (${Kr(a)})`,a),fkViolation:!1,relatedRecords:[]}}catch(s){if(!(s instanceof Error)||!s.message.includes("Violates foreign key constraint"))throw s;let i=[];for(let l of await this.foreignKeys(o,"referenced_table",e)){let c=await Ce(o,`SELECT c.* FROM ${I(l.table)} c JOIN ${I(e)} p ON ${Ru(l)} WHERE p.${I(r)} IN (${Kr(a)}) LIMIT 100`,a);c.length&&i.push({tableName:l.table,columnName:l.columns.join(", "),constraintName:l.constraintName,records:c})}return{deletedCount:0,fkViolation:!0,relatedRecords:i}}})}async forceDeleteRecords(e){let t=await this.deleteRecords(e);if(t.fkViolation)throw new me(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 me(400,{message:"At least one record is required"});let r=Object.keys(t[0]),a=await this.withConnection(o=>Wt(o,async()=>{let s=await o.prepare(`INSERT INTO ${I(e)} (${r.map(I).join(", ")}) VALUES (${Kr(r)})`);for(let i of t)s.bind(r.map(l=>ca(i[l]))),await s.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 me(400,{message:"Query is required"});return this.withConnection(async t=>{let r=performance.now(),a=await t.extractStatements(e);if(a.count!==1)throw new me(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let o=await a.prepare(0);try{if(o.statementType===wu.TRANSACTION)throw new me(400,{message:"Transactions cannot span query-runner requests. BEGIN, COMMIT, and ROLLBACK are not supported."});let s=await o.runAndReadAll(),i=performance.now()-r;if(s.returnType===gs.CHANGED_ROWS)return{columns:[],rows:[],rowCount:s.rowsChanged,duration:i,message:`OK (${s.rowsChanged} rows affected)`};if(s.returnType===gs.NOTHING)return{columns:[],rows:[],rowCount:0,duration:i,message:"OK"};let l=Ts(s);return{columns:s.columnNames(),rows:l,rowCount:l.length,duration:i,message:l.length===0?"OK":void 0}}finally{o.destroySync()}})}getFileSize(e){if(!e)return"in-memory";try{let t=Eu(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 Ce(e,`SELECT column_name, data_type, is_nullable, column_default FROM duckdb_columns() WHERE ${Ht} AND table_name = ? ORDER BY column_index`,[t])}async requireColumns(e,t){let r=await this.columns(e,t);if(!r.length)throw new me(404,{message:`Table "${t}" does not exist`});return r}async requireColumn(e,t,r){let a=await this.requireColumns(e,t);if(!a.some(o=>o.column_name===r))throw new me(404,{message:`Column "${r}" does not exist in table "${t}"`});return a}async primaryKey(e,t){let[r]=await Ce(e,`SELECT constraint_column_names AS columns FROM duckdb_constraints() WHERE ${Ht} AND table_name = ? AND constraint_type = 'PRIMARY KEY'`,[t]);return r?.columns??[]}async foreignKeys(e,t,r){return Ce(e,`SELECT constraint_name AS "constraintName", table_name AS "table", constraint_column_names AS "columns", referenced_table AS "referencedTable", referenced_column_names AS "referencedColumns" FROM duckdb_constraints() WHERE ${Ht} AND constraint_type = 'FOREIGN KEY' AND ${t} = ?`,[r])}async sampleReferencingRows(e,t){let r=[];for(let a of t){let o=await Ce(e,`SELECT * FROM ${I(a.table)} WHERE ${a.columns.map(s=>`${I(s)} IS NOT NULL`).join(" AND ")} LIMIT 100`);o.length&&r.push({tableName:a.table,columnName:a.columns.join(", "),constraintName:a.constraintName,records:o})}return r}}});var Du,ws,Cs=S(()=>{"use strict";h();Du=new Set(["admin","config","local"]),ws=(n,e)=>{let t=n.filter(r=>!Du.has(r.name)||r.name===e);return!e||t.some(r=>r.name===e)?t:[...t,{name:e,sizeOnDisk:0}]}});function Rs(n){if(!n||n.length===0)return{};let e=[];for(let t of n){let r=t.columnName,a=_u(t.value),o=t.operator.toLowerCase();if(r)switch(o){case"=":e.push({[r]:a});break;case"!=":e.push({[r]:{$ne:a}});break;case">":e.push({[r]:{$gt:a}});break;case">=":e.push({[r]:{$gte:a}});break;case"<":e.push({[r]:{$lt:a}});break;case"<=":e.push({[r]:{$lte:a}});break;case"is":e.push({[r]:a});break;case"is not":e.push({[r]:{$ne:a}});break;case"like":e.push({[r]:{$regex:Hr(String(a)),$options:""}});break;case"not like":e.push({[r]:{$not:{$regex:Hr(String(a)),$options:""}}});break;case"ilike":e.push({[r]:{$regex:Hr(String(a)),$options:"i"}});break;case"not ilike":e.push({[r]:{$not:{$regex:Hr(String(a)),$options:"i"}}});break;default:e.push({[r]:a});break}}return e.length?{$and:e}:{}}function ua(n,e){return n?Array.isArray(n)?n.length===0?{_id:1}:Object.fromEntries(n.map(t=>[t.columnName,t.direction==="desc"?-1:1])):typeof n=="string"&&n.length>0?{[n]:e==="desc"?-1:1}:{_id:1}:{_id:1}}function ma(n){return Buffer.from(JSON.stringify({offset:n})).toString("base64url")}function Ss(n){if(!n)return 0;try{let e=JSON.parse(Buffer.from(n,"base64url").toString("utf-8"));return typeof e.offset=="number"?e.offset:0}catch{return 0}}var Hr,_u,As=S(()=>{"use strict";h();ut();Hr=n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),_u=n=>{let e=n.trim();if(e==="null")return null;if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return!Number.isNaN(t)&&e!==""?t:Mr(e)?kr(e):e}});import{HTTPException as j}from"hono/http-exception";var da,_t,Ou,$u,Ns,Vt,Pu,Ds,Iu,Lu,Mu,Ot,Wr,_s=S(()=>{"use strict";h();We();Ve();ut();Ze();Cs();je();As();da=n=>n instanceof Date?n.toISOString():typeof n=="bigint"?n.toString():n&&typeof n=="object"?"_bsontype"in n&&n._bsontype==="ObjectId"?n.toHexString():Array.isArray(n)?n.map(e=>da(e)):Object.fromEntries(Object.entries(n).map(([e,t])=>[e,da(t)])):n,_t=n=>da(n),Ou=n=>n instanceof Date?"date":n&&typeof n=="object"?Array.isArray(n)?"array":"_bsontype"in n?"text":"json":typeof n=="boolean"?"boolean":typeof n=="number"||typeof n=="bigint"?"number":"text",$u=n=>{switch(n){case"number":return"numeric";case"boolean":return"boolean";case"json":return"json";case"date":return"date";case"array":return"array";case"enum":return"enum";default:return"text"}},Ns=n=>typeof n=="string"&&Mr(n),Vt=n=>kr(n),Pu=n=>{if(!Number.isFinite(n))return"n/a";let e=["B","KB","MB","GB","TB"],t=n,r=0;for(;t>=1024&&r<e.length-1;)t/=1024,r++;return`${t.toFixed(1)} ${e[r]}`},Ds=new Set(["double","string","object","array","binData","undefined","objectId","bool","date","null","regex","dbPointer","javascript","symbol","javascriptWithScope","int","timestamp","long","decimal","minKey","maxKey"]),Iu=n=>{let e=n.trim();if(Ds.has(e))return e;switch(e.toLowerCase()){case"boolean":return"bool";case"objectid":return"objectId";case"binary":return"binData";default:return e}},Lu=n=>{if(n==null)return"null";if(n instanceof Date)return"date";if(typeof n=="boolean")return"bool";if(typeof n=="number")return Number.isInteger(n)?"int":"double";if(typeof n=="bigint")return"long";if(Array.isArray(n))return"array";if(typeof n=="object"){let e=n._bsontype;return e==="ObjectId"?"objectId":e==="Decimal128"?"decimal":e==="Binary"?"binData":e==="Timestamp"?"timestamp":e?e.toLowerCase():"object"}return"string"},Mu=(n,e)=>{if(n!=null&&n.trim()!=="")try{return JSON.parse(n)}catch{return n}switch(e){case"string":return"";case"int":case"long":case"double":case"decimal":return 0;case"bool":return!1;case"array":return[];case"object":return{};case"date":return new Date;default:return null}},Ot=n=>{if(n._id&&typeof n._id=="string")return{...n,_id:Vt(n._id)};if(n._id&&typeof n._id=="object"){let e=n._id;if(Array.isArray(e.$in))return{...n,_id:{...e,$in:e.$in.map(t=>typeof t=="string"?Vt(t):t)}};if(Array.isArray(e.$nin))return{...n,_id:{...e,$nin:e.$nin.map(t=>typeof t=="string"?Vt(t):t)}}}return n},Wr=class extends se{runQuery(){throw new j(501,{message:"runQuery is not supported for MongoDB"})}buildTableDataQuery(e){throw new j(501,{message:"buildTableDataQuery is not supported for MongoDB"})}normalizeRows(e){return e.map(t=>this.normalizeRow(_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 j)return e;if(e instanceof Error){let t=e.name??"";if(t==="MongoNetworkError"||t==="MongoServerSelectionError"||t==="MongoTopologyClosedError")return new j(503,{message:e.message,cause:e})}return super.wrapError(e)}async getTableData(e){try{let{tableName:t,db:r,cursor:a,limit:o,direction:s="asc",sort:i,order:l,filters:c}=e,m=(await he(r)).collection(t),p=Rs(c??[]),d=ua(i??"",l),f=o&&o>0?o:50,y=Ss(a),g=Number.isFinite(y)&&y>=0?y:0,w=s==="desc"?Math.max(g-f,0):g,[C,N]=await Promise.all([m.countDocuments(p),m.find(p).sort(d).skip(w).limit(f).toArray()]),A=N.map(D=>_t(D)),E=w+f,R=Math.max(w-f,0);return{data:A,meta:{limit:f,total:C,hasNextPage:E<C,hasPreviousPage:w>0,nextCursor:E<C?ma(E):null,prevCursor:w>0?ma(R):null}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let s=(await(await he(t)).collection(e).find({}).limit(1e4).toArray()).map(l=>_t(l));return{cols:Array.from(new Set(s.flatMap(l=>Object.keys(l)))),rows:s}}catch(r){throw this.wrapError(r)}}async getDatabasesList(){try{let a=(await(await aa()).db().admin().listDatabases()).databases??[];if(!a[0])throw new j(500,{message:"No databases returned from MongoDB"});return ws(a,xr()).map(o=>({name:o.name,size:Pu(o.sizeOnDisk??0),owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:xr()}}async getDatabaseConnectionInfo(){try{let t=(await aa()).db().admin(),r=Ae(),a={};try{a=await t.serverStatus()}catch(o){Q("warn","db_server_status_failed",le(o))}return{host:r.host,port:r.port,user:"n/a",database:xr(),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 he(e),r=await t.listCollections().toArray(),a=[];for(let o of r){let s=await t.collection(o.name).estimatedDocumentCount();a.push({tableName:o.name,rowCount:s})}return a}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){try{let r=e?.tableName??"",a=await he(t);if((await a.listCollections({name:r}).toArray()).length>0)throw new j(400,{message:`Collection "${r}" already exists`});let s=e?.fields??[];if(s.length===0){await a.createCollection(r);return}let i={},l=[];for(let c of s){let u=Iu(c.columnType);if(!Ds.has(u))throw new j(400,{message:`Unsupported MongoDB BSON type "${c.columnType}" for field "${c.columnName}"`});c.isArray?i[c.columnName]={bsonType:"array",...u!=="array"?{items:{bsonType:u}}:{}}:i[c.columnName]={bsonType:u},c.isNullable||l.push(c.columnName)}await a.createCollection(r,{validator:{$jsonSchema:{bsonType:"object",required:l,properties:i,additionalProperties:!0}},validationAction:"error"})}catch(r){throw this.wrapError(r)}}async deleteTable({tableName:e,db:t}){try{let a=(await he(t)).collection(e),o=await a.estimatedDocumentCount();return await a.drop(),{deletedCount:o,fkViolation:!1,relatedRecords:[]}}catch(r){throw this.wrapError(r)}}async renameTable(e){try{let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=await he(a);if((await o.listCollections({name:t}).toArray()).length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if((await o.listCollections({name:r}).toArray()).length>0)throw new j(409,{message:`Collection "${r}" already exists`});await o.collection(t).rename(r)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){try{let r=await he(t);if((await r.listCollections({name:e}).toArray()).length===0)throw new j(404,{message:`Collection "${e}" does not exist`});let o=r.collection(e),s=await o.find({}).limit(200).toArray(),i=await o.estimatedDocumentCount(),l=new Map,c=new Map;for(let d of s)for(let[f,y]of Object.entries(d)){let g=Lu(y);l.has(f)||(l.set(f,new Set),c.set(f,0)),l.get(f)?.add(g),c.set(f,(c.get(f)??0)+1)}let u={},m=[];for(let[d,f]of l.entries()){let y=c.get(d)??0,g=Array.from(f).filter(C=>C!=="null"),w=f.has("null")||y<s.length;y===s.length&&s.length>0&&!w&&m.push(d),u[d]=g.length===1?{bsonType:w?[g[0],"null"]:g[0]}:{bsonType:w?[...g,"null"]:g}}let p={collection:e,estimatedDocumentCount:i,sampledDocuments:s.length,jsonSchema:{bsonType:"object",required:m.length>0?m:void 0,properties:u}};return JSON.stringify(p,null,2)}catch(r){throw this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let o=await(await he(t)).collection(e).find({}).limit(200).toArray(),s=o.length,i=new Map,l=(c,u)=>{let m=Ou(u);if(!i.has(c))i.set(c,{types:new Set([m]),nullable:!1,presentCount:1});else{let p=i.get(c);p.types.add(m),p.presentCount+=1}};for(let c of o)for(let[u,m]of Object.entries(c)){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}l(u,m)}if(s>0)for(let c of i.values())c.presentCount<s&&(c.nullable=!0);return i.has("_id")||i.set("_id",{types:new Set(["text"]),nullable:!1,presentCount:s}),Array.from(i.entries()).map(([c,u])=>{let m=u.types.values().next().value??"text";return{columnName:c,dataType:m,dataTypeLabel:$u(m),isNullable:u.nullable,columnDefault:null,isPrimaryKey:c==="_id",isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}})}catch(r){throw this.wrapError(r)}}async addColumn(e){try{let{tableName:t,columnName:r,columnType:a,defaultValue:o,isNullable:s,db:i}=e,l=await he(i),c=await l.listCollections({name:t}).toArray();if(c.length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(await l.collection(t).findOne({[r]:{$exists:!0}}))throw new j(409,{message:`Field "${r}" already exists in collection "${t}"`});let m=Mu(o,a);await l.collection(t).updateMany({},{$set:{[r]:m}});let d=c[0].options?.validator?.$jsonSchema??{},f={...d.properties??{},[r]:{bsonType:s?[a,"null"]:a}},y=[...d.required??[]];!s&&!y.includes(r)&&y.push(r),await l.command({collMod:t,validator:{$jsonSchema:{...d,bsonType:"object",properties:f,...y.length>0?{required:y}:{}}},validationAction:"warn"})}catch(t){throw this.wrapError(t)}}async deleteColumn({tableName:e,columnName:t,db:r}){try{return{deletedCount:(await(await he(r)).collection(e).updateMany({},{$unset:{[t]:""}})).modifiedCount}}catch(a){throw this.wrapError(a)}}async alterColumn(e){try{let{tableName:t,columnName:r,columnType:a,isNullable:o,db:s}=e,i=await he(s),l=await i.listCollections({name:t}).toArray();if(l.length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new j(400,{message:'Cannot alter the "_id" field'});let u=l[0].options?.validator?.$jsonSchema??{},m={...u.properties??{}},p=[...u.required??[]];m[r]={bsonType:o?[a,"null"]:a};let d=p.indexOf(r);!o&&d===-1?p.push(r):o&&d!==-1&&p.splice(d,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:r,newColumnName:a,db:o}=e,s=await he(o);if((await s.listCollections({name:t}).toArray()).length===0)throw new j(404,{message:`Collection "${t}" does not exist`});if(r==="_id")throw new j(400,{message:'Cannot rename the "_id" field'});if(!await s.collection(t).findOne({[r]:{$exists:!0}}))throw new j(404,{message:`Field "${r}" does not exist in collection "${t}"`});if(await s.collection(t).findOne({[a]:{$exists:!0}}))throw new j(409,{message:`Field "${a}" already exists in collection "${t}"`});await s.collection(t).updateMany({[r]:{$exists:!0}},{$rename:{[r]:a}})}catch(t){throw this.wrapError(t)}}async addRecord({db:e,params:t}){try{let{tableName:r,data:a}=t,s=(await he(e)).collection(r),i=_t(a);if((i._id===""||i._id===null)&&delete i._id,!(await s.insertOne(i)).insertedId)throw new j(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r}=t,o=(await he(e)).collection(r),s=0,i=this.resolveKeyColumns(t).map(c=>c||"_id"),l=this.groupUpdatesByKey({...t,primaryKeys:i},i);for(let{keyValues:c,rowUpdates:u}of l){if(u.some(f=>f.columnName==="_id"))throw new j(400,{message:'The "_id" field is immutable and cannot be updated.'});let m={};for(let f of u)m[f.columnName]=f.value;let p={};i.forEach((f,y)=>{let g=c[y];p[f]=f==="_id"&&Ns(g)?Vt(g):g});let d=await o.updateOne(p,{$set:m});if(d.matchedCount===0)throw new j(404,{message:`Record with ${this.describeKey(i,c)} not found in "${r}"`});s+=d.modifiedCount}return{updatedCount:s}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:a}=e,s=(await he(a)).collection(t),i=r[0]?.columnName??"_id",l=r.map(u=>i==="_id"&&Ns(u.value)?Vt(u.value):u.value);return{deletedCount:(await s.deleteMany({[i]:{$in:l}})).deletedCount??0,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:r,db:a}=e;if(!r||r.length===0)throw new j(400,{message:"At least one record is required"});let s=(await he(a)).collection(t),i=r.map(c=>{let u=_t(c);return(u._id===""||u._id===null)&&delete u._id,u}),l=await s.insertMany(i,{ordered:!1});return{success:!0,message:`Successfully inserted ${l.insertedCount} record${l.insertedCount!==1?"s":""}`,successCount:l.insertedCount,failureCount:r.length-l.insertedCount}}catch(t){throw this.wrapError(t)}}async executeQuery({query:e,db:t}){try{if(!e?.trim())throw new j(400,{message:"Query is required"});let r;try{r=JSON.parse(e)}catch{throw new j(400,{message:"Mongo query must be valid JSON"})}if(!r.collection||!r.operation)throw new j(400,{message:"Mongo query must include collection and operation"});let o=(await he(t)).collection(r.collection),s=performance.now(),i=[],l=0,c;switch(r.operation){case"find":{let d=Ot(r.filter??{}),f=o.find(d,r.options??{});f.sort(r.sort??ua("",void 0)),r.skip&&f.skip(r.skip),r.limit&&f.limit(r.limit),i=await f.toArray(),l=i.length;break}case"aggregate":{i=await o.aggregate(r.pipeline??[],r.options??{}).toArray(),l=i.length;break}case"insertOne":{let d=r.document;if(!d)throw new j(400,{message:"document is required"});l=(await o.insertOne(d)).insertedId?1:0,c="OK";break}case"insertMany":{let d=r.document;if(!Array.isArray(d))throw new j(400,{message:"document array is required"});l=(await o.insertMany(d)).insertedCount??0,c="OK";break}case"updateOne":{let d=Ot(r.filter??{});if(!r.update)throw new j(400,{message:"update is required"});let f=await o.updateOne(d,r.update,r.options??{});l=f.matchedCount??0,c=`OK (${f.modifiedCount??0} modified)`;break}case"updateMany":{let d=Ot(r.filter??{});if(!r.update)throw new j(400,{message:"update is required"});let f=await o.updateMany(d,r.update,r.options??{});l=f.matchedCount??0,c=`OK (${f.modifiedCount??0} modified)`;break}case"deleteOne":{let d=Ot(r.filter??{});l=(await o.deleteOne(d,r.options??{})).deletedCount??0,c="OK";break}case"deleteMany":{let d=Ot(r.filter??{});l=(await o.deleteMany(d,r.options??{})).deletedCount??0,c="OK";break}case"count":{let d=Ot(r.filter??{});l=await o.countDocuments(d),i=[{count:l}],c="OK";break}default:throw new j(400,{message:"Unsupported Mongo operation"})}let u=performance.now()-s,m=i.map(d=>_t(d));return{columns:m[0]?Object.keys(m[0]):[],rows:m,rowCount:l,duration:u,message:c}}catch(r){throw this.wrapError(r)}}}});function pa(n,e=0){if(n.length===0)return{clause:"",values:[],nextIdx:e};let t=[],r=[],a=e;for(let o of n){let s=`[${o.columnName}]`;switch(o.operator){case"=":case"!=":case">":case">=":case"<":case"<=":t.push(`${s} ${o.operator} @p${a}`),r.push(o.value),a++;break;case"is":o.value.toLowerCase()==="null"?t.push(`${s} IS NULL`):(t.push(`${s} = @p${a}`),r.push(o.value),a++);break;case"is not":o.value.toLowerCase()==="null"?t.push(`${s} IS NOT NULL`):(t.push(`${s} != @p${a}`),r.push(o.value),a++);break;case"like":case"ilike":t.push(`${s} LIKE @p${a}`),r.push(o.value),a++;break;case"not like":case"not ilike":t.push(`${s} NOT LIKE @p${a}`),r.push(o.value),a++;break;default:break}}return t.length===0?{clause:"",values:[],nextIdx:e}:{clause:`WHERE ${t.join(" AND ")}`,values:r,nextIdx:a}}function fa(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(t=>`[${t.columnName}] ${t.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY [${n}] ${e?.toUpperCase()||"ASC"}`:""}function Os(n,e,t){let r=fa(n,e),a=Array.isArray(n)?n.map(i=>i.columnName):[n],o=(Array.isArray(n)?n[0]?.direction??e:e).toUpperCase(),s=t.filter(i=>!a.includes(i)).map(i=>`[${i}] ${o}`).join(", ");return s?r?`${r}, ${s}`:`ORDER BY ${s}`:r||"ORDER BY (SELECT NULL)"}function ya(n,e){if(e)return"NVARCHAR(MAX)";let t=n.toLowerCase().trim();return{serial:"INT IDENTITY(1,1)",serial4:"INT IDENTITY(1,1)",bigserial:"BIGINT IDENTITY(1,1)",serial8:"BIGINT IDENTITY(1,1)",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",tinyint:"TINYINT",numeric:"NUMERIC",decimal:"DECIMAL",real:"REAL",float4:"REAL",float:"FLOAT","double precision":"FLOAT",float8:"FLOAT",money:"MONEY",boolean:"BIT",bool:"BIT",text:"NVARCHAR(MAX)",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"UNIQUEIDENTIFIER",json:"NVARCHAR(MAX)",jsonb:"NVARCHAR(MAX)",xml:"XML",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME2","timestamp without time zone":"DATETIME2","timestamp with time zone":"DATETIMEOFFSET",timestamptz:"DATETIMEOFFSET",interval:"VARCHAR(255)",bytea:"VARBINARY(MAX)",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)"}[t]||n.toUpperCase()}function ha(n,e){let t=n.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("newid()")?e.toUpperCase().includes("UNIQUEIDENTIFIER")?"NEWID()":null:t.includes("getdate")||t.includes("current_timestamp")?"GETDATE()":n.trim():t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":n.trim()}function $s(n,e={}){let t=ya(n.columnType,n.isArray??!1),r=`[${n.columnName}] ${t}`;if(n.isIdentity&&!t.includes("IDENTITY")&&(r+=" IDENTITY(1,1)"),!n.isNullable&&!n.isPrimaryKey&&(r+=" NOT NULL"),n.defaultValue?.trim()&&!t.includes("IDENTITY")){let a=ha(n.defaultValue,t);a!==null&&(r+=` DEFAULT ${a}`)}return e.includeUnique&&n.isUnique&&!n.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&n.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var Ps=S(()=>{"use strict";h()});import{HTTPException as Y}from"hono/http-exception";var ku,xu,Vr,Is=S(()=>{"use strict";h();ae();We();Ve();je();Ps();ku=547,xu=3726,Vr=class extends se{async runQuery(e,t,r){let o=(await J(e)).request();return r.forEach((i,l)=>{o.input(`p${l}`,i)}),(await o.query(t)).recordset}quoteIdentifier(e){return`[${e}]`}mapToUniversalType(e){return lr(e)}mapFromUniversalType(e){return{text:"NVARCHAR(MAX)",number:"INT",boolean:"BIT",json:"NVARCHAR(MAX)",date:"DATETIME2",array:"NVARCHAR(MAX)",enum:"NVARCHAR(255)"}[e]??"NVARCHAR(MAX)"}buildTableDataQuery(e){let{tableName:t,filters:r=[],sort:a=[],order:o="asc",limit:s=50,cursor:i}=e,{clause:l,values:c,nextIdx:u}=pa(r,0),m=fa(a,o)||"ORDER BY (SELECT NULL)",p=i?this.decodeOffsetCursor(i):0,d=`SELECT * FROM [${t}] ${l} ${m} OFFSET @p${u} ROWS FETCH NEXT @p${u+1} ROWS ONLY`,f=[...c,p,s+1],y=`SELECT COUNT(*) as total FROM [${t}] ${l}`;return{sql:d,values:f,countSql:y,countValues:c}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){let{cursor:a,limit:o=50}=e,s=a?this.decodeOffsetCursor(a):0;return{nextCursor:r?this.makeCursor(s+o):null,prevCursor:s>0?this.makeCursor(Math.max(0,s-o)):null}}async getTableData(e){try{let{tableName:t,db:r,limit:a=50,sort:o=[],order:s="asc",cursor:i,filters:l=[]}=e,c=await J(r),u=await this.getPrimaryKeyColumns(c,t),m=i?this.decodeOffsetCursor(i):0,{clause:p,values:d,nextIdx:f}=pa(l,0),y=Os(o,s,u),g=c.request();d.forEach((D,$)=>{g.input(`p${$}`,D)});let w=await g.query(`SELECT COUNT(*) as total FROM [${t}] ${p}`),C=Number(w.recordset[0]?.total??0),N=c.request();d.forEach((D,$)=>{N.input(`p${$}`,D)}),N.input(`p${f}`,m),N.input(`p${f+1}`,a+1);let E=(await N.query(`SELECT * FROM [${t}] ${p} ${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 J()).request().query(`
34
34
  SELECT
35
35
  d.name AS name,
36
36
  CAST(ROUND(CAST(SUM(mf.size) * 8.0 / 1024 AS DECIMAL(10,2)), 2) AS VARCHAR(20)) + ' MB' AS size,
@@ -41,7 +41,7 @@ var Ji=Object.defineProperty;var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var Xt=(n,e)=>{f
41
41
  WHERE (d.database_id > 4 OR d.name = DB_NAME())
42
42
  GROUP BY d.name, d.owner_sid, d.collation_name
43
43
  ORDER BY d.name
44
- `);if(!t.recordset[0])throw new Y(500,{message:"No databases returned from server"});return t.recordset}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let t=await(await Q()).request().query("SELECT DB_NAME() AS db");if(!t.recordset[0])throw new Y(500,{message:"No current database returned from server"});return t.recordset[0]}async getDatabaseConnectionInfo(){let t=await(await Q()).request().query(`
44
+ `);if(!t.recordset[0])throw new Y(500,{message:"No databases returned from server"});return t.recordset}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let t=await(await J()).request().query("SELECT DB_NAME() AS db");if(!t.recordset[0])throw new Y(500,{message:"No current database returned from server"});return t.recordset[0]}async getDatabaseConnectionInfo(){let t=await(await J()).request().query(`
45
45
  SELECT
46
46
  @@VERSION AS version,
47
47
  DB_NAME() AS database_name,
@@ -50,23 +50,23 @@ var Ji=Object.defineProperty;var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var Xt=(n,e)=>{f
50
50
  (SELECT local_tcp_port FROM sys.dm_exec_connections WHERE session_id = @@SPID) AS port,
51
51
  @@MAX_CONNECTIONS AS max_connections,
52
52
  (SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1) AS active_connections
53
- `);if(!t.recordset[0])throw new Y(500,{message:"No connection information returned from server"});let r=t.recordset[0],a=Re();return{host:String(r.host||a.host),port:Number(r.port||a.port),user:String(r.user),database:String(r.database_name??""),version:String(r.version),active_connections:Number(r.active_connections??0),max_connections:Number(r.max_connections)}}async getTablesList(e){let t=await Q(e),r=await t.request().query(`
53
+ `);if(!t.recordset[0])throw new Y(500,{message:"No connection information returned from server"});let r=t.recordset[0],a=Ae();return{host:String(r.host||a.host),port:Number(r.port||a.port),user:String(r.user),database:String(r.database_name??""),version:String(r.version),active_connections:Number(r.active_connections??0),max_connections:Number(r.max_connections)}}async getTablesList(e){let t=await J(e),r=await t.request().query(`
54
54
  SELECT table_name AS tableName
55
55
  FROM information_schema.tables
56
56
  WHERE table_catalog = DB_NAME()
57
57
  AND table_type = 'BASE TABLE'
58
58
  AND table_schema = 'dbo'
59
59
  ORDER BY table_name
60
- `);return!r.recordset||r.recordset.length===0?[]:Promise.all(r.recordset.map(async a=>{let o=await t.request().query(`SELECT COUNT(*) as count FROM [${a.tableName}]`);return{tableName:a.tableName,rowCount:o.recordset[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=await Q(t),i=a.map(m=>{let p=ua(m.columnType,m.isArray??!1),d=`[${m.columnName}] ${p}`;if(!m.isNullable&&!m.isPrimaryKey&&(d+=" NOT NULL"),m.defaultValue&&!p.includes("IDENTITY")){let f=ma(m.defaultValue,p);f!==null&&(d+=` DEFAULT ${f}`)}return d}),l=[],c=a.filter(m=>m.isPrimaryKey);c.length>0&&l.push(`PRIMARY KEY (${c.map(m=>`[${m.columnName}]`).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&l.push(`UNIQUE ([${m.columnName}])`);let u=o?.map(m=>`CONSTRAINT [${`FK_${r}_${m.columnName}`}] FOREIGN KEY ([${m.columnName}]) REFERENCES [${m.referencedTable}] ([${m.referencedColumn}]) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await s.request().query(`CREATE TABLE [${r}] (
60
+ `);return!r.recordset||r.recordset.length===0?[]:Promise.all(r.recordset.map(async a=>{let o=await t.request().query(`SELECT COUNT(*) as count FROM [${a.tableName}]`);return{tableName:a.tableName,rowCount:o.recordset[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=await J(t),i=a.map(m=>{let p=ya(m.columnType,m.isArray??!1),d=`[${m.columnName}] ${p}`;if(!m.isNullable&&!m.isPrimaryKey&&(d+=" NOT NULL"),m.defaultValue&&!p.includes("IDENTITY")){let f=ha(m.defaultValue,p);f!==null&&(d+=` DEFAULT ${f}`)}return d}),l=[],c=a.filter(m=>m.isPrimaryKey);c.length>0&&l.push(`PRIMARY KEY (${c.map(m=>`[${m.columnName}]`).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&l.push(`UNIQUE ([${m.columnName}])`);let u=o?.map(m=>`CONSTRAINT [${`FK_${r}_${m.columnName}`}] FOREIGN KEY ([${m.columnName}]) REFERENCES [${m.referencedTable}] ([${m.referencedColumn}]) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await s.request().query(`CREATE TABLE [${r}] (
61
61
  ${[...i,...l,...u].join(`,
62
62
  `)}
63
- )`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=await Q(r),s=await o.request().input("tableName",t).query(`
63
+ )`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=await J(r),s=await o.request().input("tableName",t).query(`
64
64
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
65
65
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
66
- `);if(Number(s.recordset[0]?.cnt??0)===0)throw new Y(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(t,r);if(!a){let l=await this.getRelatedRecordsForTable(t,r);if(l.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:l}}try{if(a){let l=await this.getForeignKeyReferences(t,r);for(let c of l)await o.request().query(`ALTER TABLE [${c.referencingTable}] DROP CONSTRAINT [${c.constraintName}]`)}return await o.request().query(`DROP TABLE [${t}]`),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(l){if(l.number===Ru)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw l instanceof Y?l:new Y(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=await Q(a);await this.assertTableExists(o,t);let s=await o.request().input("tableName",r).query(`
66
+ `);if(Number(s.recordset[0]?.cnt??0)===0)throw new Y(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(t,r);if(!a){let l=await this.getRelatedRecordsForTable(t,r);if(l.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:l}}try{if(a){let l=await this.getForeignKeyReferences(t,r);for(let c of l)await o.request().query(`ALTER TABLE [${c.referencingTable}] DROP CONSTRAINT [${c.constraintName}]`)}return await o.request().query(`DROP TABLE [${t}]`),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(l){if(l.number===xu)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw l instanceof Y?l:new Y(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=await J(a);await this.assertTableExists(o,t);let s=await o.request().input("tableName",r).query(`
67
67
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
68
68
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
69
- `);if(Number(s.recordset[0]?.cnt??0)>0)throw new Y(409,{message:`Table "${r}" already exists`});await o.request().input("oldName",t).input("newName",r).query("EXEC sp_rename @oldName, @newName")}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=await Q(t),a=await r.request().input("tableName",e).query(`
69
+ `);if(Number(s.recordset[0]?.cnt??0)>0)throw new Y(409,{message:`Table "${r}" already exists`});await o.request().input("oldName",t).input("newName",r).query("EXEC sp_rename @oldName, @newName")}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=await J(t),a=await r.request().input("tableName",e).query(`
70
70
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.TABLES
71
71
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo'
72
72
  `);if(Number(a.recordset[0]?.cnt??0)===0)throw new Y(404,{message:`Table "${e}" does not exist`});let o=await r.request().input("tableName",e).query(`
@@ -108,7 +108,7 @@ var Ji=Object.defineProperty;var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var Xt=(n,e)=>{f
108
108
  `);if(!o.recordset||o.recordset.length===0)throw new Y(500,{message:`Failed to retrieve schema for table "${e}"`});let s=o.recordset.map(i=>{let l=` [${i.COLUMN_NAME}] ${i.DATA_TYPE}`;return i.CHARACTER_MAXIMUM_LENGTH?l+=i.CHARACTER_MAXIMUM_LENGTH===-1?"(MAX)":`(${i.CHARACTER_MAXIMUM_LENGTH})`:i.NUMERIC_PRECISION!==null&&i.NUMERIC_SCALE!==null?l+=`(${i.NUMERIC_PRECISION},${i.NUMERIC_SCALE})`:i.NUMERIC_PRECISION!==null&&(l+=`(${i.NUMERIC_PRECISION})`),l+=i.IS_NULLABLE==="YES"?" NULL":" NOT NULL",i.COLUMN_DEFAULT&&(l+=` DEFAULT ${i.COLUMN_DEFAULT}`),l});return`CREATE TABLE [${e}] (
109
109
  ${s.join(`,
110
110
  `)}
111
- )`}async getTableColumns({tableName:e,db:t}){let r=await Q(t),a=await r.request().input("tableName",e).query(`
111
+ )`}async getTableColumns({tableName:e,db:t}){let r=await J(t),a=await r.request().input("tableName",e).query(`
112
112
  SELECT
113
113
  c.COLUMN_NAME AS columnName,
114
114
  c.DATA_TYPE AS dataType,
@@ -152,19 +152,19 @@ ${s.join(`,
152
152
  JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cc
153
153
  ON chk.CONSTRAINT_NAME = cc.CONSTRAINT_NAME AND cc.TABLE_SCHEMA = 'dbo'
154
154
  WHERE cc.TABLE_NAME = @tableName AND cc.TABLE_CATALOG = DB_NAME()
155
- `),s=new Map;for(let i of o.recordset){let l=this.parseCheckConstraintValues(i.checkClause);l&&s.set(i.columnName,l)}return a.recordset.map(i=>{let l=s.get(i.columnName)??null;return{columnName:i.columnName,dataType:l?"enum":nr(i.dataType),dataTypeLabel:l?"enum":gn(i.dataType),isNullable:!!i.isNullable,columnDefault:i.columnDefault??null,isPrimaryKey:!!i.isPrimaryKey,isForeignKey:!!i.isForeignKey,referencedTable:i.referencedTable??null,referencedColumn:i.referencedColumn??null,enumValues:l}})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,db:u}=e,m=await Q(u);await this.assertTableExists(m,t);let p=await m.request().input("tableName",t).input("columnName",r).query(`
155
+ `),s=new Map;for(let i of o.recordset){let l=this.parseCheckConstraintValues(i.checkClause);l&&s.set(i.columnName,l)}return a.recordset.map(i=>{let l=s.get(i.columnName)??null;return{columnName:i.columnName,dataType:l?"enum":lr(i.dataType),dataTypeLabel:l?"enum":Rn(i.dataType),isNullable:!!i.isNullable,columnDefault:i.columnDefault??null,isPrimaryKey:!!i.isPrimaryKey,isForeignKey:!!i.isForeignKey,referencedTable:i.referencedTable??null,referencedColumn:i.referencedColumn??null,enumValues:l}})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,db:u}=e,m=await J(u);await this.assertTableExists(m,t);let p=await m.request().input("tableName",t).input("columnName",r).query(`
156
156
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
157
157
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
158
- `);if(Number(p.recordset[0]?.cnt??0)>0)throw new Y(409,{message:`Column "${r}" already exists in table "${t}"`});let d=Cs({columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c},{includePrimaryKey:!0,includeUnique:!0});await m.request().query(`ALTER TABLE [${t}] ADD ${d}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:a}=e,o=await Q(a);return await this.assertTableExists(o,t),await this.assertColumnExists(o,t,r),{deletedCount:(await o.request().query(`ALTER TABLE [${t}] DROP COLUMN [${r}]`)).rowsAffected[0]??1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=await Q(i);await this.assertTableExists(l,t),await this.assertColumnExists(l,t,r);let u=(await l.request().input("tableName",t).input("columnName",r).query(`
158
+ `);if(Number(p.recordset[0]?.cnt??0)>0)throw new Y(409,{message:`Column "${r}" already exists in table "${t}"`});let d=$s({columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c},{includePrimaryKey:!0,includeUnique:!0});await m.request().query(`ALTER TABLE [${t}] ADD ${d}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:a}=e,o=await J(a);return await this.assertTableExists(o,t),await this.assertColumnExists(o,t,r),{deletedCount:(await o.request().query(`ALTER TABLE [${t}] DROP COLUMN [${r}]`)).rowsAffected[0]??1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=await J(i);await this.assertTableExists(l,t),await this.assertColumnExists(l,t,r);let u=(await l.request().input("tableName",t).input("columnName",r).query(`
159
159
  SELECT dc.name AS constraint_name
160
160
  FROM sys.default_constraints dc
161
161
  JOIN sys.columns c
162
162
  ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
163
163
  WHERE OBJECT_NAME(dc.parent_object_id) = @tableName AND c.name = @columnName
164
- `)).recordset[0]?.constraint_name;u&&await l.request().query(`ALTER TABLE [${t}] DROP CONSTRAINT [${u}]`);let m=o?"NULL":"NOT NULL";await l.request().query(`ALTER TABLE [${t}] ALTER COLUMN [${r}] ${a} ${m}`),s?.trim()&&await l.request().query(`ALTER TABLE [${t}] ADD DEFAULT ${s.trim()} FOR [${r}]`)}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=await Q(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let i=await s.request().input("tableName",t).input("columnName",a).query(`
164
+ `)).recordset[0]?.constraint_name;u&&await l.request().query(`ALTER TABLE [${t}] DROP CONSTRAINT [${u}]`);let m=o?"NULL":"NOT NULL";await l.request().query(`ALTER TABLE [${t}] ALTER COLUMN [${r}] ${a} ${m}`),s?.trim()&&await l.request().query(`ALTER TABLE [${t}] ADD DEFAULT ${s.trim()} FOR [${r}]`)}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=await J(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let i=await s.request().input("tableName",t).input("columnName",a).query(`
165
165
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
166
166
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
167
- `);if(Number(i.recordset[0]?.cnt??0)>0)throw new Y(409,{message:`Column "${a}" already exists in table "${t}"`});await s.request().query(`EXEC sp_rename '${t}.${r}', '${a}', 'COLUMN'`)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=await Q(e),s=await this.getBooleanColumnSet(r,e),i=await o.request().input("tableName",r).query("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(@tableName) AND is_identity = 1"),l=new Set(i.recordset.map(y=>y.name)),c=Object.keys(a).filter(y=>!l.has(y)),u=c.map(y=>{let g=a[y];return s.has(y)&&typeof g=="string"?g==="true"?1:0:g}),m=c.map(y=>`[${y}]`).join(", "),p=c.map((y,g)=>`@param${g}`).join(", "),d=o.request();c.forEach((y,g)=>{d.input(`param${g}`,u[g])});let f=await d.query(`INSERT INTO [${r}] (${m}) VALUES (${p})`);if(f.rowsAffected[0]===0)throw new Y(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:f.rowsAffected[0]??0}}async updateRecords({params:e,db:t}){let{tableName:r}=e,a=await Q(t),o=await this.getBooleanColumnSet(r,t),s=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,r),s);let i=this.groupUpdatesByKey(e,s),l=a.transaction();await l.begin();try{let c=0;for(let{keyValues:u,rowUpdates:m}of i){let p=l.request(),d=m.map((g,w)=>`[${g.columnName}] = @value${w}`);m.forEach((g,w)=>{let C=g.value;C!==null&&typeof C=="object"&&(C=JSON.stringify(C)),o.has(g.columnName)&&typeof C=="string"&&(C=C==="true"?1:0),p.input(`value${w}`,C)}),u.forEach((g,w)=>{p.input(`pkValue${w}`,g)});let f=s.map((g,w)=>`[${g}] = @pkValue${w}`),y=await p.query(`UPDATE [${r}] SET ${d.join(", ")} WHERE ${f.join(" AND ")}`);if(y.rowsAffected[0]===0)throw new Y(404,{message:`Record with ${this.describeKey(s,u)} not found in table "${r}"`});c+=y.rowsAffected[0]??0}return await l.commit(),{updatedCount:c}}catch(c){throw await l.rollback(),c instanceof Y?c:new Y(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=await Q(r),o=t[0]?.columnName;if(!o)throw new Y(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=a.transaction();await i.begin();try{let l=i.request();s.forEach((m,p)=>{l.input(`pk${p}`,m)});let c=s.map((m,p)=>`@pk${p}`).join(", "),u=await l.query(`DELETE FROM [${e}] WHERE [${o}] IN (${c})`);return await i.commit(),{deletedCount:u.rowsAffected[0]??0,fkViolation:!1,relatedRecords:[]}}catch(l){if(await i.rollback(),l.number===Cu)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw l instanceof Y?l:new Y(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=await Q(r),o=t[0]?.columnName;if(!o)throw new Y(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=a.transaction();await i.begin();try{let l=await this.getForeignKeyReferences(e,r),c=0,u=new Set,m=new Set,p=async(g,w,C,N)=>{let A=`${g}.${w}`;if(N.has(A))return;N.add(A);let E=await this.getForeignKeyReferences(g,r);for(let q of E){let P=i.request();C.forEach((k,me)=>{P.input(`val${me}`,k)});let U=C.map((k,me)=>`@val${me}`).join(", "),V=(await P.query(`SELECT [${q.referencedColumn}] FROM [${g}] WHERE [${w}] IN (${U})`)).recordset.map(k=>k[q.referencedColumn]);V.length>0&&await p(q.referencingTable,q.referencingColumn,V,N)}let R=i.request();C.forEach((q,P)=>{R.input(`delVal${P}`,q)});let D=C.map((q,P)=>`@delVal${P}`).join(", "),$=await R.query(`DELETE FROM [${g}] WHERE [${w}] IN (${D})`);c+=$.rowsAffected[0]??0,u.add(g)};for(let g of l)u.has(g.referencingTable)||await p(g.referencingTable,g.referencingColumn,s,m);let d=i.request();s.forEach((g,w)=>{d.input(`mainPk${w}`,g)});let f=s.map((g,w)=>`@mainPk${w}`).join(", "),y=await d.query(`DELETE FROM [${e}] WHERE [${o}] IN (${f})`);return await i.commit(),{deletedCount:(y.rowsAffected[0]??0)+c}}catch(l){throw await i.rollback(),l instanceof Y?l:new Y(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new Y(400,{message:"At least one record is required"});let o=(await Q(r)).transaction();try{let s=Object.keys(t[0]),i=s.map(c=>`[${c}]`).join(", "),l=await this.getBooleanColumnSet(e,r);await o.begin();for(let c=0;c<t.length;c++){let u=t[c],m=o.request(),p=s.map(f=>{let y=u[f];return l.has(f)&&typeof y=="string"?y==="true"?1:0:y}),d=s.map((f,y)=>`@p${c}_${y}`).join(", ");s.forEach((f,y)=>{m.input(`p${c}_${y}`,p[y])});try{await m.query(`INSERT INTO [${e}] (${i}) VALUES (${d})`)}catch(f){throw new Y(500,{message:`Failed to insert record ${c+1}: ${f instanceof Error?f.message:String(f)}`})}}return await o.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(s){throw await o.rollback(),s instanceof Y?s:new Y(500,{message:`Failed to bulk insert records into "${e}"`})}}async executeQuery({query:e,db:t}){let r=await Q(t);if(!e?.trim())throw new Y(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.request().query(a),i=performance.now()-o;if(s.recordset){let l=s.recordset;return{columns:s.recordset.columns?Object.keys(s.recordset.columns):Object.keys(l[0]??{}),rows:l,rowCount:l.length,duration:i,message:l.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:s.rowsAffected[0]??0,duration:i,message:`OK \u2014 ${s.rowsAffected[0]??0} row(s) affected`}}async getForeignKeyReferences(e,t){return(await(await Q(t)).request().input("tableName",e).query(`
167
+ `);if(Number(i.recordset[0]?.cnt??0)>0)throw new Y(409,{message:`Column "${a}" already exists in table "${t}"`});await s.request().query(`EXEC sp_rename '${t}.${r}', '${a}', 'COLUMN'`)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=await J(e),s=await this.getBooleanColumnSet(r,e),i=await o.request().input("tableName",r).query("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(@tableName) AND is_identity = 1"),l=new Set(i.recordset.map(y=>y.name)),c=Object.keys(a).filter(y=>!l.has(y)),u=c.map(y=>{let g=a[y];return s.has(y)&&typeof g=="string"?g==="true"?1:0:g}),m=c.map(y=>`[${y}]`).join(", "),p=c.map((y,g)=>`@param${g}`).join(", "),d=o.request();c.forEach((y,g)=>{d.input(`param${g}`,u[g])});let f=await d.query(`INSERT INTO [${r}] (${m}) VALUES (${p})`);if(f.rowsAffected[0]===0)throw new Y(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:f.rowsAffected[0]??0}}async updateRecords({params:e,db:t}){let{tableName:r}=e,a=await J(t),o=await this.getBooleanColumnSet(r,t),s=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,r),s);let i=this.groupUpdatesByKey(e,s),l=a.transaction();await l.begin();try{let c=0;for(let{keyValues:u,rowUpdates:m}of i){let p=l.request(),d=m.map((g,w)=>`[${g.columnName}] = @value${w}`);m.forEach((g,w)=>{let C=g.value;C!==null&&typeof C=="object"&&(C=JSON.stringify(C)),o.has(g.columnName)&&typeof C=="string"&&(C=C==="true"?1:0),p.input(`value${w}`,C)}),u.forEach((g,w)=>{p.input(`pkValue${w}`,g)});let f=s.map((g,w)=>`[${g}] = @pkValue${w}`),y=await p.query(`UPDATE [${r}] SET ${d.join(", ")} WHERE ${f.join(" AND ")}`);if(y.rowsAffected[0]===0)throw new Y(404,{message:`Record with ${this.describeKey(s,u)} not found in table "${r}"`});c+=y.rowsAffected[0]??0}return await l.commit(),{updatedCount:c}}catch(c){throw await l.rollback(),c instanceof Y?c:new Y(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=await J(r),o=t[0]?.columnName;if(!o)throw new Y(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=a.transaction();await i.begin();try{let l=i.request();s.forEach((m,p)=>{l.input(`pk${p}`,m)});let c=s.map((m,p)=>`@pk${p}`).join(", "),u=await l.query(`DELETE FROM [${e}] WHERE [${o}] IN (${c})`);return await i.commit(),{deletedCount:u.rowsAffected[0]??0,fkViolation:!1,relatedRecords:[]}}catch(l){if(await i.rollback(),l.number===ku)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw l instanceof Y?l:new Y(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=await J(r),o=t[0]?.columnName;if(!o)throw new Y(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=a.transaction();await i.begin();try{let l=await this.getForeignKeyReferences(e,r),c=0,u=new Set,m=new Set,p=async(g,w,C,N)=>{let A=`${g}.${w}`;if(N.has(A))return;N.add(A);let E=await this.getForeignKeyReferences(g,r);for(let q of E){let P=i.request();C.forEach((k,pe)=>{P.input(`val${pe}`,k)});let U=C.map((k,pe)=>`@val${pe}`).join(", "),V=(await P.query(`SELECT [${q.referencedColumn}] FROM [${g}] WHERE [${w}] IN (${U})`)).recordset.map(k=>k[q.referencedColumn]);V.length>0&&await p(q.referencingTable,q.referencingColumn,V,N)}let R=i.request();C.forEach((q,P)=>{R.input(`delVal${P}`,q)});let D=C.map((q,P)=>`@delVal${P}`).join(", "),$=await R.query(`DELETE FROM [${g}] WHERE [${w}] IN (${D})`);c+=$.rowsAffected[0]??0,u.add(g)};for(let g of l)u.has(g.referencingTable)||await p(g.referencingTable,g.referencingColumn,s,m);let d=i.request();s.forEach((g,w)=>{d.input(`mainPk${w}`,g)});let f=s.map((g,w)=>`@mainPk${w}`).join(", "),y=await d.query(`DELETE FROM [${e}] WHERE [${o}] IN (${f})`);return await i.commit(),{deletedCount:(y.rowsAffected[0]??0)+c}}catch(l){throw await i.rollback(),l instanceof Y?l:new Y(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new Y(400,{message:"At least one record is required"});let o=(await J(r)).transaction();try{let s=Object.keys(t[0]),i=s.map(c=>`[${c}]`).join(", "),l=await this.getBooleanColumnSet(e,r);await o.begin();for(let c=0;c<t.length;c++){let u=t[c],m=o.request(),p=s.map(f=>{let y=u[f];return l.has(f)&&typeof y=="string"?y==="true"?1:0:y}),d=s.map((f,y)=>`@p${c}_${y}`).join(", ");s.forEach((f,y)=>{m.input(`p${c}_${y}`,p[y])});try{await m.query(`INSERT INTO [${e}] (${i}) VALUES (${d})`)}catch(f){throw new Y(500,{message:`Failed to insert record ${c+1}: ${f instanceof Error?f.message:String(f)}`})}}return await o.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(s){throw await o.rollback(),s instanceof Y?s:new Y(500,{message:`Failed to bulk insert records into "${e}"`})}}async executeQuery({query:e,db:t}){let r=await J(t);if(!e?.trim())throw new Y(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.request().query(a),i=performance.now()-o;if(s.recordset){let l=s.recordset;return{columns:s.recordset.columns?Object.keys(s.recordset.columns):Object.keys(l[0]??{}),rows:l,rowCount:l.length,duration:i,message:l.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:s.rowsAffected[0]??0,duration:i,message:`OK \u2014 ${s.rowsAffected[0]??0} row(s) affected`}}async getForeignKeyReferences(e,t){return(await(await J(t)).request().input("tableName",e).query(`
168
168
  SELECT
169
169
  fk.name AS constraint_name,
170
170
  OBJECT_NAME(fk.parent_object_id) AS referencing_table,
@@ -174,7 +174,7 @@ ${s.join(`,
174
174
  FROM sys.foreign_keys fk
175
175
  INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
176
176
  WHERE OBJECT_NAME(fk.referenced_object_id) = @tableName
177
- `)).recordset.map(o=>({constraintName:o.constraint_name,referencingTable:o.referencing_table,referencingColumn:o.referencing_column,referencedTable:o.referenced_table,referencedColumn:o.referenced_column}))}async getRelatedRecordsForTable(e,t){let r=await this.getForeignKeyReferences(e,t);if(r.length===0)return[];let a=await Q(t),o=[];for(let s of r){let i=await a.request().query(`SELECT TOP 100 * FROM [${s.referencingTable}]`);i.recordset.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:i.recordset})}return o}async getRelatedRecords(e,t,r){let a=await this.getForeignKeyReferences(e,r);if(a.length===0)return[];let o=await Q(r),s=t.map(c=>c.value),i=[],l=new Map;for(let c of a){let u=`${c.referencingTable}.${c.referencingColumn}`;l.has(u)||l.set(u,[]),l.get(u)?.push(c)}for(let[,c]of l){let u=c[0];if(!u||!t.find(y=>y.columnName===u.referencedColumn))continue;let p=o.request();s.forEach((y,g)=>{p.input(`pk${g}`,y)});let d=s.map((y,g)=>`@pk${g}`).join(", "),f=await p.query(`SELECT TOP 100 * FROM [${u.referencingTable}] WHERE [${u.referencingColumn}] IN (${d})`);f.recordset.length>0&&i.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:f.recordset})}return i}async getTableRowCount(e,t){let a=await(await Q(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(`
177
+ `)).recordset.map(o=>({constraintName:o.constraint_name,referencingTable:o.referencing_table,referencingColumn:o.referencing_column,referencedTable:o.referenced_table,referencedColumn:o.referenced_column}))}async getRelatedRecordsForTable(e,t){let r=await this.getForeignKeyReferences(e,t);if(r.length===0)return[];let a=await J(t),o=[];for(let s of r){let i=await a.request().query(`SELECT TOP 100 * FROM [${s.referencingTable}]`);i.recordset.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:i.recordset})}return o}async getRelatedRecords(e,t,r){let a=await this.getForeignKeyReferences(e,r);if(a.length===0)return[];let o=await J(r),s=t.map(c=>c.value),i=[],l=new Map;for(let c of a){let u=`${c.referencingTable}.${c.referencingColumn}`;l.has(u)||l.set(u,[]),l.get(u)?.push(c)}for(let[,c]of l){let u=c[0];if(!u||!t.find(y=>y.columnName===u.referencedColumn))continue;let p=o.request();s.forEach((y,g)=>{p.input(`pk${g}`,y)});let d=s.map((y,g)=>`@pk${g}`).join(", "),f=await p.query(`SELECT TOP 100 * FROM [${u.referencingTable}] WHERE [${u.referencingColumn}] IN (${d})`);f.recordset.length>0&&i.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:f.recordset})}return i}async getTableRowCount(e,t){let a=await(await J(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(`
178
178
  SELECT ku.COLUMN_NAME AS columnName
179
179
  FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
180
180
  JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku
@@ -191,7 +191,7 @@ ${s.join(`,
191
191
  `);if(Number(r.recordset[0]?.cnt??0)===0)throw new Y(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let a=await e.request().input("tableName",t).input("columnName",r).query(`
192
192
  SELECT COUNT(*) as cnt FROM INFORMATION_SCHEMA.COLUMNS
193
193
  WHERE TABLE_CATALOG = DB_NAME() AND TABLE_NAME = @tableName AND COLUMN_NAME = @columnName AND TABLE_SCHEMA = 'dbo'
194
- `);if(Number(a.recordset[0]?.cnt??0)===0)throw new Y(404,{message:`Column "${r}" does not exist in table "${t}"`})}parseCheckConstraintValues(e){let t=e.match(/'([^']+)'/g);return!t||t.length===0?null:t.map(r=>r.slice(1,-1))}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){let t=this.decodeCursor(e);return Number(t?.values._offset??0)}}});function da(n){if(n.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=`\`${r.columnName}\``;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":case"ilike":e.push(`${a} LIKE ?`),t.push(r.value);break;case"not like":case"not ilike":e.push(`${a} NOT LIKE ?`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function pa(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(t=>`\`${t.columnName}\` ${t.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY \`${n}\` ${e?.toUpperCase()||"ASC"}`:""}function fa(n,e,t){let{values:r,sortColumns:a}=n;if(a.length===0)return{clause:"",values:[]};let l=t==="asc"===(e==="asc")?">":"<",c=a.map(p=>`\`${p}\``).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>r[p]);return{clause:`(${c}) ${l} (${u})`,values:m}}function Su(n,e){if(e)return"JSON";let t=n.toLowerCase().trim();return{serial:"INT AUTO_INCREMENT",serial4:"INT AUTO_INCREMENT",bigserial:"BIGINT AUTO_INCREMENT",serial8:"BIGINT AUTO_INCREMENT",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",numeric:"DECIMAL",decimal:"DECIMAL",real:"FLOAT",float4:"FLOAT",float:"FLOAT","double precision":"DOUBLE",float8:"DOUBLE",money:"DECIMAL(19, 4)",boolean:"TINYINT(1)",bool:"TINYINT(1)",text:"LONGTEXT",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"CHAR(36)",json:"JSON",jsonb:"JSON",xml:"LONGTEXT",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME","timestamp without time zone":"DATETIME","timestamp with time zone":"DATETIME",timestamptz:"DATETIME",interval:"VARCHAR(255)",bytea:"LONGBLOB",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)",point:"POINT",line:"LINESTRING",polygon:"POLYGON"}[t]||n.toUpperCase()}function Au(n,e){if(!n?.trim())return null;let t=n.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("uuid()")?!e.toUpperCase().includes("CHAR")&&!e.toUpperCase().includes("TEXT")?null:"(UUID())":t.includes("current_timestamp")||t.includes("now()")?"(CURRENT_TIMESTAMP)":t.includes("current_date")?"(CURRENT_DATE)":`(${n.trim()})`:t==="null"?"NULL":t==="true"?"1":t==="false"?"0":n.trim()}function Kr(n,e={}){let t=Su(n.columnType,n.isArray??!1),r=`\`${n.columnName}\` ${t}`;if(!n.isNullable&&!n.isPrimaryKey&&(r+=" NOT NULL"),n.defaultValue&&!t.includes("AUTO_INCREMENT")){let a=Au(n.defaultValue,t);a!==null&&(r+=` DEFAULT ${a}`)}return(n.isIdentity||e.preserveAutoIncrement)&&!t.includes("AUTO_INCREMENT")&&(r+=" AUTO_INCREMENT"),e.includeUnique&&n.isUnique&&!n.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&n.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var As=S(()=>{"use strict";h()});import{HTTPException as H}from"hono/http-exception";var Ns,Nu,jr,Ds=S(()=>{"use strict";h();ne();je();He();Fe();As();Ns=1451,Nu=1217,jr=class extends oe{mariaDb;async runQuery(e,t,r){let a=J(e),[o]=await a.execute(t,r);return o}quoteIdentifier(e){return`\`${e}\``}mapToUniversalType(e){return rr(e)}mapFromUniversalType(e){return{text:"LONGTEXT",number:"INT",boolean:"TINYINT(1)",json:"JSON",date:"DATETIME",array:"JSON",enum:"TEXT"}[e]??"LONGTEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:a=50,direction:o="asc",sort:s=[],order:i="asc",filters:l=[]}=e,c=[],u=i;Array.isArray(s)&&s.length>0?(c=s.map(E=>E.columnName),u=s[0].direction):typeof s=="string"&&s&&(c=[s]);let{clause:m,values:p}=da(l),d="",f=[];if(r){let E=this.decodeCursor(r);if(E){let R=fa(E,o,u);d=R.clause,f=R.values}}let y="";m&&d?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?y=m:d&&(y=`WHERE ${d}`);let g=pa((Array.isArray(s),s),i),w=g;o==="desc"?g?w=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):c.length>0&&(w=`ORDER BY ${c.map(E=>`\`${E}\` ${u==="asc"?"DESC":"ASC"}`).join(", ")}`):!g&&c.length>0&&(w=`ORDER BY ${c.map(E=>`\`${E}\` ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM \`${t}\` ${y} ${w} LIMIT ${a+1}`,N=[...p,...f],A=`SELECT COUNT(*) as total FROM \`${t}\` ${m}`;return{sql:C,values:N,countSql:A,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,i=[];Array.isArray(o)&&o.length>0?i=o.map(d=>d.columnName):typeof o=="string"&&o&&(i=[o]);let l=d=>this.encodeCursor({values:Object.fromEntries(i.map(f=>[f,d[f]])),sortColumns:i}),c=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(r&&(m=l(u)),s&&(p=l(c))):(s&&(m=l(u)),r&&(p=l(c))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:i="asc",cursor:l,filters:c=[]}=e,u=J(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=i;Array.isArray(s)&&s.length>0?(p=s.map(k=>k.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=[...p,...m.filter(k=>!p.includes(k))],{clause:y,values:g}=da(c),w="",C=[];if(l){let k=this.decodeCursor(l);if(k){let me=fa(k,o,d);w=me.clause,C=me.values}}let N="";y&&w?N=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${w}`:y?N=y:w&&(N=`WHERE ${w}`);let A=pa((Array.isArray(s),s),i),E=m.filter(k=>!p.includes(k)),R=A;if(o==="desc")if(A){if(R=A.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),E.length){let k=d==="asc"?"DESC":"ASC";R+=`, ${E.map(me=>`\`${me}\` ${k}`).join(", ")}`}}else f.length>0&&(R=`ORDER BY ${f.map(k=>`\`${k}\` ${d==="asc"?"DESC":"ASC"}`).join(", ")}`);else!A&&f.length>0?R=`ORDER BY ${f.map(k=>`\`${k}\` ${d.toUpperCase()}`).join(", ")}`:E.length&&(R+=`, ${E.map(k=>`\`${k}\` ${d.toUpperCase()}`).join(", ")}`);let[D]=await u.execute(`SELECT COUNT(*) as total FROM \`${t}\` ${y}`,g),$=Number(D[0]?.total??0),[q]=await u.execute(`SELECT * FROM \`${t}\` ${N} ${R} LIMIT ${Math.floor(a)+1}`,[...g,...C]),P=q,U=P.length>a;U&&(P=P.slice(0,a)),o==="desc"&&(P=P.reverse());let te=null,V=null;if(P.length>0&&f.length>0){let k=P[0],me=P[P.length-1],De=Ge=>({values:Object.fromEntries(f.map(at=>[at,Ge[at]])),sortColumns:f});o==="asc"?(U&&(te=this.encodeCursor(De(me))),l&&(V=this.encodeCursor(De(k)))):(l&&(te=this.encodeCursor(De(me))),U&&(V=this.encodeCursor(De(k))))}return{data:P,meta:{limit:a,total:$,hasNextPage:o==="asc"?U:!!l,hasPreviousPage:o==="asc"?!!l:U,nextCursor:te,prevCursor:V}}}async getDatabasesList(){try{let e=J(),[t]=await e.execute(`
194
+ `);if(Number(a.recordset[0]?.cnt??0)===0)throw new Y(404,{message:`Column "${r}" does not exist in table "${t}"`})}parseCheckConstraintValues(e){let t=e.match(/'([^']+)'/g);return!t||t.length===0?null:t.map(r=>r.slice(1,-1))}makeCursor(e){return this.encodeCursor({values:{_offset:e},sortColumns:["_offset"]})}decodeOffsetCursor(e){let t=this.decodeCursor(e);return Number(t?.values._offset??0)}}});function ba(n){if(n.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=`\`${r.columnName}\``;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":case"ilike":e.push(`${a} LIKE ?`),t.push(r.value);break;case"not like":case"not ilike":e.push(`${a} NOT LIKE ?`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function ga(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(t=>`\`${t.columnName}\` ${t.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY \`${n}\` ${e?.toUpperCase()||"ASC"}`:""}function Ta(n,e,t){let{values:r,sortColumns:a}=n;if(a.length===0)return{clause:"",values:[]};let l=t==="asc"===(e==="asc")?">":"<",c=a.map(p=>`\`${p}\``).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>r[p]);return{clause:`(${c}) ${l} (${u})`,values:m}}function vu(n,e){if(e)return"JSON";let t=n.toLowerCase().trim();return{serial:"INT AUTO_INCREMENT",serial4:"INT AUTO_INCREMENT",bigserial:"BIGINT AUTO_INCREMENT",serial8:"BIGINT AUTO_INCREMENT",int:"INT",int4:"INT",integer:"INT",bigint:"BIGINT",int8:"BIGINT",smallint:"SMALLINT",int2:"SMALLINT",numeric:"DECIMAL",decimal:"DECIMAL",real:"FLOAT",float4:"FLOAT",float:"FLOAT","double precision":"DOUBLE",float8:"DOUBLE",money:"DECIMAL(19, 4)",boolean:"TINYINT(1)",bool:"TINYINT(1)",text:"LONGTEXT",varchar:"VARCHAR(255)","character varying":"VARCHAR(255)",char:"CHAR(1)",character:"CHAR(1)",bpchar:"CHAR",uuid:"CHAR(36)",json:"JSON",jsonb:"JSON",xml:"LONGTEXT",date:"DATE",time:"TIME","time without time zone":"TIME",timestamp:"DATETIME","timestamp without time zone":"DATETIME","timestamp with time zone":"DATETIME",timestamptz:"DATETIME",interval:"VARCHAR(255)",bytea:"LONGBLOB",inet:"VARCHAR(45)",cidr:"VARCHAR(45)",macaddr:"VARCHAR(17)",macaddr8:"VARCHAR(23)",point:"POINT",line:"LINESTRING",polygon:"POLYGON"}[t]||n.toUpperCase()}function qu(n,e){if(!n?.trim())return null;let t=n.trim().toLowerCase();return t.includes("(")&&t.includes(")")?t.includes("uuid()")?!e.toUpperCase().includes("CHAR")&&!e.toUpperCase().includes("TEXT")?null:"(UUID())":t.includes("current_timestamp")||t.includes("now()")?"(CURRENT_TIMESTAMP)":t.includes("current_date")?"(CURRENT_DATE)":`(${n.trim()})`:t==="null"?"NULL":t==="true"?"1":t==="false"?"0":n.trim()}function Yr(n,e={}){let t=vu(n.columnType,n.isArray??!1),r=`\`${n.columnName}\` ${t}`;if(!n.isNullable&&!n.isPrimaryKey&&(r+=" NOT NULL"),n.defaultValue&&!t.includes("AUTO_INCREMENT")){let a=qu(n.defaultValue,t);a!==null&&(r+=` DEFAULT ${a}`)}return(n.isIdentity||e.preserveAutoIncrement)&&!t.includes("AUTO_INCREMENT")&&(r+=" AUTO_INCREMENT"),e.includeUnique&&n.isUnique&&!n.isPrimaryKey&&(r+=" UNIQUE"),e.includePrimaryKey&&n.isPrimaryKey&&(r+=" PRIMARY KEY"),r}var Ls=S(()=>{"use strict";h()});import{HTTPException as H}from"hono/http-exception";var Ms,Uu,zr,ks=S(()=>{"use strict";h();ae();We();Ve();je();Ls();Ms=1451,Uu=1217,zr=class extends se{mariaDb;async runQuery(e,t,r){let a=X(e),[o]=await a.execute(t,r);return o}quoteIdentifier(e){return`\`${e}\``}mapToUniversalType(e){return ir(e)}mapFromUniversalType(e){return{text:"LONGTEXT",number:"INT",boolean:"TINYINT(1)",json:"JSON",date:"DATETIME",array:"JSON",enum:"TEXT"}[e]??"LONGTEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:a=50,direction:o="asc",sort:s=[],order:i="asc",filters:l=[]}=e,c=[],u=i;Array.isArray(s)&&s.length>0?(c=s.map(E=>E.columnName),u=s[0].direction):typeof s=="string"&&s&&(c=[s]);let{clause:m,values:p}=ba(l),d="",f=[];if(r){let E=this.decodeCursor(r);if(E){let R=Ta(E,o,u);d=R.clause,f=R.values}}let y="";m&&d?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?y=m:d&&(y=`WHERE ${d}`);let g=ga((Array.isArray(s),s),i),w=g;o==="desc"?g?w=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):c.length>0&&(w=`ORDER BY ${c.map(E=>`\`${E}\` ${u==="asc"?"DESC":"ASC"}`).join(", ")}`):!g&&c.length>0&&(w=`ORDER BY ${c.map(E=>`\`${E}\` ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM \`${t}\` ${y} ${w} LIMIT ${a+1}`,N=[...p,...f],A=`SELECT COUNT(*) as total FROM \`${t}\` ${m}`;return{sql:C,values:N,countSql:A,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,i=[];Array.isArray(o)&&o.length>0?i=o.map(d=>d.columnName):typeof o=="string"&&o&&(i=[o]);let l=d=>this.encodeCursor({values:Object.fromEntries(i.map(f=>[f,d[f]])),sortColumns:i}),c=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(r&&(m=l(u)),s&&(p=l(c))):(s&&(m=l(u)),r&&(p=l(c))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:i="asc",cursor:l,filters:c=[]}=e,u=X(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=i;Array.isArray(s)&&s.length>0?(p=s.map(k=>k.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=[...p,...m.filter(k=>!p.includes(k))],{clause:y,values:g}=ba(c),w="",C=[];if(l){let k=this.decodeCursor(l);if(k){let pe=Ta(k,o,d);w=pe.clause,C=pe.values}}let N="";y&&w?N=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${w}`:y?N=y:w&&(N=`WHERE ${w}`);let A=ga((Array.isArray(s),s),i),E=m.filter(k=>!p.includes(k)),R=A;if(o==="desc")if(A){if(R=A.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"),E.length){let k=d==="asc"?"DESC":"ASC";R+=`, ${E.map(pe=>`\`${pe}\` ${k}`).join(", ")}`}}else f.length>0&&(R=`ORDER BY ${f.map(k=>`\`${k}\` ${d==="asc"?"DESC":"ASC"}`).join(", ")}`);else!A&&f.length>0?R=`ORDER BY ${f.map(k=>`\`${k}\` ${d.toUpperCase()}`).join(", ")}`:E.length&&(R+=`, ${E.map(k=>`\`${k}\` ${d.toUpperCase()}`).join(", ")}`);let[D]=await u.execute(`SELECT COUNT(*) as total FROM \`${t}\` ${y}`,g),$=Number(D[0]?.total??0),[q]=await u.execute(`SELECT * FROM \`${t}\` ${N} ${R} LIMIT ${Math.floor(a)+1}`,[...g,...C]),P=q,U=P.length>a;U&&(P=P.slice(0,a)),o==="desc"&&(P=P.reverse());let re=null,V=null;if(P.length>0&&f.length>0){let k=P[0],pe=P[P.length-1],Oe=Je=>({values:Object.fromEntries(f.map(it=>[it,Je[it]])),sortColumns:f});o==="asc"?(U&&(re=this.encodeCursor(Oe(pe))),l&&(V=this.encodeCursor(Oe(k)))):(l&&(re=this.encodeCursor(Oe(pe))),U&&(V=this.encodeCursor(Oe(k))))}return{data:P,meta:{limit:a,total:$,hasNextPage:o==="asc"?U:!!l,hasPreviousPage:o==="asc"?!!l:U,nextCursor:re,prevCursor:V}}}async getDatabasesList(){try{let e=X(),[t]=await e.execute(`
195
195
  SELECT
196
196
  s.SCHEMA_NAME AS name,
197
197
  CONCAT(ROUND(COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024, 2), ' MB') AS size,
@@ -202,7 +202,7 @@ ${s.join(`,
202
202
  WHERE (s.SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') OR s.SCHEMA_NAME = DATABASE())
203
203
  GROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME
204
204
  ORDER BY s.SCHEMA_NAME
205
- `);if(!t[0])throw new H(500,{message:"No databases returned from server"});return t}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=J(),[t]=await e.execute("SELECT DATABASE() AS db");if(!t[0])throw new H(500,{message:"No current database returned from server"});return t[0]}async getDatabaseConnectionInfo(){let e=J(),[t]=await e.execute(`
205
+ `);if(!t[0])throw new H(500,{message:"No databases returned from server"});return t}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=X(),[t]=await e.execute("SELECT DATABASE() AS db");if(!t[0])throw new H(500,{message:"No current database returned from server"});return t[0]}async getDatabaseConnectionInfo(){let e=X(),[t]=await e.execute(`
206
206
  SELECT
207
207
  VERSION() AS version,
208
208
  DATABASE() AS database_name,
@@ -210,15 +210,15 @@ ${s.join(`,
210
210
  @@hostname AS host,
211
211
  @@port AS port,
212
212
  @@max_connections AS max_connections
213
- `),[r]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new H(500,{message:"No connection information returned from server"});let a=t[0],o=Re();return{host:String(a.host||o.host),port:Number(a.port||o.port),user:String(a.user),database:String(a.database_name??""),version:String(a.version),active_connections:Number(r[0]?.cnt??0),max_connections:Number(a.max_connections)}}async getTablesList(e){let t=J(e),[r]=await t.execute(`
213
+ `),[r]=await e.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!t[0])throw new H(500,{message:"No connection information returned from server"});let a=t[0],o=Ae();return{host:String(a.host||o.host),port:Number(a.port||o.port),user:String(a.user),database:String(a.database_name??""),version:String(a.version),active_connections:Number(r[0]?.cnt??0),max_connections:Number(a.max_connections)}}async getTablesList(e){let t=X(e),[r]=await t.execute(`
214
214
  SELECT table_name as tableName
215
215
  FROM information_schema.tables
216
216
  WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
217
217
  ORDER BY table_name
218
- `);return!r||r.length===0?[]:Promise.all(r.map(async a=>{let[o]=await t.execute(`SELECT COUNT(*) as count FROM \`${a.tableName}\``);return{tableName:a.tableName,rowCount:o[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=J(t),i=a.map(m=>Kr(m)),l=[],c=a.filter(m=>m.isPrimaryKey);c.length>0&&l.push(`PRIMARY KEY (${c.map(m=>`\`${m.columnName}\``).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&l.push(`UNIQUE KEY \`uq_${r}_${m.columnName}\` (\`${m.columnName}\`)`);let u=o?.map(m=>`CONSTRAINT \`${`fk_${r}_${m.columnName}_${m.referencedTable}_${m.referencedColumn}`}\` FOREIGN KEY (\`${m.columnName}\`) REFERENCES \`${m.referencedTable}\` (\`${m.referencedColumn}\`) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await s.execute(`CREATE TABLE \`${r}\` (
218
+ `);return!r||r.length===0?[]:Promise.all(r.map(async a=>{let[o]=await t.execute(`SELECT COUNT(*) as count FROM \`${a.tableName}\``);return{tableName:a.tableName,rowCount:o[0]?.count??0}}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=X(t),i=a.map(m=>Yr(m)),l=[],c=a.filter(m=>m.isPrimaryKey);c.length>0&&l.push(`PRIMARY KEY (${c.map(m=>`\`${m.columnName}\``).join(", ")})`);for(let m of a)m.isUnique&&!m.isPrimaryKey&&l.push(`UNIQUE KEY \`uq_${r}_${m.columnName}\` (\`${m.columnName}\`)`);let u=o?.map(m=>`CONSTRAINT \`${`fk_${r}_${m.columnName}_${m.referencedTable}_${m.referencedColumn}`}\` FOREIGN KEY (\`${m.columnName}\`) REFERENCES \`${m.referencedTable}\` (\`${m.referencedColumn}\`) ON UPDATE ${m.onUpdate} ON DELETE ${m.onDelete}`)??[];await s.execute(`CREATE TABLE \`${r}\` (
219
219
  ${[...i,...l,...u].join(`,
220
220
  `)}
221
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=J(r),[s]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(s[0]?.cnt??0)===0)throw new H(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(o,t);if(!a){let l=await this.getRelatedRecordsForTable(t,r);if(l.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:l}}try{if(a){let l=await o.getConnection();try{await l.execute("SET FOREIGN_KEY_CHECKS = 0"),await l.execute(`DROP TABLE \`${t}\``),await l.execute("SET FOREIGN_KEY_CHECKS = 1")}finally{l.release()}}else await o.execute(`DROP TABLE \`${t}\``);return{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(l){await o.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{});let c=l;if(c.errno===Nu||c.errno===Ns)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw l instanceof H?l:new H(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=J(a);await this.assertTableExists(o,t);let[s]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[r]);if(Number(s[0]?.cnt??0)>0)throw new H(409,{message:`Table "${r}" already exists`});await o.execute(`RENAME TABLE \`${t.replaceAll("`","``")}\` TO \`${r.replaceAll("`","``")}\``)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=J(t),[a]=await r.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[e]);if(Number(a[0]?.cnt??0)===0)throw new H(404,{message:`Table "${e}" does not exist`});let[o]=await r.execute(`SHOW CREATE TABLE \`${e}\``),s=o[0],i=s?.["Create Table"]??s?.create_table??"";if(!i)throw new H(500,{message:`Failed to retrieve schema for table "${e}"`});return i}async getTableColumns({tableName:e,db:t}){let r=J(t),a=await this.isMariaDb(r)?`EXISTS (
221
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=X(r),[s]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(s[0]?.cnt??0)===0)throw new H(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(o,t);if(!a){let l=await this.getRelatedRecordsForTable(t,r);if(l.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:l}}try{if(a){let l=await o.getConnection();try{await l.execute("SET FOREIGN_KEY_CHECKS = 0"),await l.execute(`DROP TABLE \`${t}\``),await l.execute("SET FOREIGN_KEY_CHECKS = 1")}finally{l.release()}}else await o.execute(`DROP TABLE \`${t}\``);return{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(l){await o.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{});let c=l;if(c.errno===Uu||c.errno===Ms)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(t,r)};throw l instanceof H?l:new H(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=X(a);await this.assertTableExists(o,t);let[s]=await o.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[r]);if(Number(s[0]?.cnt??0)>0)throw new H(409,{message:`Table "${r}" already exists`});await o.execute(`RENAME TABLE \`${t.replaceAll("`","``")}\` TO \`${r.replaceAll("`","``")}\``)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=X(t),[a]=await r.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[e]);if(Number(a[0]?.cnt??0)===0)throw new H(404,{message:`Table "${e}" does not exist`});let[o]=await r.execute(`SHOW CREATE TABLE \`${e}\``),s=o[0],i=s?.["Create Table"]??s?.create_table??"";if(!i)throw new H(500,{message:`Failed to retrieve schema for table "${e}"`});return i}async getTableColumns({tableName:e,db:t}){let r=X(t),a=await this.isMariaDb(r)?`EXISTS (
222
222
  SELECT 1 FROM information_schema.CHECK_CONSTRAINTS cc
223
223
  WHERE cc.CONSTRAINT_SCHEMA = c.TABLE_SCHEMA
224
224
  AND cc.TABLE_NAME = c.TABLE_NAME
@@ -242,10 +242,10 @@ ${s.join(`,
242
242
  AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
243
243
  WHERE c.TABLE_SCHEMA = DATABASE()
244
244
  AND c.TABLE_NAME = ?
245
- ORDER BY c.ORDINAL_POSITION`,[e]);if(!o||o.length===0)throw new H(404,{message:`Table "${e}" does not exist`});return o.map(s=>{let i=s.dataType==="enum"||s.dataType==="set",[l,c]=s.isJsonText?["json","json"]:[s.dataType,s.columnType];return{columnName:s.columnName,dataType:rr(l,c),dataTypeLabel:bn(l,c),isNullable:!!s.isNullable,columnDefault:s.columnDefault??null,isPrimaryKey:!!s.isPrimaryKey,isForeignKey:!!s.isForeignKey,referencedTable:s.referencedTable??null,referencedColumn:s.referencedColumn??null,enumValues:i?this.parseMysqlEnumValues(s.columnType):null}})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,isArray:u,db:m}=e,p=J(m);await this.assertTableExists(p,t);let[d]=await p.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,r]);if(Number(d[0]?.cnt??0)>0)throw new H(409,{message:`Column "${r}" already exists in table "${t}"`});let f=Kr({columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,isArray:u},{includePrimaryKey:!0,includeUnique:!0});await p.execute(`ALTER TABLE \`${t}\` ADD COLUMN ${f}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:a}=e,o=J(a);await this.assertTableExists(o,t),await this.assertColumnExists(o,t,r);let[s]=await o.execute(`ALTER TABLE \`${t}\` DROP COLUMN \`${r}\``);return{deletedCount:s.affectedRows}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=J(i);await this.assertTableExists(l,t);let[c]=await l.execute("SELECT EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1",[t,r]),u=c[0];if(!u)throw new H(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=Kr({columnName:r,columnType:a,defaultValue:s,isNullable:o},{preserveAutoIncrement:u.EXTRA?.toLowerCase().includes("auto_increment")});await l.execute(`ALTER TABLE \`${t}\` MODIFY COLUMN ${m}`)}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=J(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let[i]=await s.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,a]);if(Number(i[0]?.cnt??0)>0)throw new H(409,{message:`Column "${a}" already exists in table "${t}"`});await s.execute(`ALTER TABLE \`${t}\` RENAME COLUMN \`${r}\` TO \`${a}\``)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=J(e),s=await this.getBooleanColumnSet(r,e),i=Object.keys(a),l=Object.values(a).map((u,m)=>s.has(i[m])&&typeof u=="string"?u==="true"?1:0:u),[c]=await o.execute(`INSERT INTO \`${r}\` (${i.map(u=>`\`${u}\``).join(", ")}) VALUES (${i.map(()=>"?").join(", ")})`,l);if(c.affectedRows===0)throw new H(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:c.affectedRows}}async updateRecords({params:e,db:t}){let{tableName:r}=e,a=J(t),o=await this.getBooleanColumnSet(r,t),s=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,r),s);let i=this.groupUpdatesByKey(e,s),l=await a.getConnection();await l.beginTransaction();try{let c=0;for(let{keyValues:u,rowUpdates:m}of i){let p=m.map(g=>`\`${g.columnName}\` = ?`),d=m.map(g=>g.value!==null&&typeof g.value=="object"?JSON.stringify(g.value):o.has(g.columnName)&&typeof g.value=="string"?g.value==="true"?1:0:g.value);d.push(...u);let f=s.map(g=>`\`${g}\` = ?`),[y]=await l.execute(`UPDATE \`${r}\` SET ${p.join(", ")} WHERE ${f.join(" AND ")}`,d);if(y.affectedRows===0)throw new H(404,{message:`Record with ${this.describeKey(s,u)} not found in table "${r}"`});c+=y.affectedRows}return await l.commit(),{updatedCount:c}}catch(c){throw await l.rollback(),c instanceof H?c:new H(500,{message:`Failed to update records in "${r}"`})}finally{l.release()}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=J(r),o=t[0]?.columnName;if(!o)throw new H(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(c=>c.value),i=s.map(()=>"?").join(", "),l=await a.getConnection();await l.beginTransaction();try{let[c]=await l.execute(`DELETE FROM \`${e}\` WHERE \`${o}\` IN (${i})`,s);return await l.commit(),{deletedCount:c.affectedRows,fkViolation:!1,relatedRecords:[]}}catch(c){if(await l.rollback(),c.errno===Ns)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw c instanceof H?c:new H(500,{message:`Failed to delete records from "${e}"`})}finally{l.release()}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=J(r),o=t[0]?.columnName;if(!o)throw new H(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=await a.getConnection();await i.beginTransaction();try{await i.execute("SET FOREIGN_KEY_CHECKS = 0");let l=await this.getForeignKeyReferences(e,r),c=0,u=new Set,m=new Set,p=async(y,g,w,C)=>{let N=`${y}.${g}`;if(C.has(N))return;C.add(N);let A=await this.getForeignKeyReferences(y,r);for(let D of A){let $=w.map(()=>"?").join(", "),[q]=await i.execute(`SELECT \`${D.referencedColumn}\` FROM \`${y}\` WHERE \`${g}\` IN (${$})`,w),P=q.map(U=>U[D.referencedColumn]);P.length>0&&await p(D.referencingTable,D.referencingColumn,P,C)}let E=w.map(()=>"?").join(", "),[R]=await i.execute(`DELETE FROM \`${y}\` WHERE \`${g}\` IN (${E})`,w);c+=R.affectedRows,u.add(y)};for(let y of l)u.has(y.referencingTable)||await p(y.referencingTable,y.referencingColumn,s,m);let d=s.map(()=>"?").join(", "),[f]=await i.execute(`DELETE FROM \`${e}\` WHERE \`${o}\` IN (${d})`,s);return await i.execute("SET FOREIGN_KEY_CHECKS = 1"),await i.commit(),{deletedCount:f.affectedRows+c}}catch(l){throw await i.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{}),await i.rollback(),l instanceof H?l:new H(500,{message:`Failed to force delete records from "${e}"`})}finally{i.release()}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new H(400,{message:"At least one record is required"});let o=await J(r).getConnection();try{let s=Object.keys(t[0]),i=s.map(c=>`\`${c}\``).join(", "),l=await this.getBooleanColumnSet(e,r);await o.beginTransaction();for(let c=0;c<t.length;c++){let u=t[c],m=s.map(p=>{let d=u[p];return l.has(p)&&typeof d=="string"?d==="true"?1:0:d});try{await o.execute(`INSERT INTO \`${e}\` (${i}) VALUES (${s.map(()=>"?").join(", ")})`,m)}catch(p){throw new H(500,{message:`Failed to insert record ${c+1}: ${p instanceof Error?p.message:String(p)}`})}}return await o.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(s){throw await o.rollback(),s instanceof H?s:new H(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=J(t);if(!e?.trim())throw new H(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),[s,i]=await r.execute(a),l=performance.now()-o;if(Array.isArray(s)){let u=s;return{columns:i?i.map(p=>p.name):Object.keys(u[0]??{}),rows:u,rowCount:u.length,duration:l,message:u.length===0?"OK":void 0}}let c=s;return{columns:[],rows:[],rowCount:c.affectedRows,duration:l,message:`OK \u2014 ${c.affectedRows} row(s) affected`}}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[r]=await e.execute(`SELECT COLUMN_NAME as column_name
245
+ ORDER BY c.ORDINAL_POSITION`,[e]);if(!o||o.length===0)throw new H(404,{message:`Table "${e}" does not exist`});return o.map(s=>{let i=s.dataType==="enum"||s.dataType==="set",[l,c]=s.isJsonText?["json","json"]:[s.dataType,s.columnType];return{columnName:s.columnName,dataType:ir(l,c),dataTypeLabel:Cn(l,c),isNullable:!!s.isNullable,columnDefault:s.columnDefault??null,isPrimaryKey:!!s.isPrimaryKey,isForeignKey:!!s.isForeignKey,referencedTable:s.referencedTable??null,referencedColumn:s.referencedColumn??null,enumValues:i?this.parseMysqlEnumValues(s.columnType):null}})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,isArray:u,db:m}=e,p=X(m);await this.assertTableExists(p,t);let[d]=await p.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,r]);if(Number(d[0]?.cnt??0)>0)throw new H(409,{message:`Column "${r}" already exists in table "${t}"`});let f=Yr({columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,isArray:u},{includePrimaryKey:!0,includeUnique:!0});await p.execute(`ALTER TABLE \`${t}\` ADD COLUMN ${f}`)}async deleteColumn(e){let{tableName:t,columnName:r,db:a}=e,o=X(a);await this.assertTableExists(o,t),await this.assertColumnExists(o,t,r);let[s]=await o.execute(`ALTER TABLE \`${t}\` DROP COLUMN \`${r}\``);return{deletedCount:s.affectedRows}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=X(i);await this.assertTableExists(l,t);let[c]=await l.execute("SELECT EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1",[t,r]),u=c[0];if(!u)throw new H(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=Yr({columnName:r,columnType:a,defaultValue:s,isNullable:o},{preserveAutoIncrement:u.EXTRA?.toLowerCase().includes("auto_increment")});await l.execute(`ALTER TABLE \`${t}\` MODIFY COLUMN ${m}`)}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=X(o);await this.assertTableExists(s,t),await this.assertColumnExists(s,t,r);let[i]=await s.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,a]);if(Number(i[0]?.cnt??0)>0)throw new H(409,{message:`Column "${a}" already exists in table "${t}"`});await s.execute(`ALTER TABLE \`${t}\` RENAME COLUMN \`${r}\` TO \`${a}\``)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=X(e),s=await this.getBooleanColumnSet(r,e),i=Object.keys(a),l=Object.values(a).map((u,m)=>s.has(i[m])&&typeof u=="string"?u==="true"?1:0:u),[c]=await o.execute(`INSERT INTO \`${r}\` (${i.map(u=>`\`${u}\``).join(", ")}) VALUES (${i.map(()=>"?").join(", ")})`,l);if(c.affectedRows===0)throw new H(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:c.affectedRows}}async updateRecords({params:e,db:t}){let{tableName:r}=e,a=X(t),o=await this.getBooleanColumnSet(r,t),s=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,r),s);let i=this.groupUpdatesByKey(e,s),l=await a.getConnection();await l.beginTransaction();try{let c=0;for(let{keyValues:u,rowUpdates:m}of i){let p=m.map(g=>`\`${g.columnName}\` = ?`),d=m.map(g=>g.value!==null&&typeof g.value=="object"?JSON.stringify(g.value):o.has(g.columnName)&&typeof g.value=="string"?g.value==="true"?1:0:g.value);d.push(...u);let f=s.map(g=>`\`${g}\` = ?`),[y]=await l.execute(`UPDATE \`${r}\` SET ${p.join(", ")} WHERE ${f.join(" AND ")}`,d);if(y.affectedRows===0)throw new H(404,{message:`Record with ${this.describeKey(s,u)} not found in table "${r}"`});c+=y.affectedRows}return await l.commit(),{updatedCount:c}}catch(c){throw await l.rollback(),c instanceof H?c:new H(500,{message:`Failed to update records in "${r}"`})}finally{l.release()}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=X(r),o=t[0]?.columnName;if(!o)throw new H(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(c=>c.value),i=s.map(()=>"?").join(", "),l=await a.getConnection();await l.beginTransaction();try{let[c]=await l.execute(`DELETE FROM \`${e}\` WHERE \`${o}\` IN (${i})`,s);return await l.commit(),{deletedCount:c.affectedRows,fkViolation:!1,relatedRecords:[]}}catch(c){if(await l.rollback(),c.errno===Ms)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(e,t,r)};throw c instanceof H?c:new H(500,{message:`Failed to delete records from "${e}"`})}finally{l.release()}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=X(r),o=t[0]?.columnName;if(!o)throw new H(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=await a.getConnection();await i.beginTransaction();try{await i.execute("SET FOREIGN_KEY_CHECKS = 0");let l=await this.getForeignKeyReferences(e,r),c=0,u=new Set,m=new Set,p=async(y,g,w,C)=>{let N=`${y}.${g}`;if(C.has(N))return;C.add(N);let A=await this.getForeignKeyReferences(y,r);for(let D of A){let $=w.map(()=>"?").join(", "),[q]=await i.execute(`SELECT \`${D.referencedColumn}\` FROM \`${y}\` WHERE \`${g}\` IN (${$})`,w),P=q.map(U=>U[D.referencedColumn]);P.length>0&&await p(D.referencingTable,D.referencingColumn,P,C)}let E=w.map(()=>"?").join(", "),[R]=await i.execute(`DELETE FROM \`${y}\` WHERE \`${g}\` IN (${E})`,w);c+=R.affectedRows,u.add(y)};for(let y of l)u.has(y.referencingTable)||await p(y.referencingTable,y.referencingColumn,s,m);let d=s.map(()=>"?").join(", "),[f]=await i.execute(`DELETE FROM \`${e}\` WHERE \`${o}\` IN (${d})`,s);return await i.execute("SET FOREIGN_KEY_CHECKS = 1"),await i.commit(),{deletedCount:f.affectedRows+c}}catch(l){throw await i.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{}),await i.rollback(),l instanceof H?l:new H(500,{message:`Failed to force delete records from "${e}"`})}finally{i.release()}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new H(400,{message:"At least one record is required"});let o=await X(r).getConnection();try{let s=Object.keys(t[0]),i=s.map(c=>`\`${c}\``).join(", "),l=await this.getBooleanColumnSet(e,r);await o.beginTransaction();for(let c=0;c<t.length;c++){let u=t[c],m=s.map(p=>{let d=u[p];return l.has(p)&&typeof d=="string"?d==="true"?1:0:d});try{await o.execute(`INSERT INTO \`${e}\` (${i}) VALUES (${s.map(()=>"?").join(", ")})`,m)}catch(p){throw new H(500,{message:`Failed to insert record ${c+1}: ${p instanceof Error?p.message:String(p)}`})}}return await o.commit(),{success:!0,message:`Successfully inserted ${t.length} record${t.length!==1?"s":""}`,successCount:t.length,failureCount:0}}catch(s){throw await o.rollback(),s instanceof H?s:new H(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=X(t);if(!e?.trim())throw new H(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),[s,i]=await r.execute(a),l=performance.now()-o;if(Array.isArray(s)){let u=s;return{columns:i?i.map(p=>p.name):Object.keys(u[0]??{}),rows:u,rowCount:u.length,duration:l,message:u.length===0?"OK":void 0}}let c=s;return{columns:[],rows:[],rowCount:c.affectedRows,duration:l,message:`OK \u2014 ${c.affectedRows} row(s) affected`}}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[r]=await e.execute(`SELECT COLUMN_NAME as column_name
246
246
  FROM information_schema.COLUMNS
247
247
  WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_KEY = 'PRI'
248
- ORDER BY ORDINAL_POSITION`,[t]);return r.map(a=>a.column_name)}async getForeignKeyReferences(e,t){let r=J(t),[a]=await r.execute(`SELECT
248
+ ORDER BY ORDINAL_POSITION`,[t]);return r.map(a=>a.column_name)}async getForeignKeyReferences(e,t){let r=X(t),[a]=await r.execute(`SELECT
249
249
  kcu.CONSTRAINT_NAME AS constraint_name,
250
250
  kcu.TABLE_NAME AS referencing_table,
251
251
  kcu.COLUMN_NAME AS referencing_column,
@@ -258,21 +258,21 @@ ${s.join(`,
258
258
  AND kcu.TABLE_NAME = tc.TABLE_NAME
259
259
  WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
260
260
  AND kcu.TABLE_SCHEMA = DATABASE()
261
- AND kcu.REFERENCED_TABLE_NAME = ?`,[e]);return a.map(o=>({constraintName:o.constraint_name,referencingTable:o.referencing_table,referencingColumn:o.referencing_column,referencedTable:o.referenced_table,referencedColumn:o.referenced_column}))}async getRelatedRecordsForTable(e,t){let r=await this.getForeignKeyReferences(e,t);if(r.length===0)return[];let a=J(t),o=[];for(let s of r){let[i]=await a.execute(`SELECT * FROM \`${s.referencingTable}\` LIMIT 100`);i.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:i})}return o}async getRelatedRecords(e,t,r){let a=await this.getForeignKeyReferences(e,r);if(a.length===0)return[];let o=J(r),s=t.map(c=>c.value),i=[],l=new Map;for(let c of a){let u=`${c.referencingTable}.${c.referencingColumn}`;l.has(u)||l.set(u,[]),l.get(u)?.push(c)}for(let[,c]of l){let u=c[0];if(!u||!t.find(f=>f.columnName===u.referencedColumn))continue;let p=s.map(()=>"?").join(", "),[d]=await o.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${p}) LIMIT 100`,s);d.length>0&&i.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return i}async getTableRowCount(e,t){let[r]=await e.execute(`SELECT COUNT(*) as count FROM \`${t}\``);return Number(r[0]?.count??0)}async getBooleanColumnSet(e,t){let r=await this.getTableColumns({tableName:e,db:t});return new Set(r.filter(a=>a.dataTypeLabel==="boolean").map(a=>a.columnName))}async assertTableExists(e,t){let[r]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(r[0]?.cnt??0)===0)throw new H(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let[a]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,r]);if(Number(a[0]?.cnt??0)===0)throw new H(404,{message:`Column "${r}" does not exist in table "${t}"`})}parseMysqlEnumValues(e){let t=e.match(/^(?:enum|set)\((.+)\)$/i);return t?.[1]?t[1].split(",").map(r=>r.trim().replace(/^'|'$/g,"")):null}}});import{HTTPException as Hr}from"hono/http-exception";function Ls(n,e,t){let r=[];for(let a of n){let o=I(a.columnName),s=t.get(a.columnName),i=a.value.toLowerCase()==="null";switch(a.operator){case"=":case"!=":case">":case">=":case"<":case"<=":r.push(`${o} ${a.operator} ${Ie(a.value,s,e)}`);break;case"is":r.push(i?`${o} IS NULL`:`${o} = ${Ie(a.value,s,e)}`);break;case"is not":r.push(i?`${o} IS NOT NULL`:`${o} != ${Ie(a.value,s,e)}`);break;case"like":r.push(`${Kt(o,s)} LIKE ${e(a.value)}`);break;case"not like":r.push(`${Kt(o,s)} NOT LIKE ${e(a.value)}`);break;case"ilike":r.push(`UPPER(${Kt(o,s)}) LIKE UPPER(${e(a.value)})`);break;case"not ilike":r.push(`UPPER(${Kt(o,s)}) NOT LIKE UPPER(${e(a.value)})`);break}}return r}function ba(n,e,t){if(e)throw new Hr(400,{message:"Oracle has no array column type. Use a json column (JSON on Oracle 23ai) instead."});let r=n.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)"}[r]??n.toUpperCase()}function ga(n,e){let t=n.trim(),r=t.toLowerCase();return r==="now()"||r==="current_timestamp"?"CURRENT_TIMESTAMP":r==="current_date"?"CURRENT_DATE":r==="true"||r==="false"?e?r.toUpperCase():r==="true"?"1":"0":t}var I,Xe,ya,ha,_s,Du,Os,_u,Kt,Ou,Ie,jt,$s,Ps,Is,$u,Ms,ks,xs=S(()=>{"use strict";h();I=n=>{if(n.includes('"')||n.includes("\0"))throw new Hr(400,{message:`Oracle identifiers cannot contain double quotes: ${n}`});return`"${n}"`},Xe=()=>{let n=[];return{values:n,bind:t=>(n.push(t),`:${n.length}`)}},ya='YYYY-MM-DD"T"HH24:MI:SS',ha=`${ya}.FF9`,_s=`${ha}TZH:TZM`,Du=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?\s*(Z|[+-]\d{2}(?::?\d{2})?)?$/i,Os=n=>{let e=n.toUpperCase();return e==="DATE"?"date":e.startsWith("TIMESTAMP")?e.includes("WITH LOCAL TIME ZONE")?"timestampLtz":e.includes("WITH TIME ZONE")?"timestampTz":"timestamp":null},_u=n=>{let e=n?Os(n):null;return e==="date"?ya:e==="timestampTz"?_s:e?ha:null},Kt=(n,e)=>{let t=_u(e);return t?`TO_CHAR(${n}, '${t}')`:n},Ou=(n,e)=>{let t=n instanceof Date?n.toISOString():n;if(typeof t!="string")throw new Hr(400,{message:`Invalid Oracle ${e} value`});let r=t.trim().match(Du);if(!r)throw new Hr(400,{message:`Invalid Oracle date or timestamp value: ${t}`});let[,a,o,s,i="00",l="00",c="00",u="",m]=r,p=`${a}-${o}-${s}T${i}:${l}:${c}`;if(e==="date")return p;let d=`${p}.${u.padEnd(9,"0")}`;if(e==="timestamp")return d;if(!m||m.toUpperCase()==="Z")return`${d}+00:00`;let f=m.replace(":","");return`${d}${f.slice(0,3)}:${f.slice(3).padEnd(2,"0")}`},Ie=(n,e,t)=>{let r=e?Os(e):null;if(!r)return t(n);let a=t(n==null?null:Ou(n,r));return r==="date"?`TO_DATE(${a}, '${ya}')`:r==="timestamp"?`TO_TIMESTAMP(${a}, '${ha}')`:`TO_TIMESTAMP_TZ(${a}, '${_s}')`},jt=(n,e)=>n.map(({COLUMN_NAME:t,DATA_TYPE:r})=>{let a=`${e?`${e}.`:""}${I(t)}`,o=Kt(a,r);return o===a?a:`${o} AS ${I(t)}`}).join(", "),$s=n=>{let e=new Map;for(let t of n){let r=e.get(t.CONSTRAINT_NAME);if(r){r.columns.push(t.REFERENCING_COLUMN),r.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()]},Ps=n=>n.length?`WHERE ${n.join(" AND ")}`:"";Is=(n,e)=>`ORDER BY ${n.map(t=>`${e?`${e}.`:""}${t.column===null?"ROWID":I(t.column)} ${t.direction.toUpperCase()}`).join(", ")}`,$u=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),Ms=n=>$u.has(n.toLowerCase().trim());ks="GENERATED BY DEFAULT ON NULL AS IDENTITY"});var vs,qs=S(()=>{"use strict";h();vs=n=>{if(typeof n!="string"||!/^[+-]?\d+$/.test(n))return n;let e=Number(n);return Number.isSafeInteger(e)?e:n}});import{HTTPException as ue}from"hono/http-exception";import we from"oracledb";var Ta,Us,Bs,tt,Fs,Pu,Lu,Ks,Wr,Iu,Mu,js,Vr,Hs=S(()=>{"use strict";h();ne();je();He();Fe();xs();qs();Ta=n=>n.oracleServerVersion>=23e8,Us=n=>Buffer.isBuffer(n)?n.toString("hex"):n,Bs=n=>{switch(n.dbType){case we.DB_TYPE_NUMBER:return{type:we.STRING,converter:vs};case we.DB_TYPE_CLOB:case we.DB_TYPE_NCLOB:return{type:we.STRING};case we.DB_TYPE_BLOB:return{type:we.BUFFER,converter:Us};case we.DB_TYPE_RAW:case we.DB_TYPE_LONG_RAW:return{converter:Us}}},tt=(n,e)=>n==null?null:typeof n=="boolean"?e==="BOOLEAN"?n:Number(n):typeof n=="bigint"?n.toString():n instanceof Date||typeof n!="object"?n:JSON.stringify(n),Fs=n=>{let e=n.DATA_DEFAULT?.trim();return e&&e.toUpperCase()!=="NULL"?e:null},Pu=n=>{switch(n.DATA_TYPE){case"NUMBER":return n.DATA_PRECISION===null?n.DATA_SCALE===0?"INTEGER":"NUMBER":n.DATA_SCALE?`NUMBER(${n.DATA_PRECISION},${n.DATA_SCALE})`:`NUMBER(${n.DATA_PRECISION})`;case"FLOAT":return`FLOAT(${n.DATA_PRECISION})`;case"VARCHAR2":case"NVARCHAR2":case"CHAR":case"NCHAR":return`${n.DATA_TYPE}(${n.CHAR_LENGTH})`;case"RAW":return`RAW(${n.DATA_LENGTH})`;default:return n.DATA_TYPE}},Lu=(n,e)=>`${e?`${e}.`:""}${n==="ROWID"?"ROWID":I(n)}`,Ks=n=>n.columns.map((e,t)=>`c.${I(e)} = p.${I(n.referencedColumns[t])}`).join(" AND "),Wr=(n,e,t)=>`(${n.keys.map(r=>`(${n.columns.map((a,o)=>`${Lu(a,e)} = ${t(r[o],a)}`).join(" AND ")})`).join(" OR ")})`,Iu=n=>n.dbType===we.DB_TYPE_DATE||n.dbType===we.DB_TYPE_TIMESTAMP||n.dbType===we.DB_TYPE_TIMESTAMP_TZ||n.dbType===we.DB_TYPE_TIMESTAMP_LTZ,Mu=[["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."]],js={CASCADE:" ON DELETE CASCADE","SET NULL":" ON DELETE SET NULL",RESTRICT:"","NO ACTION":""},Vr=class extends oe{async runQuery(e,t,r){return this.withConnection(a=>this.query(a,t,r))}quoteIdentifier(e){return I(e)}mapToUniversalType(e){return sr(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 ue)){let t=Mu.find(([r])=>e.message.startsWith(r));if(t)return new ue(400,{message:`${t[1]} (${e.message.split(`
262
- `)[0]})`,cause:e});if(e.message.startsWith("ORA-00955"))return new ue(409,{message:e.message.split(`
263
- `)[0],cause:e})}return super.wrapError(e)}async withConnection(e){try{let t=await(await Xn()).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 r=await e(t);return await t.commit(),r}catch(r){throw await t.rollback().catch(()=>{}),r}})}async query(e,t,r=[]){return(await e.execute(t,r,{outFormat:we.OUT_FORMAT_OBJECT,fetchTypeHandler:Bs})).rows??[]}async execute(e,t,r=[]){return(await e.execute(t,r)).rowsAffected??0}async getTableData(e){let{tableName:t,limit:r=50,sort:a=[],order:o="asc",cursor:s,filters:i=[]}=e;return this.withConnection(async l=>{let c=await this.requireColumns(l,t),u=new Map(c.map(D=>[D.COLUMN_NAME,D.DATA_TYPE])),m=await this.primaryKey(l,t),p=this.orderTerms(a,o,m.length?m:[null]),d=s?Number(this.decodeCursor(s)?.values._offset??0):0,{values:f,bind:y}=Xe(),g=Ps(Ls(i,y,u)),w=[...f],[C]=await this.query(l,`SELECT COUNT(*) AS "total" FROM ${I(t)} ${g}`,w),N="t",A=await this.query(l,`SELECT ${jt(c,N)} FROM ${I(t)} ${N} ${g} ${Is(p,N)} OFFSET ${y(d)} ROWS FETCH NEXT ${y(r+1)} ROWS ONLY`,f),E=A.length>r,R=D=>this.encodeCursor({values:{_offset:D},sortColumns:["_offset"]});return{data:A.slice(0,r).map(D=>this.normalizeRow(D)),meta:{limit:r,total:Number(C?.total??0),hasNextPage:E,hasPreviousPage:d>0,nextCursor:E?R(d+r):null,prevCursor:d>0?R(Math.max(0,d-r)):null}}})}async exportTableData({tableName:e}){return this.withConnection(async t=>{let r=await this.requireColumns(t,e),a=await this.query(t,`SELECT ${jt(r)} FROM ${I(e)}`);if(!a.length)throw new ue(404,{message:`Table "${e}" does not exist or has no data`});return{cols:r.map(o=>o.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,
261
+ AND kcu.REFERENCED_TABLE_NAME = ?`,[e]);return a.map(o=>({constraintName:o.constraint_name,referencingTable:o.referencing_table,referencingColumn:o.referencing_column,referencedTable:o.referenced_table,referencedColumn:o.referenced_column}))}async getRelatedRecordsForTable(e,t){let r=await this.getForeignKeyReferences(e,t);if(r.length===0)return[];let a=X(t),o=[];for(let s of r){let[i]=await a.execute(`SELECT * FROM \`${s.referencingTable}\` LIMIT 100`);i.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:i})}return o}async getRelatedRecords(e,t,r){let a=await this.getForeignKeyReferences(e,r);if(a.length===0)return[];let o=X(r),s=t.map(c=>c.value),i=[],l=new Map;for(let c of a){let u=`${c.referencingTable}.${c.referencingColumn}`;l.has(u)||l.set(u,[]),l.get(u)?.push(c)}for(let[,c]of l){let u=c[0];if(!u||!t.find(f=>f.columnName===u.referencedColumn))continue;let p=s.map(()=>"?").join(", "),[d]=await o.execute(`SELECT * FROM \`${u.referencingTable}\` WHERE \`${u.referencingColumn}\` IN (${p}) LIMIT 100`,s);d.length>0&&i.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return i}async getTableRowCount(e,t){let[r]=await e.execute(`SELECT COUNT(*) as count FROM \`${t}\``);return Number(r[0]?.count??0)}async getBooleanColumnSet(e,t){let r=await this.getTableColumns({tableName:e,db:t});return new Set(r.filter(a=>a.dataTypeLabel==="boolean").map(a=>a.columnName))}async assertTableExists(e,t){let[r]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?",[t]);if(Number(r[0]?.cnt??0)===0)throw new H(404,{message:`Table "${t}" does not exist`})}async assertColumnExists(e,t,r){let[a]=await e.execute("SELECT COUNT(*) as cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",[t,r]);if(Number(a[0]?.cnt??0)===0)throw new H(404,{message:`Column "${r}" does not exist in table "${t}"`})}parseMysqlEnumValues(e){let t=e.match(/^(?:enum|set)\((.+)\)$/i);return t?.[1]?t[1].split(",").map(r=>r.trim().replace(/^'|'$/g,"")):null}}});import{HTTPException as Gr}from"hono/http-exception";function Bs(n,e,t){let r=[];for(let a of n){let o=L(a.columnName),s=t.get(a.columnName),i=a.value.toLowerCase()==="null";switch(a.operator){case"=":case"!=":case">":case">=":case"<":case"<=":r.push(`${o} ${a.operator} ${ke(a.value,s,e)}`);break;case"is":r.push(i?`${o} IS NULL`:`${o} = ${ke(a.value,s,e)}`);break;case"is not":r.push(i?`${o} IS NOT NULL`:`${o} != ${ke(a.value,s,e)}`);break;case"like":r.push(`${Yt(o,s)} LIKE ${e(a.value)}`);break;case"not like":r.push(`${Yt(o,s)} NOT LIKE ${e(a.value)}`);break;case"ilike":r.push(`UPPER(${Yt(o,s)}) LIKE UPPER(${e(a.value)})`);break;case"not ilike":r.push(`UPPER(${Yt(o,s)}) NOT LIKE UPPER(${e(a.value)})`);break}}return r}function Ca(n,e,t){if(e)throw new Gr(400,{message:"Oracle has no array column type. Use a json column (JSON on Oracle 23ai) instead."});let r=n.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)"}[r]??n.toUpperCase()}function Ra(n,e){let t=n.trim(),r=t.toLowerCase();return r==="now()"||r==="current_timestamp"?"CURRENT_TIMESTAMP":r==="current_date"?"CURRENT_DATE":r==="true"||r==="false"?e?r.toUpperCase():r==="true"?"1":"0":t}var L,tt,Ea,wa,xs,Bu,vs,Fu,Yt,Ku,ke,zt,qs,Us,Fs,ju,Ks,js,Hs=S(()=>{"use strict";h();L=n=>{if(n.includes('"')||n.includes("\0"))throw new Gr(400,{message:`Oracle identifiers cannot contain double quotes: ${n}`});return`"${n}"`},tt=()=>{let n=[];return{values:n,bind:t=>(n.push(t),`:${n.length}`)}},Ea='YYYY-MM-DD"T"HH24:MI:SS',wa=`${Ea}.FF9`,xs=`${wa}TZH:TZM`,Bu=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?\s*(Z|[+-]\d{2}(?::?\d{2})?)?$/i,vs=n=>{let e=n.toUpperCase();return e==="DATE"?"date":e.startsWith("TIMESTAMP")?e.includes("WITH LOCAL TIME ZONE")?"timestampLtz":e.includes("WITH TIME ZONE")?"timestampTz":"timestamp":null},Fu=n=>{let e=n?vs(n):null;return e==="date"?Ea:e==="timestampTz"?xs:e?wa:null},Yt=(n,e)=>{let t=Fu(e);return t?`TO_CHAR(${n}, '${t}')`:n},Ku=(n,e)=>{let t=n instanceof Date?n.toISOString():n;if(typeof t!="string")throw new Gr(400,{message:`Invalid Oracle ${e} value`});let r=t.trim().match(Bu);if(!r)throw new Gr(400,{message:`Invalid Oracle date or timestamp value: ${t}`});let[,a,o,s,i="00",l="00",c="00",u="",m]=r,p=`${a}-${o}-${s}T${i}:${l}:${c}`;if(e==="date")return p;let d=`${p}.${u.padEnd(9,"0")}`;if(e==="timestamp")return d;if(!m||m.toUpperCase()==="Z")return`${d}+00:00`;let f=m.replace(":","");return`${d}${f.slice(0,3)}:${f.slice(3).padEnd(2,"0")}`},ke=(n,e,t)=>{let r=e?vs(e):null;if(!r)return t(n);let a=t(n==null?null:Ku(n,r));return r==="date"?`TO_DATE(${a}, '${Ea}')`:r==="timestamp"?`TO_TIMESTAMP(${a}, '${wa}')`:`TO_TIMESTAMP_TZ(${a}, '${xs}')`},zt=(n,e)=>n.map(({COLUMN_NAME:t,DATA_TYPE:r})=>{let a=`${e?`${e}.`:""}${L(t)}`,o=Yt(a,r);return o===a?a:`${o} AS ${L(t)}`}).join(", "),qs=n=>{let e=new Map;for(let t of n){let r=e.get(t.CONSTRAINT_NAME);if(r){r.columns.push(t.REFERENCING_COLUMN),r.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()]},Us=n=>n.length?`WHERE ${n.join(" AND ")}`:"";Fs=(n,e)=>`ORDER BY ${n.map(t=>`${e?`${e}.`:""}${t.column===null?"ROWID":L(t.column)} ${t.direction.toUpperCase()}`).join(", ")}`,ju=new Set(["serial","serial4","bigserial","serial8","smallserial","serial2"]),Ks=n=>ju.has(n.toLowerCase().trim());js="GENERATED BY DEFAULT ON NULL AS IDENTITY"});var Ws,Vs=S(()=>{"use strict";h();Ws=n=>{if(typeof n!="string"||!/^[+-]?\d+$/.test(n))return n;let e=Number(n);return Number.isSafeInteger(e)?e:n}});import{HTTPException as de}from"hono/http-exception";import Re from"oracledb";var Sa,Ys,zs,at,Gs,Hu,Wu,Qs,Qr,Vu,Yu,Js,Jr,Xs=S(()=>{"use strict";h();ae();We();Ve();je();Hs();Vs();Sa=n=>n.oracleServerVersion>=23e8,Ys=n=>Buffer.isBuffer(n)?n.toString("hex"):n,zs=n=>{switch(n.dbType){case Re.DB_TYPE_NUMBER:return{type:Re.STRING,converter:Ws};case Re.DB_TYPE_CLOB:case Re.DB_TYPE_NCLOB:return{type:Re.STRING};case Re.DB_TYPE_BLOB:return{type:Re.BUFFER,converter:Ys};case Re.DB_TYPE_RAW:case Re.DB_TYPE_LONG_RAW:return{converter:Ys}}},at=(n,e)=>n==null?null:typeof n=="boolean"?e==="BOOLEAN"?n:Number(n):typeof n=="bigint"?n.toString():n instanceof Date||typeof n!="object"?n:JSON.stringify(n),Gs=n=>{let e=n.DATA_DEFAULT?.trim();return e&&e.toUpperCase()!=="NULL"?e:null},Hu=n=>{switch(n.DATA_TYPE){case"NUMBER":return n.DATA_PRECISION===null?n.DATA_SCALE===0?"INTEGER":"NUMBER":n.DATA_SCALE?`NUMBER(${n.DATA_PRECISION},${n.DATA_SCALE})`:`NUMBER(${n.DATA_PRECISION})`;case"FLOAT":return`FLOAT(${n.DATA_PRECISION})`;case"VARCHAR2":case"NVARCHAR2":case"CHAR":case"NCHAR":return`${n.DATA_TYPE}(${n.CHAR_LENGTH})`;case"RAW":return`RAW(${n.DATA_LENGTH})`;default:return n.DATA_TYPE}},Wu=(n,e)=>`${e?`${e}.`:""}${n==="ROWID"?"ROWID":L(n)}`,Qs=n=>n.columns.map((e,t)=>`c.${L(e)} = p.${L(n.referencedColumns[t])}`).join(" AND "),Qr=(n,e,t)=>`(${n.keys.map(r=>`(${n.columns.map((a,o)=>`${Wu(a,e)} = ${t(r[o],a)}`).join(" AND ")})`).join(" OR ")})`,Vu=n=>n.dbType===Re.DB_TYPE_DATE||n.dbType===Re.DB_TYPE_TIMESTAMP||n.dbType===Re.DB_TYPE_TIMESTAMP_TZ||n.dbType===Re.DB_TYPE_TIMESTAMP_LTZ,Yu=[["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."]],Js={CASCADE:" ON DELETE CASCADE","SET NULL":" ON DELETE SET NULL",RESTRICT:"","NO ACTION":""},Jr=class extends se{async runQuery(e,t,r){return this.withConnection(a=>this.query(a,t,r))}quoteIdentifier(e){return L(e)}mapToUniversalType(e){return mr(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 de)){let t=Yu.find(([r])=>e.message.startsWith(r));if(t)return new de(400,{message:`${t[1]} (${e.message.split(`
262
+ `)[0]})`,cause:e});if(e.message.startsWith("ORA-00955"))return new de(409,{message:e.message.split(`
263
+ `)[0],cause:e})}return super.wrapError(e)}async withConnection(e){try{let t=await(await na()).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 r=await e(t);return await t.commit(),r}catch(r){throw await t.rollback().catch(()=>{}),r}})}async query(e,t,r=[]){return(await e.execute(t,r,{outFormat:Re.OUT_FORMAT_OBJECT,fetchTypeHandler:zs})).rows??[]}async execute(e,t,r=[]){return(await e.execute(t,r)).rowsAffected??0}async getTableData(e){let{tableName:t,limit:r=50,sort:a=[],order:o="asc",cursor:s,filters:i=[]}=e;return this.withConnection(async l=>{let c=await this.requireColumns(l,t),u=new Map(c.map(D=>[D.COLUMN_NAME,D.DATA_TYPE])),m=await this.primaryKey(l,t),p=this.orderTerms(a,o,m.length?m:[null]),d=s?Number(this.decodeCursor(s)?.values._offset??0):0,{values:f,bind:y}=tt(),g=Us(Bs(i,y,u)),w=[...f],[C]=await this.query(l,`SELECT COUNT(*) AS "total" FROM ${L(t)} ${g}`,w),N="t",A=await this.query(l,`SELECT ${zt(c,N)} FROM ${L(t)} ${N} ${g} ${Fs(p,N)} OFFSET ${y(d)} ROWS FETCH NEXT ${y(r+1)} ROWS ONLY`,f),E=A.length>r,R=D=>this.encodeCursor({values:{_offset:D},sortColumns:["_offset"]});return{data:A.slice(0,r).map(D=>this.normalizeRow(D)),meta:{limit:r,total:Number(C?.total??0),hasNextPage:E,hasPreviousPage:d>0,nextCursor:E?R(d+r):null,prevCursor:d>0?R(Math.max(0,d-r)):null}}})}async exportTableData({tableName:e}){return this.withConnection(async t=>{let r=await this.requireColumns(t,e),a=await this.query(t,`SELECT ${zt(r)} FROM ${L(e)}`);if(!a.length)throw new de(404,{message:`Table "${e}" does not exist or has no data`});return{cols:r.map(o=>o.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,
264
264
  (SELECT NVL(SUM(bytes), 0) FROM user_segments) AS bytes,
265
265
  (SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET') AS encoding
266
- 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 Xn().catch(t=>{throw this.wrapError(t)});return this.withConnection(async t=>{let[r]=await this.query(t,"SELECT USER AS u FROM dual"),{host:a,port:o}=Re();return{host:a,port:o,user:r?.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 r=await this.query(t,`SELECT table_name, num_rows FROM user_tables
266
+ 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 na().catch(t=>{throw this.wrapError(t)});return this.withConnection(async t=>{let[r]=await this.query(t,"SELECT USER AS u FROM dual"),{host:a,port:o}=Ae();return{host:a,port:o,user:r?.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 r=await this.query(t,`SELECT table_name, num_rows FROM user_tables
267
267
  WHERE dropped = 'NO' AND nested = 'NO' AND secondary = 'N' AND (iot_type IS NULL OR iot_type = 'IOT')
268
- ORDER BY table_name`),a=r.filter(s=>s.NUM_ROWS===null||s.NUM_ROWS<1e5),o=new Map;if(a.length){let s=await this.query(t,a.map((i,l)=>`SELECT ${l} AS n, COUNT(*) AS c FROM ${I(i.TABLE_NAME)}`).join(" UNION ALL "));for(let i of s)o.set(a[i.N].TABLE_NAME,Number(i.C))}return r.map(s=>({tableName:s.TABLE_NAME,rowCount:o.get(s.TABLE_NAME)??Number(s.NUM_ROWS??0)}))})}async createTable({tableData:e}){let{tableName:t,fields:r,foreignKeys:a=[]}=e;for(let o of a){if(o.onUpdate!=="NO ACTION"&&o.onUpdate!=="RESTRICT")throw new ue(400,{message:`Oracle foreign keys have no ON UPDATE actions (${o.onUpdate} on "${o.columnName}"). Use NO ACTION.`});if(!(o.onDelete in js))throw new ue(400,{message:`Oracle foreign keys do not support ON DELETE ${o.onDelete} (on "${o.columnName}"). Use CASCADE, SET NULL or NO ACTION.`})}await this.withConnection(async o=>{let s=Ta(o),i=r.filter(c=>c.isPrimaryKey).map(c=>c.columnName),l=r.map(c=>this.columnDefinition(c,{withConstraints:!1,native:s}));i.length&&l.push(`PRIMARY KEY (${i.map(I).join(", ")})`);for(let c of r)c.isUnique&&!c.isPrimaryKey&&l.push(`UNIQUE (${I(c.columnName)})`);for(let c of a)l.push(`FOREIGN KEY (${I(c.columnName)}) REFERENCES ${I(c.referencedTable)} (${I(c.referencedColumn)})${js[c.onDelete]}`);await o.execute(`CREATE TABLE ${I(t)} (${l.join(", ")})`)})}async deleteTable({tableName:e,cascade:t}){return this.withConnection(async r=>{await this.requireColumns(r,e);let a=(await this.foreignKeys(r,"referenced",e)).filter(s=>s.referencingTable!==e);if(a.length&&!t)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.sampleReferencingRows(r,a)};let[o]=await this.query(r,`SELECT COUNT(*) AS c FROM ${I(e)}`);return await r.execute(`DROP TABLE ${I(e)}${t?" CASCADE CONSTRAINTS":""}`),{deletedCount:Number(o?.C??0),fkViolation:!1,relatedRecords:[]}})}async renameTable({tableName:e,newTableName:t}){this.assertDifferentTableName(e,t),await this.withConnection(async r=>{if(await this.requireColumns(r,e),(await this.columns(r,t)).length)throw new ue(409,{message:`Table "${t}" already exists`});await r.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
268
+ ORDER BY table_name`),a=r.filter(s=>s.NUM_ROWS===null||s.NUM_ROWS<1e5),o=new Map;if(a.length){let s=await this.query(t,a.map((i,l)=>`SELECT ${l} AS n, COUNT(*) AS c FROM ${L(i.TABLE_NAME)}`).join(" UNION ALL "));for(let i of s)o.set(a[i.N].TABLE_NAME,Number(i.C))}return r.map(s=>({tableName:s.TABLE_NAME,rowCount:o.get(s.TABLE_NAME)??Number(s.NUM_ROWS??0)}))})}async createTable({tableData:e}){let{tableName:t,fields:r,foreignKeys:a=[]}=e;for(let o of a){if(o.onUpdate!=="NO ACTION"&&o.onUpdate!=="RESTRICT")throw new de(400,{message:`Oracle foreign keys have no ON UPDATE actions (${o.onUpdate} on "${o.columnName}"). Use NO ACTION.`});if(!(o.onDelete in Js))throw new de(400,{message:`Oracle foreign keys do not support ON DELETE ${o.onDelete} (on "${o.columnName}"). Use CASCADE, SET NULL or NO ACTION.`})}await this.withConnection(async o=>{let s=Sa(o),i=r.filter(c=>c.isPrimaryKey).map(c=>c.columnName),l=r.map(c=>this.columnDefinition(c,{withConstraints:!1,native:s}));i.length&&l.push(`PRIMARY KEY (${i.map(L).join(", ")})`);for(let c of r)c.isUnique&&!c.isPrimaryKey&&l.push(`UNIQUE (${L(c.columnName)})`);for(let c of a)l.push(`FOREIGN KEY (${L(c.columnName)}) REFERENCES ${L(c.referencedTable)} (${L(c.referencedColumn)})${Js[c.onDelete]}`);await o.execute(`CREATE TABLE ${L(t)} (${l.join(", ")})`)})}async deleteTable({tableName:e,cascade:t}){return this.withConnection(async r=>{await this.requireColumns(r,e);let a=(await this.foreignKeys(r,"referenced",e)).filter(s=>s.referencingTable!==e);if(a.length&&!t)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.sampleReferencingRows(r,a)};let[o]=await this.query(r,`SELECT COUNT(*) AS c FROM ${L(e)}`);return await r.execute(`DROP TABLE ${L(e)}${t?" CASCADE CONSTRAINTS":""}`),{deletedCount:Number(o?.C??0),fkViolation:!1,relatedRecords:[]}})}async renameTable({tableName:e,newTableName:t}){this.assertDifferentTableName(e,t),await this.withConnection(async r=>{if(await this.requireColumns(r,e),(await this.columns(r,t)).length)throw new de(409,{message:`Table "${t}" already exists`});await r.execute(`ALTER TABLE ${L(e)} RENAME TO ${L(t)}`)})}async getTableSchema({tableName:e}){return this.withConnection(async t=>{await this.requireColumns(t,e),await t.execute(`BEGIN
269
269
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
270
270
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', TRUE);
271
- END;`);let[r]=await this.query(t,"SELECT DBMS_METADATA.GET_DDL('TABLE', :1) AS ddl FROM dual",[e]);return r?.DDL.trim()??""})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let r=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),o=new Map((await this.foreignKeys(t,"referencing",e)).flatMap(s=>s.columns.map((i,l)=>[i,{referencedTable:s.referencedTable,referencedColumn:s.referencedColumns[l]}])));return r.map(s=>{let i=o.get(s.COLUMN_NAME),l=Pu(s);return{columnName:s.COLUMN_NAME,dataType:sr(l),dataTypeLabel:wn(l),isNullable:s.NULLABLE==="Y",columnDefault:s.GENERATION_TYPE?`GENERATED ${s.GENERATION_TYPE}${s.DEFAULT_ON_NULL==="YES"?" ON NULL":""} AS IDENTITY`:Fs(s),isPrimaryKey:a.has(s.COLUMN_NAME),isForeignKey:!!i,referencedTable:i?.referencedTable??null,referencedColumn:i?.referencedColumn??null,enumValues:null}})})}async addColumn(e){let{tableName:t,columnName:r}=e;await this.withConnection(async a=>{if((await this.requireColumns(a,t)).some(i=>i.COLUMN_NAME===r))throw new ue(409,{message:`Column "${r}" already exists in table "${t}"`});let s=this.columnDefinition(e,{withConstraints:!0,native:Ta(a)});await a.execute(`ALTER TABLE ${I(t)} ADD (${s})`)})}async deleteColumn({tableName:e,columnName:t}){return await this.withConnection(async r=>{await this.requireColumn(r,e,t),await r.execute(`ALTER TABLE ${I(e)} DROP COLUMN ${I(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s}=e;await this.withConnection(async i=>{let l=Ta(i),c=(await this.requireColumn(i,t,r)).find(m=>m.COLUMN_NAME===r),u=`${I(r)} ${ba(a,!1,l)}`;s?.trim()?u+=` DEFAULT ${ga(s,l)}`:c&&!c.GENERATION_TYPE&&Fs(c)&&(u+=" DEFAULT NULL"),c?.NULLABLE==="Y"!==o&&(u+=o?" NULL":" NOT NULL"),await i.execute(`ALTER TABLE ${I(t)} MODIFY (${u})`)})}async renameColumn({tableName:e,columnName:t,newColumnName:r}){await this.withConnection(async a=>{if((await this.requireColumn(a,e,t)).some(s=>s.COLUMN_NAME===r))throw new ue(409,{message:`Column "${r}" already exists in table "${e}"`});await a.execute(`ALTER TABLE ${I(e)} RENAME COLUMN ${I(t)} TO ${I(r)}`)})}async addRecord({params:e}){let{tableName:t,data:r}=e,a=Object.keys(r);if(!a.length)throw new ue(400,{message:"No data provided for insert"});return{insertedCount:await this.inTransaction(async s=>{let i=await this.columnTypes(s,t),{values:l,bind:c}=Xe(),u=a.map(m=>Ie(tt(r[m],i.get(m)),i.get(m),c));return this.execute(s,`INSERT INTO ${I(t)} (${a.map(I).join(", ")}) VALUES (${u.join(", ")})`,l)})}}async updateRecords({params:e}){let{tableName:t}=e,r=this.resolveKeyColumns(e),a=this.groupUpdatesByKey(e,r);return{updatedCount:await this.inTransaction(async s=>{this.assertWholeKey(await this.primaryKey(s,t),r);let i=await this.columnTypes(s,t),l=0;for(let{keyValues:c,rowUpdates:u}of a){let{values:m,bind:p}=Xe(),d=u.map(g=>`${I(g.columnName)} = ${Ie(tt(g.value,i.get(g.columnName)),i.get(g.columnName),p)}`).join(", "),f=r.map((g,w)=>`${I(g)} = ${Ie(tt(c[w],i.get(g)),i.get(g),p)}`).join(" AND "),y=await this.execute(s,`UPDATE ${I(t)} SET ${d} WHERE ${f}`,m);if(y===0)throw new ue(404,{message:`Record with ${this.describeKey(r,c)} not found in table "${t}"`});l+=y}return l})}}async deleteRecords({tableName:e,primaryKeys:t}){let r=t[0]?.columnName;if(!r)throw new ue(400,{message:"Primary key column name is required"});let a={columns:[r],keys:t.map(o=>[o.value])};return this.withConnection(async o=>{this.assertDeletableKey(await this.primaryKey(o,e));let s=await this.columnTypes(o,e);try{let{values:i,bind:l}=Xe(),c=Wr(a,void 0,(m,p)=>Ie(tt(m,s.get(p)),s.get(p),l)),u=await this.execute(o,`DELETE FROM ${I(e)} WHERE ${c}`,i);return await o.commit(),{deletedCount:u,fkViolation:!1,relatedRecords:[]}}catch(i){if(await o.rollback().catch(()=>{}),!(i instanceof Error)||!i.message.startsWith("ORA-02292"))throw i;let l=[];for(let c of await this.foreignKeys(o,"referenced",e)){let u=await this.requireColumns(o,c.referencingTable),{values:m,bind:p}=Xe(),d=Wr(a,"p",(y,g)=>Ie(tt(y,s.get(g)),s.get(g),p)),f=await this.query(o,`SELECT ${jt(u,"c")} FROM ${I(c.referencingTable)} c JOIN ${I(e)} p ON ${Ks(c)} WHERE ${d} FETCH FIRST 100 ROWS ONLY`,m);f.length&&l.push({tableName:c.referencingTable,columnName:c.columns.join(", "),constraintName:c.constraintName,records:f})}return{deletedCount:0,fkViolation:!0,relatedRecords:l}}})}async forceDeleteRecords({tableName:e,primaryKeys:t}){let r=t[0]?.columnName;if(!r)throw new ue(400,{message:"Primary key column name is required"});let a=async(s,i,l,c)=>{if(!l.keys.length)return 0;if(c.includes(i))throw new ue(400,{message:`Cannot force delete: the foreign keys ${[...c,i].map(y=>`"${y}"`).join(" -> ")} form a cycle.`});let u=await this.columnTypes(s,i),m=0;for(let y of await this.foreignKeys(s,"referenced",i)){let{values:g,bind:w}=Xe(),C=Wr(l,"p",(A,E)=>E==="ROWID"?`CHARTOROWID(${w(A)})`:Ie(tt(A,u.get(E)),u.get(E),w)),N=await this.query(s,`SELECT DISTINCT ROWIDTOCHAR(c.ROWID) AS "__rowid" FROM ${I(y.referencingTable)} c JOIN ${I(i)} p ON ${Ks(y)} WHERE ${C}`,g);m+=await a(s,y.referencingTable,{columns:["ROWID"],keys:N.map(A=>[A.__rowid])},[...c,i])}let{values:p,bind:d}=Xe(),f=Wr(l,void 0,(y,g)=>g==="ROWID"?`CHARTOROWID(${d(y)})`:Ie(tt(y,u.get(g)),u.get(g),d));return m+await this.execute(s,`DELETE FROM ${I(i)} WHERE ${f}`,p)};return{deletedCount:await this.inTransaction(async s=>(this.assertDeletableKey(await this.primaryKey(s,e)),a(s,e,{columns:[r],keys:t.map(i=>[i.value])},[])))}}async bulkInsertRecords({tableName:e,records:t}){if(!t?.length)throw new ue(400,{message:"At least one record is required"});let r=Object.keys(t[0]),a=await this.inTransaction(async o=>{let s=await this.columnTypes(o,e),i=[],l=t.map((u,m)=>{let{values:p,bind:d}=Xe(),f=r.map(y=>Ie(tt(u[y],s.get(y)),s.get(y),d));return m===0&&(i=f),p});return(await o.executeMany(`INSERT INTO ${I(e)} (${r.map(I).join(", ")}) VALUES (${i.join(", ")})`,l)).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 ue(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 o=>{let s=performance.now(),i=await o.execute(a,[],{outFormat:we.OUT_FORMAT_OBJECT,fetchTypeHandler:Bs,autoCommit:!0,resultSet:!0}),l=performance.now()-s;if(i.resultSet){if(i.metaData?.some(Iu))throw await i.resultSet.close(),new ue(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:l,message:u.length===0?"OK":void 0}}let c=i.rowsAffected??0;return{columns:[],rows:[],rowCount:c,duration:l,message:i.rowsAffected===void 0?"OK":`OK (${c} rows affected)`}})}columnDefinition(e,{withConstraints:t,native:r}){let a=`${I(e.columnName)} ${ba(e.columnType,e.isArray??!1,r)}`;return e.isIdentity||Ms(e.columnType)?a+=` ${ks}`:e.defaultValue?.trim()&&(a+=` DEFAULT ${ga(e.defaultValue,r)}`),!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,
271
+ END;`);let[r]=await this.query(t,"SELECT DBMS_METADATA.GET_DDL('TABLE', :1) AS ddl FROM dual",[e]);return r?.DDL.trim()??""})}async getTableColumns({tableName:e}){return this.withConnection(async t=>{let r=await this.requireColumns(t,e),a=new Set(await this.primaryKey(t,e)),o=new Map((await this.foreignKeys(t,"referencing",e)).flatMap(s=>s.columns.map((i,l)=>[i,{referencedTable:s.referencedTable,referencedColumn:s.referencedColumns[l]}])));return r.map(s=>{let i=o.get(s.COLUMN_NAME),l=Hu(s);return{columnName:s.COLUMN_NAME,dataType:mr(l),dataTypeLabel:Nn(l),isNullable:s.NULLABLE==="Y",columnDefault:s.GENERATION_TYPE?`GENERATED ${s.GENERATION_TYPE}${s.DEFAULT_ON_NULL==="YES"?" ON NULL":""} AS IDENTITY`:Gs(s),isPrimaryKey:a.has(s.COLUMN_NAME),isForeignKey:!!i,referencedTable:i?.referencedTable??null,referencedColumn:i?.referencedColumn??null,enumValues:null}})})}async addColumn(e){let{tableName:t,columnName:r}=e;await this.withConnection(async a=>{if((await this.requireColumns(a,t)).some(i=>i.COLUMN_NAME===r))throw new de(409,{message:`Column "${r}" already exists in table "${t}"`});let s=this.columnDefinition(e,{withConstraints:!0,native:Sa(a)});await a.execute(`ALTER TABLE ${L(t)} ADD (${s})`)})}async deleteColumn({tableName:e,columnName:t}){return await this.withConnection(async r=>{await this.requireColumn(r,e,t),await r.execute(`ALTER TABLE ${L(e)} DROP COLUMN ${L(t)}`)}),{deletedCount:1}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s}=e;await this.withConnection(async i=>{let l=Sa(i),c=(await this.requireColumn(i,t,r)).find(m=>m.COLUMN_NAME===r),u=`${L(r)} ${Ca(a,!1,l)}`;s?.trim()?u+=` DEFAULT ${Ra(s,l)}`:c&&!c.GENERATION_TYPE&&Gs(c)&&(u+=" DEFAULT NULL"),c?.NULLABLE==="Y"!==o&&(u+=o?" NULL":" NOT NULL"),await i.execute(`ALTER TABLE ${L(t)} MODIFY (${u})`)})}async renameColumn({tableName:e,columnName:t,newColumnName:r}){await this.withConnection(async a=>{if((await this.requireColumn(a,e,t)).some(s=>s.COLUMN_NAME===r))throw new de(409,{message:`Column "${r}" already exists in table "${e}"`});await a.execute(`ALTER TABLE ${L(e)} RENAME COLUMN ${L(t)} TO ${L(r)}`)})}async addRecord({params:e}){let{tableName:t,data:r}=e,a=Object.keys(r);if(!a.length)throw new de(400,{message:"No data provided for insert"});return{insertedCount:await this.inTransaction(async s=>{let i=await this.columnTypes(s,t),{values:l,bind:c}=tt(),u=a.map(m=>ke(at(r[m],i.get(m)),i.get(m),c));return this.execute(s,`INSERT INTO ${L(t)} (${a.map(L).join(", ")}) VALUES (${u.join(", ")})`,l)})}}async updateRecords({params:e}){let{tableName:t}=e,r=this.resolveKeyColumns(e),a=this.groupUpdatesByKey(e,r);return{updatedCount:await this.inTransaction(async s=>{this.assertWholeKey(await this.primaryKey(s,t),r);let i=await this.columnTypes(s,t),l=0;for(let{keyValues:c,rowUpdates:u}of a){let{values:m,bind:p}=tt(),d=u.map(g=>`${L(g.columnName)} = ${ke(at(g.value,i.get(g.columnName)),i.get(g.columnName),p)}`).join(", "),f=r.map((g,w)=>`${L(g)} = ${ke(at(c[w],i.get(g)),i.get(g),p)}`).join(" AND "),y=await this.execute(s,`UPDATE ${L(t)} SET ${d} WHERE ${f}`,m);if(y===0)throw new de(404,{message:`Record with ${this.describeKey(r,c)} not found in table "${t}"`});l+=y}return l})}}async deleteRecords({tableName:e,primaryKeys:t}){let r=t[0]?.columnName;if(!r)throw new de(400,{message:"Primary key column name is required"});let a={columns:[r],keys:t.map(o=>[o.value])};return this.withConnection(async o=>{this.assertDeletableKey(await this.primaryKey(o,e));let s=await this.columnTypes(o,e);try{let{values:i,bind:l}=tt(),c=Qr(a,void 0,(m,p)=>ke(at(m,s.get(p)),s.get(p),l)),u=await this.execute(o,`DELETE FROM ${L(e)} WHERE ${c}`,i);return await o.commit(),{deletedCount:u,fkViolation:!1,relatedRecords:[]}}catch(i){if(await o.rollback().catch(()=>{}),!(i instanceof Error)||!i.message.startsWith("ORA-02292"))throw i;let l=[];for(let c of await this.foreignKeys(o,"referenced",e)){let u=await this.requireColumns(o,c.referencingTable),{values:m,bind:p}=tt(),d=Qr(a,"p",(y,g)=>ke(at(y,s.get(g)),s.get(g),p)),f=await this.query(o,`SELECT ${zt(u,"c")} FROM ${L(c.referencingTable)} c JOIN ${L(e)} p ON ${Qs(c)} WHERE ${d} FETCH FIRST 100 ROWS ONLY`,m);f.length&&l.push({tableName:c.referencingTable,columnName:c.columns.join(", "),constraintName:c.constraintName,records:f})}return{deletedCount:0,fkViolation:!0,relatedRecords:l}}})}async forceDeleteRecords({tableName:e,primaryKeys:t}){let r=t[0]?.columnName;if(!r)throw new de(400,{message:"Primary key column name is required"});let a=async(s,i,l,c)=>{if(!l.keys.length)return 0;if(c.includes(i))throw new de(400,{message:`Cannot force delete: the foreign keys ${[...c,i].map(y=>`"${y}"`).join(" -> ")} form a cycle.`});let u=await this.columnTypes(s,i),m=0;for(let y of await this.foreignKeys(s,"referenced",i)){let{values:g,bind:w}=tt(),C=Qr(l,"p",(A,E)=>E==="ROWID"?`CHARTOROWID(${w(A)})`:ke(at(A,u.get(E)),u.get(E),w)),N=await this.query(s,`SELECT DISTINCT ROWIDTOCHAR(c.ROWID) AS "__rowid" FROM ${L(y.referencingTable)} c JOIN ${L(i)} p ON ${Qs(y)} WHERE ${C}`,g);m+=await a(s,y.referencingTable,{columns:["ROWID"],keys:N.map(A=>[A.__rowid])},[...c,i])}let{values:p,bind:d}=tt(),f=Qr(l,void 0,(y,g)=>g==="ROWID"?`CHARTOROWID(${d(y)})`:ke(at(y,u.get(g)),u.get(g),d));return m+await this.execute(s,`DELETE FROM ${L(i)} WHERE ${f}`,p)};return{deletedCount:await this.inTransaction(async s=>(this.assertDeletableKey(await this.primaryKey(s,e)),a(s,e,{columns:[r],keys:t.map(i=>[i.value])},[])))}}async bulkInsertRecords({tableName:e,records:t}){if(!t?.length)throw new de(400,{message:"At least one record is required"});let r=Object.keys(t[0]),a=await this.inTransaction(async o=>{let s=await this.columnTypes(o,e),i=[],l=t.map((u,m)=>{let{values:p,bind:d}=tt(),f=r.map(y=>ke(at(u[y],s.get(y)),s.get(y),d));return m===0&&(i=f),p});return(await o.executeMany(`INSERT INTO ${L(e)} (${r.map(L).join(", ")}) VALUES (${i.join(", ")})`,l)).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 de(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 o=>{let s=performance.now(),i=await o.execute(a,[],{outFormat:Re.OUT_FORMAT_OBJECT,fetchTypeHandler:zs,autoCommit:!0,resultSet:!0}),l=performance.now()-s;if(i.resultSet){if(i.metaData?.some(Vu))throw await i.resultSet.close(),new de(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:l,message:u.length===0?"OK":void 0}}let c=i.rowsAffected??0;return{columns:[],rows:[],rowCount:c,duration:l,message:i.rowsAffected===void 0?"OK":`OK (${c} rows affected)`}})}columnDefinition(e,{withConstraints:t,native:r}){let a=`${L(e.columnName)} ${Ca(e.columnType,e.isArray??!1,r)}`;return e.isIdentity||Ks(e.columnType)?a+=` ${js}`:e.defaultValue?.trim()&&(a+=` DEFAULT ${Ra(e.defaultValue,r)}`),!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,
272
272
  c.nullable, c.data_default, c.default_on_null, i.generation_type
273
273
  FROM user_tab_columns c
274
274
  LEFT JOIN user_tab_identity_cols i ON i.table_name = c.table_name AND i.column_name = c.column_name
275
- WHERE c.table_name = :1 ORDER BY c.column_id`,[t])}async columnTypes(e,t){let r=await this.requireColumns(e,t);return new Map(r.map(a=>[a.COLUMN_NAME,a.DATA_TYPE]))}async requireColumns(e,t){let r=await this.columns(e,t);if(!r.length)throw new ue(404,{message:`Table "${t}" does not exist`});return r}async requireColumn(e,t,r){let a=await this.requireColumns(e,t);if(!a.some(o=>o.COLUMN_NAME===r))throw new ue(404,{message:`Column "${r}" does not exist in table "${t}"`});return a}async primaryKey(e,t){return(await this.query(e,`SELECT cc.column_name FROM user_constraints c
275
+ WHERE c.table_name = :1 ORDER BY c.column_id`,[t])}async columnTypes(e,t){let r=await this.requireColumns(e,t);return new Map(r.map(a=>[a.COLUMN_NAME,a.DATA_TYPE]))}async requireColumns(e,t){let r=await this.columns(e,t);if(!r.length)throw new de(404,{message:`Table "${t}" does not exist`});return r}async requireColumn(e,t,r){let a=await this.requireColumns(e,t);if(!a.some(o=>o.COLUMN_NAME===r))throw new de(404,{message:`Column "${r}" does not exist in table "${t}"`});return a}async primaryKey(e,t){return(await this.query(e,`SELECT cc.column_name FROM user_constraints c
276
276
  JOIN user_cons_columns cc ON cc.constraint_name = c.constraint_name
277
277
  WHERE c.constraint_type = 'P' AND c.table_name = :1
278
278
  ORDER BY cc.position`,[t])).map(a=>a.COLUMN_NAME)}async foreignKeys(e,t,r){let a=await this.query(e,`SELECT c.constraint_name, c.table_name AS referencing_table, cc.column_name AS referencing_column,
@@ -282,10 +282,10 @@ ${s.join(`,
282
282
  JOIN user_constraints r ON r.constraint_name = c.r_constraint_name AND r.owner = c.r_owner
283
283
  JOIN user_cons_columns rc ON rc.constraint_name = r.constraint_name AND rc.position = cc.position
284
284
  WHERE c.constraint_type = 'R' AND ${t==="referencing"?"c":"r"}.table_name = :1
285
- ORDER BY c.constraint_name, cc.position`,[r]);return $s(a)}async sampleReferencingRows(e,t){let r=[];for(let a of t){let o=await this.requireColumns(e,a.referencingTable),s=await this.query(e,`SELECT ${jt(o)} FROM ${I(a.referencingTable)} WHERE ${a.columns.map(i=>`${I(i)} IS NOT NULL`).join(" AND ")} FETCH FIRST 100 ROWS ONLY`);s.length&&r.push({tableName:a.referencingTable,columnName:a.columns.join(", "),constraintName:a.constraintName,records:s})}return r}}});function Ea(n){if(n.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=t.length+1,o=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${o} ${r.operator} $${a}`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${o} IS NULL`):(e.push(`${o} = $${a}`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${o} IS NOT NULL`):(e.push(`${o} != $${a}`),t.push(r.value));break;case"like":e.push(`${o}::text LIKE $${a}`),t.push(r.value);break;case"not like":e.push(`${o}::text NOT LIKE $${a}`),t.push(r.value);break;case"ilike":e.push(`${o}::text ILIKE $${a}`),t.push(r.value);break;case"not ilike":e.push(`${o}::text NOT ILIKE $${a}`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function wa(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(r=>`"${r.columnName}" ${r.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY "${n}" ${e?.toUpperCase()||"ASC"}`:""}function Ca(n,e,t,r){let{values:a,sortColumns:o}=n,s=[],i=[],u=t==="asc"===(e==="asc");if(o.length>0){let m=o.map(f=>`"${f}"`).join(", "),p=o.map((f,y)=>`$${r+y}`).join(", "),d=u?">":"<";s.push(`(${m}) ${d} (${p})`);for(let f of o)i.push(a[f])}return{clause:s.length>0?`(${s.join(" AND ")})`:"",values:i}}var Me,Ws=S(()=>{"use strict";h();Me=n=>`(SELECT sp.schema_name FROM unnest(current_schemas(false)) WITH ORDINALITY AS sp(schema_name, position)
285
+ ORDER BY c.constraint_name, cc.position`,[r]);return qs(a)}async sampleReferencingRows(e,t){let r=[];for(let a of t){let o=await this.requireColumns(e,a.referencingTable),s=await this.query(e,`SELECT ${zt(o)} FROM ${L(a.referencingTable)} WHERE ${a.columns.map(i=>`${L(i)} IS NOT NULL`).join(" AND ")} FETCH FIRST 100 ROWS ONLY`);s.length&&r.push({tableName:a.referencingTable,columnName:a.columns.join(", "),constraintName:a.constraintName,records:s})}return r}}});function Aa(n){if(n.length===0)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=t.length+1,o=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${o} ${r.operator} $${a}`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${o} IS NULL`):(e.push(`${o} = $${a}`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${o} IS NOT NULL`):(e.push(`${o} != $${a}`),t.push(r.value));break;case"like":e.push(`${o}::text LIKE $${a}`),t.push(r.value);break;case"not like":e.push(`${o}::text NOT LIKE $${a}`),t.push(r.value);break;case"ilike":e.push(`${o}::text ILIKE $${a}`),t.push(r.value);break;case"not ilike":e.push(`${o}::text NOT ILIKE $${a}`),t.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function Na(n,e){return Array.isArray(n)?n.length===0?"":`ORDER BY ${n.map(r=>`"${r.columnName}" ${r.direction.toUpperCase()}`).join(", ")}`:n&&typeof n=="string"?`ORDER BY "${n}" ${e?.toUpperCase()||"ASC"}`:""}function Da(n,e,t,r){let{values:a,sortColumns:o}=n,s=[],i=[],u=t==="asc"===(e==="asc");if(o.length>0){let m=o.map(f=>`"${f}"`).join(", "),p=o.map((f,y)=>`$${r+y}`).join(", "),d=u?">":"<";s.push(`(${m}) ${d} (${p})`);for(let f of o)i.push(a[f])}return{clause:s.length>0?`(${s.join(" AND ")})`:"",values:i}}var xe,Zs=S(()=>{"use strict";h();xe=n=>`(SELECT sp.schema_name FROM unnest(current_schemas(false)) WITH ORDINALITY AS sp(schema_name, position)
286
286
  JOIN information_schema.tables it
287
287
  ON it.table_schema = sp.schema_name AND it.table_name = ${n}
288
- ORDER BY sp.position LIMIT 1)`});import{HTTPException as v}from"hono/http-exception";var Yr,Vs=S(()=>{"use strict";h();ne();je();He();Fe();Ws();Yr=class extends oe{databaseSizeSupport;async runQuery(e,t,r){return(await re(e).query(t,r)).rows}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return tr(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"BOOLEAN",json:"JSONB",date:"TIMESTAMP WITH TIME ZONE",array:"TEXT[]",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:a=50,direction:o="asc",sort:s=[],order:i="asc",filters:l=[],db:c}=e,u=re(c),m=[],p=i;Array.isArray(s)&&s.length>0?(m=s.map(P=>P.columnName),p=s[0].direction):typeof s=="string"&&s&&(m=[s]);let d=m.length>0?[...m]:["ctid"],{clause:f,values:y}=Ea(l),g="",w=[];if(r){let P=this.decodeCursor(r);if(P){let U=Ca(P,o,p,y.length+1);g=U.clause,w=U.values}}let C="";f&&g?C=`WHERE ${f.replace(/^WHERE\s+/i,"")} AND ${g}`:f?C=f:g&&(C=`WHERE ${g}`);let N=wa((Array.isArray(s),s),i),A=N;o==="desc"?N?A=N.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):A=`ORDER BY ${d.map(U=>`"${U}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!N&&d.length>0&&(A=`ORDER BY ${d.map(U=>`"${U}" ${p.toUpperCase()}`).join(", ")}`);let E=y.length+w.length+1,R=`SELECT * FROM "${t}" ${C} ${A} LIMIT $${E}`,D=[...y,...w,a+1],$=`SELECT COUNT(*) as total FROM "${t}" ${f}`;return{sql:R,values:D,countSql:$,countValues:y}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,i=[];Array.isArray(o)&&o.length>0?i=o.map(d=>d.columnName):typeof o=="string"&&o&&(i=[o]),i.length===0&&(i=["ctid"]);let l=d=>{let f={values:Object.fromEntries(i.map(y=>[y,d[y]])),sortColumns:i};return this.encodeCursor(f)},c=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(r&&(m=l(u)),s&&(p=l(c))):(s&&(m=l(u)),r&&(p=l(c))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:i="asc",cursor:l,filters:c=[]}=e,u=re(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=i;Array.isArray(s)&&s.length>0?(p=s.map(O=>O.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=m.length?m:["ctid"],y=[...p,...f.filter(O=>!p.includes(O))],{clause:g,values:w}=Ea(c),C="",N=[];if(l){let O=this.decodeCursor(l);if(O){let K=Ca(O,o,d,w.length+1);C=K.clause,N=K.values}}let A="";g&&C?A=`WHERE ${g.replace(/^WHERE\s+/i,"")} AND ${C}`:g?A=g:C&&(A=`WHERE ${C}`);let E=wa((Array.isArray(s),s),i),R=E;if(o==="desc"?E?R=E.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):R=`ORDER BY ${y.map(K=>`"${K}" ${d==="asc"?"DESC":"ASC"}`).join(", ")}`:!E&&y.length>0&&(R=`ORDER BY ${y.map(K=>`"${K}" ${d.toUpperCase()}`).join(", ")}`),E){let O=f.filter(Ot=>!p.includes(Ot)),K=d==="desc"!=(o==="desc")?"DESC":"ASC";O.length&&(R+=`, ${O.map(Ot=>`${this.quoteIdentifier(Ot)} ${K}`).join(", ")}`)}let D=await u.query(`SELECT COUNT(*) as total FROM "${t}" ${g}`,w),$=Number(D.rows[0].total),q=y.includes("ctid"),P=[...m.map(O=>`"${O}"`),...q?["ctid"]:[]],U=w.length+N.length+1,V=(await u.query(`SELECT ${["*",...P].join(", ")} FROM "${t}" ${A} ${R} LIMIT $${U}`,[...w,...N,a+1])).rows,k=V.length>a;k&&(V=V.slice(0,a)),o==="desc"&&(V=V.reverse());let me=V.map(O=>{if(!q)return O;let{ctid:K,...Ot}=O;return Ot}).filter(O=>Object.keys(O).length>0),De=O=>({values:Object.fromEntries(y.map(K=>[K,O[K]])),sortColumns:y}),Ge=null,at=null;if(V.length>0){let O=V[0],K=V[V.length-1];o==="asc"?(k&&(Ge=this.encodeCursor(De(K))),l&&(at=this.encodeCursor(De(O)))):(l&&(Ge=this.encodeCursor(De(K))),k&&(at=this.encodeCursor(De(O))))}return{data:me,meta:{limit:a,total:$,hasNextPage:o==="asc"?k:!!l,hasPreviousPage:o==="asc"?!!l:k,nextCursor:Ge,prevCursor:at}}}async getDatabasesList(){try{let e=re(),t=await this.supportsDatabaseSize(e)?"pg_size_pretty(pg_database_size(d.datname))":"'unknown'",{rows:r}=await e.query(`
288
+ ORDER BY sp.position LIMIT 1)`});import{HTTPException as v}from"hono/http-exception";var Xr,ei=S(()=>{"use strict";h();ae();We();Ve();je();Zs();Xr=class extends se{databaseSizeSupport;async runQuery(e,t,r){return(await ne(e).query(t,r)).rows}quoteIdentifier(e){return`"${e}"`}mapToUniversalType(e){return sr(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"BOOLEAN",json:"JSONB",date:"TIMESTAMP WITH TIME ZONE",array:"TEXT[]",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:a=50,direction:o="asc",sort:s=[],order:i="asc",filters:l=[],db:c}=e,u=ne(c),m=[],p=i;Array.isArray(s)&&s.length>0?(m=s.map(P=>P.columnName),p=s[0].direction):typeof s=="string"&&s&&(m=[s]);let d=m.length>0?[...m]:["ctid"],{clause:f,values:y}=Aa(l),g="",w=[];if(r){let P=this.decodeCursor(r);if(P){let U=Da(P,o,p,y.length+1);g=U.clause,w=U.values}}let C="";f&&g?C=`WHERE ${f.replace(/^WHERE\s+/i,"")} AND ${g}`:f?C=f:g&&(C=`WHERE ${g}`);let N=Na((Array.isArray(s),s),i),A=N;o==="desc"?N?A=N.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):A=`ORDER BY ${d.map(U=>`"${U}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!N&&d.length>0&&(A=`ORDER BY ${d.map(U=>`"${U}" ${p.toUpperCase()}`).join(", ")}`);let E=y.length+w.length+1,R=`SELECT * FROM "${t}" ${C} ${A} LIMIT $${E}`,D=[...y,...w,a+1],$=`SELECT COUNT(*) as total FROM "${t}" ${f}`;return{sql:R,values:D,countSql:$,countValues:y}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(t.length===0)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,i=[];Array.isArray(o)&&o.length>0?i=o.map(d=>d.columnName):typeof o=="string"&&o&&(i=[o]),i.length===0&&(i=["ctid"]);let l=d=>{let f={values:Object.fromEntries(i.map(y=>[y,d[y]])),sortColumns:i};return this.encodeCursor(f)},c=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(r&&(m=l(u)),s&&(p=l(c))):(s&&(m=l(u)),r&&(p=l(c))),{nextCursor:m,prevCursor:p}}async getTableData(e){let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:i="asc",cursor:l,filters:c=[]}=e,u=ne(r),m=await this.getPrimaryKeyColumns(u,t),p=[],d=i;Array.isArray(s)&&s.length>0?(p=s.map(O=>O.columnName),d=s[0].direction):typeof s=="string"&&s&&(p=[s]);let f=m.length?m:["ctid"],y=[...p,...f.filter(O=>!p.includes(O))],{clause:g,values:w}=Aa(c),C="",N=[];if(l){let O=this.decodeCursor(l);if(O){let K=Da(O,o,d,w.length+1);C=K.clause,N=K.values}}let A="";g&&C?A=`WHERE ${g.replace(/^WHERE\s+/i,"")} AND ${C}`:g?A=g:C&&(A=`WHERE ${C}`);let E=Na((Array.isArray(s),s),i),R=E;if(o==="desc"?E?R=E.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):R=`ORDER BY ${y.map(K=>`"${K}" ${d==="asc"?"DESC":"ASC"}`).join(", ")}`:!E&&y.length>0&&(R=`ORDER BY ${y.map(K=>`"${K}" ${d.toUpperCase()}`).join(", ")}`),E){let O=f.filter(Mt=>!p.includes(Mt)),K=d==="desc"!=(o==="desc")?"DESC":"ASC";O.length&&(R+=`, ${O.map(Mt=>`${this.quoteIdentifier(Mt)} ${K}`).join(", ")}`)}let D=await u.query(`SELECT COUNT(*) as total FROM "${t}" ${g}`,w),$=Number(D.rows[0].total),q=y.includes("ctid"),P=[...m.map(O=>`"${O}"`),...q?["ctid"]:[]],U=w.length+N.length+1,V=(await u.query(`SELECT ${["*",...P].join(", ")} FROM "${t}" ${A} ${R} LIMIT $${U}`,[...w,...N,a+1])).rows,k=V.length>a;k&&(V=V.slice(0,a)),o==="desc"&&(V=V.reverse());let pe=V.map(O=>{if(!q)return O;let{ctid:K,...Mt}=O;return Mt}).filter(O=>Object.keys(O).length>0),Oe=O=>({values:Object.fromEntries(y.map(K=>[K,O[K]])),sortColumns:y}),Je=null,it=null;if(V.length>0){let O=V[0],K=V[V.length-1];o==="asc"?(k&&(Je=this.encodeCursor(Oe(K))),l&&(it=this.encodeCursor(Oe(O)))):(l&&(Je=this.encodeCursor(Oe(K))),k&&(it=this.encodeCursor(Oe(O))))}return{data:pe,meta:{limit:a,total:$,hasNextPage:o==="asc"?k:!!l,hasPreviousPage:o==="asc"?!!l:k,nextCursor:Je,prevCursor:it}}}async getDatabasesList(){try{let e=ne(),t=await this.supportsDatabaseSize(e)?"pg_size_pretty(pg_database_size(d.datname))":"'unknown'",{rows:r}=await e.query(`
289
289
  SELECT
290
290
  d.datname as name,
291
291
  ${t} as size,
@@ -295,7 +295,7 @@ ${s.join(`,
295
295
  WHERE d.datistemplate = false
296
296
  AND (d.datname NOT IN ('postgres', 'rdsadmin') OR d.datname = current_database())
297
297
  ORDER BY d.datname;
298
- `);if(!r[0])throw new v(500,{message:"No databases returned from database"});return r}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=re(),{rows:t}=await e.query("SELECT current_database() AS db;");if(!t[0])throw new v(500,{message:"No current database returned from database"});return t[0]}async getDatabaseConnectionInfo(){let e=re(),{rows:t}=await e.query(`
298
+ `);if(!r[0])throw new v(500,{message:"No databases returned from database"});return r}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){let e=ne(),{rows:t}=await e.query("SELECT current_database() AS db;");if(!t[0])throw new v(500,{message:"No current database returned from database"});return t[0]}async getDatabaseConnectionInfo(){let e=ne(),{rows:t}=await e.query(`
299
299
  SELECT
300
300
  version() as version,
301
301
  current_database() as database,
@@ -304,25 +304,25 @@ ${s.join(`,
304
304
  inet_server_port()::int4 as port,
305
305
  (SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,
306
306
  (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;
307
- `);if(!t[0])throw new v(500,{message:"No connection information returned from database"});let{connectionInfoSchema:r}=await Promise.resolve().then(()=>(ne(),Lo)),a=r.parse(t[0]),o=Re();return{host:a.host||o.host,port:a.port||o.port,user:a.user,database:a.database,version:a.version.toString(),active_connections:a.active_connections,max_connections:a.max_connections}}async getTablesList(e){let t=re(e),r=o=>o.replaceAll('"','""'),{rows:a}=await t.query(`
307
+ `);if(!t[0])throw new v(500,{message:"No connection information returned from database"});let{connectionInfoSchema:r}=await Promise.resolve().then(()=>(ae(),xo)),a=r.parse(t[0]),o=Ae();return{host:a.host||o.host,port:a.port||o.port,user:a.user,database:a.database,version:a.version.toString(),active_connections:a.active_connections,max_connections:a.max_connections}}async getTablesList(e){let t=ne(e),r=c=>c.replaceAll('"','""'),{rows:a}=await t.query(`
308
308
  SELECT table_schema as "schemaName", table_name as "tableName"
309
309
  FROM information_schema.tables
310
310
  WHERE table_type = 'BASE TABLE'
311
311
  AND table_schema NOT IN ('pg_catalog', 'information_schema')
312
312
  AND table_schema NOT LIKE 'pg_toast%'
313
313
  ORDER BY table_schema, table_name;
314
- `);return a[0]?Promise.all(a.map(async o=>{let{rows:s}=await t.query(`SELECT COUNT(*)::integer as count FROM "${r(o.schemaName)}"."${r(o.tableName)}"`);return{schemaName:o.schemaName,tableName:o.tableName,rowCount:s[0]?.count??0}})):[]}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=re(t),i=a.filter(u=>u.isPrimaryKey).map(u=>u.columnName),l=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&&l.push(`PRIMARY KEY (${i.map(u=>`"${u}"`).join(", ")})`);let c=o?.map(u=>`CONSTRAINT "${`fk_${r}_${u.columnName}_${u.referencedTable}_${u.referencedColumn}`}" FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await s.query(`CREATE TABLE "${r}" (
314
+ `);if(!a[0])return[];let o=4,s=Array.from({length:o},()=>[]);a.forEach((c,u)=>{s[u%o]?.push(`SELECT ${u} AS index, COUNT(*) AS count FROM "${r(c.schemaName)}"."${r(c.tableName)}"`)});let i=await Promise.all(s.filter(c=>c.length>0).map(c=>t.query(c.join(" UNION ALL ")))),l=new Map(i.flatMap(({rows:c})=>c.map(u=>[u.index,Number(u.count)])));return a.map((c,u)=>({schemaName:c.schemaName,tableName:c.tableName,rowCount:l.get(u)??0}))}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=ne(t),i=a.filter(u=>u.isPrimaryKey).map(u=>u.columnName),l=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&&l.push(`PRIMARY KEY (${i.map(u=>`"${u}"`).join(", ")})`);let c=o?.map(u=>`CONSTRAINT "${`fk_${r}_${u.columnName}_${u.referencedTable}_${u.referencedColumn}`}" FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await s.query(`CREATE TABLE "${r}" (
315
315
  ${[...l,...c].join(`,
316
316
  `)}
317
- );`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=re(r),{rows:s}=await o.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!s[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(o,t);if(!a&&(await this.getFkReferencesForTable(o,t)).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};try{return await o.query(`DROP TABLE "${t}" ${a?"CASCADE":"RESTRICT"}`),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(l){if(l.code==="2BP01")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};throw l instanceof v?l:new v(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,schemaName:a,db:o}=e;this.assertDifferentTableName(t,r);let s=re(o),{rows:i}=await s.query(`SELECT table_schema as "schemaName" FROM information_schema.tables WHERE table_name = $1 AND table_schema NOT IN ('pg_catalog', 'information_schema') AND table_schema NOT LIKE 'pg_toast%';`,[t]),l=i.map(m=>m.schemaName);if(l.length===0)throw new v(404,{message:`Table "${t}" does not exist`});if(a&&!l.includes(a))throw new v(404,{message:`Table "${a}"."${t}" does not exist`});if(!a&&l.length>1)throw new v(400,{message:`Table "${t}" exists in multiple schemas (${l.join(", ")}); rename is ambiguous`});let c=a??l[0],{rows:u}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = $2) as exists;",[r,c]);if(u[0]?.exists)throw new v(409,{message:`Table "${r}" already exists`});await s.query(`ALTER TABLE "${c.replaceAll('"','""')}"."${t.replaceAll('"','""')}" RENAME TO "${r.replaceAll('"','""')}"`)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=re(t),{rows:a}=await r.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = ANY(current_schemas(false)) AND table_name = $1) as exists",[e]);if(!a[0]?.exists)throw new v(404,{message:`Table "${e}" does not exist`});let{rows:o}=await r.query(`SELECT column_name, data_type, udt_name, is_nullable, column_default, character_maximum_length, numeric_precision, numeric_scale
318
- FROM information_schema.columns WHERE table_schema = ${Me("$1")} AND table_name = $1 ORDER BY ordinal_position`,[e]),{rows:s}=await r.query(`SELECT tc.constraint_name, tc.constraint_type, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
317
+ );`)}async deleteTable(e){let{tableName:t,db:r,cascade:a}=e,o=ne(r),{rows:s}=await o.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!s[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let i=await this.getTableRowCount(o,t);if(!a&&(await this.getFkReferencesForTable(o,t)).length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};try{return await o.query(`DROP TABLE "${t}" ${a?"CASCADE":"RESTRICT"}`),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(l){if(l.code==="2BP01")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecordsForTable(o,t)};throw l instanceof v?l:new v(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){try{let{tableName:t,newTableName:r,schemaName:a,db:o}=e;this.assertDifferentTableName(t,r);let s=ne(o),{rows:i}=await s.query(`SELECT table_schema as "schemaName" FROM information_schema.tables WHERE table_name = $1 AND table_schema NOT IN ('pg_catalog', 'information_schema') AND table_schema NOT LIKE 'pg_toast%';`,[t]),l=i.map(m=>m.schemaName);if(l.length===0)throw new v(404,{message:`Table "${t}" does not exist`});if(a&&!l.includes(a))throw new v(404,{message:`Table "${a}"."${t}" does not exist`});if(!a&&l.length>1)throw new v(400,{message:`Table "${t}" exists in multiple schemas (${l.join(", ")}); rename is ambiguous`});let c=a??l[0],{rows:u}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = $2) as exists;",[r,c]);if(u[0]?.exists)throw new v(409,{message:`Table "${r}" already exists`});await s.query(`ALTER TABLE "${c.replaceAll('"','""')}"."${t.replaceAll('"','""')}" RENAME TO "${r.replaceAll('"','""')}"`)}catch(t){throw this.wrapError(t)}}async getTableSchema({tableName:e,db:t}){let r=ne(t),{rows:a}=await r.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = ANY(current_schemas(false)) AND table_name = $1) as exists",[e]);if(!a[0]?.exists)throw new v(404,{message:`Table "${e}" does not exist`});let{rows:o}=await r.query(`SELECT column_name, data_type, udt_name, is_nullable, column_default, character_maximum_length, numeric_precision, numeric_scale
318
+ FROM information_schema.columns WHERE table_schema = ${xe("$1")} AND table_name = $1 ORDER BY ordinal_position`,[e]),{rows:s}=await r.query(`SELECT tc.constraint_name, tc.constraint_type, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
319
319
  FROM information_schema.table_constraints tc
320
320
  JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
321
321
  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'
322
- WHERE tc.table_schema = ${Me("$1")} AND tc.table_name = $1 ORDER BY tc.constraint_type, tc.constraint_name`,[e]),{rows:i}=await r.query(`SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = ${Me("$1")} AND tablename = $1
323
- AND indexname NOT IN (SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = ${Me("$1")} AND table_name = $1 AND constraint_type = 'PRIMARY KEY')`,[e]),l=d=>{let{data_type:f,udt_name:y,character_maximum_length:g,numeric_precision:w,numeric_scale:C}=d;return f==="USER-DEFINED"?y:f==="ARRAY"?`${y.replace(/^_/,"")}[]`:(f==="character varying"||f==="varchar")&&g?`varchar(${g})`:f==="character"&&g?`char(${g})`:f==="numeric"&&w!==null?C!==null&&C>0?`numeric(${w}, ${C})`:`numeric(${w})`:f==="timestamp with time zone"?"timestamp with time zone":f==="timestamp without time zone"?"timestamp":{"character varying":"varchar",character:"char","double precision":"float8",integer:"integer",bigint:"bigint",smallint:"smallint",boolean:"boolean",text:"text",uuid:"uuid",json:"json",jsonb:"jsonb",date:"date",time:"time",bytea:"bytea"}[f]||f},c=[`create table public.${e} (`],u=o.map(d=>{let f=` ${d.column_name} ${l(d)}`;return d.is_nullable==="NO"&&(f+=" not null"),d.column_default!==null&&(f+=` default ${d.column_default}`),f}),m=new Map;for(let d of s){let f=m.get(d.constraint_name)??[];f.push(d),m.set(d.constraint_name,f)}let p=[];for(let[d,f]of m){let y=f[0],g=f.map(w=>w.column_name).join(", ");y.constraint_type==="PRIMARY KEY"?p.push(` constraint ${d} primary key (${g})`):y.constraint_type==="FOREIGN KEY"?p.push(` constraint ${d} foreign key (${g}) references ${y.foreign_table_name} (${y.foreign_column_name})`):y.constraint_type==="UNIQUE"&&p.push(` constraint ${d} unique (${g})`)}c.push([...u,...p].join(`,
322
+ WHERE tc.table_schema = ${xe("$1")} AND tc.table_name = $1 ORDER BY tc.constraint_type, tc.constraint_name`,[e]),{rows:i}=await r.query(`SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = ${xe("$1")} AND tablename = $1
323
+ AND indexname NOT IN (SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = ${xe("$1")} AND table_name = $1 AND constraint_type = 'PRIMARY KEY')`,[e]),l=d=>{let{data_type:f,udt_name:y,character_maximum_length:g,numeric_precision:w,numeric_scale:C}=d;return f==="USER-DEFINED"?y:f==="ARRAY"?`${y.replace(/^_/,"")}[]`:(f==="character varying"||f==="varchar")&&g?`varchar(${g})`:f==="character"&&g?`char(${g})`:f==="numeric"&&w!==null?C!==null&&C>0?`numeric(${w}, ${C})`:`numeric(${w})`:f==="timestamp with time zone"?"timestamp with time zone":f==="timestamp without time zone"?"timestamp":{"character varying":"varchar",character:"char","double precision":"float8",integer:"integer",bigint:"bigint",smallint:"smallint",boolean:"boolean",text:"text",uuid:"uuid",json:"json",jsonb:"jsonb",date:"date",time:"time",bytea:"bytea"}[f]||f},c=[`create table public.${e} (`],u=o.map(d=>{let f=` ${d.column_name} ${l(d)}`;return d.is_nullable==="NO"&&(f+=" not null"),d.column_default!==null&&(f+=` default ${d.column_default}`),f}),m=new Map;for(let d of s){let f=m.get(d.constraint_name)??[];f.push(d),m.set(d.constraint_name,f)}let p=[];for(let[d,f]of m){let y=f[0],g=f.map(w=>w.column_name).join(", ");y.constraint_type==="PRIMARY KEY"?p.push(` constraint ${d} primary key (${g})`):y.constraint_type==="FOREIGN KEY"?p.push(` constraint ${d} foreign key (${g}) references ${y.foreign_table_name} (${y.foreign_column_name})`):y.constraint_type==="UNIQUE"&&p.push(` constraint ${d} unique (${g})`)}c.push([...u,...p].join(`,
324
324
  `)),c.push(") tablespace pg_default;");for(let d of i)[...m.values()].some(y=>y[0].constraint_type==="UNIQUE"&&y[0].constraint_name===d.indexname)||(c.push(""),c.push(`${d.indexdef};`));return c.join(`
325
- `)}async getTableColumns({tableName:e,db:t}){let r=re(t),{rows:a}=await r.query(`SELECT
325
+ `)}async getTableColumns({tableName:e,db:t}){let r=ne(t),{rows:a}=await r.query(`SELECT
326
326
  c.column_name as "columnName", c.data_type as "dataType", c.udt_name as "udtName",
327
327
  c.is_nullable = 'YES' as "isNullable", c.column_default as "columnDefault",
328
328
  CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END as "isPrimaryKey",
@@ -335,16 +335,16 @@ ${s.join(`,
335
335
  LEFT JOIN (
336
336
  SELECT ku.column_name FROM information_schema.table_constraints tc
337
337
  JOIN information_schema.key_column_usage ku ON tc.constraint_name = ku.constraint_name AND tc.table_schema = ku.table_schema
338
- WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = ${Me("$1")} AND tc.table_name = $1
338
+ WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = ${xe("$1")} AND tc.table_name = $1
339
339
  ) pk ON c.column_name = pk.column_name
340
340
  LEFT JOIN (
341
341
  SELECT kcu.column_name, ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
342
342
  FROM information_schema.table_constraints tc
343
343
  JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
344
344
  JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema
345
- WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = ${Me("$1")} AND tc.table_name = $1
345
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = ${xe("$1")} AND tc.table_name = $1
346
346
  ) fk ON c.column_name = fk.column_name
347
- WHERE c.table_schema = ${Me("$1")} AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e]);if(!a||a.length===0)throw new v(404,{message:`Table "${e}" does not exist`});return a.map(o=>{let s=null;return o.enumValues&&(Array.isArray(o.enumValues)?s=o.enumValues:typeof o.enumValues=="string"&&(s=o.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:o.columnName,dataType:tr(o.dataType),dataTypeLabel:hn(o.dataType),isNullable:o.isNullable,columnDefault:o.columnDefault,isPrimaryKey:o.isPrimaryKey,isForeignKey:o.isForeignKey,referencedTable:o.referencedTable,referencedColumn:o.referencedColumn,enumValues:s}})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,isArray:u,db:m}=e,p=re(m),{rows:d}=await p.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!d[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let{rows:f}=await p.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${Me("$1")}) as exists;`,[t,r]);if(f[0]?.exists)throw new v(409,{message:`Column "${r}" already exists in table "${t}"`});let y=`"${r}" ${a}`;u&&(y+="[]"),s&&(y+=" PRIMARY KEY"),l&&!s&&(y+=" UNIQUE"),i||(y+=" NOT NULL"),c&&(y+=" GENERATED ALWAYS AS IDENTITY"),o?.trim()&&!c&&(y+=` DEFAULT ${o.trim()}`),await p.query(`ALTER TABLE "${t}" ADD COLUMN ${y}`)}async deleteColumn(e){let{tableName:t,columnName:r,cascade:a,db:o}=e,s=re(o),{rows:i}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!i[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let{rows:l}=await s.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${Me("$1")}) as exists;`,[t,r]);if(!l[0]?.exists)throw new v(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rowCount:c}=await s.query(`ALTER TABLE "${t}" DROP COLUMN "${r}" ${a?"CASCADE":"RESTRICT"}`);return{deletedCount:c??0}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=re(i),{rows:c}=await l.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 v(404,{message:`Table "${t}" does not exist`});let{rows:u}=await l.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${Me("$1")}) as exists;`,[t,r]);if(!u[0]?.exists)throw new v(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=await l.connect();try{await m.query("BEGIN"),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" TYPE ${a}`),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" ${o?"DROP":"SET"} NOT NULL`),s?.trim()?await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" SET DEFAULT ${s.trim()}`):await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" DROP DEFAULT`),await m.query("COMMIT")}catch(p){throw await m.query("ROLLBACK"),p}finally{m.release()}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=re(o),i=`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${Me("$1")}) as exists;`,{rows:l}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!l[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let{rows:c}=await s.query(i,[t,r]);if(!c[0]?.exists)throw new v(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rows:u}=await s.query(i,[t,a]);if(u[0]?.exists)throw new v(409,{message:`Column "${a}" already exists in table "${t}"`});await s.query(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${a}"`)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=re(e),s=Object.keys(a),i=Object.values(a),l=s.map((m,p)=>`$${p+1}`).join(", "),c=s.map(m=>`"${m}"`).join(", "),u=await o.query(`INSERT INTO "${r}" (${c}) VALUES (${l}) RETURNING *`,i);if(u.rowCount===0)throw new v(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:u.rowCount??0}}async updateRecords({params:e,db:t}){let{tableName:r}=e,a=re(t),o=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,r),o);let s=this.groupUpdatesByKey(e,o);await a.query("BEGIN");try{let i=0;for(let{keyValues:l,rowUpdates:c}of s){let u=c.map((f,y)=>`"${f.columnName}" = $${y+1}`),m=c.map(f=>f.value!==null&&typeof f.value=="object"?JSON.stringify(f.value):f.value),p=o.map((f,y)=>`"${f}" = $${m.length+y+1}`);m.push(...l);let d=await a.query(`UPDATE "${r}" SET ${u.join(", ")} WHERE ${p.join(" AND ")} RETURNING *`,m);if(d.rowCount===0)throw new v(404,{message:`Record with ${this.describeKey(o,l)} not found in table "${r}"`});i+=d.rowCount??0}return await a.query("COMMIT"),{updatedCount:i}}catch(i){throw await a.query("ROLLBACK"),i instanceof v?i:new v(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=re(r),o=t[0]?.columnName;if(!o)throw new v(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=s.map((l,c)=>`$${c+1}`).join(", ");try{await a.query("BEGIN");let l=await a.query(`DELETE FROM "${e}" WHERE "${o}" IN (${i}) RETURNING *`,s);return await a.query("COMMIT"),{deletedCount:l.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(l){if(await a.query("ROLLBACK"),l.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(a,e,t,r)};throw l instanceof v?l:new v(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=re(r),o=t[0]?.columnName;if(!o)throw new v(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(i=>i.value);await a.query("BEGIN");try{let i=await this.getFkConstraints(a,e),l=0,c=new Set,u=async(d,f,y)=>{let g=await this.getFkConstraints(a,d);for(let N of g){let A=y.map((D,$)=>`$${$+1}`).join(", "),{rows:E}=await a.query(`SELECT "${N.referencedColumn}" FROM "${d}" WHERE "${f}" IN (${A})`,y),R=E.map(D=>D[N.referencedColumn]);R.length>0&&await u(N.referencingTable,N.referencingColumn,R)}let w=y.map((N,A)=>`$${A+1}`).join(", "),C=await a.query(`DELETE FROM "${d}" WHERE "${f}" IN (${w})`,y);l+=C.rowCount??0,c.add(d)};for(let d of i)c.has(d.referencingTable)||await u(d.referencingTable,d.referencingColumn,s);let m=s.map((d,f)=>`$${f+1}`).join(", "),p=await a.query(`DELETE FROM "${e}" WHERE "${o}" IN (${m}) RETURNING *`,s);return await a.query("COMMIT"),{deletedCount:(p.rowCount??0)+l}}catch(i){throw await a.query("ROLLBACK"),i instanceof v?i:new v(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new v(400,{message:"At least one record is required"});let o=await re(r).connect();try{let s=Object.keys(t[0]),i=s.map(c=>`"${c}"`).join(", "),l=0;await o.query("BEGIN");for(let c of t){let u=s.map(p=>c[p]),m=s.map((p,d)=>`$${d+1}`).join(", ");try{await o.query(`INSERT INTO "${e}" (${i}) VALUES (${m}) RETURNING *`,u),l++}catch(p){throw new v(500,{message:`Failed: ${p instanceof Error?p.message:String(p)}`})}}return await o.query("COMMIT"),{success:!0,message:`Bulk insert completed: ${l} records inserted`,successCount:l,failureCount:0}}catch(s){throw await o.query("ROLLBACK"),s instanceof v?s:new v(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=re(t);if(!e?.trim())throw new v(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.query(a),i=performance.now()-o;return{columns:s.fields.map(l=>l.name),rows:s.rows,rowCount:s.rows.length,duration:i,message:s.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 getPrimaryKeyColumns(e,t){return(await e.query(`SELECT a.attname as column_name
347
+ WHERE c.table_schema = ${xe("$1")} AND c.table_name = $1 ORDER BY c.ordinal_position;`,[e]);if(!a||a.length===0)throw new v(404,{message:`Table "${e}" does not exist`});return a.map(o=>{let s=null;return o.enumValues&&(Array.isArray(o.enumValues)?s=o.enumValues:typeof o.enumValues=="string"&&(s=o.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:o.columnName,dataType:sr(o.dataType),dataTypeLabel:wn(o.dataType),isNullable:o.isNullable,columnDefault:o.columnDefault,isPrimaryKey:o.isPrimaryKey,isForeignKey:o.isForeignKey,referencedTable:o.referencedTable,referencedColumn:o.referencedColumn,enumValues:s}})}async addColumn(e){let{tableName:t,columnName:r,columnType:a,defaultValue:o,isPrimaryKey:s,isNullable:i,isUnique:l,isIdentity:c,isArray:u,db:m}=e,p=ne(m),{rows:d}=await p.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!d[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let{rows:f}=await p.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${xe("$1")}) as exists;`,[t,r]);if(f[0]?.exists)throw new v(409,{message:`Column "${r}" already exists in table "${t}"`});let y=`"${r}" ${a}`;u&&(y+="[]"),s&&(y+=" PRIMARY KEY"),l&&!s&&(y+=" UNIQUE"),i||(y+=" NOT NULL"),c&&(y+=" GENERATED ALWAYS AS IDENTITY"),o?.trim()&&!c&&(y+=` DEFAULT ${o.trim()}`),await p.query(`ALTER TABLE "${t}" ADD COLUMN ${y}`)}async deleteColumn(e){let{tableName:t,columnName:r,cascade:a,db:o}=e,s=ne(o),{rows:i}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!i[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let{rows:l}=await s.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${xe("$1")}) as exists;`,[t,r]);if(!l[0]?.exists)throw new v(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rowCount:c}=await s.query(`ALTER TABLE "${t}" DROP COLUMN "${r}" ${a?"CASCADE":"RESTRICT"}`);return{deletedCount:c??0}}async alterColumn(e){let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=ne(i),{rows:c}=await l.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 v(404,{message:`Table "${t}" does not exist`});let{rows:u}=await l.query(`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${xe("$1")}) as exists;`,[t,r]);if(!u[0]?.exists)throw new v(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=await l.connect();try{await m.query("BEGIN"),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" TYPE ${a}`),await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" ${o?"DROP":"SET"} NOT NULL`),s?.trim()?await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" SET DEFAULT ${s.trim()}`):await m.query(`ALTER TABLE "${t}" ALTER COLUMN "${r}" DROP DEFAULT`),await m.query("COMMIT")}catch(p){throw await m.query("ROLLBACK"),p}finally{m.release()}}async renameColumn(e){let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=ne(o),i=`SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = ${xe("$1")}) as exists;`,{rows:l}=await s.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1 AND table_schema = ANY(current_schemas(false))) as exists;",[t]);if(!l[0]?.exists)throw new v(404,{message:`Table "${t}" does not exist`});let{rows:c}=await s.query(i,[t,r]);if(!c[0]?.exists)throw new v(404,{message:`Column "${r}" does not exist in table "${t}"`});let{rows:u}=await s.query(i,[t,a]);if(u[0]?.exists)throw new v(409,{message:`Column "${a}" already exists in table "${t}"`});await s.query(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${a}"`)}async addRecord({db:e,params:t}){let{tableName:r,data:a}=t,o=ne(e),s=Object.keys(a),i=Object.values(a),l=s.map((m,p)=>`$${p+1}`).join(", "),c=s.map(m=>`"${m}"`).join(", "),u=await o.query(`INSERT INTO "${r}" (${c}) VALUES (${l}) RETURNING *`,i);if(u.rowCount===0)throw new v(500,{message:`Failed to insert record into "${r}"`});return{insertedCount:u.rowCount??0}}async updateRecords({params:e,db:t}){let{tableName:r}=e,a=ne(t),o=this.resolveKeyColumns(e);this.assertWholeKey(await this.getPrimaryKeyColumns(a,r),o);let s=this.groupUpdatesByKey(e,o);await a.query("BEGIN");try{let i=0;for(let{keyValues:l,rowUpdates:c}of s){let u=c.map((f,y)=>`"${f.columnName}" = $${y+1}`),m=c.map(f=>f.value!==null&&typeof f.value=="object"?JSON.stringify(f.value):f.value),p=o.map((f,y)=>`"${f}" = $${m.length+y+1}`);m.push(...l);let d=await a.query(`UPDATE "${r}" SET ${u.join(", ")} WHERE ${p.join(" AND ")} RETURNING *`,m);if(d.rowCount===0)throw new v(404,{message:`Record with ${this.describeKey(o,l)} not found in table "${r}"`});i+=d.rowCount??0}return await a.query("COMMIT"),{updatedCount:i}}catch(i){throw await a.query("ROLLBACK"),i instanceof v?i:new v(500,{message:`Failed to update records in "${r}"`})}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=ne(r),o=t[0]?.columnName;if(!o)throw new v(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(l=>l.value),i=s.map((l,c)=>`$${c+1}`).join(", ");try{await a.query("BEGIN");let l=await a.query(`DELETE FROM "${e}" WHERE "${o}" IN (${i}) RETURNING *`,s);return await a.query("COMMIT"),{deletedCount:l.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(l){if(await a.query("ROLLBACK"),l.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(a,e,t,r)};throw l instanceof v?l:new v(500,{message:`Failed to delete records from "${e}"`})}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=ne(r),o=t[0]?.columnName;if(!o)throw new v(400,{message:"Primary key column name is required"});this.assertDeletableKey(await this.getPrimaryKeyColumns(a,e));let s=t.map(i=>i.value);await a.query("BEGIN");try{let i=await this.getFkConstraints(a,e),l=0,c=new Set,u=async(d,f,y)=>{let g=await this.getFkConstraints(a,d);for(let N of g){let A=y.map((D,$)=>`$${$+1}`).join(", "),{rows:E}=await a.query(`SELECT "${N.referencedColumn}" FROM "${d}" WHERE "${f}" IN (${A})`,y),R=E.map(D=>D[N.referencedColumn]);R.length>0&&await u(N.referencingTable,N.referencingColumn,R)}let w=y.map((N,A)=>`$${A+1}`).join(", "),C=await a.query(`DELETE FROM "${d}" WHERE "${f}" IN (${w})`,y);l+=C.rowCount??0,c.add(d)};for(let d of i)c.has(d.referencingTable)||await u(d.referencingTable,d.referencingColumn,s);let m=s.map((d,f)=>`$${f+1}`).join(", "),p=await a.query(`DELETE FROM "${e}" WHERE "${o}" IN (${m}) RETURNING *`,s);return await a.query("COMMIT"),{deletedCount:(p.rowCount??0)+l}}catch(i){throw await a.query("ROLLBACK"),i instanceof v?i:new v(500,{message:`Failed to force delete records from "${e}"`})}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t||t.length===0)throw new v(400,{message:"At least one record is required"});let o=await ne(r).connect();try{let s=Object.keys(t[0]),i=s.map(c=>`"${c}"`).join(", "),l=0;await o.query("BEGIN");for(let c of t){let u=s.map(p=>c[p]),m=s.map((p,d)=>`$${d+1}`).join(", ");try{await o.query(`INSERT INTO "${e}" (${i}) VALUES (${m}) RETURNING *`,u),l++}catch(p){throw new v(500,{message:`Failed: ${p instanceof Error?p.message:String(p)}`})}}return await o.query("COMMIT"),{success:!0,message:`Bulk insert completed: ${l} records inserted`,successCount:l,failureCount:0}}catch(s){throw await o.query("ROLLBACK"),s instanceof v?s:new v(500,{message:`Failed to bulk insert records into "${e}"`})}finally{o.release()}}async executeQuery({query:e,db:t}){let r=ne(t);if(!e?.trim())throw new v(400,{message:"Query is required"});let a=e.trim().replace(/;+$/,""),o=performance.now(),s=await r.query(a),i=performance.now()-o;return{columns:s.fields.map(l=>l.name),rows:s.rows,rowCount:s.rows.length,duration:i,message:s.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 getPrimaryKeyColumns(e,t){return(await e.query(`SELECT a.attname as column_name
348
348
  FROM pg_index i
349
349
  JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
350
350
  WHERE i.indrelid = $1::regclass AND i.indisprimary
@@ -353,8 +353,8 @@ ${s.join(`,
353
353
  FROM information_schema.table_constraints AS tc
354
354
  JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
355
355
  JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name AND ccu.table_schema = tc.table_schema
356
- WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1`,[t]);return r.map(a=>({constraintName:a.constraint_name,referencingTable:a.referencing_table,referencingColumn:a.referencing_column,referencedTable:a.referenced_table,referencedColumn:a.referenced_column}))}async getFkReferencesForTable(e,t){return this.getFkConstraints(e,t)}async getRelatedRecordsForTable(e,t){let r=await this.getFkReferencesForTable(e,t);if(r.length===0)return[];let a=[];for(let o of r){let{rows:s}=await e.query(`SELECT * FROM "${o.referencingTable}" LIMIT 100`);s.length>0&&a.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return a}async getRelatedRecords(e,t,r,a){let o=await this.getFkConstraints(e,t);if(o.length===0)return[];let s=[],i=r.map(c=>c.value),l=new Map;for(let c of o){let u=`${c.referencingTable}.${c.referencingColumn}`,m=l.get(u)??[];m.push(c),l.set(u,m)}for(let[,c]of l){let u=c[0];if(!u||!r.find(f=>f.columnName===u.referencedColumn))continue;let p=i.map((f,y)=>`$${y+1}`).join(", "),{rows:d}=await e.query(`SELECT * FROM "${u.referencingTable}" WHERE "${u.referencingColumn}" IN (${p}) LIMIT 100`,i);d.length>0&&s.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return s}async getTableRowCount(e,t){let{rows:r}=await e.query(`SELECT COUNT(*) as count FROM "${t}"`);return Number.parseInt(r[0]?.count??"0",10)}}});function Xs(n){let e=[],t="",r=0,a=!1,o=!1;for(;r<n.length;){let s=n[r];if(a){s==="'"?a=!1:t+=s,r++;continue}if(o){if(s==="\\"&&r+1<n.length){t+=n[r+1],r+=2;continue}s==='"'?o=!1:t+=s,r++;continue}if(s==="'"){a=!0,r++;continue}if(s==='"'){o=!0,r++;continue}if(s===" "||s===" "||s===`
357
- `){t.length>0&&(e.push(t),t=""),r++;continue}t+=s,r++}if(a||o)throw new Error("Unterminated quoted string in command");return t.length>0&&e.push(t),e}function Zs(n,e){if(n.length===0)return At(e);let t=n[0]?.toUpperCase()??"",r=n[1]?.toUpperCase();if((t==="ZRANGE"||t==="ZREVRANGE"||t==="ZRANGEBYSCORE")&&n.some(o=>o.toUpperCase()==="WITHSCORES"))return xu(e);if(r){let o=`${t} ${r}`,s=Qs[o];if(s)return s(e)}let a=Qs[t];return a?a(e):typeof e=="string"||typeof e=="number"||e===null?Ce(e):ku(e)?We(e):At(e)}var ku,Js,At,Ce,Ys,We,zs,xu,vu,Gs,Qs,ei=S(()=>{"use strict";h();ku=n=>Array.isArray(n)&&n.every(e=>typeof e=="string"||e===null),Js=n=>Array.isArray(n)&&n.length%2===0;At=n=>({columns:["result"],rows:[{result:typeof n=="string"?n:JSON.stringify(n,null,2)}],rowCount:1}),Ce=n=>n===null?{columns:["value"],rows:[{value:null}],rowCount:0}:{columns:["value"],rows:[{value:n}],rowCount:1},Ys=n=>({columns:["status"],rows:[{status:n}],rowCount:1}),We=n=>Array.isArray(n)?{columns:["#","value"],rows:n.map((e,t)=>({"#":t,value:e})),rowCount:n.length}:At(n),zs=n=>{if(!Js(n))return At(n);let e=[];for(let t=0;t<n.length;t+=2)e.push({field:n[t],value:n[t+1]});return{columns:["field","value"],rows:e,rowCount:e.length}},xu=n=>{if(!Js(n))return We(n);let e=[];for(let t=0;t<n.length;t+=2)e.push({member:n[t],score:n[t+1]});return{columns:["member","score"],rows:e,rowCount:e.length}},vu=n=>{if(typeof n!="string")return At(n);let e=[],t="";for(let r of n.split(/\r?\n/)){if(!r.trim())continue;if(r.startsWith("#")){t=r.replace(/^#\s*/,"").trim();continue}let a=r.indexOf(":");a<0||e.push({section:t,key:r.slice(0,a),value:r.slice(a+1)})}return{columns:["section","key","value"],rows:e,rowCount:e.length}},Gs=n=>{if(!Array.isArray(n))return At(n);let e=n.map(t=>{if(!Array.isArray(t)||t.length<2)return{id:null,fields:null};let[r,a]=t,o={};if(Array.isArray(a))for(let s=0;s<a.length;s+=2)o[String(a[s])]=a[s+1];return{id:r,fields:o}});return{columns:["id","fields"],rows:e,rowCount:e.length}},Qs={PING:Ys,GET:Ce,SET:Ys,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:We,MGET:We,KEYS:We,LRANGE:We,SMEMBERS:We,HGETALL:zs,HKEYS:We,HVALS:We,"CONFIG GET":zs,ZRANGE:We,INFO:vu,XRANGE:Gs,XREVRANGE:Gs}});import{createHash as qu,randomBytes as Uu}from"crypto";import{HTTPException as _}from"hono/http-exception";import{z as Ye}from"zod";function ri(n){let e={};for(let t of n.split(/\r?\n/)){if(!t||t.startsWith("#"))continue;let r=t.indexOf(":");r<0||(e[t.slice(0,r)]=t.slice(r+1))}return e}function rm(n){let e=new Map;for(let t of n.split(/\r?\n/)){let r=t.match(/^db(\d+):keys=(\d+)/);r&&e.set(Number(r[1]),Number(r[2]))}return e}function ni(n){let e=n.key;if(e==null||e==="")throw new _(400,{message:"Field 'key' is required"});return String(e)}function Na(n){let e=n.ttl;if(e==null||e==="")return null;let t=typeof e=="number"?e:Number.parseInt(String(e),10);return Number.isFinite(t)?t:null}function Qr(n){return typeof n=="string"?n:n==null?"":typeof n=="object"?JSON.stringify(n):String(n)}function ai(n,e){if(typeof n=="string"){try{let t=JSON.parse(n);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}throw new _(400,{message:`Value for ${e} must be a JSON object`})}if(n&&typeof n=="object"&&!Array.isArray(n))return n;throw new _(400,{message:`Value for ${e} must be a JSON object`})}function oi(n,e){if(Array.isArray(n))return n;if(typeof n=="string")try{let t=JSON.parse(n);if(Array.isArray(t))return t}catch{}throw new _(400,{message:`Value for ${e} must be a JSON array`})}function nm(n){let e;if(Array.isArray(n))e=n;else if(typeof n=="string")try{e=JSON.parse(n)}catch{throw new _(400,{message:"Value for zset must be an array of {member, score} entries"})}else throw new _(400,{message:"Value for zset must be an array of {member, score} entries"});let t=[];for(let r of e){if(!r||typeof r!="object")throw new _(400,{message:"Each zset entry must be an object with 'member' and 'score'"});let a=r;if(a.member===void 0||a.score===void 0)throw new _(400,{message:"Each zset entry must include 'member' and 'score'"});let o=typeof a.score=="number"?a.score:Number(a.score);if(!Number.isFinite(o))throw new _(400,{message:`Invalid score: ${String(a.score)}`});t.push({member:String(a.member),score:o})}return t}function am(n){if(!n)return[];let e=[];for(let t=0;t<n.length;t+=2){let r=Number(n[t+1]);e.push({member:n[t],score:Number.isFinite(r)?r:0})}return e}function om(n){if(!Array.isArray(n))return{length:0,firstId:null,lastId:null};let e={};for(let s=0;s<n.length;s+=2)e[String(n[s])]=n[s+1];let t=typeof e.length=="number"?e.length:Number.parseInt(String(e.length??"0"),10)||0,r=e["first-entry"],a=e["last-entry"],o=s=>Array.isArray(s)&&typeof s[0]=="string"?s[0]:null;return{length:t,firstId:o(r),lastId:o(a)}}var Yt,Ra,Ht,Bu,Fu,Ku,ju,Hu,Wu,Vu,Yu,zu,rt,ye,Gu,Qu,Wt,Ju,Ne,Xu,zr,ee,Gr,ct,Vt,Sa,Oe,Aa,Zu,em,Ve,Nt,Dt,ti,tm,Jr,si=S(()=>{"use strict";h();je();He();ei();Yt=["strings","hashes","lists","sets","zsets","streams"],Ra={strings:"string",hashes:"hash",lists:"list",sets:"set",zsets:"zset",streams:"stream"},Ht="Schema is fixed for Redis tables; this operation is not supported",Bu="Sorting is not supported for Redis tables",Fu="Filtering is not supported for Redis tables",Ku="Backward pagination is not supported for Redis tables (SCAN is forward-only)",ju=10,Hu=3e4,Wu=1e4,Vu=256*1024,Yu=8*1024*1024,zu=n=>Yt.includes(n),rt=n=>{if(!zu(n))throw new _(404,{message:`Table "${n}" does not exist in Redis. Valid tables: ${Yt.join(", ")}`});return n},ye=n=>{if(n==="")return lt();let e=Number.parseInt(n,10);if(!Number.isFinite(e)||e<0)throw new _(400,{message:`Invalid Redis database index: "${n}". Expected a non-negative integer.`});return e},Gu=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),Qu=n=>{try{return Ye.object({scanCursor:Ye.string().regex(/^\d+$/),search:Ye.string().max(512).optional(),exactPattern:Ye.boolean(),type:Ye.enum(["string","hash","list","set","zset","stream"]).optional()}).parse(JSON.parse(Buffer.from(n,"base64url").toString("utf-8")))}catch{return null}},Wt=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),Ju=n=>{try{return Ye.object({key:Ye.string().min(1).max(16*1024),type:Ye.enum(["string","hash","list","set","zset","stream","unknown"]),cursor:Ye.string().min(1).max(512),direction:Ye.enum(["forward","backward"])}).parse(JSON.parse(Buffer.from(n,"base64url").toString("utf8")))}catch{return null}},Ne=n=>{let e=n.toString("utf8");return Buffer.from(e,"utf8").equals(n)?{base64:n.toString("base64url"),utf8:e}:{base64:n.toString("base64url")}},Xu=n=>n.replaceAll(/[\\*?[\]]/g,"\\$&"),zr=n=>{let e=Buffer.isBuffer(n)?n.toString("utf8"):String(n);return["string","hash","list","set","zset","stream"].includes(e)?e:"unknown"},ee=n=>Buffer.from(n,"base64url"),Gr=n=>n==="-"?Buffer.alloc(0):ee(n),ct=n=>qu("sha256").update(n).digest("base64url"),Vt=()=>new _(409,{message:"This key changed since it was loaded. Reload it or explicitly overwrite."}),Sa=n=>{let e=n instanceof Error?n.message:String(n);return/(NOPERM|unknown command|not allowed|unsupported)/i.test(e)},Oe=(n,e)=>{if(n!==e)throw new _(400,{message:`This operation requires a ${e} key, but the key is ${n}.`})},Aa=n=>{if(n===null)throw Vt();if(!Array.isArray(n))return;let e=n.find(t=>Array.isArray(t)&&t[0]instanceof Error);if(e)throw new _(400,{message:e[0].message})},Zu=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),em=n=>{try{return JSON.parse(Buffer.from(n,"base64url").toString("utf-8"))}catch{return null}},Ve=n=>({columnName:n.columnName,dataType:n.dataType,dataTypeLabel:n.dataTypeLabel??(n.dataType==="number"?"int":n.dataType==="json"?"json":n.dataType==="array"?"array":"text"),isNullable:n.isNullable??!1,columnDefault:n.columnDefault??null,isPrimaryKey:n.isPrimaryKey??!1,isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}),Nt=Ve({columnName:"key",dataType:"text",isPrimaryKey:!0}),Dt=Ve({columnName:"ttl",dataType:"number",isNullable:!0}),ti={strings:[Nt,Ve({columnName:"value",dataType:"text",isNullable:!0}),Dt],hashes:[Nt,Ve({columnName:"value",dataType:"json"}),Dt],lists:[Nt,Ve({columnName:"value",dataType:"array"}),Dt],sets:[Nt,Ve({columnName:"value",dataType:"array"}),Dt],zsets:[Nt,Ve({columnName:"value",dataType:"json"}),Dt],streams:[Nt,Ve({columnName:"length",dataType:"number"}),Ve({columnName:"first-id",dataType:"text",isNullable:!0}),Ve({columnName:"last-id",dataType:"text",isNullable:!0}),Dt]},tm={strings:`-- Redis string keys
356
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = $1`,[t]);return r.map(a=>({constraintName:a.constraint_name,referencingTable:a.referencing_table,referencingColumn:a.referencing_column,referencedTable:a.referenced_table,referencedColumn:a.referenced_column}))}async getFkReferencesForTable(e,t){return this.getFkConstraints(e,t)}async getRelatedRecordsForTable(e,t){let r=await this.getFkReferencesForTable(e,t);if(r.length===0)return[];let a=[];for(let o of r){let{rows:s}=await e.query(`SELECT * FROM "${o.referencingTable}" LIMIT 100`);s.length>0&&a.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return a}async getRelatedRecords(e,t,r,a){let o=await this.getFkConstraints(e,t);if(o.length===0)return[];let s=[],i=r.map(c=>c.value),l=new Map;for(let c of o){let u=`${c.referencingTable}.${c.referencingColumn}`,m=l.get(u)??[];m.push(c),l.set(u,m)}for(let[,c]of l){let u=c[0];if(!u||!r.find(f=>f.columnName===u.referencedColumn))continue;let p=i.map((f,y)=>`$${y+1}`).join(", "),{rows:d}=await e.query(`SELECT * FROM "${u.referencingTable}" WHERE "${u.referencingColumn}" IN (${p}) LIMIT 100`,i);d.length>0&&s.push({tableName:u.referencingTable,columnName:u.referencingColumn,constraintName:u.constraintName,records:d})}return s}async getTableRowCount(e,t){let{rows:r}=await e.query(`SELECT COUNT(*) as count FROM "${t}"`);return Number.parseInt(r[0]?.count??"0",10)}}});function si(n){let e=[],t="",r=0,a=!1,o=!1;for(;r<n.length;){let s=n[r];if(a){s==="'"?a=!1:t+=s,r++;continue}if(o){if(s==="\\"&&r+1<n.length){t+=n[r+1],r+=2;continue}s==='"'?o=!1:t+=s,r++;continue}if(s==="'"){a=!0,r++;continue}if(s==='"'){o=!0,r++;continue}if(s===" "||s===" "||s===`
357
+ `){t.length>0&&(e.push(t),t=""),r++;continue}t+=s,r++}if(a||o)throw new Error("Unterminated quoted string in command");return t.length>0&&e.push(t),e}function ii(n,e){if(n.length===0)return $t(e);let t=n[0]?.toUpperCase()??"",r=n[1]?.toUpperCase();if((t==="ZRANGE"||t==="ZREVRANGE"||t==="ZRANGEBYSCORE")&&n.some(o=>o.toUpperCase()==="WITHSCORES"))return Gu(e);if(r){let o=`${t} ${r}`,s=ai[o];if(s)return s(e)}let a=ai[t];return a?a(e):typeof e=="string"||typeof e=="number"||e===null?Se(e):zu(e)?Ye(e):$t(e)}var zu,oi,$t,Se,ti,Ye,ri,Gu,Qu,ni,ai,li=S(()=>{"use strict";h();zu=n=>Array.isArray(n)&&n.every(e=>typeof e=="string"||e===null),oi=n=>Array.isArray(n)&&n.length%2===0;$t=n=>({columns:["result"],rows:[{result:typeof n=="string"?n:JSON.stringify(n,null,2)}],rowCount:1}),Se=n=>n===null?{columns:["value"],rows:[{value:null}],rowCount:0}:{columns:["value"],rows:[{value:n}],rowCount:1},ti=n=>({columns:["status"],rows:[{status:n}],rowCount:1}),Ye=n=>Array.isArray(n)?{columns:["#","value"],rows:n.map((e,t)=>({"#":t,value:e})),rowCount:n.length}:$t(n),ri=n=>{if(!oi(n))return $t(n);let e=[];for(let t=0;t<n.length;t+=2)e.push({field:n[t],value:n[t+1]});return{columns:["field","value"],rows:e,rowCount:e.length}},Gu=n=>{if(!oi(n))return Ye(n);let e=[];for(let t=0;t<n.length;t+=2)e.push({member:n[t],score:n[t+1]});return{columns:["member","score"],rows:e,rowCount:e.length}},Qu=n=>{if(typeof n!="string")return $t(n);let e=[],t="";for(let r of n.split(/\r?\n/)){if(!r.trim())continue;if(r.startsWith("#")){t=r.replace(/^#\s*/,"").trim();continue}let a=r.indexOf(":");a<0||e.push({section:t,key:r.slice(0,a),value:r.slice(a+1)})}return{columns:["section","key","value"],rows:e,rowCount:e.length}},ni=n=>{if(!Array.isArray(n))return $t(n);let e=n.map(t=>{if(!Array.isArray(t)||t.length<2)return{id:null,fields:null};let[r,a]=t,o={};if(Array.isArray(a))for(let s=0;s<a.length;s+=2)o[String(a[s])]=a[s+1];return{id:r,fields:o}});return{columns:["id","fields"],rows:e,rowCount:e.length}},ai={PING:ti,GET:Se,SET:ti,TYPE:Se,TTL:Se,EXISTS:Se,DBSIZE:Se,DEL:Se,INCR:Se,DECR:Se,STRLEN:Se,LLEN:Se,SCARD:Se,ZCARD:Se,HLEN:Se,HGET:Se,HMGET:Ye,MGET:Ye,KEYS:Ye,LRANGE:Ye,SMEMBERS:Ye,HGETALL:ri,HKEYS:Ye,HVALS:Ye,"CONFIG GET":ri,ZRANGE:Ye,INFO:Qu,XRANGE:ni,XREVRANGE:ni}});import{createHash as Ju,randomBytes as Xu}from"crypto";import{HTTPException as _}from"hono/http-exception";import{z as Ge}from"zod";function ui(n){let e={};for(let t of n.split(/\r?\n/)){if(!t||t.startsWith("#"))continue;let r=t.indexOf(":");r<0||(e[t.slice(0,r)]=t.slice(r+1))}return e}function ym(n){let e=new Map;for(let t of n.split(/\r?\n/)){let r=t.match(/^db(\d+):keys=(\d+)/);r&&e.set(Number(r[1]),Number(r[2]))}return e}function mi(n){let e=n.key;if(e==null||e==="")throw new _(400,{message:"Field 'key' is required"});return String(e)}function Pa(n){let e=n.ttl;if(e==null||e==="")return null;let t=typeof e=="number"?e:Number.parseInt(String(e),10);return Number.isFinite(t)?t:null}function tn(n){return typeof n=="string"?n:n==null?"":typeof n=="object"?JSON.stringify(n):String(n)}function di(n,e){if(typeof n=="string"){try{let t=JSON.parse(n);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}throw new _(400,{message:`Value for ${e} must be a JSON object`})}if(n&&typeof n=="object"&&!Array.isArray(n))return n;throw new _(400,{message:`Value for ${e} must be a JSON object`})}function pi(n,e){if(Array.isArray(n))return n;if(typeof n=="string")try{let t=JSON.parse(n);if(Array.isArray(t))return t}catch{}throw new _(400,{message:`Value for ${e} must be a JSON array`})}function hm(n){let e;if(Array.isArray(n))e=n;else if(typeof n=="string")try{e=JSON.parse(n)}catch{throw new _(400,{message:"Value for zset must be an array of {member, score} entries"})}else throw new _(400,{message:"Value for zset must be an array of {member, score} entries"});let t=[];for(let r of e){if(!r||typeof r!="object")throw new _(400,{message:"Each zset entry must be an object with 'member' and 'score'"});let a=r;if(a.member===void 0||a.score===void 0)throw new _(400,{message:"Each zset entry must include 'member' and 'score'"});let o=typeof a.score=="number"?a.score:Number(a.score);if(!Number.isFinite(o))throw new _(400,{message:`Invalid score: ${String(a.score)}`});t.push({member:String(a.member),score:o})}return t}function bm(n){if(!n)return[];let e=[];for(let t=0;t<n.length;t+=2){let r=Number(n[t+1]);e.push({member:n[t],score:Number.isFinite(r)?r:0})}return e}function gm(n){if(!Array.isArray(n))return{length:0,firstId:null,lastId:null};let e={};for(let s=0;s<n.length;s+=2)e[String(n[s])]=n[s+1];let t=typeof e.length=="number"?e.length:Number.parseInt(String(e.length??"0"),10)||0,r=e["first-entry"],a=e["last-entry"],o=s=>Array.isArray(s)&&typeof s[0]=="string"?s[0]:null;return{length:t,firstId:o(r),lastId:o(a)}}var Xt,_a,Gt,Zu,em,tm,rm,nm,am,om,sm,im,ot,be,lm,cm,Qt,um,_e,mm,Zr,te,en,pt,Jt,Oa,Pe,$a,dm,pm,ze,Pt,It,ci,fm,rn,fi=S(()=>{"use strict";h();We();Ve();li();Xt=["strings","hashes","lists","sets","zsets","streams"],_a={strings:"string",hashes:"hash",lists:"list",sets:"set",zsets:"zset",streams:"stream"},Gt="Schema is fixed for Redis tables; this operation is not supported",Zu="Sorting is not supported for Redis tables",em="Filtering is not supported for Redis tables",tm="Backward pagination is not supported for Redis tables (SCAN is forward-only)",rm=10,nm=3e4,am=1e4,om=256*1024,sm=8*1024*1024,im=n=>Xt.includes(n),ot=n=>{if(!im(n))throw new _(404,{message:`Table "${n}" does not exist in Redis. Valid tables: ${Xt.join(", ")}`});return n},be=n=>{if(n==="")return dt();let e=Number.parseInt(n,10);if(!Number.isFinite(e)||e<0)throw new _(400,{message:`Invalid Redis database index: "${n}". Expected a non-negative integer.`});return e},lm=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),cm=n=>{try{return Ge.object({scanCursor:Ge.string().regex(/^\d+$/),search:Ge.string().max(512).optional(),exactPattern:Ge.boolean(),type:Ge.enum(["string","hash","list","set","zset","stream"]).optional()}).parse(JSON.parse(Buffer.from(n,"base64url").toString("utf-8")))}catch{return null}},Qt=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),um=n=>{try{return Ge.object({key:Ge.string().min(1).max(16*1024),type:Ge.enum(["string","hash","list","set","zset","stream","unknown"]),cursor:Ge.string().min(1).max(512),direction:Ge.enum(["forward","backward"])}).parse(JSON.parse(Buffer.from(n,"base64url").toString("utf8")))}catch{return null}},_e=n=>{let e=n.toString("utf8");return Buffer.from(e,"utf8").equals(n)?{base64:n.toString("base64url"),utf8:e}:{base64:n.toString("base64url")}},mm=n=>n.replaceAll(/[\\*?[\]]/g,"\\$&"),Zr=n=>{let e=Buffer.isBuffer(n)?n.toString("utf8"):String(n);return["string","hash","list","set","zset","stream"].includes(e)?e:"unknown"},te=n=>Buffer.from(n,"base64url"),en=n=>n==="-"?Buffer.alloc(0):te(n),pt=n=>Ju("sha256").update(n).digest("base64url"),Jt=()=>new _(409,{message:"This key changed since it was loaded. Reload it or explicitly overwrite."}),Oa=n=>{let e=n instanceof Error?n.message:String(n);return/(NOPERM|unknown command|not allowed|unsupported)/i.test(e)},Pe=(n,e)=>{if(n!==e)throw new _(400,{message:`This operation requires a ${e} key, but the key is ${n}.`})},$a=n=>{if(n===null)throw Jt();if(!Array.isArray(n))return;let e=n.find(t=>Array.isArray(t)&&t[0]instanceof Error);if(e)throw new _(400,{message:e[0].message})},dm=n=>Buffer.from(JSON.stringify(n)).toString("base64url"),pm=n=>{try{return JSON.parse(Buffer.from(n,"base64url").toString("utf-8"))}catch{return null}},ze=n=>({columnName:n.columnName,dataType:n.dataType,dataTypeLabel:n.dataTypeLabel??(n.dataType==="number"?"int":n.dataType==="json"?"json":n.dataType==="array"?"array":"text"),isNullable:n.isNullable??!1,columnDefault:n.columnDefault??null,isPrimaryKey:n.isPrimaryKey??!1,isForeignKey:!1,referencedTable:null,referencedColumn:null,enumValues:null}),Pt=ze({columnName:"key",dataType:"text",isPrimaryKey:!0}),It=ze({columnName:"ttl",dataType:"number",isNullable:!0}),ci={strings:[Pt,ze({columnName:"value",dataType:"text",isNullable:!0}),It],hashes:[Pt,ze({columnName:"value",dataType:"json"}),It],lists:[Pt,ze({columnName:"value",dataType:"array"}),It],sets:[Pt,ze({columnName:"value",dataType:"array"}),It],zsets:[Pt,ze({columnName:"value",dataType:"json"}),It],streams:[Pt,ze({columnName:"length",dataType:"number"}),ze({columnName:"first-id",dataType:"text",isNullable:!0}),ze({columnName:"last-id",dataType:"text",isNullable:!0}),It]},fm={strings:`-- Redis string keys
358
358
  -- Columns: key (text, PK), value (text), ttl (number, seconds; -1 = no TTL, -2 = missing)
359
359
  -- Backed by: GET / SET / EXPIRE`,hashes:`-- Redis hash keys
360
360
  -- Columns: key (text, PK), value (json: {field: value, ...}), ttl (number)
@@ -366,15 +366,15 @@ ${s.join(`,
366
366
  -- Columns: key (text, PK), value (json: [{member, score}, ...]), ttl (number)
367
367
  -- Backed by: ZRANGE WITHSCORES / ZADD / EXPIRE`,streams:`-- Redis stream keys
368
368
  -- Columns: key (text, PK), length (number), first-id (text), last-id (text), ttl (number)
369
- -- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},Jr=class extends oe{countCache=new Map;runQuery(){throw new _(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new _(501,{message:"buildTableDataQuery is not supported for Redis"})}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"string":return"text";case"hash":return"json";case"list":case"set":return"array";case"zset":case"stream":return"json";case"integer":case"number":case"ttl":return"number";default:return"text"}}mapFromUniversalType(e){return"string"}async scanKeys(e){try{let{db:t,limit:r,search:a,exactPattern:o,type:s,cursor:i}=e,l=ye(t),c=await Ae(l),u="0";if(i){let C=Qu(i);if(!C||C.search!==a||C.exactPattern!==o||C.type!==s)throw new _(400,{message:"Invalid or stale key scan cursor"});u=C.scanCursor}let m=a?o?a:`*${Xu(a)}*`:"*",p=[u,"MATCH",m,"COUNT",r];s&&p.push("TYPE",s);let[d,f]=await c.scanBuffer(...p),y=Buffer.isBuffer(d)?d.toString("utf8"):d,g=c.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,N)=>{let A=N*3,E=w[A+2]?.[1];return{key:Ne(C),type:zr(w[A]?.[1]),ttlMs:Number(w[A+1]?.[1]??-2),memoryBytes:E==null?null:Number(E)}}),nextCursor:y==="0"?null:Gu({scanCursor:y,search:a,exactPattern:o,type:s}),hasMore:y!=="0"}}catch(t){throw this.wrapError(t)}}async getKeyDetails(e){try{let{db:t,key:r,cursor:a,limit:o,full:s,direction:i}=e,l=Gr(r),c=await Ae(ye(t)),[u,m,p,d]=await Promise.all([c.callBuffer("TYPE",l),c.pttl(l),c.call("MEMORY","USAGE",l).catch(()=>null),c.callBuffer("DUMP",l)]),f=d;if(!f)throw new _(404,{message:"Redis key no longer exists"});let y=zr(u),g={key:Ne(l),type:y,ttlMs:Number(m),memoryBytes:p===null?null:Number(p),revision:ct(f)},w=a?Ju(a):null;if(a&&(!w||w.key!==r||w.type!==y||w.direction!==i))throw new _(400,{message:"Invalid or stale key details cursor"});if(y==="string"){let C=await c.strlen(l),N=s?Yu:Vu,A=await c.getrangeBuffer(l,0,N-1);return{...g,length:C,value:{kind:"string",value:Ne(A),truncated:C>N},nextCursor:null,hasMore:!1}}if(y==="hash"){let[C,N]=await Promise.all([c.hlen(l),c.hscanBuffer(l,w?.cursor??"0","COUNT",String(o))]),[A,E]=N,R=Buffer.isBuffer(A)?A.toString("utf8"):A,D=[];for(let $=0;$<E.length;$+=2)D.push({field:Ne(E[$]),value:Ne(E[$+1])});return{...g,length:C,value:{kind:"hash",entries:D},nextCursor:R==="0"?null:Wt({key:r,type:y,cursor:R,direction:i}),hasMore:R!=="0"}}if(y==="list"){let C=Number.parseInt(w?.cursor??"0",10),N=await c.llen(l),A=await c.lrangeBuffer(l,C,C+o-1),E=C+A.length,R=E<N;return{...g,length:N,value:{kind:"list",entries:A.map((D,$)=>({index:C+$,value:Ne(D)}))},nextCursor:R?Wt({key:r,type:y,cursor:String(E),direction:i}):null,hasMore:R}}if(y==="set"){let[C,N]=await Promise.all([c.scard(l),c.sscanBuffer(l,w?.cursor??"0","COUNT",String(o))]),[A,E]=N,R=Buffer.isBuffer(A)?A.toString("utf8"):A;return{...g,length:C,value:{kind:"set",members:E.map(Ne)},nextCursor:R==="0"?null:Wt({key:r,type:y,cursor:R,direction:i}),hasMore:R!=="0"}}if(y==="zset"){let[C,N]=await Promise.all([c.zcard(l),c.zscanBuffer(l,w?.cursor??"0","COUNT",String(o))]),[A,E]=N,R=Buffer.isBuffer(A)?A.toString("utf8"):A,D=[];for(let $=0;$<E.length;$+=2)D.push({member:Ne(E[$]),score:(()=>{let q=E[$+1].toString("utf8");return q==="inf"?"inf":q==="-inf"?"-inf":Number(q)})()});return{...g,length:C,value:{kind:"zset",entries:D},nextCursor:R==="0"?null:Wt({key:r,type:y,cursor:R,direction:i}),hasMore:R!=="0"}}if(y==="stream"){let C=w?.cursor??(i==="forward"?"-":"+"),[N,A]=await Promise.all([c.xlen(l),i==="forward"?c.xrangeBuffer(l,C,"+","COUNT",o+1):c.xrevrangeBuffer(l,C,"-","COUNT",o+1)]),E=A.length>o,D=A.slice(0,o).map(([q,P])=>{let U=[];for(let te=0;te<P.length;te+=2)U.push({field:Ne(P[te]),value:Ne(P[te+1])});return{id:q.toString("utf8"),fields:U}}),$=D.at(-1)?.id;return{...g,length:N,value:{kind:"stream",entries:D},nextCursor:E&&$?Wt({key:r,type:y,cursor:`(${$}`,direction:i}):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 Ae(ye(e.db)),r=Gr(e.key),a=zr(await t.callBuffer("TYPE",r));if(a==="unknown")throw new _(404,{message:"Redis key no longer exists"});if(Oe(a,"string"),e.expectedRevision){let l=await t.callBuffer("DUMP",r);if(!l||ct(l)!==e.expectedRevision)throw Vt()}let o=await t.strlen(r),s=await t.getrangeBuffer(r,e.offset,e.offset+e.limit-1),i=e.offset+s.length;return{chunk:Ne(s),length:o,nextOffset:i<o?i:null,hasMore:i<o}}catch(t){throw this.wrapError(t)}}async createKey(e){let t=null;try{t=await Lr(ye(e.db));let r=ee(e.key.base64);if(await t.watch(r),await t.exists(r)!==0)throw new _(409,{message:"A Redis key with this name already exists."});if(e.type!==e.value.kind)throw new _(400,{message:"The initial value does not match the selected Redis key type."});let a=t.multi();switch(e.value.kind){case"string":a.set(r,ee(e.value.value.base64));break;case"hash":a.hset(r,...e.value.entries.flatMap(({field:s,value:i})=>[ee(s.base64),ee(i.base64)]));break;case"list":a.rpush(r,...e.value.entries.map(s=>ee(s.base64)));break;case"set":a.sadd(r,...e.value.members.map(s=>ee(s.base64)));break;case"zset":a.zadd(r,...e.value.entries.flatMap(({member:s,score:i})=>[i,ee(s.base64)]));break;case"stream":a.xadd(r,e.value.id,...e.value.fields.flatMap(({field:s,value:i})=>[ee(s.base64),ee(i.base64)]));break}e.ttlMs!==null&&a.pexpire(r,e.ttlMs),Aa(await a.exec());let o=await t.callBuffer("DUMP",r);if(!o)throw Vt();return{key:Ne(r),revision:ct(o),deleted:!1}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async applyKeyAction(e){let t=null;try{t=await Lr(ye(e.db));let r=Gr(e.key),a=e.operation.action==="rename"?ee(e.operation.newKey.base64):null;a&&!a.equals(r)?await t.watch(r,a):await t.watch(r);let[o,s,i]=await Promise.all([t.callBuffer("DUMP",r),t.callBuffer("TYPE",r),t.pttl(r)]),l=o;if(!l)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&ct(l)!==e.expectedRevision)throw Vt();let c=zr(s);if(a&&!a.equals(r)&&await t.exists(a)!==0)throw new _(409,{message:"A Redis key with the new name already exists."});let u=t.multi();switch(e.operation.action){case"rename":if(!a||a.equals(r))return{key:Ne(r),revision:ct(l),deleted:!1};u.rename(r,a);break;case"setTtl":e.operation.ttlMs===null?u.persist(r):u.pexpire(r,e.operation.ttlMs);break;case"setString":Oe(c,"string"),u.set(r,ee(e.operation.value.base64)),i>0&&u.pexpire(r,i);break;case"upsertHash":Oe(c,"hash"),u.hset(r,ee(e.operation.field.base64),ee(e.operation.value.base64));break;case"deleteHash":Oe(c,"hash"),u.hdel(r,ee(e.operation.field.base64));break;case"pushList":Oe(c,"list"),e.operation.side==="left"?u.lpush(r,ee(e.operation.value.base64)):u.rpush(r,ee(e.operation.value.base64));break;case"setList":Oe(c,"list"),u.lset(r,e.operation.index,ee(e.operation.value.base64));break;case"deleteList":{Oe(c,"list");let d=Buffer.concat([Buffer.from("db-studio:list-delete:"),Uu(32)]);u.lset(r,e.operation.index,d),u.lrem(r,1,d);break}case"addSet":Oe(c,"set"),u.sadd(r,ee(e.operation.member.base64));break;case"removeSet":Oe(c,"set"),u.srem(r,ee(e.operation.member.base64));break;case"upsertZset":Oe(c,"zset"),u.zadd(r,e.operation.score,ee(e.operation.member.base64));break;case"removeZset":Oe(c,"zset"),u.zrem(r,ee(e.operation.member.base64));break;case"appendStream":Oe(c,"stream"),u.xadd(r,e.operation.id,...e.operation.fields.flatMap(({field:d,value:f})=>[ee(d.base64),ee(f.base64)]));break;case"deleteStream":Oe(c,"stream"),u.xdel(r,e.operation.id);break}Aa(await u.exec());let m=a&&!a.equals(r)?a:r,p=await t.callBuffer("DUMP",m);return{key:Ne(m),revision:p?ct(p):null,deleted:p===null}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async deleteKey(e){let t=null;try{t=await Lr(ye(e.db));let r=Gr(e.key);await t.watch(r);let a=await t.callBuffer("DUMP",r);if(!a)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&ct(a)!==e.expectedRevision)throw Vt();let o=t.multi().del(r);return Aa(await o.exec()),{deleted:!0}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async getDatabasesList(){try{let e=await Ae(lt()),t=1,r=!1,a=null;try{a=await e.call("CONFIG","GET","databases")}catch(l){if(!Sa(l))throw l}if(Array.isArray(a)&&a.length>=2){let l=Number.parseInt(String(a[1]),10);Number.isFinite(l)&&l>0&&(t=l,r=!0)}let o="";try{o=await e.info("keyspace")}catch(l){if(!Sa(l))throw l}let s=rm(o);return(r?Array.from({length:t},(l,c)=>c):[lt()]).map(l=>({name:String(l),size:`${s.get(l)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(lt())}}async getDatabaseConnectionInfo(){try{let e=await Ae(lt()),[t,r]=await Promise.all([e.info("server"),e.info("clients")]),a=ri(t),o=ri(r),s=Number.parseInt(o.maxclients??"0",10);if(!Number.isFinite(s)||s===0){let l=await e.call("CONFIG","GET","maxclients").catch(c=>{if(!Sa(c))throw c;return null});Array.isArray(l)&&l.length>=2&&(s=Number.parseInt(String(l[1]),10)||0)}let i=e.options;return{host:i.host??null,port:i.port??null,user:i.username||"default",database:String(i.db??lt()),version:a.redis_version??"unknown",active_connections:Number.parseInt(o.connected_clients??"0",10)||0,max_connections:s||0}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=ye(e),r=await this.getCachedCounts(t);return Yt.map(a=>({tableName:a,rowCount:r[a]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new _(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new _(400,{message:"Bulk deletion of Redis tables is not supported. Use FLUSHDB from the query runner to clear the entire logical database."})}async renameTable(e){throw new _(400,{message:Ht})}async getTableSchema({tableName:e}){let t=rt(e);return tm[t]}async getTableColumns({tableName:e}){let t=rt(e);return ti[t]}async addColumn(e){throw new _(400,{message:Ht})}async deleteColumn(e){throw new _(400,{message:Ht})}async alterColumn(e){throw new _(400,{message:Ht})}async renameColumn(e){throw new _(400,{message:Ht})}async getTableData(e){try{let{tableName:t,db:r,cursor:a,limit:o=50,direction:s="asc",sort:i,filters:l}=e;if(s==="desc")throw new _(400,{message:Ku});if(i&&i.length>0)throw new _(400,{message:Bu});if(l&&l.length>0)throw new _(400,{message:Fu});let c=rt(t),u=Ra[c],m=ye(r),p=await Ae(m),d="0";if(a){let D=em(a);if(!D||D.type!==c)throw new _(400,{message:"Invalid or mismatched cursor"});d=D.scanCursor}let f=[],y=0,g=!1;for(;f.length<o&&y<ju;){let[D,$]=await p.scan(d,"MATCH","*","COUNT",Math.max(o*2,100),"TYPE",u);if(f.push(...$),d=D,y++,D==="0"){g=!0;break}}let w=f.slice(0,o),C=f.slice(o),N=await this.hydrateRows(p,c,w),A=await p.dbsize(),E=!g||C.length>0,R=E&&!g?Zu({scanCursor:d,type:c}):null;return{data:N,meta:{limit:o,total:A,hasNextPage:E,hasPreviousPage:!1,nextCursor:R,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,r){if(r.length===0)return[];let a=e.pipeline();for(let l of r)a.ttl(l);let o=await a.exec()??[],s=e.pipeline();for(let l of r)switch(t){case"strings":s.get(l);break;case"hashes":s.hgetall(l);break;case"lists":s.lrange(l,0,-1);break;case"sets":s.smembers(l);break;case"zsets":s.zrange(l,0,-1,"WITHSCORES");break;case"streams":s.xinfo("STREAM",l);break}let i=await s.exec()??[];return r.map((l,c)=>{let u=o[c]?.[1]??-2,m=i[c]?.[1];if(t==="streams"){let d=om(m);return this.normalizeRow({key:l,length:d.length,"first-id":d.firstId,"last-id":d.lastId,ttl:u})}let p;switch(t){case"strings":p=m??null;break;case"hashes":p=m;break;case"lists":case"sets":p=m;break;case"zsets":p=am(m);break}return this.normalizeRow({key:l,value:p,ttl:u})})}async getCachedCounts(e){let t=this.countCache.get(e);if(t&&Date.now()-t.timestamp<Hu)return t.counts;let r=await Ae(e),a={},o=r.pipeline();for(let i of Yt)o.scan("0","MATCH","*","COUNT",Wu,"TYPE",Ra[i]);let s=await o.exec()??[];return Yt.forEach((i,l)=>{let c=s[l]?.[1];a[i]=c?.[1]?.length??0}),this.countCache.set(e,{timestamp:Date.now(),counts:a}),a}async addRecord({db:e,params:t}){try{let{tableName:r,data:a}=t,o=rt(r),s=ni(a),i=Na(a),l=await Ae(ye(e));return await this.writeRecord(l,o,s,a.value,{mode:"create",ttl:i}),this.countCache.delete(ye(e)),{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:a,primaryKey:o,primaryKeys:s}=t,i=rt(r),l=s?.[0]||o||"key",c=await Ae(ye(e)),u=new Map;for(let p of a){let d=p.rowData[l];if(d==null)throw new _(400,{message:`Primary key "${l}" not found in row data`});let f=String(d),y=u.get(f)??{...p.rowData};y[p.columnName]=p.value,u.set(f,y)}let m=0;for(let[p,d]of u.entries()){let f=d.value,y=Na(d);await this.writeRecord(c,i,p,f,{mode:"update",ttl:y});let g=d[l],w=g==null?p:String(g);if(w!==p&&await c.renamenx(p,w)===0)throw new _(409,{message:`Key "${w}" already exists`});m++}return{updatedCount:m}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:a}=e;rt(t);let o=await Ae(ye(a)),s=r.map(l=>String(l.value));if(s.length===0)return{deletedCount:0,fkViolation:!1,relatedRecords:[]};let i=await o.del(...s);return this.countCache.delete(ye(a)),{deletedCount:i,fkViolation:!1,relatedRecords:[]}}catch(t){throw this.wrapError(t)}}async forceDeleteRecords(e){return{deletedCount:(await this.deleteRecords(e)).deletedCount}}async bulkInsertRecords(e){try{let{tableName:t,records:r,db:a}=e;if(!r||r.length===0)throw new _(400,{message:"At least one record is required"});let o=rt(t),s=await Ae(ye(a)),i=[],l=0;for(let c=0;c<r.length;c++){let u=r[c];try{let m=ni(u),p=Na(u);await this.writeRecord(s,o,m,u.value,{mode:"create",ttl:p}),l++}catch(m){i.push({recordIndex:c,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(ye(a)),{success:i.length===0,message:`Inserted ${l} of ${r.length} record${r.length===1?"":"s"}`,successCount:l,failureCount:i.length,...i.length>0?{errors:i}:{}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=rt(e),a=ye(t),o=await Ae(a),s=Ra[r],i=[],l="0";do{let[m,p]=await o.scan(l,"MATCH","*","COUNT",1e3,"TYPE",s);i.push(...p),l=m}while(l!=="0");if(i.length===0)throw new _(404,{message:`Table "${e}" has no data`});let c=await this.hydrateRows(o,r,i);return{cols:ti[r].map(m=>m.columnName),rows:c}}catch(r){throw this.wrapError(r)}}async writeRecord(e,t,r,a,o){if(t==="streams"&&o.mode==="update")throw new _(400,{message:"Streams are append-only; updating a stream record is not supported"});if(o.mode==="create")if(t==="strings"){if(await e.set(r,typeof a=="string"?a:JSON.stringify(a),"NX")===null)throw new _(409,{message:`Key "${r}" already exists`})}else{if(await e.exists(r))throw new _(409,{message:`Key "${r}" already exists`});await this.writeCollectionValue(e,t,r,a)}else if(t==="strings"){if(await e.set(r,typeof a=="string"?a:JSON.stringify(a),"XX")===null)throw new _(404,{message:`Key "${r}" does not exist`})}else{if(!await e.exists(r))throw new _(404,{message:`Key "${r}" does not exist`});await e.del(r),await this.writeCollectionValue(e,t,r,a)}o.ttl!==null&&o.ttl>0&&await e.expire(r,o.ttl)}async writeCollectionValue(e,t,r,a){switch(t){case"hashes":{let o=ai(a,"hash"),s=[];for(let[i,l]of Object.entries(o))s.push(i,Qr(l));if(s.length===0)throw new _(400,{message:"Hash must have at least one field"});await e.hset(r,...s);return}case"lists":{let o=oi(a,"list");if(o.length===0)throw new _(400,{message:"List must have at least one element"});await e.rpush(r,...o.map(Qr));return}case"sets":{let o=oi(a,"set");if(o.length===0)throw new _(400,{message:"Set must have at least one member"});await e.sadd(r,...o.map(Qr));return}case"zsets":{let o=nm(a);if(o.length===0)throw new _(400,{message:"Sorted set must have at least one member"});let s=[];for(let i of o)s.push(i.score,i.member);await e.zadd(r,...s);return}case"streams":{let o=ai(a,"stream"),s=[];for(let[i,l]of Object.entries(o))s.push(i,Qr(l));if(s.length===0)throw new _(400,{message:"Stream entry must have at least one field"});await e.xadd(r,"*",...s);return}}}async executeQuery({query:e,db:t}){let r=performance.now();try{if(!e?.trim())throw new _(400,{message:"Query is required"});let a;try{a=Xs(e.trim())}catch(u){throw new _(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(a.length===0)throw new _(400,{message:"Empty command"});let o=await Ae(ye(t)),[s,...i]=a,l;try{l=await o.call(s,...i)}catch(u){let m=u instanceof Error?u.message:String(u);return{columns:["error"],rows:[{error:m}],rowCount:0,duration:performance.now()-r,error:m}}return{...Zs(a,l),duration:performance.now()-r,message:typeof l=="string"?l:void 0}}catch(a){throw this.wrapError(a)}}}});function Da(n){if(!n.length)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":e.push(`CAST(${a} AS TEXT) LIKE ?`),t.push(r.value);break;case"not like":e.push(`CAST(${a} AS TEXT) NOT LIKE ?`),t.push(r.value);break;case"ilike":e.push(`CAST(${a} AS TEXT) LIKE ? COLLATE NOCASE`),t.push(r.value);break;case"not ilike":e.push(`CAST(${a} AS TEXT) NOT LIKE ? COLLATE NOCASE`),t.push(r.value);break;default:break}}return e.length?{clause:`WHERE ${e.join(" AND ")}`,values:t}:{clause:"",values:[]}}function _a(n,e){return Array.isArray(n)?n.length?`ORDER BY ${n.map(t=>`"${t.columnName}" ${t.direction.toUpperCase()}`).join(", ")}`:"":n&&typeof n=="string"?`ORDER BY "${n}" ${e?.toUpperCase()||"ASC"}`:""}function Oa(n,e,t){let{values:r,sortColumns:a}=n;if(!a.length)return{clause:"",values:[]};let l=t==="asc"===(e==="asc")?">":"<",c=a.map(p=>`"${p}"`).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>r[p]);return{clause:`(${c}) ${l} (${u})`,values:m}}function Xr(n,e){let t=e;for(;t<n.length;)if(/\s/.test(n[t]))t++;else if(n.startsWith("--",t)){let r=n.indexOf(`
370
- `,t);t=r===-1?n.length:r+1}else if(n.startsWith("/*",t)){let r=n.indexOf("*/",t+2);t=r===-1?n.length:r+2}else break;return t}function ii(n){let e=[],t=0,r=!1,a=Xr(n,0);for(;a<n.length;){let o=n[a];if(o===";"){t===0&&(r=!0,e=[]),a=Xr(n,a+1);continue}if(r)return!0;let s=sm[o];if(s){let i=n.indexOf(s,a+1);a=i===-1?n.length:i+1}else if(/[A-Za-z_]/.test(o)){let i=/^[A-Za-z_][A-Za-z0-9_$]*/.exec(n.slice(a))?.[0]??o,l=i.toUpperCase();e[0]==="CREATE"&&(e[1]==="TRIGGER"||(e[1]==="TEMP"||e[1]==="TEMPORARY")&&e[2]==="TRIGGER")&&(l==="BEGIN"||t>0&&l==="CASE")?t++:t>0&&l==="END"&&t--,e.length<3&&e.push(l),a+=i.length}else a++;a=Xr(n,a)}return!1}function li(n){return im.test(n.slice(Xr(n,0)))}var sm,im,ci=S(()=>{"use strict";h();sm={"'":"'",'"':'"',"`":"`","[":"]"};im=/^(begin|start\s+transaction|commit|end|rollback|savepoint|release)\b/i});import{statSync as lm}from"fs";import{HTTPException as W}from"hono/http-exception";var ui,cm,_t,um,mm,dm,$a,X,mi,Zr,di=S(()=>{"use strict";h();ne();je();He();ci();ui=n=>n.every(e=>e!==null),cm=n=>n==null?null:typeof n=="boolean"?n?1:0:typeof n=="string"||typeof n=="number"||typeof n=="bigint"?n:n instanceof Date?n.toISOString():JSON.stringify(n),_t=(n,e=[])=>({sql:n,args:e.map(cm)}),um=BigInt(Number.MIN_SAFE_INTEGER),mm=BigInt(Number.MAX_SAFE_INTEGER),dm=n=>typeof n=="bigint"?n>=um&&n<=mm?Number(n):n.toString():n instanceof ArrayBuffer?Buffer.from(n):n,$a=({columns:n,rows:e})=>e.map(t=>Object.fromEntries(n.map((r,a)=>[r,dm(t[a])]))),X=async(n,e,t=[])=>$a(await n.execute(_t(e,t))),mi=n=>n instanceof Error&&n.message.includes("FOREIGN KEY constraint failed"),Zr=class extends oe{schemaChange=Promise.resolve();serializeSchemaChange(e){let t=this.schemaChange.then(e);return this.schemaChange=t.catch(()=>{}),t}async runQuery(e,t,r){return await X(await ae(),t,r)}quoteIdentifier(e){return`"${e.replaceAll('"','""')}"`}mapToUniversalType(e){return ar(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"INTEGER",json:"TEXT",date:"TEXT",array:"TEXT",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:a=50,direction:o="asc",sort:s=[],order:i="asc",filters:l=[]}=e,c=[],u=i;Array.isArray(s)&&s.length>0?(c=s.map(E=>E.columnName),u=s[0].direction):typeof s=="string"&&s&&(c=[s]),c.length||(c=["rowid"]);let{clause:m,values:p}=Da(l),d="",f=[];if(r){let E=this.decodeCursor(r);if(E){let R=Oa(E,o,u);d=R.clause,f=R.values}}let y="";m&&d?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?y=m:d&&(y=`WHERE ${d}`);let g=_a((Array.isArray(s),s),i),w=g;o==="desc"?g?w=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):w=`ORDER BY ${c.map(E=>`"${E}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(w=`ORDER BY ${c.map(E=>`"${E}" ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM "${t}" ${y} ${w} LIMIT ?`,N=[...p,...f,a+1],A=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:C,values:N,countSql:A,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(!t.length)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,i=[];Array.isArray(o)&&o.length>0?i=o.map(d=>d.columnName):typeof o=="string"&&o&&(i=[o]),i.length||(i=["rowid"]);let l=d=>{let f={values:Object.fromEntries(i.map(y=>[y,d[y]])),sortColumns:i};return this.encodeCursor(f)},c=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(r&&(m=l(u)),s&&(p=l(c))):(s&&(m=l(u)),r&&(p=l(c))),{nextCursor:m,prevCursor:p}}async getTableData(e){try{let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:i="asc",cursor:l,filters:c=[]}=e,u=await ae(),p=(await X(u,`PRAGMA table_info("${t}")`)).filter(O=>O.pk>0).sort((O,K)=>O.pk-K.pk).map(O=>O.name),d=[],f=i;Array.isArray(s)&&s.length>0?(d=s.map(O=>O.columnName),f=s[0].direction):typeof s=="string"&&s&&(d=[s]);let y=[...d,...p.filter(O=>!d.includes(O))],g=y.length===0;g&&y.push("rowid");let{clause:w,values:C}=Da(c),N="",A=[];if(l){let O=this.decodeCursor(l);if(O){let K=Oa(O,o,f);N=K.clause,A=K.values}}let E="";w&&N?E=`WHERE ${w.replace(/^WHERE\s+/i,"")} AND ${N}`:w?E=w:N&&(E=`WHERE ${N}`);let R=_a((Array.isArray(s),s),i),D=p.filter(O=>!d.includes(O)),$=R;if(o==="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(K=>`"${K}" ${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[q]=await X(u,`SELECT COUNT(*) as total FROM "${t}" ${w}`,C),P=Number(q?.total??0),te=await X(u,`SELECT ${g?"*, rowid":"*"} FROM "${t}" ${E} ${$} LIMIT ?`,[...C,...A,a+1]),V=te.length>a,k=V?te.slice(0,a):te;o==="desc"&&(k=k.reverse());let me=O=>({values:Object.fromEntries(y.map(K=>[K,O[K]])),sortColumns:y}),De=null,Ge=null;if(k.length>0){let O=k[0],K=k[k.length-1];o==="asc"?(V&&(De=this.encodeCursor(me(K))),l&&(Ge=this.encodeCursor(me(O)))):(l&&(De=this.encodeCursor(me(K))),V&&(Ge=this.encodeCursor(me(O))))}return{data:g?k.map(({rowid:O,...K})=>K):k,meta:{limit:a,total:P,hasNextPage:o==="asc"?V:!!l,hasPreviousPage:o==="asc"?!!l:V,nextCursor:De,prevCursor:Ge}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let e=await ae(),t=await X(e,"PRAGMA database_list");if(!t.length)throw new W(500,{message:"No databases returned from SQLite"});return t.filter(r=>r.name!=="temp").map(r=>({name:r.name,size:e.protocol==="file"?this.getFileSize(r.file):"N/A",owner:"",encoding:"UTF-8"}))}catch(e){throw e instanceof W?e:this.wrapError(e)}}async getCurrentDatabase(){try{return{db:(await X(await ae(),"PRAGMA database_list")).find(r=>r.name==="main")?.name??"main"}}catch(e){throw this.wrapError(e)}}async getDatabaseConnectionInfo(){try{let[e]=await X(await ae(),"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 ae(),r=await X(t,"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name");if(!r.length)return[];let a=await t.batch(r.map(o=>`SELECT COUNT(*) as count FROM ${this.quoteIdentifier(o.name)}`),"read");return r.map((o,s)=>({tableName:o.name,rowCount:$a(a[s])[0]?.count??0}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=a.filter(u=>u.isPrimaryKey).map(u=>u.columnName),i=a.map(u=>{if(s.length===1&&u.isPrimaryKey&&u.isIdentity)return`"${u.columnName}" INTEGER PRIMARY KEY AUTOINCREMENT`;let m=`"${u.columnName}" ${u.columnType}`;return s.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});s.length>1&&i.push(`PRIMARY KEY (${s.map(u=>`"${u}"`).join(", ")})`);let l=o?.map(u=>`FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await(await ae()).execute(`CREATE TABLE "${r}" (${[...i,...l].join(", ")})`)}async deleteTable(e){let{tableName:t,cascade:r}=e,a=await ae();if(!await this.tableExists(a,t))throw new W(404,{message:`Table "${t}" does not exist`});let[o]=await X(a,`SELECT COUNT(*) as count FROM "${t}"`),s=o?.count??0;if(!r&&(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:s,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 W?i:new W(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=await ae();if(!await this.tableExists(o,t))throw new W(404,{message:`Table "${t}" does not exist`});if(await this.tableExists(o,r))throw new W(409,{message:`Table "${r}" already exists`});try{await o.execute(`ALTER TABLE ${this.quoteIdentifier(t)} RENAME TO ${this.quoteIdentifier(r)}`)}catch(s){throw this.wrapError(s)}}async getTableSchema({tableName:e,db:t}){try{let[r]=await X(await ae(),"SELECT sql FROM sqlite_master WHERE type='table' AND name=?",[e]);if(!r)throw new W(404,{message:`Table "${e}" does not exist`});return r.sql}catch(r){throw r instanceof W?r:this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let r=await ae();if(!await this.tableExists(r,e))throw new W(404,{message:`Table "${e}" does not exist`});let a=await X(r,`PRAGMA table_info("${e}")`),o=await X(r,`PRAGMA foreign_key_list("${e}")`),s=new Map;for(let i of o)s.set(i.from,i);return a.map(i=>{let l=s.get(i.name),c=i.type.toLowerCase();return{columnName:i.name,dataType:ar(c),dataTypeLabel:Tn(c),isNullable:i.notnull===0&&i.pk===0,columnDefault:i.dflt_value,isPrimaryKey:i.pk>0,isForeignKey:s.has(i.name),referencedTable:l?.table??null,referencedColumn:l?.to??null,enumValues:null}})}catch(r){throw r instanceof W?r:this.wrapError(r)}}async addColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,columnType:a,defaultValue:o,isNullable:s,isUnique:i,db:l}=e,c=await ae();if(!await this.tableExists(c,t))throw new W(404,{message:`Table "${t}" does not exist`});if((await X(c,`PRAGMA table_info("${t}")`)).some(p=>p.name===r))throw new W(409,{message:`Column "${r}" already exists in table "${t}"`});let m=`"${r}" ${a}`;i&&(m+=" UNIQUE"),s||(m+=" NOT NULL"),o?.trim()&&(m+=` DEFAULT ${o.trim()}`);try{await c.execute(`ALTER TABLE "${t}" ADD COLUMN ${m}`)}catch(p){throw this.wrapError(p)}})}async deleteColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,db:a}=e,o=await ae();if(!await this.tableExists(o,t))throw new W(404,{message:`Table "${t}" does not exist`});if(!(await X(o,`PRAGMA table_info("${t}")`)).some(i=>i.name===r))throw new W(404,{message:`Column "${r}" does not exist in table "${t}"`});try{await o.execute(`ALTER TABLE "${t}" DROP COLUMN "${r}"`)}catch(i){throw this.wrapError(i)}return{deletedCount:1}})}async alterColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=await ae(),c=E=>this.quoteIdentifier(E);if(!await this.tableExists(l,t))throw new W(404,{message:`Table "${t}" does not exist`});let u=await X(l,`PRAGMA table_info(${c(t)})`);if(!u.some(E=>E.name===r))throw new W(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=u.filter(E=>E.pk>0).sort((E,R)=>E.pk-R.pk),p=m.length>1,d=u.map(E=>{let R=E.name===r,D=R?a:E.type,$=R?o:E.notnull===0,q=R?s?.trim()||null:E.dflt_value,P=E.pk>0,U=`${c(E.name)} ${D}`;return!p&&P&&(U+=" PRIMARY KEY"),!P&&!$&&(U+=" NOT NULL"),q&&(U+=` DEFAULT ${q}`),U});p&&d.push(`PRIMARY KEY (${m.map(E=>c(E.name)).join(", ")})`);let f=await X(l,`PRAGMA foreign_key_list(${c(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(te=>c(te.from)).join(", "),D=E.map(te=>te.to),$=ui(D)?` (${D.map(c).join(", ")})`:"",{table:q,on_update:P,on_delete:U}=E[0];return`FOREIGN KEY (${R}) REFERENCES ${c(q)}${$} ON UPDATE ${P} ON DELETE ${U}`}),w=u.map(E=>c(E.name)).join(", "),C=`${t}_alter_${Date.now()}`,N=await X(l,"SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL",[t]),A=await X(l,"SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?",[t]);try{await l.migrate([`CREATE TABLE ${c(C)} (${[...d,...g].join(", ")})`,`INSERT INTO ${c(C)} (${w}) SELECT ${w} FROM ${c(t)}`,`DROP TABLE ${c(t)}`,`ALTER TABLE ${c(C)} RENAME TO ${c(t)}`,...N.map(({sql:E})=>E),...A.map(({sql:E})=>E)])}catch(E){throw this.wrapError(E)}})}async renameColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=await ae();if(!await this.tableExists(s,t))throw new W(404,{message:`Table "${t}" does not exist`});let i=await X(s,`PRAGMA table_info("${t}")`);if(!i.some(l=>l.name===r))throw new W(404,{message:`Column "${r}" does not exist in table "${t}"`});if(i.some(l=>l.name===a))throw new W(409,{message:`Column "${a}" already exists in table "${t}"`});try{await s.execute(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${a}"`)}catch(l){throw this.wrapError(l)}})}async addRecord({params:e}){let{tableName:t,data:r}=e,a=Object.keys(r);if(!a.length)throw new W(400,{message:"No data provided for insert"});let o=a.map(i=>`"${i}"`).join(", "),s=a.map(()=>"?").join(", ");try{let l=await(await ae()).execute(_t(`INSERT INTO "${t}" (${o}) VALUES (${s})`,Object.values(r)));if(l.rowsAffected===0)throw new W(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:l.rowsAffected}}catch(i){throw this.wrapError(i)}}async updateRecords({db:e,params:t}){let{tableName:r}=t,a=this.resolveKeyColumns(t),o=this.groupUpdatesByKey(t,a);try{let s=await ae();this.assertWholeKey(await this.getPrimaryKeyColumns(s,r),a);let i=await s.transaction("write");try{let l=0;for(let{keyValues:c,rowUpdates:u}of o){let m=u.map(f=>`"${f.columnName}" = ?`).join(", "),p=a.map(f=>`"${f}" = ?`).join(" AND "),d=await i.execute(_t(`UPDATE "${r}" SET ${m} WHERE ${p}`,[...u.map(f=>f.value),...c]));if(d.rowsAffected===0)throw new W(404,{message:`Record with ${this.describeKey(a,c)} not found in table "${r}"`});l+=d.rowsAffected}return await i.commit(),{updatedCount:l}}catch(l){throw await i.rollback(),l}finally{i.close()}}catch(s){throw this.wrapError(s)}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=t[0]?.columnName;if(!a)throw new W(400,{message:"Primary key column name is required"});let o=t.map(l=>l.value),s=o.map(()=>"?").join(", "),i=await ae();try{return this.assertDeletableKey(await this.getPrimaryKeyColumns(i,e)),{deletedCount:(await i.execute(_t(`DELETE FROM "${e}" WHERE "${a}" IN (${s})`,o))).rowsAffected,fkViolation:!1,relatedRecords:[]}}catch(l){if(mi(l))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(i,e,t)};throw this.wrapError(l)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=t[0]?.columnName;if(!a)throw new W(400,{message:"Primary key column name is required"});let o=l=>this.quoteIdentifier(l),s=t.map(l=>l.value),i=`${o(a)} IN (${s.map(()=>"?").join(", ")})`;try{let l=await ae();this.assertDeletableKey(await this.getPrimaryKeyColumns(l,e));let c=await this.getForeignKeysByParent(l),u=[],m=async(d,f,y)=>{for(let g of c.get(d)??[]){if(y.includes(g.childTable))continue;let w=ui(g.parentColumns)?g.parentColumns:await this.getPrimaryKeyColumns(l,d),C=`(${g.childColumns.map(o).join(", ")}) IN (SELECT ${w.map(o).join(", ")} FROM ${o(d)} WHERE ${f})`;await m(g.childTable,C,[...y,g.childTable])}u.push(_t(`DELETE FROM ${o(d)} WHERE ${f}`,s))};return await m(e,i,[e]),{deletedCount:(await l.batch(u,"write")).reduce((d,f)=>d+f.rowsAffected,0)}}catch(l){throw mi(l)?new W(409,{message:`Cannot force delete from "${e}": rows are still referenced through a foreign key cycle`}):this.wrapError(l)}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t?.length)throw new W(400,{message:"At least one record is required"});let a=Object.keys(t[0]),o=a.map(l=>`"${l}"`).join(", "),s=a.map(()=>"?").join(", "),i=`INSERT INTO "${e}" (${o}) VALUES (${s})`;try{return await(await ae()).batch(t.map(c=>_t(i,a.map(u=>c[u]))),"write"),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}catch(l){throw this.wrapError(l)}}async executeQuery({query:e,db:t}){if(!e?.trim())throw new W(400,{message:"Query is required"});let r=e.trim().replace(/;+$/,"");if(li(r))throw new W(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(ii(r))throw new W(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let a=performance.now();try{let o=await(await ae()).execute(r),s=performance.now()-a;if(o.columns.length>0){let i=$a(o);return{columns:o.columns,rows:i,rowCount:i.length,duration:s,message:i.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:o.rowsAffected,duration:s,message:`OK (${o.rowsAffected} rows affected)`}}catch(o){throw this.wrapError(o)}}async tableExists(e,t){return(await X(e,"SELECT name FROM sqlite_master WHERE type='table' AND name=?",[t])).length>0}async getPrimaryKeyColumns(e,t){return(await X(e,`PRAGMA table_info(${this.quoteIdentifier(t)})`)).filter(a=>a.pk>0).sort((a,o)=>a.pk-o.pk).map(a=>a.name)}async getForeignKeysByParent(e){let t=await X(e,`SELECT m.name AS child, f.id, f."table" AS parent, f."from", f."to"
369
+ -- Backed by: XINFO STREAM / XADD / EXPIRE (read-only \u2014 streams are append-only)`},rn=class extends se{countCache=new Map;runQuery(){throw new _(501,{message:"runQuery is not supported for Redis"})}buildTableDataQuery(e){throw new _(501,{message:"buildTableDataQuery is not supported for Redis"})}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(){return{nextCursor:null,prevCursor:null}}quoteIdentifier(e){return e}mapToUniversalType(e){switch(e.toLowerCase()){case"string":return"text";case"hash":return"json";case"list":case"set":return"array";case"zset":case"stream":return"json";case"integer":case"number":case"ttl":return"number";default:return"text"}}mapFromUniversalType(e){return"string"}async scanKeys(e){try{let{db:t,limit:r,search:a,exactPattern:o,type:s,cursor:i}=e,l=be(t),c=await De(l),u="0";if(i){let C=cm(i);if(!C||C.search!==a||C.exactPattern!==o||C.type!==s)throw new _(400,{message:"Invalid or stale key scan cursor"});u=C.scanCursor}let m=a?o?a:`*${mm(a)}*`:"*",p=[u,"MATCH",m,"COUNT",r];s&&p.push("TYPE",s);let[d,f]=await c.scanBuffer(...p),y=Buffer.isBuffer(d)?d.toString("utf8"):d,g=c.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,N)=>{let A=N*3,E=w[A+2]?.[1];return{key:_e(C),type:Zr(w[A]?.[1]),ttlMs:Number(w[A+1]?.[1]??-2),memoryBytes:E==null?null:Number(E)}}),nextCursor:y==="0"?null:lm({scanCursor:y,search:a,exactPattern:o,type:s}),hasMore:y!=="0"}}catch(t){throw this.wrapError(t)}}async getKeyDetails(e){try{let{db:t,key:r,cursor:a,limit:o,full:s,direction:i}=e,l=en(r),c=await De(be(t)),[u,m,p,d]=await Promise.all([c.callBuffer("TYPE",l),c.pttl(l),c.call("MEMORY","USAGE",l).catch(()=>null),c.callBuffer("DUMP",l)]),f=d;if(!f)throw new _(404,{message:"Redis key no longer exists"});let y=Zr(u),g={key:_e(l),type:y,ttlMs:Number(m),memoryBytes:p===null?null:Number(p),revision:pt(f)},w=a?um(a):null;if(a&&(!w||w.key!==r||w.type!==y||w.direction!==i))throw new _(400,{message:"Invalid or stale key details cursor"});if(y==="string"){let C=await c.strlen(l),N=s?sm:om,A=await c.getrangeBuffer(l,0,N-1);return{...g,length:C,value:{kind:"string",value:_e(A),truncated:C>N},nextCursor:null,hasMore:!1}}if(y==="hash"){let[C,N]=await Promise.all([c.hlen(l),c.hscanBuffer(l,w?.cursor??"0","COUNT",String(o))]),[A,E]=N,R=Buffer.isBuffer(A)?A.toString("utf8"):A,D=[];for(let $=0;$<E.length;$+=2)D.push({field:_e(E[$]),value:_e(E[$+1])});return{...g,length:C,value:{kind:"hash",entries:D},nextCursor:R==="0"?null:Qt({key:r,type:y,cursor:R,direction:i}),hasMore:R!=="0"}}if(y==="list"){let C=Number.parseInt(w?.cursor??"0",10),N=await c.llen(l),A=await c.lrangeBuffer(l,C,C+o-1),E=C+A.length,R=E<N;return{...g,length:N,value:{kind:"list",entries:A.map((D,$)=>({index:C+$,value:_e(D)}))},nextCursor:R?Qt({key:r,type:y,cursor:String(E),direction:i}):null,hasMore:R}}if(y==="set"){let[C,N]=await Promise.all([c.scard(l),c.sscanBuffer(l,w?.cursor??"0","COUNT",String(o))]),[A,E]=N,R=Buffer.isBuffer(A)?A.toString("utf8"):A;return{...g,length:C,value:{kind:"set",members:E.map(_e)},nextCursor:R==="0"?null:Qt({key:r,type:y,cursor:R,direction:i}),hasMore:R!=="0"}}if(y==="zset"){let[C,N]=await Promise.all([c.zcard(l),c.zscanBuffer(l,w?.cursor??"0","COUNT",String(o))]),[A,E]=N,R=Buffer.isBuffer(A)?A.toString("utf8"):A,D=[];for(let $=0;$<E.length;$+=2)D.push({member:_e(E[$]),score:(()=>{let q=E[$+1].toString("utf8");return q==="inf"?"inf":q==="-inf"?"-inf":Number(q)})()});return{...g,length:C,value:{kind:"zset",entries:D},nextCursor:R==="0"?null:Qt({key:r,type:y,cursor:R,direction:i}),hasMore:R!=="0"}}if(y==="stream"){let C=w?.cursor??(i==="forward"?"-":"+"),[N,A]=await Promise.all([c.xlen(l),i==="forward"?c.xrangeBuffer(l,C,"+","COUNT",o+1):c.xrevrangeBuffer(l,C,"-","COUNT",o+1)]),E=A.length>o,D=A.slice(0,o).map(([q,P])=>{let U=[];for(let re=0;re<P.length;re+=2)U.push({field:_e(P[re]),value:_e(P[re+1])});return{id:q.toString("utf8"),fields:U}}),$=D.at(-1)?.id;return{...g,length:N,value:{kind:"stream",entries:D},nextCursor:E&&$?Qt({key:r,type:y,cursor:`(${$}`,direction:i}):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 De(be(e.db)),r=en(e.key),a=Zr(await t.callBuffer("TYPE",r));if(a==="unknown")throw new _(404,{message:"Redis key no longer exists"});if(Pe(a,"string"),e.expectedRevision){let l=await t.callBuffer("DUMP",r);if(!l||pt(l)!==e.expectedRevision)throw Jt()}let o=await t.strlen(r),s=await t.getrangeBuffer(r,e.offset,e.offset+e.limit-1),i=e.offset+s.length;return{chunk:_e(s),length:o,nextOffset:i<o?i:null,hasMore:i<o}}catch(t){throw this.wrapError(t)}}async createKey(e){let t=null;try{t=await vr(be(e.db));let r=te(e.key.base64);if(await t.watch(r),await t.exists(r)!==0)throw new _(409,{message:"A Redis key with this name already exists."});if(e.type!==e.value.kind)throw new _(400,{message:"The initial value does not match the selected Redis key type."});let a=t.multi();switch(e.value.kind){case"string":a.set(r,te(e.value.value.base64));break;case"hash":a.hset(r,...e.value.entries.flatMap(({field:s,value:i})=>[te(s.base64),te(i.base64)]));break;case"list":a.rpush(r,...e.value.entries.map(s=>te(s.base64)));break;case"set":a.sadd(r,...e.value.members.map(s=>te(s.base64)));break;case"zset":a.zadd(r,...e.value.entries.flatMap(({member:s,score:i})=>[i,te(s.base64)]));break;case"stream":a.xadd(r,e.value.id,...e.value.fields.flatMap(({field:s,value:i})=>[te(s.base64),te(i.base64)]));break}e.ttlMs!==null&&a.pexpire(r,e.ttlMs),$a(await a.exec());let o=await t.callBuffer("DUMP",r);if(!o)throw Jt();return{key:_e(r),revision:pt(o),deleted:!1}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async applyKeyAction(e){let t=null;try{t=await vr(be(e.db));let r=en(e.key),a=e.operation.action==="rename"?te(e.operation.newKey.base64):null;a&&!a.equals(r)?await t.watch(r,a):await t.watch(r);let[o,s,i]=await Promise.all([t.callBuffer("DUMP",r),t.callBuffer("TYPE",r),t.pttl(r)]),l=o;if(!l)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&pt(l)!==e.expectedRevision)throw Jt();let c=Zr(s);if(a&&!a.equals(r)&&await t.exists(a)!==0)throw new _(409,{message:"A Redis key with the new name already exists."});let u=t.multi();switch(e.operation.action){case"rename":if(!a||a.equals(r))return{key:_e(r),revision:pt(l),deleted:!1};u.rename(r,a);break;case"setTtl":e.operation.ttlMs===null?u.persist(r):u.pexpire(r,e.operation.ttlMs);break;case"setString":Pe(c,"string"),u.set(r,te(e.operation.value.base64)),i>0&&u.pexpire(r,i);break;case"upsertHash":Pe(c,"hash"),u.hset(r,te(e.operation.field.base64),te(e.operation.value.base64));break;case"deleteHash":Pe(c,"hash"),u.hdel(r,te(e.operation.field.base64));break;case"pushList":Pe(c,"list"),e.operation.side==="left"?u.lpush(r,te(e.operation.value.base64)):u.rpush(r,te(e.operation.value.base64));break;case"setList":Pe(c,"list"),u.lset(r,e.operation.index,te(e.operation.value.base64));break;case"deleteList":{Pe(c,"list");let d=Buffer.concat([Buffer.from("db-studio:list-delete:"),Xu(32)]);u.lset(r,e.operation.index,d),u.lrem(r,1,d);break}case"addSet":Pe(c,"set"),u.sadd(r,te(e.operation.member.base64));break;case"removeSet":Pe(c,"set"),u.srem(r,te(e.operation.member.base64));break;case"upsertZset":Pe(c,"zset"),u.zadd(r,e.operation.score,te(e.operation.member.base64));break;case"removeZset":Pe(c,"zset"),u.zrem(r,te(e.operation.member.base64));break;case"appendStream":Pe(c,"stream"),u.xadd(r,e.operation.id,...e.operation.fields.flatMap(({field:d,value:f})=>[te(d.base64),te(f.base64)]));break;case"deleteStream":Pe(c,"stream"),u.xdel(r,e.operation.id);break}$a(await u.exec());let m=a&&!a.equals(r)?a:r,p=await t.callBuffer("DUMP",m);return{key:_e(m),revision:p?pt(p):null,deleted:p===null}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async deleteKey(e){let t=null;try{t=await vr(be(e.db));let r=en(e.key);await t.watch(r);let a=await t.callBuffer("DUMP",r);if(!a)throw new _(404,{message:"Redis key no longer exists"});if(!e.force&&pt(a)!==e.expectedRevision)throw Jt();let o=t.multi().del(r);return $a(await o.exec()),{deleted:!0}}catch(r){throw this.wrapError(r)}finally{t&&await t.quit().catch(()=>t?.disconnect())}}async getDatabasesList(){try{let e=await De(dt()),t=1,r=!1,a=null;try{a=await e.call("CONFIG","GET","databases")}catch(l){if(!Oa(l))throw l}if(Array.isArray(a)&&a.length>=2){let l=Number.parseInt(String(a[1]),10);Number.isFinite(l)&&l>0&&(t=l,r=!0)}let o="";try{o=await e.info("keyspace")}catch(l){if(!Oa(l))throw l}let s=ym(o);return(r?Array.from({length:t},(l,c)=>c):[dt()]).map(l=>({name:String(l),size:`${s.get(l)??0} keys`,owner:"n/a",encoding:"n/a"}))}catch(e){throw this.wrapError(e)}}async getCurrentDatabase(){return{db:String(dt())}}async getDatabaseConnectionInfo(){try{let e=await De(dt()),[t,r]=await Promise.all([e.info("server"),e.info("clients")]),a=ui(t),o=ui(r),s=Number.parseInt(o.maxclients??"0",10);if(!Number.isFinite(s)||s===0){let l=await e.call("CONFIG","GET","maxclients").catch(c=>{if(!Oa(c))throw c;return null});Array.isArray(l)&&l.length>=2&&(s=Number.parseInt(String(l[1]),10)||0)}let i=e.options;return{host:i.host??null,port:i.port??null,user:i.username||"default",database:String(i.db??dt()),version:a.redis_version??"unknown",active_connections:Number.parseInt(o.connected_clients??"0",10)||0,max_connections:s||0}}catch(e){throw this.wrapError(e)}}async getTablesList(e){try{let t=be(e),r=await this.getCachedCounts(t);return Xt.map(a=>({tableName:a,rowCount:r[a]}))}catch(t){throw this.wrapError(t)}}async createTable(){throw new _(400,{message:"Redis tables are fixed; cannot create new ones"})}async deleteTable(e){throw new _(400,{message:"Bulk deletion of Redis tables is not supported. Use FLUSHDB from the query runner to clear the entire logical database."})}async renameTable(e){throw new _(400,{message:Gt})}async getTableSchema({tableName:e}){let t=ot(e);return fm[t]}async getTableColumns({tableName:e}){let t=ot(e);return ci[t]}async addColumn(e){throw new _(400,{message:Gt})}async deleteColumn(e){throw new _(400,{message:Gt})}async alterColumn(e){throw new _(400,{message:Gt})}async renameColumn(e){throw new _(400,{message:Gt})}async getTableData(e){try{let{tableName:t,db:r,cursor:a,limit:o=50,direction:s="asc",sort:i,filters:l}=e;if(s==="desc")throw new _(400,{message:tm});if(i&&i.length>0)throw new _(400,{message:Zu});if(l&&l.length>0)throw new _(400,{message:em});let c=ot(t),u=_a[c],m=be(r),p=await De(m),d="0";if(a){let D=pm(a);if(!D||D.type!==c)throw new _(400,{message:"Invalid or mismatched cursor"});d=D.scanCursor}let f=[],y=0,g=!1;for(;f.length<o&&y<rm;){let[D,$]=await p.scan(d,"MATCH","*","COUNT",Math.max(o*2,100),"TYPE",u);if(f.push(...$),d=D,y++,D==="0"){g=!0;break}}let w=f.slice(0,o),C=f.slice(o),N=await this.hydrateRows(p,c,w),A=await p.dbsize(),E=!g||C.length>0,R=E&&!g?dm({scanCursor:d,type:c}):null;return{data:N,meta:{limit:o,total:A,hasNextPage:E,hasPreviousPage:!1,nextCursor:R,prevCursor:null}}}catch(t){throw this.wrapError(t)}}async hydrateRows(e,t,r){if(r.length===0)return[];let a=e.pipeline();for(let l of r)a.ttl(l);let o=await a.exec()??[],s=e.pipeline();for(let l of r)switch(t){case"strings":s.get(l);break;case"hashes":s.hgetall(l);break;case"lists":s.lrange(l,0,-1);break;case"sets":s.smembers(l);break;case"zsets":s.zrange(l,0,-1,"WITHSCORES");break;case"streams":s.xinfo("STREAM",l);break}let i=await s.exec()??[];return r.map((l,c)=>{let u=o[c]?.[1]??-2,m=i[c]?.[1];if(t==="streams"){let d=gm(m);return this.normalizeRow({key:l,length:d.length,"first-id":d.firstId,"last-id":d.lastId,ttl:u})}let p;switch(t){case"strings":p=m??null;break;case"hashes":p=m;break;case"lists":case"sets":p=m;break;case"zsets":p=bm(m);break}return this.normalizeRow({key:l,value:p,ttl:u})})}async getCachedCounts(e){let t=this.countCache.get(e);if(t&&Date.now()-t.timestamp<nm)return t.counts;let r=await De(e),a={},o=r.pipeline();for(let i of Xt)o.scan("0","MATCH","*","COUNT",am,"TYPE",_a[i]);let s=await o.exec()??[];return Xt.forEach((i,l)=>{let c=s[l]?.[1];a[i]=c?.[1]?.length??0}),this.countCache.set(e,{timestamp:Date.now(),counts:a}),a}async addRecord({db:e,params:t}){try{let{tableName:r,data:a}=t,o=ot(r),s=mi(a),i=Pa(a),l=await De(be(e));return await this.writeRecord(l,o,s,a.value,{mode:"create",ttl:i}),this.countCache.delete(be(e)),{insertedCount:1}}catch(r){throw this.wrapError(r)}}async updateRecords({db:e,params:t}){try{let{tableName:r,updates:a,primaryKey:o,primaryKeys:s}=t,i=ot(r),l=s?.[0]||o||"key",c=await De(be(e)),u=new Map;for(let p of a){let d=p.rowData[l];if(d==null)throw new _(400,{message:`Primary key "${l}" not found in row data`});let f=String(d),y=u.get(f)??{...p.rowData};y[p.columnName]=p.value,u.set(f,y)}let m=0;for(let[p,d]of u.entries()){let f=d.value,y=Pa(d);await this.writeRecord(c,i,p,f,{mode:"update",ttl:y});let g=d[l],w=g==null?p:String(g);if(w!==p&&await c.renamenx(p,w)===0)throw new _(409,{message:`Key "${w}" already exists`});m++}return{updatedCount:m}}catch(r){throw this.wrapError(r)}}async deleteRecords(e){try{let{tableName:t,primaryKeys:r,db:a}=e;ot(t);let o=await De(be(a)),s=r.map(l=>String(l.value));if(s.length===0)return{deletedCount:0,fkViolation:!1,relatedRecords:[]};let i=await o.del(...s);return this.countCache.delete(be(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:r,db:a}=e;if(!r||r.length===0)throw new _(400,{message:"At least one record is required"});let o=ot(t),s=await De(be(a)),i=[],l=0;for(let c=0;c<r.length;c++){let u=r[c];try{let m=mi(u),p=Pa(u);await this.writeRecord(s,o,m,u.value,{mode:"create",ttl:p}),l++}catch(m){i.push({recordIndex:c,error:m instanceof Error?m.message:String(m)})}}return this.countCache.delete(be(a)),{success:i.length===0,message:`Inserted ${l} of ${r.length} record${r.length===1?"":"s"}`,successCount:l,failureCount:i.length,...i.length>0?{errors:i}:{}}}catch(t){throw this.wrapError(t)}}async exportTableData({tableName:e,db:t}){try{let r=ot(e),a=be(t),o=await De(a),s=_a[r],i=[],l="0";do{let[m,p]=await o.scan(l,"MATCH","*","COUNT",1e3,"TYPE",s);i.push(...p),l=m}while(l!=="0");if(i.length===0)throw new _(404,{message:`Table "${e}" has no data`});let c=await this.hydrateRows(o,r,i);return{cols:ci[r].map(m=>m.columnName),rows:c}}catch(r){throw this.wrapError(r)}}async writeRecord(e,t,r,a,o){if(t==="streams"&&o.mode==="update")throw new _(400,{message:"Streams are append-only; updating a stream record is not supported"});if(o.mode==="create")if(t==="strings"){if(await e.set(r,typeof a=="string"?a:JSON.stringify(a),"NX")===null)throw new _(409,{message:`Key "${r}" already exists`})}else{if(await e.exists(r))throw new _(409,{message:`Key "${r}" already exists`});await this.writeCollectionValue(e,t,r,a)}else if(t==="strings"){if(await e.set(r,typeof a=="string"?a:JSON.stringify(a),"XX")===null)throw new _(404,{message:`Key "${r}" does not exist`})}else{if(!await e.exists(r))throw new _(404,{message:`Key "${r}" does not exist`});await e.del(r),await this.writeCollectionValue(e,t,r,a)}o.ttl!==null&&o.ttl>0&&await e.expire(r,o.ttl)}async writeCollectionValue(e,t,r,a){switch(t){case"hashes":{let o=di(a,"hash"),s=[];for(let[i,l]of Object.entries(o))s.push(i,tn(l));if(s.length===0)throw new _(400,{message:"Hash must have at least one field"});await e.hset(r,...s);return}case"lists":{let o=pi(a,"list");if(o.length===0)throw new _(400,{message:"List must have at least one element"});await e.rpush(r,...o.map(tn));return}case"sets":{let o=pi(a,"set");if(o.length===0)throw new _(400,{message:"Set must have at least one member"});await e.sadd(r,...o.map(tn));return}case"zsets":{let o=hm(a);if(o.length===0)throw new _(400,{message:"Sorted set must have at least one member"});let s=[];for(let i of o)s.push(i.score,i.member);await e.zadd(r,...s);return}case"streams":{let o=di(a,"stream"),s=[];for(let[i,l]of Object.entries(o))s.push(i,tn(l));if(s.length===0)throw new _(400,{message:"Stream entry must have at least one field"});await e.xadd(r,"*",...s);return}}}async executeQuery({query:e,db:t}){let r=performance.now();try{if(!e?.trim())throw new _(400,{message:"Query is required"});let a;try{a=si(e.trim())}catch(u){throw new _(400,{message:u instanceof Error?u.message:"Invalid Redis command"})}if(a.length===0)throw new _(400,{message:"Empty command"});let o=await De(be(t)),[s,...i]=a,l;try{l=await o.call(s,...i)}catch(u){let m=u instanceof Error?u.message:String(u);return{columns:["error"],rows:[{error:m}],rowCount:0,duration:performance.now()-r,error:m}}return{...ii(a,l),duration:performance.now()-r,message:typeof l=="string"?l:void 0}}catch(a){throw this.wrapError(a)}}}});function Ia(n){if(!n.length)return{clause:"",values:[]};let e=[],t=[];for(let r of n){let a=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${a} ${r.operator} ?`),t.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${a} IS NULL`):(e.push(`${a} = ?`),t.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${a} IS NOT NULL`):(e.push(`${a} != ?`),t.push(r.value));break;case"like":e.push(`CAST(${a} AS TEXT) LIKE ?`),t.push(r.value);break;case"not like":e.push(`CAST(${a} AS TEXT) NOT LIKE ?`),t.push(r.value);break;case"ilike":e.push(`CAST(${a} AS TEXT) LIKE ? COLLATE NOCASE`),t.push(r.value);break;case"not ilike":e.push(`CAST(${a} AS TEXT) NOT LIKE ? COLLATE NOCASE`),t.push(r.value);break;default:break}}return e.length?{clause:`WHERE ${e.join(" AND ")}`,values:t}:{clause:"",values:[]}}function La(n,e){return Array.isArray(n)?n.length?`ORDER BY ${n.map(t=>`"${t.columnName}" ${t.direction.toUpperCase()}`).join(", ")}`:"":n&&typeof n=="string"?`ORDER BY "${n}" ${e?.toUpperCase()||"ASC"}`:""}function Ma(n,e,t){let{values:r,sortColumns:a}=n;if(!a.length)return{clause:"",values:[]};let l=t==="asc"===(e==="asc")?">":"<",c=a.map(p=>`"${p}"`).join(", "),u=a.map(()=>"?").join(", "),m=a.map(p=>r[p]);return{clause:`(${c}) ${l} (${u})`,values:m}}function nn(n,e){let t=e;for(;t<n.length;)if(/\s/.test(n[t]))t++;else if(n.startsWith("--",t)){let r=n.indexOf(`
370
+ `,t);t=r===-1?n.length:r+1}else if(n.startsWith("/*",t)){let r=n.indexOf("*/",t+2);t=r===-1?n.length:r+2}else break;return t}function yi(n){let e=[],t=0,r=!1,a=nn(n,0);for(;a<n.length;){let o=n[a];if(o===";"){t===0&&(r=!0,e=[]),a=nn(n,a+1);continue}if(r)return!0;let s=Tm[o];if(s){let i=n.indexOf(s,a+1);a=i===-1?n.length:i+1}else if(/[A-Za-z_]/.test(o)){let i=/^[A-Za-z_][A-Za-z0-9_$]*/.exec(n.slice(a))?.[0]??o,l=i.toUpperCase();e[0]==="CREATE"&&(e[1]==="TRIGGER"||(e[1]==="TEMP"||e[1]==="TEMPORARY")&&e[2]==="TRIGGER")&&(l==="BEGIN"||t>0&&l==="CASE")?t++:t>0&&l==="END"&&t--,e.length<3&&e.push(l),a+=i.length}else a++;a=nn(n,a)}return!1}function hi(n){return Em.test(n.slice(nn(n,0)))}var Tm,Em,bi=S(()=>{"use strict";h();Tm={"'":"'",'"':'"',"`":"`","[":"]"};Em=/^(begin|start\s+transaction|commit|end|rollback|savepoint|release)\b/i});import{statSync as wm}from"fs";import{HTTPException as W}from"hono/http-exception";var gi,Cm,Lt,Rm,Sm,Am,ka,Z,Ti,an,Ei=S(()=>{"use strict";h();ae();We();Ve();bi();gi=n=>n.every(e=>e!==null),Cm=n=>n==null?null:typeof n=="boolean"?n?1:0:typeof n=="string"||typeof n=="number"||typeof n=="bigint"?n:n instanceof Date?n.toISOString():JSON.stringify(n),Lt=(n,e=[])=>({sql:n,args:e.map(Cm)}),Rm=BigInt(Number.MIN_SAFE_INTEGER),Sm=BigInt(Number.MAX_SAFE_INTEGER),Am=n=>typeof n=="bigint"?n>=Rm&&n<=Sm?Number(n):n.toString():n instanceof ArrayBuffer?Buffer.from(n):n,ka=({columns:n,rows:e})=>e.map(t=>Object.fromEntries(n.map((r,a)=>[r,Am(t[a])]))),Z=async(n,e,t=[])=>ka(await n.execute(Lt(e,t))),Ti=n=>n instanceof Error&&n.message.includes("FOREIGN KEY constraint failed"),an=class extends se{schemaChange=Promise.resolve();serializeSchemaChange(e){let t=this.schemaChange.then(e);return this.schemaChange=t.catch(()=>{}),t}async runQuery(e,t,r){return await Z(await oe(),t,r)}quoteIdentifier(e){return`"${e.replaceAll('"','""')}"`}mapToUniversalType(e){return cr(e)}mapFromUniversalType(e){return{text:"TEXT",number:"INTEGER",boolean:"INTEGER",json:"TEXT",date:"TEXT",array:"TEXT",enum:"TEXT"}[e]??"TEXT"}buildTableDataQuery(e){let{tableName:t,cursor:r="",limit:a=50,direction:o="asc",sort:s=[],order:i="asc",filters:l=[]}=e,c=[],u=i;Array.isArray(s)&&s.length>0?(c=s.map(E=>E.columnName),u=s[0].direction):typeof s=="string"&&s&&(c=[s]),c.length||(c=["rowid"]);let{clause:m,values:p}=Ia(l),d="",f=[];if(r){let E=this.decodeCursor(r);if(E){let R=Ma(E,o,u);d=R.clause,f=R.values}}let y="";m&&d?y=`WHERE ${m.replace(/^WHERE\s+/i,"")} AND ${d}`:m?y=m:d&&(y=`WHERE ${d}`);let g=La((Array.isArray(s),s),i),w=g;o==="desc"?g?w=g.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):w=`ORDER BY ${c.map(E=>`"${E}" ${u==="asc"?"DESC":"ASC"}`).join(", ")}`:g||(w=`ORDER BY ${c.map(E=>`"${E}" ${u.toUpperCase()}`).join(", ")}`);let C=`SELECT * FROM "${t}" ${y} ${w} LIMIT ?`,N=[...p,...f,a+1],A=`SELECT COUNT(*) as total FROM "${t}" ${m}`;return{sql:C,values:N,countSql:A,countValues:p}}normalizeRows(e){return e.map(t=>this.normalizeRow(t))}buildCursors(e,t,r){if(!t.length)return{nextCursor:null,prevCursor:null};let{direction:a="asc",sort:o=[],cursor:s}=e,i=[];Array.isArray(o)&&o.length>0?i=o.map(d=>d.columnName):typeof o=="string"&&o&&(i=[o]),i.length||(i=["rowid"]);let l=d=>{let f={values:Object.fromEntries(i.map(y=>[y,d[y]])),sortColumns:i};return this.encodeCursor(f)},c=t[0],u=t[t.length-1],m=null,p=null;return a==="asc"?(r&&(m=l(u)),s&&(p=l(c))):(s&&(m=l(u)),r&&(p=l(c))),{nextCursor:m,prevCursor:p}}async getTableData(e){try{let{tableName:t,db:r,limit:a=50,direction:o="asc",sort:s=[],order:i="asc",cursor:l,filters:c=[]}=e,u=await oe(),p=(await Z(u,`PRAGMA table_info("${t}")`)).filter(O=>O.pk>0).sort((O,K)=>O.pk-K.pk).map(O=>O.name),d=[],f=i;Array.isArray(s)&&s.length>0?(d=s.map(O=>O.columnName),f=s[0].direction):typeof s=="string"&&s&&(d=[s]);let y=[...d,...p.filter(O=>!d.includes(O))],g=y.length===0;g&&y.push("rowid");let{clause:w,values:C}=Ia(c),N="",A=[];if(l){let O=this.decodeCursor(l);if(O){let K=Ma(O,o,f);N=K.clause,A=K.values}}let E="";w&&N?E=`WHERE ${w.replace(/^WHERE\s+/i,"")} AND ${N}`:w?E=w:N&&(E=`WHERE ${N}`);let R=La((Array.isArray(s),s),i),D=p.filter(O=>!d.includes(O)),$=R;if(o==="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(K=>`"${K}" ${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[q]=await Z(u,`SELECT COUNT(*) as total FROM "${t}" ${w}`,C),P=Number(q?.total??0),re=await Z(u,`SELECT ${g?"*, rowid":"*"} FROM "${t}" ${E} ${$} LIMIT ?`,[...C,...A,a+1]),V=re.length>a,k=V?re.slice(0,a):re;o==="desc"&&(k=k.reverse());let pe=O=>({values:Object.fromEntries(y.map(K=>[K,O[K]])),sortColumns:y}),Oe=null,Je=null;if(k.length>0){let O=k[0],K=k[k.length-1];o==="asc"?(V&&(Oe=this.encodeCursor(pe(K))),l&&(Je=this.encodeCursor(pe(O)))):(l&&(Oe=this.encodeCursor(pe(K))),V&&(Je=this.encodeCursor(pe(O))))}return{data:g?k.map(({rowid:O,...K})=>K):k,meta:{limit:a,total:P,hasNextPage:o==="asc"?V:!!l,hasPreviousPage:o==="asc"?!!l:V,nextCursor:Oe,prevCursor:Je}}}catch(t){throw this.wrapError(t)}}async getDatabasesList(){try{let e=await oe(),t=await Z(e,"PRAGMA database_list");if(!t.length)throw new W(500,{message:"No databases returned from SQLite"});return t.filter(r=>r.name!=="temp").map(r=>({name:r.name,size:e.protocol==="file"?this.getFileSize(r.file):"N/A",owner:"",encoding:"UTF-8"}))}catch(e){throw e instanceof W?e:this.wrapError(e)}}async getCurrentDatabase(){try{return{db:(await Z(await oe(),"PRAGMA database_list")).find(r=>r.name==="main")?.name??"main"}}catch(e){throw this.wrapError(e)}}async getDatabaseConnectionInfo(){try{let[e]=await Z(await oe(),"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 oe(),r=await Z(t,"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name");if(!r.length)return[];let a=await t.batch(r.map(o=>`SELECT COUNT(*) as count FROM ${this.quoteIdentifier(o.name)}`),"read");return r.map((o,s)=>({tableName:o.name,rowCount:ka(a[s])[0]?.count??0}))}catch(t){throw this.wrapError(t)}}async createTable({tableData:e,db:t}){let{tableName:r,fields:a,foreignKeys:o}=e,s=a.filter(u=>u.isPrimaryKey).map(u=>u.columnName),i=a.map(u=>{if(s.length===1&&u.isPrimaryKey&&u.isIdentity)return`"${u.columnName}" INTEGER PRIMARY KEY AUTOINCREMENT`;let m=`"${u.columnName}" ${u.columnType}`;return s.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});s.length>1&&i.push(`PRIMARY KEY (${s.map(u=>`"${u}"`).join(", ")})`);let l=o?.map(u=>`FOREIGN KEY ("${u.columnName}") REFERENCES "${u.referencedTable}" ("${u.referencedColumn}") ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)??[];await(await oe()).execute(`CREATE TABLE "${r}" (${[...i,...l].join(", ")})`)}async deleteTable(e){let{tableName:t,cascade:r}=e,a=await oe();if(!await this.tableExists(a,t))throw new W(404,{message:`Table "${t}" does not exist`});let[o]=await Z(a,`SELECT COUNT(*) as count FROM "${t}"`),s=o?.count??0;if(!r&&(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:s,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 W?i:new W(500,{message:`Failed to delete table "${t}"`})}}async renameTable(e){let{tableName:t,newTableName:r,db:a}=e;this.assertDifferentTableName(t,r);let o=await oe();if(!await this.tableExists(o,t))throw new W(404,{message:`Table "${t}" does not exist`});if(await this.tableExists(o,r))throw new W(409,{message:`Table "${r}" already exists`});try{await o.execute(`ALTER TABLE ${this.quoteIdentifier(t)} RENAME TO ${this.quoteIdentifier(r)}`)}catch(s){throw this.wrapError(s)}}async getTableSchema({tableName:e,db:t}){try{let[r]=await Z(await oe(),"SELECT sql FROM sqlite_master WHERE type='table' AND name=?",[e]);if(!r)throw new W(404,{message:`Table "${e}" does not exist`});return r.sql}catch(r){throw r instanceof W?r:this.wrapError(r)}}async getTableColumns({tableName:e,db:t}){try{let r=await oe();if(!await this.tableExists(r,e))throw new W(404,{message:`Table "${e}" does not exist`});let a=await Z(r,`PRAGMA table_info("${e}")`),o=await Z(r,`PRAGMA foreign_key_list("${e}")`),s=new Map;for(let i of o)s.set(i.from,i);return a.map(i=>{let l=s.get(i.name),c=i.type.toLowerCase();return{columnName:i.name,dataType:cr(c),dataTypeLabel:Sn(c),isNullable:i.notnull===0&&i.pk===0,columnDefault:i.dflt_value,isPrimaryKey:i.pk>0,isForeignKey:s.has(i.name),referencedTable:l?.table??null,referencedColumn:l?.to??null,enumValues:null}})}catch(r){throw r instanceof W?r:this.wrapError(r)}}async addColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,columnType:a,defaultValue:o,isNullable:s,isUnique:i,db:l}=e,c=await oe();if(!await this.tableExists(c,t))throw new W(404,{message:`Table "${t}" does not exist`});if((await Z(c,`PRAGMA table_info("${t}")`)).some(p=>p.name===r))throw new W(409,{message:`Column "${r}" already exists in table "${t}"`});let m=`"${r}" ${a}`;i&&(m+=" UNIQUE"),s||(m+=" NOT NULL"),o?.trim()&&(m+=` DEFAULT ${o.trim()}`);try{await c.execute(`ALTER TABLE "${t}" ADD COLUMN ${m}`)}catch(p){throw this.wrapError(p)}})}async deleteColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,db:a}=e,o=await oe();if(!await this.tableExists(o,t))throw new W(404,{message:`Table "${t}" does not exist`});if(!(await Z(o,`PRAGMA table_info("${t}")`)).some(i=>i.name===r))throw new W(404,{message:`Column "${r}" does not exist in table "${t}"`});try{await o.execute(`ALTER TABLE "${t}" DROP COLUMN "${r}"`)}catch(i){throw this.wrapError(i)}return{deletedCount:1}})}async alterColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,columnType:a,isNullable:o,defaultValue:s,db:i}=e,l=await oe(),c=E=>this.quoteIdentifier(E);if(!await this.tableExists(l,t))throw new W(404,{message:`Table "${t}" does not exist`});let u=await Z(l,`PRAGMA table_info(${c(t)})`);if(!u.some(E=>E.name===r))throw new W(404,{message:`Column "${r}" does not exist in table "${t}"`});let m=u.filter(E=>E.pk>0).sort((E,R)=>E.pk-R.pk),p=m.length>1,d=u.map(E=>{let R=E.name===r,D=R?a:E.type,$=R?o:E.notnull===0,q=R?s?.trim()||null:E.dflt_value,P=E.pk>0,U=`${c(E.name)} ${D}`;return!p&&P&&(U+=" PRIMARY KEY"),!P&&!$&&(U+=" NOT NULL"),q&&(U+=` DEFAULT ${q}`),U});p&&d.push(`PRIMARY KEY (${m.map(E=>c(E.name)).join(", ")})`);let f=await Z(l,`PRAGMA foreign_key_list(${c(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(re=>c(re.from)).join(", "),D=E.map(re=>re.to),$=gi(D)?` (${D.map(c).join(", ")})`:"",{table:q,on_update:P,on_delete:U}=E[0];return`FOREIGN KEY (${R}) REFERENCES ${c(q)}${$} ON UPDATE ${P} ON DELETE ${U}`}),w=u.map(E=>c(E.name)).join(", "),C=`${t}_alter_${Date.now()}`,N=await Z(l,"SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name=? AND sql IS NOT NULL",[t]),A=await Z(l,"SELECT sql FROM sqlite_master WHERE type='trigger' AND tbl_name=?",[t]);try{await l.migrate([`CREATE TABLE ${c(C)} (${[...d,...g].join(", ")})`,`INSERT INTO ${c(C)} (${w}) SELECT ${w} FROM ${c(t)}`,`DROP TABLE ${c(t)}`,`ALTER TABLE ${c(C)} RENAME TO ${c(t)}`,...N.map(({sql:E})=>E),...A.map(({sql:E})=>E)])}catch(E){throw this.wrapError(E)}})}async renameColumn(e){return this.serializeSchemaChange(async()=>{let{tableName:t,columnName:r,newColumnName:a,db:o}=e,s=await oe();if(!await this.tableExists(s,t))throw new W(404,{message:`Table "${t}" does not exist`});let i=await Z(s,`PRAGMA table_info("${t}")`);if(!i.some(l=>l.name===r))throw new W(404,{message:`Column "${r}" does not exist in table "${t}"`});if(i.some(l=>l.name===a))throw new W(409,{message:`Column "${a}" already exists in table "${t}"`});try{await s.execute(`ALTER TABLE "${t}" RENAME COLUMN "${r}" TO "${a}"`)}catch(l){throw this.wrapError(l)}})}async addRecord({params:e}){let{tableName:t,data:r}=e,a=Object.keys(r);if(!a.length)throw new W(400,{message:"No data provided for insert"});let o=a.map(i=>`"${i}"`).join(", "),s=a.map(()=>"?").join(", ");try{let l=await(await oe()).execute(Lt(`INSERT INTO "${t}" (${o}) VALUES (${s})`,Object.values(r)));if(l.rowsAffected===0)throw new W(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:l.rowsAffected}}catch(i){throw this.wrapError(i)}}async updateRecords({db:e,params:t}){let{tableName:r}=t,a=this.resolveKeyColumns(t),o=this.groupUpdatesByKey(t,a);try{let s=await oe();this.assertWholeKey(await this.getPrimaryKeyColumns(s,r),a);let i=await s.transaction("write");try{let l=0;for(let{keyValues:c,rowUpdates:u}of o){let m=u.map(f=>`"${f.columnName}" = ?`).join(", "),p=a.map(f=>`"${f}" = ?`).join(" AND "),d=await i.execute(Lt(`UPDATE "${r}" SET ${m} WHERE ${p}`,[...u.map(f=>f.value),...c]));if(d.rowsAffected===0)throw new W(404,{message:`Record with ${this.describeKey(a,c)} not found in table "${r}"`});l+=d.rowsAffected}return await i.commit(),{updatedCount:l}}catch(l){throw await i.rollback(),l}finally{i.close()}}catch(s){throw this.wrapError(s)}}async deleteRecords({tableName:e,primaryKeys:t,db:r}){let a=t[0]?.columnName;if(!a)throw new W(400,{message:"Primary key column name is required"});let o=t.map(l=>l.value),s=o.map(()=>"?").join(", "),i=await oe();try{return this.assertDeletableKey(await this.getPrimaryKeyColumns(i,e)),{deletedCount:(await i.execute(Lt(`DELETE FROM "${e}" WHERE "${a}" IN (${s})`,o))).rowsAffected,fkViolation:!1,relatedRecords:[]}}catch(l){if(Ti(l))return{deletedCount:0,fkViolation:!0,relatedRecords:await this.getRelatedRecords(i,e,t)};throw this.wrapError(l)}}async forceDeleteRecords({tableName:e,primaryKeys:t,db:r}){let a=t[0]?.columnName;if(!a)throw new W(400,{message:"Primary key column name is required"});let o=l=>this.quoteIdentifier(l),s=t.map(l=>l.value),i=`${o(a)} IN (${s.map(()=>"?").join(", ")})`;try{let l=await oe();this.assertDeletableKey(await this.getPrimaryKeyColumns(l,e));let c=await this.getForeignKeysByParent(l),u=[],m=async(d,f,y)=>{for(let g of c.get(d)??[]){if(y.includes(g.childTable))continue;let w=gi(g.parentColumns)?g.parentColumns:await this.getPrimaryKeyColumns(l,d),C=`(${g.childColumns.map(o).join(", ")}) IN (SELECT ${w.map(o).join(", ")} FROM ${o(d)} WHERE ${f})`;await m(g.childTable,C,[...y,g.childTable])}u.push(Lt(`DELETE FROM ${o(d)} WHERE ${f}`,s))};return await m(e,i,[e]),{deletedCount:(await l.batch(u,"write")).reduce((d,f)=>d+f.rowsAffected,0)}}catch(l){throw Ti(l)?new W(409,{message:`Cannot force delete from "${e}": rows are still referenced through a foreign key cycle`}):this.wrapError(l)}}async bulkInsertRecords({tableName:e,records:t,db:r}){if(!t?.length)throw new W(400,{message:"At least one record is required"});let a=Object.keys(t[0]),o=a.map(l=>`"${l}"`).join(", "),s=a.map(()=>"?").join(", "),i=`INSERT INTO "${e}" (${o}) VALUES (${s})`;try{return await(await oe()).batch(t.map(c=>Lt(i,a.map(u=>c[u]))),"write"),{success:!0,message:`Bulk insert completed: ${t.length} records inserted`,successCount:t.length,failureCount:0}}catch(l){throw this.wrapError(l)}}async executeQuery({query:e,db:t}){if(!e?.trim())throw new W(400,{message:"Query is required"});let r=e.trim().replace(/;+$/,"");if(hi(r))throw new W(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(yi(r))throw new W(400,{message:"The query runner runs one statement at a time. Run each statement separately."});let a=performance.now();try{let o=await(await oe()).execute(r),s=performance.now()-a;if(o.columns.length>0){let i=ka(o);return{columns:o.columns,rows:i,rowCount:i.length,duration:s,message:i.length===0?"OK":void 0}}return{columns:[],rows:[],rowCount:o.rowsAffected,duration:s,message:`OK (${o.rowsAffected} rows affected)`}}catch(o){throw this.wrapError(o)}}async tableExists(e,t){return(await Z(e,"SELECT name FROM sqlite_master WHERE type='table' AND name=?",[t])).length>0}async getPrimaryKeyColumns(e,t){return(await Z(e,`PRAGMA table_info(${this.quoteIdentifier(t)})`)).filter(a=>a.pk>0).sort((a,o)=>a.pk-o.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"
371
371
  FROM sqlite_master m JOIN pragma_foreign_key_list(m.name) f
372
372
  WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%'
373
- ORDER BY m.name, f.id, f.seq`),r=new Map,a=new Map;for(let o of t){let s=`${o.child}\0${o.id}`,i=r.get(s);i||(i={childTable:o.child,childColumns:[],parentColumns:[]},r.set(s,i),a.set(o.parent,[...a.get(o.parent)??[],i])),i.childColumns.push(o.from),i.parentColumns.push(o.to)}return a}getFileSize(e){if(!e)return"in-memory";try{let r=lm(e).size;return r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/(1024*1024)).toFixed(1)} MB`}catch{return"N/A"}}async getFkReferencesForTable(e,t){return(await X(e,`SELECT m.name AS child, f."from", f."to"
373
+ ORDER BY m.name, f.id, f.seq`),r=new Map,a=new Map;for(let o of t){let s=`${o.child}\0${o.id}`,i=r.get(s);i||(i={childTable:o.child,childColumns:[],parentColumns:[]},r.set(s,i),a.set(o.parent,[...a.get(o.parent)??[],i])),i.childColumns.push(o.from),i.parentColumns.push(o.to)}return a}getFileSize(e){if(!e)return"in-memory";try{let r=wm(e).size;return r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/(1024*1024)).toFixed(1)} MB`}catch{return"N/A"}}async getFkReferencesForTable(e,t){return(await Z(e,`SELECT m.name AS child, f."from", f."to"
374
374
  FROM sqlite_master m JOIN pragma_foreign_key_list(m.name) f
375
- WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%' AND m.name != ? AND f."table" = ?`,[t,t])).map(a=>({constraintName:`fk_${a.child}_${a.from}_${t}_${a.to}`,referencingTable:a.child,referencingColumn:a.from,referencedTable:t,referencedColumn:a.to??""}))}async getRelatedRecordsForTable(e,t){let r=await this.getFkReferencesForTable(e,t),a=[];for(let o of r){let s=await X(e,`SELECT * FROM "${o.referencingTable}" LIMIT 100`);s.length>0&&a.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return a}async getRelatedRecords(e,t,r){let a=await this.getFkReferencesForTable(e,t),o=[];for(let s of a){if(!r.find(m=>m.columnName===s.referencedColumn))continue;let l=r.map(m=>m.value),c=l.map(()=>"?").join(", "),u=await X(e,`SELECT * FROM "${s.referencingTable}" WHERE "${s.referencingColumn}" IN (${c}) LIMIT 100`,l);u.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:u})}return o}}});function pi(){he.register("pg",new Yr),he.register("mysql",new jr),he.register("mssql",new Fr),he.register("mongodb",new Br),he.register("sqlite",new Zr),he.register("redis",new Jr),he.register("duckdb",new qr),he.register("oracle",new Vr),he.register("clickhouse",new Mr)}var fi=S(()=>{"use strict";h();Je();as();ds();Es();Ss();Ds();Hs();Vs();si();di()});import{HTTPException as Pa}from"hono/http-exception";import{DatabaseError as pm}from"pg";import{ZodError as yi}from"zod";function bi(n,e){let t=xt(e.req.method,e.req.path),r=fm(n),a=ym(n);if(Vn("error","request_failed",{operation:t,error_type:r}),Hn(n,{operation:t,status:a,dbType:Kn(e.req.path)}),n instanceof Pa)return e.json({error:n.message??"Internal server error"},n.status);if(n instanceof yi){let o=n.issues[0];return e.json({error:"Validation error",details:o.message},400)}return n instanceof Error&&hi(n)?e.json({error:"Database connection failed",details:n.message},503):e.json({error:n instanceof Error?n.message:"Internal server error"},500)}var fm,hi,ym,gi=S(()=>{"use strict";h();vt();fm=n=>n instanceof Pa?"HTTPException":n instanceof Error?n.name:"UnknownError",hi=n=>{let e=n;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||n.message.includes("ECONNREFUSED")||n.message.includes("connection refused")||n.message.includes("timeout expired")||n.message.includes("Connection terminated")||n.message.includes("MongoNetworkError")||n.message.includes("MongoServerSelectionError")||n instanceof pm&&n.code?.startsWith("08")===!0},ym=n=>n instanceof Pa?n.status:n instanceof yi?400:n instanceof Error&&hi(n)?503:500});function Ei(n){if(!n)return`You are a database assistant for db-studio. Keep answers concise and focused.
375
+ WHERE m.type = 'table' AND m.name NOT LIKE 'sqlite_%' AND m.name != ? AND f."table" = ?`,[t,t])).map(a=>({constraintName:`fk_${a.child}_${a.from}_${t}_${a.to}`,referencingTable:a.child,referencingColumn:a.from,referencedTable:t,referencedColumn:a.to??""}))}async getRelatedRecordsForTable(e,t){let r=await this.getFkReferencesForTable(e,t),a=[];for(let o of r){let s=await Z(e,`SELECT * FROM "${o.referencingTable}" LIMIT 100`);s.length>0&&a.push({tableName:o.referencingTable,columnName:o.referencingColumn,constraintName:o.constraintName,records:s})}return a}async getRelatedRecords(e,t,r){let a=await this.getFkReferencesForTable(e,t),o=[];for(let s of a){if(!r.find(m=>m.columnName===s.referencedColumn))continue;let l=r.map(m=>m.value),c=l.map(()=>"?").join(", "),u=await Z(e,`SELECT * FROM "${s.referencingTable}" WHERE "${s.referencingColumn}" IN (${c}) LIMIT 100`,l);u.length>0&&o.push({tableName:s.referencingTable,columnName:s.referencingColumn,constraintName:s.constraintName,records:u})}return o}}});function wi(){ge.register("pg",new Xr),ge.register("mysql",new zr),ge.register("mssql",new Vr),ge.register("mongodb",new Wr),ge.register("sqlite",new an),ge.register("redis",new rn),ge.register("duckdb",new jr),ge.register("oracle",new Jr),ge.register("clickhouse",new Ur)}var Ci=S(()=>{"use strict";h();et();ds();Es();_s();Is();ks();Xs();ei();fi();Ei()});import{HTTPException as Ri}from"hono/http-exception";import{DatabaseError as Nm}from"pg";import{ZodError as Si}from"zod";function Ni(n,e){let t=Dt(e.req.method,e.req.path),r=Dm(n),a=Ft(e.req.path),o=lt();if(Q(r>=500?"error":"warn","request_failed",{operation:t,db_type:a,method:e.req.method,status:r,...le(n)}),Qn(n,{operation:t,status:r,dbType:a}),n instanceof Ri)return e.json({error:n.message??"Internal server error",requestId:o},n.status);if(n instanceof Si){let s=n.issues[0];return e.json({error:"Validation error",details:s.message,requestId:o},400)}return n instanceof Error&&Ai(n)?e.json({error:"Database connection failed",details:n.message,requestId:o},503):e.json({error:n instanceof Error?n.message:"Internal server error",requestId:o},500)}var Ai,Dm,Di=S(()=>{"use strict";h();Kt();Ze();Ai=n=>{let e=n;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||n.message.includes("ECONNREFUSED")||n.message.includes("connection refused")||n.message.includes("timeout expired")||n.message.includes("Connection terminated")||n.message.includes("MongoNetworkError")||n.message.includes("MongoServerSelectionError")||n instanceof Nm&&n.code?.startsWith("08")===!0},Dm=n=>n instanceof Ri?n.status:n instanceof Si?400:n instanceof Error&&Ai(n)?503:500});function Oi(n){if(!n)return`You are a database assistant for db-studio. Keep answers concise and focused.
376
376
 
377
- The user chose not to share their database schema. Do not claim to know their table or column names. Ask for the minimum missing details needed to answer accurately, generate queries in fenced code blocks, and warn before potentially destructive or expensive operations.`;let e=n.dbType.toLowerCase(),t=Z[n.dbType].label;return e.includes("mongo")?`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
377
+ The user chose not to share their database schema. Do not claim to know their table or column names. Ask for the minimum missing details needed to answer accurately, generate queries in fenced code blocks, and warn before potentially destructive or expensive operations.`;let e=n.dbType.toLowerCase(),t=ee[n.dbType].label;return e.includes("mongo")?`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
378
378
 
379
379
  **Your Role:**
380
380
  1. Keep responses SHORT - 2-3 sentences maximum unless generating a query
@@ -388,7 +388,7 @@ The user chose not to share their database schema. Do not claim to know their ta
388
388
  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
389
389
 
390
390
  **Database Context:**
391
- ${Ti(n)}
391
+ ${_i(n)}
392
392
 
393
393
  **Guidelines:**
394
394
  1. Always generate syntactically correct MongoDB queries
@@ -450,7 +450,7 @@ This will return the top 5 customers by revenue."`:`You are a database assistant
450
450
  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
451
451
 
452
452
  **Database Context:**
453
- ${Ti(n)}
453
+ ${_i(n)}
454
454
 
455
455
  **Guidelines:**
456
456
  1. Always generate syntactically correct SQL for the database type (${t})
@@ -488,7 +488,7 @@ LIMIT 5;
488
488
 
489
489
  This will return the 5 customers with the highest total order value. You might also want to see:
490
490
  - Revenue trends over time for these customers
491
- - Their most frequently ordered products"`}function Ti(n){let t=`Database Type: ${Z[n.dbType].label}
491
+ - Their most frequently ordered products"`}function _i(n){let t=`Database Type: ${ee[n.dbType].label}
492
492
 
493
493
  `;t+=`**Tables and Columns:**
494
494
  `;for(let r of n.tables){t+=`
@@ -502,12 +502,12 @@ This will return the 5 customers with the highest total order value. You might a
502
502
  `)}if(n.relationships&&n.relationships.length>0){t+=`
503
503
  **Relationships:**
504
504
  `;for(let r of n.relationships)t+=` - ${r.fromTable}.${r.fromColumn} -> ${r.toTable}.${r.toColumn}
505
- `}return t}var wi=S(()=>{"use strict";h();ne()});function hm(n){let e={name:n.columnName,type:n.dataTypeLabel,nullable:n.isNullable};return n.isPrimaryKey&&(e.isPrimaryKey=!0),n.isForeignKey&&n.referencedTable&&n.referencedColumn&&(e.foreignKey=`${n.referencedTable}.${n.referencedColumn}`),n.enumValues&&n.enumValues.length>0&&(e.enumValues=n.enumValues,e.description=`Enum values: ${n.enumValues.join(", ")}`),e}function bm(n){let e=[];for(let t of n)for(let r of t.columns)if(r.foreignKey){let[a,o]=r.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:r.name,toTable:a,toColumn:o})}return e}function gm(n){if(n==null)return"";if(n instanceof Date)return n.toISOString();if(typeof n=="bigint")return n.toString();if(typeof n=="object")try{return JSON.stringify(n)}catch{return String(n)}return String(n)}async function Tm(n,e,t){try{return(await n.getTableData({tableName:e,db:t,limit:3})).data.map(a=>Object.fromEntries(Object.entries(a).map(([o,s])=>[o,gm(s)])))}catch(r){return console.warn(`Could not fetch sample data for table ${e}:`,r),[]}}async function Em(n,e,t){try{return await n.getTableColumns({tableName:e,db:t})}catch(r){return console.warn(`Could not fetch columns for table ${e}:`,r),[]}}async function wm(n,e={}){let t=et(),{includeSampleData:r=!1,maxTables:a}=e,o=F(t);try{let s=await o.getTablesList(n),l=s.slice(0,a??s.length).map(async({schemaName:m,tableName:p})=>{let[d,f]=await Promise.all([Em(o,p,n),r?Tm(o,p,n):Promise.resolve([])]),y={name:m?`${m}.${p}`:p,columns:d.map(hm)};return f.length>0&&(y.sampleData=f),y}),c=await Promise.all(l),u=bm(c);return{dbType:t,tables:c,relationships:u}}catch(s){throw console.error("Error fetching database schema:",s),new Error(`Failed to fetch database schema: ${s instanceof Error?s.message:"Unknown error"}`)}}async function Ci(n){return wm(n,{includeSampleData:!0,includeDescriptions:!0})}var Ri=S(()=>{"use strict";h();Je();st()});import{zValidator as Cm}from"@hono/zod-validator";import{Hono as Rm}from"hono";import{HTTPException as Si}from"hono/http-exception";var Sm,Ai,Ni,Di=S(()=>{"use strict";h();$t();ne();wi();Ri();Sm=new Set(["localhost","127.0.0.1","::1","[::1]"]),Ai=()=>{let n;try{n=new URL(Qe.PROXY_URL)}catch{throw new Si(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=Sm.has(n.hostname)||n.hostname.endsWith(".localhost");if(n.protocol!=="https:"&&!(n.protocol==="http:"&&e))throw new Si(500,{message:"DB_STUDIO_PROXY_URL must use HTTPS unless it points at loopback"});return n.origin},Ni=new Rm().basePath("/chat").get("/limit",async n=>{let e=Ai();try{let t=await fetch(`${e}/chat/limit`,{headers:{"cf-connecting-ip":n.req.header("cf-connecting-ip")??"","x-real-ip":n.req.header("x-real-ip")??"","x-forwarded-for":n.req.header("x-forwarded-for")??"","x-api-key":n.req.header("x-api-key")??""}});return t.ok?n.json(await t.json(),200):n.json({limit:3,used:3,remaining:0},200)}catch{return n.json({limit:3,used:3,remaining:0},200)}}).post("/",Cm("json",fn),async n=>{let{messages:e,data:t,provider:r,model:a}=n.req.valid("json"),{db:o,conversationId:s,includeSchema:i}=t,l=i?await Ci(o):null,c=Ei(l),u={messages:e,conversationId:s,systemPrompt:c,provider:r,model:a},m=await fetch(`${Ai()}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":n.req.header("cf-connecting-ip")??"","x-real-ip":n.req.header("x-real-ip")??"","x-forwarded-for":n.req.header("x-forwarded-for")??"","x-api-key":n.req.header("x-api-key")??"","x-byok-gemini":n.req.header("x-byok-gemini")??"","x-byok-openai":n.req.header("x-byok-openai")??"","x-byok-anthropic":n.req.header("x-byok-anthropic")??"","x-byok-grok":n.req.header("x-byok-grok")??"","x-byok-openrouter":n.req.header("x-byok-openrouter")??""},body:JSON.stringify(u)});if(!m.ok){let p=await m.json();return n.json({error:p.error||"Proxy request failed"},m.status)}return new Response(m.body,{status:m.status,headers:m.headers})})});import{Hono as Am}from"hono";var _i,Oi=S(()=>{"use strict";h();Je();st();_i=new Am().basePath("/databases").get("/",async n=>{let e=et(),r=await F(e).getDatabasesList();return n.json({data:{databases:r,dbType:e}},200)}).get("/current",async n=>{let e=et(),r=await F(e).getCurrentDatabase();return n.json({data:{db:r.db,dbType:e}},200)}).get("/connection",async n=>{let e=et(),r=await F(e).getDatabaseConnectionInfo();return n.json({data:r},200)})});import{zValidator as ke}from"@hono/zod-validator";import{Hono as Nm}from"hono";var $i,Pi=S(()=>{"use strict";h();ne();Je();$i=new Nm().basePath("/keys").get("/",ke("query",_n),async n=>{let e=n.req.valid("query"),t=n.get("dbType"),r=it(F(t),t);return n.json({data:await r.scanKeys(e)},200)}).post("/",ke("query",x),ke("json",Ln),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType"),a=it(F(r),r);return n.json({data:await a.createKey({db:e,...t})},200)}).get("/:key/raw",ke("param",gt),ke("query",Pn),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=it(F(r),r);return n.json({data:await a.getStringChunk({...t,key:e})},200)}).get("/:key",ke("param",gt),ke("query",$n),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=it(F(r),r);return n.json({data:await a.getKeyDetails({...t,key:e})},200)}).post("/:key/actions",ke("param",gt),ke("query",x),ke("json",In),async n=>{let{key:e}=n.req.valid("param"),{db:t}=n.req.valid("query"),r=n.req.valid("json"),a=n.get("dbType"),o=it(F(a),a);return n.json({data:await o.applyKeyAction({db:t,key:e,...r})},200)}).delete("/:key",ke("param",gt),ke("query",Mn),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=it(F(r),r);return n.json({data:await a.deleteKey({...t,key:e})},200)})});import{zValidator as Li}from"@hono/zod-validator";import{Hono as Dm}from"hono";var Ii,Mi=S(()=>{"use strict";h();ne();Je();Ii=new Dm().basePath("/query").post("/",Li("query",x),Li("json",Nn),async n=>{let{query:e}=n.req.valid("json"),{db:t}=n.req.valid("query"),r=n.get("dbType"),o=await F(r).executeQuery({query:e,db:t});return n.json({data:o},200)})});import{zValidator as ze}from"@hono/zod-validator";import{Hono as _m}from"hono";var ki,xi=S(()=>{"use strict";h();ne();Je();ki=new _m().basePath("/records").post("/",ze("query",x),ze("json",ln),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,data:r}=n.req.valid("json"),a=n.get("dbType"),o=F(a),{insertedCount:s}=await o.addRecord({db:e,params:{tableName:t,data:r}});return n.json({data:`Record inserted into "${t}" with ${s} rows inserted`},200)}).patch("/",ze("query",x),ze("json",vn),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType"),a=F(r),{updatedCount:o}=await a.updateRecords({params:t,db:e});return n.json({data:`Updated ${o} records in "${t.tableName}"`},200)}).delete("/",ze("query",x),ze("json",lr),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,primaryKeys:r}=n.req.valid("json"),a=n.get("dbType"),o=F(a),{deletedCount:s,fkViolation:i,relatedRecords:l}=await o.deleteRecords({tableName:t,primaryKeys:r,db:e});return i?n.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:l}},409):n.json({data:{deletedCount:s,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",ze("query",x),ze("json",lr),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,primaryKeys:r}=n.req.valid("json"),a=n.get("dbType"),s=await F(a).forceDeleteRecords({tableName:t,primaryKeys:r,db:e});return n.json({data:s},200)}).post("/bulk",ze("query",x),ze("json",pn),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,records:r}=n.req.valid("json"),a=n.get("dbType"),s=await F(a).bulkInsertRecords({tableName:t,records:r,db:e});return console.log("result",s),n.json({data:s},200)})});import{utils as zt,write as Om}from"xlsx";function qi({cols:n,rows:e,format:t,tableName:r}){switch(t){case"json":{let a=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(a,"utf-8"))}case"csv":{let a=zt.aoa_to_sheet(vi(n,e)),o=zt.sheet_to_csv(a);return new Uint8Array(Buffer.from(o,"utf-8"))}case"xlsx":{let a=zt.aoa_to_sheet(vi(n,e)),o=zt.book_new();zt.book_append_sheet(o,a,r.slice(0,31));let s=Om(o,{bookType:"xlsx",type:"buffer"});return new Uint8Array(s)}}}var $m,vi,Ui=S(()=>{"use strict";h();$m=n=>n==null||n instanceof Date?n:Buffer.isBuffer(n)?`0x${n.toString("hex")}`:typeof n=="object"?JSON.stringify(n):typeof n=="bigint"?n.toString():n,vi=(n,e)=>[n,...e?.map(t=>n?.map(r=>$m(t[r])))??[]]});import{zValidator as z}from"@hono/zod-validator";import{Hono as Pm}from"hono";var Bi,Fi=S(()=>{"use strict";h();ne();Je();Ui();Bi=new Pm().basePath("/tables").get("/",z("query",x),async n=>{let{db:e}=n.req.valid("query"),t=n.get("dbType"),a=await F(t).getTablesList(e);return n.json({data:a},200)}).post("/",z("query",x),z("json",Sn),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType");return await F(r).createTable({tableData:t,db:e}),n.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",z("query",An),z("param",be),async n=>{let{db:e,cascade:t}=n.req.valid("query"),{tableName:r}=n.req.valid("param"),a=n.get("dbType"),s=await F(a).deleteTable({tableName:r,db:e,cascade:t});return n.json({data:s},200)}).patch("/:tableName/rename",z("query",x),z("param",be),z("json",Mt),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.req.valid("json"),a=n.get("dbType");return await F(a).renameTable({tableName:t,db:e,...r}),n.json({data:`Table "${t}" renamed to "${r.newTableName}"`},200)}).delete("/:tableName/columns/:columnName",z("query",dn),z("param",ge),async n=>{let{db:e,cascade:t}=n.req.valid("query"),{tableName:r,columnName:a}=n.req.valid("param"),o=n.get("dbType"),s=F(o),{deletedCount:i}=await s.deleteColumn({tableName:r,columnName:a,cascade:t,db:e});return n.json({data:`Column "${a}" deleted successfully from table "${r}" with ${i} rows deleted`},200)}).post("/:tableName/columns",z("query",x),z("param",be),z("json",xe),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.req.valid("json"),a=n.get("dbType");return await F(a).addColumn({tableName:t,db:e,...r}),n.json({data:`Column "${r.columnName}" added successfully to table "${t}"`},200)}).patch("/:tableName/columns/:columnName/rename",z("query",x),z("param",ge),z("json",ur),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,columnName:r}=n.req.valid("param"),a=n.req.valid("json"),o=n.get("dbType");return await F(o).renameColumn({tableName:t,columnName:r,db:e,...a}),n.json({data:`Column "${r}" renamed to "${a.newColumnName}" in table "${t}"`},200)}).patch("/:tableName/columns/:columnName",z("query",x),z("param",ge),z("json",pt),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,columnName:r}=n.req.valid("param"),a=n.req.valid("json"),o=n.get("dbType");return await F(o).alterColumn({tableName:t,columnName:r,db:e,...a}),n.json({data:`Column "${r}" updated successfully in table "${t}"`},200)}).get("/:tableName/columns",z("query",x),z("param",be),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.get("dbType"),o=await F(r).getTableColumns({tableName:t,db:e});return n.json({data:o},200)}).get("/:tableName/schema",z("query",x),z("param",be),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.get("dbType"),o=await F(r).getTableSchema({tableName:t,db:e});return n.json({data:{schema:o}},200)}).get("/:tableName/data",z("param",be),z("query",xn),async n=>{let{tableName:e}=n.req.valid("param"),{cursor:t,limit:r,direction:a,sort:o,order:s,filters:i,db:l}=n.req.valid("query"),c=n.get("dbType"),m=await F(c).getTableData({tableName:e,cursor:t,limit:r,direction:a,sort:o,order:s,filters:i,db:l});return n.json({data:m},200)}).get("/:tableName/export",z("param",be),z("query",Dn),async n=>{let{tableName:e}=n.req.valid("param"),{db:t,format:r}=n.req.valid("query"),a=n.get("dbType"),o=F(a),{cols:s,rows:i}=await o.exportTableData({tableName:e,db:t}),l=qi({cols:s,rows:i,format:r,tableName:e}),c;switch(r){case"csv":c="text/csv";break;case"xlsx":c="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";break;case"json":c="application/json";break}return new Response(l,{headers:{"Content-Type":c??"","Content-Disposition":`attachment; filename="${e}_export.${r}"`}})})});import{Hono as Lm}from"hono";import{z as Ki}from"zod";var Im,ji,Hi=S(()=>{"use strict";h();vt();Im=Ki.object({enabled:Ki.boolean()}).strict(),ji=new Lm().basePath("/telemetry").get("/config",async n=>((n.req.header("x-db-studio-gpc")==="1"||n.req.header("sec-gpc")==="1")&&br(!1),jn(),n.json({data:hr()},200))).put("/preference",async n=>{let e=Im.safeParse(await n.req.json().catch(()=>{}));return e.success?(br(e.data.enabled),n.json({data:hr()},200)):n.json({error:"Invalid telemetry preference"},400)}).post("/reset",async n=>n.json({data:{installationId:Un()}},200))});var zi={};Xt(zi,{createServer:()=>Fm});import{existsSync as Wi}from"fs";import nt from"path";import{fileURLToPath as Mm}from"url";import{serveStatic as Gt}from"@hono/node-server/serve-static";import{zValidator as km}from"@hono/zod-validator";import{Hono as xm}from"hono";import{cors as vm}from"hono/cors";import{HTTPException as qm}from"hono/http-exception";import{logger as Um}from"hono/logger";import{prettyJSON as Bm}from"hono/pretty-json";import{z as Vi}from"zod";var Ue,Qt,Yi,Fm,Gi=S(()=>{"use strict";h();$t();Je();fi();gi();vt();Di();Oi();Pi();Mi();xi();Fi();Hi();({API_PREFIX:Ue}=Qe),Qt=()=>{if(process.env.NODE_ENV==="development")return nt.resolve(process.cwd(),"../web/dist");let n=nt.dirname(Mm(import.meta.url)),e=nt.resolve(n,"./web-dist"),t=nt.resolve(process.cwd(),"../web/dist"),r=nt.resolve(e,"index.html"),a=nt.resolve(t,"index.html");return!Wi(r)&&Wi(a)?t:e},Yi=Vi.object({dbType:Vi.string().refine(n=>he.getSupportedTypes().includes(n),{message:`Invalid database type. Supported types: ${he.getSupportedTypes().join(", ")}`})}),Fm=()=>{pi();let n=new xm({strict:!1}).use("/*",vm({origin:e=>{if(!e)return;if((process.env.ALLOWED_ORIGINS?.split(",").map(r=>r.trim()).filter(Boolean)??[]).includes(e))return e;if(process.env.NODE_ENV==="development")try{let r=new URL(e);if(r.hostname==="localhost"||r.hostname.endsWith(".localhost")||r.hostname==="127.0.0.1")return e}catch{}},allowMethods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowHeaders:["Content-Type","X-Run-Id","X-DB-Studio-GPC","x-byok-gemini","x-byok-openai","x-byok-anthropic","x-byok-grok","x-byok-openrouter"],maxAge:600})).use(Bm({space:2})).use(process.env.NODE_ENV==="development"?Um():(e,t)=>t()).use(`${Ue}/*`,async(e,t)=>{if(e.req.path.startsWith(`${Ue}/telemetry`))return t();let r=performance.now(),a=xt(e.req.method,e.req.path),o=e.req.path.split("/")[2],s=he.getSupportedTypes().find(i=>i===o);await Wn(a,s,t),gr({event:"server_operation",properties:{operation:a,method:e.req.method,outcome:Fn(e.res.status),duration_bucket:Bn(performance.now()-r),db_type:s}})}).use("/favicon.ico",Gt({path:nt.resolve(Qt(),"favicon.ico")})).onError(bi).route(Ue,_i).route(Ue,Ni).route(Ue,ji).use("/assets/*",Gt({root:Qt()})).use("/image.png",Gt({root:Qt()})).use(`${Ue}/:dbType/*`,km("param",Yi,(e,t)=>{if(!e.success){let r=t.req.param("dbType");throw new qm(400,{message:`Invalid database type: "${r}". Supported types: ${he.getSupportedTypes().join(", ")}`})}}),async(e,t)=>{let{dbType:r}=Yi.parse({dbType:e.req.param("dbType")});e.set("dbType",r),await t()}).route(`${Ue}/:dbType`,Bi).route(`${Ue}/:dbType`,ki).route(`${Ue}/:dbType`,Ii).route(`${Ue}/:dbType`,$i);return process.env.NODE_ENV!=="test"&&(n.all(`${Ue}/*`,e=>e.json({error:"Not found"},404)),n.use("/*",Gt({root:Qt()})),n.get("/*",Gt({path:nt.resolve(Qt(),"index.html")}))),{app:n}}});h();h();(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new n.Error().stack;e&&(n._sentryDebugIds=n._sentryDebugIds||{},n._sentryDebugIds[e]="86de4c89-127a-4461-864f-505b73881ed5",n._sentryDebugIdIdentifier="sentry-dbid-86de4c89-127a-4461-864f-505b73881ed5")}catch{}})();h();$t();import{intro as Km,log as tn,outro as Qi,spinner as jm}from"@clack/prompts";import{serve as Hm}from"@hono/node-server";import Jt from"picocolors";h();import{program as nn}from"commander";var Ka=()=>{nn.name("db-studio").option("-e, --env <path>","Path to custom .env file").option("-p, --port <port>","Port to run the server on").option("-d, --database-url <url>","Database URL to use").option("-n, --var-name <name>","Custom environment variable name (default: DATABASE_URL)").option("--open","Open db-studio in the default browser").option("--no-open","Do not open db-studio in the default browser").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv);let n=nn.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&nn.error("Do not combine --open and --no-open"),{...n,open:e?!0:t?!1:void 0}};h();import{readFile as Xi}from"fs/promises";import{resolve as Zi}from"path";import{cancel as Zt,isCancel as an,note as ja,select as el,spinner as tl,text as Ha}from"@clack/prompts";import{parse as rl}from"dotenv";import on from"picocolors";var Wa=async(n,e)=>{let t=e||"DATABASE_URL";if(n?.[t])return n[t];if(process.env[t])return process.env[t];let r=tl();r.start("Looking for database connection..."),n?ja(on.red(`${t} not found in .env or process.env`)):ja(on.red(`No .env file found and ${t} not set in process.env`));let a=await el({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((an(a)||a==="cancel")&&(Zt("No database connection provided. Exiting..."),process.exit(0)),a==="other-env"){r.start("Waiting for path...");let s=await Ha({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(l){if(!l?.trim())return"Path is required"}});an(s)&&(Zt("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let i=Zi(s);try{let l=await Xi(i,"utf-8"),c=rl(l);if(c[t])return c[t];throw new Error(`${t} still missing in custom file`)}catch(l){let c=l;Zt(`Cannot read or parse file: ${on.dim(c.message)}`),process.exit(1)}}r.stop("Manual input...");let o=await Ha({message:`Paste your ${t}`,placeholder:"postgresql://user:password@localhost:5432/mydb or sqlite:///path/to/db.sqlite",validate(s){if(!s?.trim())return"Connection string is required!";if(!s.trim().startsWith("sqlite://"))try{new URL(s);return}catch{return"Must be a valid URL format"}}});return an(o)&&(Zt("Cancelled."),process.exit(0)),o.trim()};h();import{access as nl,readFile as al}from"fs/promises";import{dirname as ol,resolve as sn}from"path";import{parse as sl}from"dotenv";var il=async n=>{let e=sn(n);for(;;){let t=sn(e,".env");try{return await nl(t),t}catch{}let r=ol(e);if(r===e)return null;e=r}},ut=async n=>{let e;if(n?e=sn(n):e=await il(process.cwd()),!e)return null;try{let t=await al(e,"utf-8");return sl(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};h();import ll from"open";var Va=n=>n===!0,Ya=async n=>{await ll(n)};h();ne();var fc=Object.values(Z).flatMap(({protocols:n})=>n).map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),yc=new RegExp(`\\b(?:${fc}):\\/\\/\\S+`,"gi"),hc=/\b(authToken=)[^&\s]+/gi,Io=n=>n.replace(yc,e=>`the configured database${e.match(/[),.]+$/)?.[0]??""}`).replace(hc,"$1[redacted]");h();rn();ne();import{intro as bc,outro as gc}from"@clack/prompts";import Tt from"picocolors";var Mo=()=>{bc(Tt.inverse(" db-studio ")),console.log(Tt.bold(`
505
+ `}return t}var $i=S(()=>{"use strict";h();ae()});function _m(n){let e={name:n.columnName,type:n.dataTypeLabel,nullable:n.isNullable};return n.isPrimaryKey&&(e.isPrimaryKey=!0),n.isForeignKey&&n.referencedTable&&n.referencedColumn&&(e.foreignKey=`${n.referencedTable}.${n.referencedColumn}`),n.enumValues&&n.enumValues.length>0&&(e.enumValues=n.enumValues,e.description=`Enum values: ${n.enumValues.join(", ")}`),e}function Om(n){let e=[];for(let t of n)for(let r of t.columns)if(r.foreignKey){let[a,o]=r.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:r.name,toTable:a,toColumn:o})}return e}function $m(n){if(n==null)return"";if(n instanceof Date)return n.toISOString();if(typeof n=="bigint")return n.toString();if(typeof n=="object")try{return JSON.stringify(n)}catch{return String(n)}return String(n)}async function Pm(n,e,t){try{return(await n.getTableData({tableName:e,db:t,limit:3})).data.map(a=>Object.fromEntries(Object.entries(a).map(([o,s])=>[o,$m(s)])))}catch(r){return Q("warn","schema_sample_rows_failed",le(r)),[]}}async function Im(n,e,t){try{return await n.getTableColumns({tableName:e,db:t})}catch(r){return Q("warn","schema_columns_failed",le(r)),[]}}async function Lm(n,e={}){let t=nt(),{includeSampleData:r=!1,maxTables:a}=e,o=F(t);try{let s=await o.getTablesList(n),l=s.slice(0,a??s.length).map(async({schemaName:m,tableName:p})=>{let[d,f]=await Promise.all([Im(o,p,n),r?Pm(o,p,n):Promise.resolve([])]),y={name:m?`${m}.${p}`:p,columns:d.map(_m)};return f.length>0&&(y.sampleData=f),y}),c=await Promise.all(l),u=Om(c);return{dbType:t,tables:c,relationships:u}}catch(s){throw Q("error","schema_fetch_failed",le(s)),new Error(`Failed to fetch database schema: ${s instanceof Error?s.message:"Unknown error"}`)}}async function Pi(n){return Lm(n,{includeSampleData:!0,includeDescriptions:!0})}var Ii=S(()=>{"use strict";h();et();ut();Ze()});import{zValidator as Mm}from"@hono/zod-validator";import{Hono as km}from"hono";import{HTTPException as Li}from"hono/http-exception";var xm,Mi,ki,xi=S(()=>{"use strict";h();kt();ae();Ze();$i();Ii();xm=new Set(["localhost","127.0.0.1","::1","[::1]"]),Mi=()=>{let n;try{n=new URL(Xe.PROXY_URL)}catch{throw new Li(500,{message:"DB_STUDIO_PROXY_URL is not a valid URL"})}let e=xm.has(n.hostname)||n.hostname.endsWith(".localhost");if(n.protocol!=="https:"&&!(n.protocol==="http:"&&e))throw new Li(500,{message:"DB_STUDIO_PROXY_URL must use HTTPS unless it points at loopback"});return n.origin},ki=new km().basePath("/chat").get("/limit",async n=>{let e=Mi();try{let t=await fetch(`${e}/chat/limit`,{headers:{"cf-connecting-ip":n.req.header("cf-connecting-ip")??"","x-real-ip":n.req.header("x-real-ip")??"","x-forwarded-for":n.req.header("x-forwarded-for")??"","x-api-key":n.req.header("x-api-key")??"","x-request-id":lt()??""}});return t.ok?n.json(await t.json(),200):(Q("warn","chat_limit_unavailable",{proxy_status:t.status}),n.json({limit:3,used:3,remaining:0},200))}catch(t){return Q("warn","chat_limit_unavailable",le(t)),n.json({limit:3,used:3,remaining:0},200)}}).post("/",Mm("json",Tn),async n=>{let{messages:e,data:t,provider:r,model:a}=n.req.valid("json"),{db:o,conversationId:s,includeSchema:i}=t,l=i?await Pi(o):null,c=Oi(l),u={messages:e,conversationId:s,systemPrompt:c,provider:r,model:a},m=await fetch(`${Mi()}/chat`,{method:"POST",headers:{"Content-Type":"application/json","cf-connecting-ip":n.req.header("cf-connecting-ip")??"","x-real-ip":n.req.header("x-real-ip")??"","x-forwarded-for":n.req.header("x-forwarded-for")??"","x-api-key":n.req.header("x-api-key")??"","x-byok-gemini":n.req.header("x-byok-gemini")??"","x-byok-openai":n.req.header("x-byok-openai")??"","x-byok-anthropic":n.req.header("x-byok-anthropic")??"","x-byok-grok":n.req.header("x-byok-grok")??"","x-byok-openrouter":n.req.header("x-byok-openrouter")??"","x-request-id":lt()??""},body:JSON.stringify(u)});if(!m.ok){Q("warn","chat_proxy_rejected",{proxy_status:m.status,provider:r,model:a});let p=await m.json();return n.json({error:p.error||"Proxy request failed"},m.status)}return new Response(m.body,{status:m.status,headers:m.headers})})});import{Hono as vm}from"hono";var vi,qi=S(()=>{"use strict";h();et();ut();vi=new vm().basePath("/databases").get("/",async n=>{let e=nt(),r=await F(e).getDatabasesList();return n.json({data:{databases:r,dbType:e}},200)}).get("/current",async n=>{let e=nt(),r=await F(e).getCurrentDatabase();return n.json({data:{db:r.db,dbType:e}},200)}).get("/connection",async n=>{let e=nt(),r=await F(e).getDatabaseConnectionInfo();return n.json({data:r},200)})});import{zValidator as ve}from"@hono/zod-validator";import{Hono as qm}from"hono";var Ui,Bi=S(()=>{"use strict";h();ae();et();Ui=new qm().basePath("/keys").get("/",ve("query",Ln),async n=>{let e=n.req.valid("query"),t=n.get("dbType"),r=mt(F(t),t);return n.json({data:await r.scanKeys(e)},200)}).post("/",ve("query",x),ve("json",vn),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType"),a=mt(F(r),r);return n.json({data:await a.createKey({db:e,...t})},200)}).get("/:key/raw",ve("param",Ct),ve("query",xn),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=mt(F(r),r);return n.json({data:await a.getStringChunk({...t,key:e})},200)}).get("/:key",ve("param",Ct),ve("query",kn),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=mt(F(r),r);return n.json({data:await a.getKeyDetails({...t,key:e})},200)}).post("/:key/actions",ve("param",Ct),ve("query",x),ve("json",qn),async n=>{let{key:e}=n.req.valid("param"),{db:t}=n.req.valid("query"),r=n.req.valid("json"),a=n.get("dbType"),o=mt(F(a),a);return n.json({data:await o.applyKeyAction({db:t,key:e,...r})},200)}).delete("/:key",ve("param",Ct),ve("query",Un),async n=>{let{key:e}=n.req.valid("param"),t=n.req.valid("query"),r=n.get("dbType"),a=mt(F(r),r);return n.json({data:await a.deleteKey({...t,key:e})},200)})});import{zValidator as Fi}from"@hono/zod-validator";import{Hono as Um}from"hono";var Ki,ji=S(()=>{"use strict";h();ae();et();Ki=new Um().basePath("/query").post("/",Fi("query",x),Fi("json",Pn),async n=>{let{query:e}=n.req.valid("json"),{db:t}=n.req.valid("query"),r=n.get("dbType"),o=await F(r).executeQuery({query:e,db:t});return n.json({data:o},200)})});import{zValidator as Qe}from"@hono/zod-validator";import{Hono as Bm}from"hono";var Hi,Wi=S(()=>{"use strict";h();ae();et();Hi=new Bm().basePath("/records").post("/",Qe("query",x),Qe("json",pn),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,data:r}=n.req.valid("json"),a=n.get("dbType"),o=F(a),{insertedCount:s}=await o.addRecord({db:e,params:{tableName:t,data:r}});return n.json({data:`Record inserted into "${t}" with ${s} rows inserted`},200)}).patch("/",Qe("query",x),Qe("json",Kn),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType"),a=F(r),{updatedCount:o}=await a.updateRecords({params:t,db:e});return n.json({data:`Updated ${o} records in "${t.tableName}"`},200)}).delete("/",Qe("query",x),Qe("json",pr),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,primaryKeys:r}=n.req.valid("json"),a=n.get("dbType"),o=F(a),{deletedCount:s,fkViolation:i,relatedRecords:l}=await o.deleteRecords({tableName:t,primaryKeys:r,db:e});return i?n.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:l}},409):n.json({data:{deletedCount:s,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",Qe("query",x),Qe("json",pr),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,primaryKeys:r}=n.req.valid("json"),a=n.get("dbType"),s=await F(a).forceDeleteRecords({tableName:t,primaryKeys:r,db:e});return n.json({data:s},200)}).post("/bulk",Qe("query",x),Qe("json",gn),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,records:r}=n.req.valid("json"),a=n.get("dbType"),s=await F(a).bulkInsertRecords({tableName:t,records:r,db:e});return n.json({data:s},200)})});import{utils as Zt,write as Fm}from"xlsx";function Yi({cols:n,rows:e,format:t,tableName:r}){switch(t){case"json":{let a=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(a,"utf-8"))}case"csv":{let a=Zt.aoa_to_sheet(Vi(n,e)),o=Zt.sheet_to_csv(a);return new Uint8Array(Buffer.from(o,"utf-8"))}case"xlsx":{let a=Zt.aoa_to_sheet(Vi(n,e)),o=Zt.book_new();Zt.book_append_sheet(o,a,r.slice(0,31));let s=Fm(o,{bookType:"xlsx",type:"buffer"});return new Uint8Array(s)}}}var Km,Vi,zi=S(()=>{"use strict";h();Km=n=>n==null||n instanceof Date?n:Buffer.isBuffer(n)?`0x${n.toString("hex")}`:typeof n=="object"?JSON.stringify(n):typeof n=="bigint"?n.toString():n,Vi=(n,e)=>[n,...e?.map(t=>n?.map(r=>Km(t[r])))??[]]});import{zValidator as z}from"@hono/zod-validator";import{Hono as jm}from"hono";var Gi,Qi=S(()=>{"use strict";h();ae();et();zi();Gi=new jm().basePath("/tables").get("/",z("query",x),async n=>{let{db:e}=n.req.valid("query"),t=n.get("dbType"),a=await F(t).getTablesList(e);return n.json({data:a},200)}).post("/",z("query",x),z("json",On),async n=>{let{db:e}=n.req.valid("query"),t=n.req.valid("json"),r=n.get("dbType");return await F(r).createTable({tableData:t,db:e}),n.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",z("query",$n),z("param",Te),async n=>{let{db:e,cascade:t}=n.req.valid("query"),{tableName:r}=n.req.valid("param"),a=n.get("dbType"),s=await F(a).deleteTable({tableName:r,db:e,cascade:t});return n.json({data:s},200)}).patch("/:tableName/rename",z("query",x),z("param",Te),z("json",Ut),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.req.valid("json"),a=n.get("dbType");return await F(a).renameTable({tableName:t,db:e,...r}),n.json({data:`Table "${t}" renamed to "${r.newTableName}"`},200)}).delete("/:tableName/columns/:columnName",z("query",bn),z("param",Ee),async n=>{let{db:e,cascade:t}=n.req.valid("query"),{tableName:r,columnName:a}=n.req.valid("param"),o=n.get("dbType"),s=F(o),{deletedCount:i}=await s.deleteColumn({tableName:r,columnName:a,cascade:t,db:e});return n.json({data:`Column "${a}" deleted successfully from table "${r}" with ${i} rows deleted`},200)}).post("/:tableName/columns",z("query",x),z("param",Te),z("json",qe),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.req.valid("json"),a=n.get("dbType");return await F(a).addColumn({tableName:t,db:e,...r}),n.json({data:`Column "${r.columnName}" added successfully to table "${t}"`},200)}).patch("/:tableName/columns/:columnName/rename",z("query",x),z("param",Ee),z("json",yr),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,columnName:r}=n.req.valid("param"),a=n.req.valid("json"),o=n.get("dbType");return await F(o).renameColumn({tableName:t,columnName:r,db:e,...a}),n.json({data:`Column "${r}" renamed to "${a.newColumnName}" in table "${t}"`},200)}).patch("/:tableName/columns/:columnName",z("query",x),z("param",Ee),z("json",bt),async n=>{let{db:e}=n.req.valid("query"),{tableName:t,columnName:r}=n.req.valid("param"),a=n.req.valid("json"),o=n.get("dbType");return await F(o).alterColumn({tableName:t,columnName:r,db:e,...a}),n.json({data:`Column "${r}" updated successfully in table "${t}"`},200)}).get("/:tableName/columns",z("query",x),z("param",Te),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.get("dbType"),o=await F(r).getTableColumns({tableName:t,db:e});return n.json({data:o},200)}).get("/:tableName/schema",z("query",x),z("param",Te),async n=>{let{db:e}=n.req.valid("query"),{tableName:t}=n.req.valid("param"),r=n.get("dbType"),o=await F(r).getTableSchema({tableName:t,db:e});return n.json({data:{schema:o}},200)}).get("/:tableName/data",z("param",Te),z("query",Fn),async n=>{let{tableName:e}=n.req.valid("param"),{cursor:t,limit:r,direction:a,sort:o,order:s,filters:i,db:l}=n.req.valid("query"),c=n.get("dbType"),m=await F(c).getTableData({tableName:e,cursor:t,limit:r,direction:a,sort:o,order:s,filters:i,db:l});return n.json({data:m},200)}).get("/:tableName/export",z("param",Te),z("query",In),async n=>{let{tableName:e}=n.req.valid("param"),{db:t,format:r}=n.req.valid("query"),a=n.get("dbType"),o=F(a),{cols:s,rows:i}=await o.exportTableData({tableName:e,db:t}),l=Yi({cols:s,rows:i,format:r,tableName:e}),c;switch(r){case"csv":c="text/csv";break;case"xlsx":c="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";break;case"json":c="application/json";break}return new Response(l,{headers:{"Content-Type":c??"","Content-Disposition":`attachment; filename="${e}_export.${r}"`}})})});import{Hono as Hm}from"hono";import{z as Ji}from"zod";var Wm,Xi,Zi=S(()=>{"use strict";h();Kt();Wm=Ji.object({enabled:Ji.boolean()}).strict(),Xi=new Hm().basePath("/telemetry").get("/config",async n=>((n.req.header("x-db-studio-gpc")==="1"||n.req.header("sec-gpc")==="1")&&Cr(!1),Gn(),n.json({data:wr()},200))).put("/preference",async n=>{let e=Wm.safeParse(await n.req.json().catch(()=>{}));return e.success?(Cr(e.data.enabled),n.json({data:wr()},200)):n.json({error:"Invalid telemetry preference"},400)}).post("/reset",async n=>n.json({data:{installationId:Vn()}},200))});var nl={};nr(nl,{createServer:()=>Zm});import{existsSync as el}from"fs";import st from"path";import{fileURLToPath as Vm}from"url";import{serveStatic as er}from"@hono/node-server/serve-static";import{zValidator as Ym}from"@hono/zod-validator";import{Hono as zm}from"hono";import{cors as Gm}from"hono/cors";import{HTTPException as Qm}from"hono/http-exception";import{logger as Jm}from"hono/logger";import{prettyJSON as Xm}from"hono/pretty-json";import{z as tl}from"zod";var Fe,tr,rl,Zm,al=S(()=>{"use strict";h();kt();et();Ci();Di();Kt();Ze();xi();qi();Bi();ji();Wi();Qi();Zi();({API_PREFIX:Fe}=Xe),tr=()=>{if(process.env.NODE_ENV==="development")return st.resolve(process.cwd(),"../web/dist");let n=st.dirname(Vm(import.meta.url)),e=st.resolve(n,"./web-dist"),t=st.resolve(process.cwd(),"../web/dist"),r=st.resolve(e,"index.html"),a=st.resolve(t,"index.html");return!el(r)&&el(a)?t:e},rl=tl.object({dbType:tl.string().refine(n=>ge.getSupportedTypes().includes(n),{message:`Invalid database type. Supported types: ${ge.getSupportedTypes().join(", ")}`})}),Zm=()=>{wi();let n=new zm({strict:!1}).use("/*",(e,t)=>{let r=Fo(e.req.header("x-request-id"));return Ko({requestId:r,operation:Dt(e.req.method,e.req.path),dbType:Ft(e.req.path)},async()=>{await t(),e.header("X-Request-Id",r)})}).use("/*",Gm({origin:e=>{if(!e)return;if((process.env.ALLOWED_ORIGINS?.split(",").map(r=>r.trim()).filter(Boolean)??[]).includes(e))return e;if(process.env.NODE_ENV==="development")try{let r=new URL(e);if(r.hostname==="localhost"||r.hostname.endsWith(".localhost")||r.hostname==="127.0.0.1")return e}catch{}},allowMethods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],allowHeaders:["Content-Type","X-Run-Id","X-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(Xm({space:2})).use(process.env.NODE_ENV==="development"?Jm():(e,t)=>t()).use(`${Fe}/*`,async(e,t)=>{if(e.req.path.startsWith(`${Fe}/telemetry`))return t();let r=performance.now(),a=Dt(e.req.method,e.req.path),o=e.req.path.split("/")[2],s=ge.getSupportedTypes().find(i=>i===o);await Jn(a,s,t),Rr({event:"server_operation",properties:{operation:a,method:e.req.method,outcome:zn(e.res.status),duration_bucket:Yn(performance.now()-r),db_type:s}})}).use("/favicon.ico",er({path:st.resolve(tr(),"favicon.ico")})).onError(Ni).route(Fe,vi).route(Fe,ki).route(Fe,Xi).use("/assets/*",er({root:tr()})).use("/image.png",er({root:tr()})).use(`${Fe}/:dbType/*`,Ym("param",rl,(e,t)=>{if(!e.success){let r=t.req.param("dbType");throw new Qm(400,{message:`Invalid database type: "${r}". Supported types: ${ge.getSupportedTypes().join(", ")}`})}}),async(e,t)=>{let{dbType:r}=rl.parse({dbType:e.req.param("dbType")});e.set("dbType",r),await t()}).route(`${Fe}/:dbType`,Gi).route(`${Fe}/:dbType`,Hi).route(`${Fe}/:dbType`,Ki).route(`${Fe}/:dbType`,Ui);return process.env.NODE_ENV!=="test"&&(n.all(`${Fe}/*`,e=>e.json({error:"Not found"},404)),n.use("/*",er({root:tr()})),n.get("/*",er({path:st.resolve(tr(),"index.html")}))),{app:n}}});h();h();(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new n.Error().stack;e&&(n._sentryDebugIds=n._sentryDebugIds||{},n._sentryDebugIds[e]="15319065-444a-462f-b1f3-fe5e5971de4c",n._sentryDebugIdIdentifier="sentry-dbid-15319065-444a-462f-b1f3-fe5e5971de4c")}catch{}})();h();kt();import{intro as ed,log as sn,outro as ol,spinner as td}from"@clack/prompts";import{serve as rd}from"@hono/node-server";import rr from"picocolors";h();import{program as cn}from"commander";var Va=()=>{cn.name("db-studio").option("-e, --env <path>","Path to custom .env file").option("-p, --port <port>","Port to run the server on").option("-d, --database-url <url>","Database URL to use").option("-n, --var-name <name>","Custom environment variable name (default: DATABASE_URL)").option("--open","Open db-studio in the default browser").option("--no-open","Do not open db-studio in the default browser").option("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv);let n=cn.opts(),e=process.argv.includes("--open"),t=process.argv.includes("--no-open");return e&&t&&cn.error("Do not combine --open and --no-open"),{...n,open:e?!0:t?!1:void 0}};h();import{readFile as il}from"fs/promises";import{resolve as ll}from"path";import{cancel as ar,isCancel as un,note as Ya,select as cl,spinner as ul,text as za}from"@clack/prompts";import{parse as ml}from"dotenv";import mn from"picocolors";var Ga=async(n,e)=>{let t=e||"DATABASE_URL";if(n?.[t])return n[t];if(process.env[t])return process.env[t];let r=ul();r.start("Looking for database connection..."),n?Ya(mn.red(`${t} not found in .env or process.env`)):Ya(mn.red(`No .env file found and ${t} not set in process.env`));let a=await cl({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((un(a)||a==="cancel")&&(ar("No database connection provided. Exiting..."),process.exit(0)),a==="other-env"){r.start("Waiting for path...");let s=await za({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(l){if(!l?.trim())return"Path is required"}});un(s)&&(ar("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let i=ll(s);try{let l=await il(i,"utf-8"),c=ml(l);if(c[t])return c[t];throw new Error(`${t} still missing in custom file`)}catch(l){let c=l;ar(`Cannot read or parse file: ${mn.dim(c.message)}`),process.exit(1)}}r.stop("Manual input...");let o=await za({message:`Paste your ${t}`,placeholder:"postgresql://user:password@localhost:5432/mydb or sqlite:///path/to/db.sqlite",validate(s){if(!s?.trim())return"Connection string is required!";if(!s.trim().startsWith("sqlite://"))try{new URL(s);return}catch{return"Must be a valid URL format"}}});return un(o)&&(ar("Cancelled."),process.exit(0)),o.trim()};h();import{access as dl,readFile as pl}from"fs/promises";import{dirname as fl,resolve as dn}from"path";import{parse as yl}from"dotenv";var hl=async n=>{let e=dn(n);for(;;){let t=dn(e,".env");try{return await dl(t),t}catch{}let r=fl(e);if(r===e)return null;e=r}},ft=async n=>{let e;if(n?e=dn(n):e=await hl(process.cwd()),!e)return null;try{let t=await pl(e,"utf-8");return yl(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};h();import bl from"open";var Qa=n=>n===!0,Ja=async n=>{await bl(n)};h();ae();var Rc=Object.values(ee).flatMap(({protocols:n})=>n).map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|"),Sc=new RegExp(`\\b(?:${Rc}):\\/\\/\\S+`,"gi"),Ac=/\b(authToken=)[^&\s]+/gi,vo=n=>n.replace(Sc,e=>`the configured database${e.match(/[),.]+$/)?.[0]??""}`).replace(Ac,"$1[redacted]");h();ln();ae();import{intro as Nc,outro as Dc}from"@clack/prompts";import Rt from"picocolors";var qo=()=>{Nc(Rt.inverse(" db-studio ")),console.log(Rt.bold(`
506
506
  Usage:`)),console.log(` db-studio [options]
507
- `),console.log(Tt.bold("Supported Databases:")),console.log(` ${Object.values(Z).map(({label:n})=>n).join(", ")}
508
- `),console.log(Tt.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
509
- `),console.log(Tt.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
510
- `),gc(Tt.green(`For more information, visit: ${Ba.SITE_DOCS_LINK}`))};h();$t();ne();import{intro as Ec,note as wc,outro as xo}from"@clack/prompts";import qe from"picocolors";Fe();var vo=async(n,e,t)=>{Ec(qe.inverse(" db-studio "));let r=t||Qe.VAR_NAME,a=null;if(e)a=e;else{let o=n?await ut(n):await ut();o?.[r]?a=o[r]:process.env[r]&&(a=process.env[r]??null)}a?xo(qe.green(`\u2713 Database connection configured (using ${r})`)):(wc(qe.red(`\u2717 ${r} not found`),"Status"),console.log(qe.yellow(`
511
- To configure database connection:`)),console.log(qe.dim(` \u2022 Supported databases: ${Object.values(Z).map(({label:o})=>o).join(", ")}`)),console.log(qe.dim(` \u2022 Also via wire-compatible URLs: ${Object.keys(pr).map(o=>`${o}://`).join(", ")}`)),console.log(qe.dim(` \u2022 Add ${r} 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>
512
- `)),xo(qe.yellow("\u26A0 No database connection configured")))};h();qn();import{intro as Rc,outro as Sc}from"@clack/prompts";import qo from"picocolors";var Uo=()=>{Rc(qo.inverse(" db-studio ")),Sc(qo.green(`\u{1F680} db-studio v${ot.version}`))};var Wm=async()=>{let{env:n,port:e,databaseUrl:t,varName:r,open:a,status:o,help:s,version:i}=Ka();s&&(Mo(),process.exit(0)),i&&(Uo(),process.exit(0)),o&&(await vo(n,t,r),process.exit(0)),Km(Jt.inverse(" db-studio "));let l=n?await ut(n):await ut();if(l)for(let[P,U]of Object.entries(l))process.env[P]===void 0&&(process.env[P]=U);let c=Number.parseInt(e??process.env.PORT??String(Qe.PORT),10),u=process.env.HOST,m=r||Qe.VAR_NAME,p=!!l?.[m],d=!!process.env[m],f=t||await Wa(l,m),y=t?"Using database URL from --database-url":p?`Found ${m} in ${n??".env"}`:d?`Found ${m} in environment`:"Using database URL provided interactively";tn.success(y),process.env.DATABASE_URL=f;let{initServerObservability:g}=await Promise.resolve().then(()=>(vt(),Vo));g();let{checkDatabaseConnection:w,getDatabaseConnectionDetails:C}=await Promise.resolve().then(()=>(Xo(),Jo)),{type:N,name:A,destination:E}=C(f),R=jm();R.start(`Connecting to ${A}...`);try{await w(N),R.stop(`Connected to ${A} at ${E}`)}catch(P){throw R.stop(`Could not connect to ${A} at ${E}`),P}let{createServer:D}=await Promise.resolve().then(()=>(Gi(),zi)),{app:$}=D();Hm({fetch:$.fetch,hostname:u,port:c});let q=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${c}`;if(tn.success(`Server listening at ${Jt.cyan(q)}`),Va(a))try{await Ya(q),tn.success("Opened db-studio in your browser")}catch{tn.warn(`Could not open your browser. Visit ${Jt.cyan(q)}`)}Qi(Jt.green("Ready"))};process.env.NODE_ENV!=="test"&&Wm().catch(n=>{let e=n instanceof Error?n.message:String(n);Qi(Jt.red(`Startup failed: ${Io(e)}`)),process.exit(1)});var zT=void 0;export{zT as default,Wm as main};
507
+ `),console.log(Rt.bold("Supported Databases:")),console.log(` ${Object.values(ee).map(({label:n})=>n).join(", ")}
508
+ `),console.log(Rt.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
509
+ `),console.log(Rt.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
510
+ `),Dc(Rt.green(`For more information, visit: ${Ha.SITE_DOCS_LINK}`))};h();kt();ae();import{intro as kc,note as xc,outro as Wo}from"@clack/prompts";import Be from"picocolors";je();var Vo=async(n,e,t)=>{kc(Be.inverse(" db-studio "));let r=t||Xe.VAR_NAME,a=null;if(e)a=e;else{let o=n?await ft(n):await ft();o?.[r]?a=o[r]:process.env[r]&&(a=process.env[r]??null)}a?Wo(Be.green(`\u2713 Database connection configured (using ${r})`)):(xc(Be.red(`\u2717 ${r} not found`),"Status"),console.log(Be.yellow(`
511
+ To configure database connection:`)),console.log(Be.dim(` \u2022 Supported databases: ${Object.values(ee).map(({label:o})=>o).join(", ")}`)),console.log(Be.dim(` \u2022 Also via wire-compatible URLs: ${Object.keys(gr).map(o=>`${o}://`).join(", ")}`)),console.log(Be.dim(` \u2022 Add ${r} to your .env file or set it in process.env`)),console.log(Be.dim(" \u2022 Use -d flag: db-studio -d <url>")),console.log(Be.dim(" \u2022 Use -e flag: db-studio -e <path-to-env>")),console.log(Be.dim(` \u2022 Use -n flag: db-studio -n <var-name>
512
+ `)),Wo(Be.yellow("\u26A0 No database connection configured")))};h();Wn();import{intro as qc,outro as Uc}from"@clack/prompts";import Yo from"picocolors";var zo=()=>{qc(Yo.inverse(" db-studio ")),Uc(Yo.green(`\u{1F680} db-studio v${ct.version}`))};var nd=async()=>{let{env:n,port:e,databaseUrl:t,varName:r,open:a,status:o,help:s,version:i}=Va();s&&(qo(),process.exit(0)),i&&(zo(),process.exit(0)),o&&(await Vo(n,t,r),process.exit(0)),ed(rr.inverse(" db-studio "));let l=n?await ft(n):await ft();if(l)for(let[P,U]of Object.entries(l))process.env[P]===void 0&&(process.env[P]=U);let c=Number.parseInt(e??process.env.PORT??String(Xe.PORT),10),u=process.env.HOST,m=r||Xe.VAR_NAME,p=!!l?.[m],d=!!process.env[m],f=t||await Ga(l,m),y=t?"Using database URL from --database-url":p?`Found ${m} in ${n??".env"}`:d?`Found ${m} in environment`:"Using database URL provided interactively";sn.success(y),process.env.DATABASE_URL=f;let{initServerObservability:g}=await Promise.resolve().then(()=>(Kt(),es));g();let{checkDatabaseConnection:w,getDatabaseConnectionDetails:C}=await Promise.resolve().then(()=>(ss(),os)),{type:N,name:A,destination:E}=C(f),R=td();R.start(`Connecting to ${A}...`);try{await w(N),R.stop(`Connected to ${A} at ${E}`)}catch(P){throw R.stop(`Could not connect to ${A} at ${E}`),P}let{createServer:D}=await Promise.resolve().then(()=>(al(),nl)),{app:$}=D();rd({fetch:$.fetch,hostname:u,port:c});let q=process.env.DB_STUDIO_SERVER_URL??process.env.PORTLESS_URL??`http://localhost:${c}`;if(sn.success(`Server listening at ${rr.cyan(q)}`),Qa(a))try{await Ja(q),sn.success("Opened db-studio in your browser")}catch{sn.warn(`Could not open your browser. Visit ${rr.cyan(q)}`)}ol(rr.green("Ready"))};process.env.NODE_ENV!=="test"&&nd().catch(n=>{let e=n instanceof Error?n.message:String(n);ol(rr.red(`Startup failed: ${vo(e)}`)),process.exit(1)});var gE=void 0;export{gE as default,nd as main};
513
513
  //# sourceMappingURL=index.js.map