db-studio 1.2.24 → 1.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core-dist/assets/{_baseUniq-riwirsMn.js → _baseUniq-CO5fFgqV.js} +1 -1
- package/dist/core-dist/assets/{_pathlessLayout-DmCNfa5q.js → _pathlessLayout-C3BlW5Hc.js} +2 -2
- package/dist/core-dist/assets/_queryId-iSqlGQ2Y.js +1 -0
- package/dist/core-dist/assets/_table-SO2FYYAw.js +8 -0
- package/dist/core-dist/assets/{arc-Bmwb62d7.js → arc-B_zMY48V.js} +1 -1
- package/dist/core-dist/assets/{architectureDiagram-VXUJARFQ-DAdKU_Vv.js → architectureDiagram-VXUJARFQ-C9lykiZH.js} +1 -1
- package/dist/core-dist/assets/{blockDiagram-VD42YOAC-CKWdAOVU.js → blockDiagram-VD42YOAC-DhqK2eyG.js} +1 -1
- package/dist/core-dist/assets/{c4Diagram-YG6GDRKO-B_sL4HQA.js → c4Diagram-YG6GDRKO-CQrcwS8f.js} +1 -1
- package/dist/core-dist/assets/{cdoe-editor-DAlfFmLj.js → cdoe-editor-C6mx2_AO.js} +1 -1
- package/dist/core-dist/assets/channel-4io835lz.js +1 -0
- package/dist/core-dist/assets/{chunk-4BX2VUAB-Cce3fVJH.js → chunk-4BX2VUAB-CdIpYPgB.js} +1 -1
- package/dist/core-dist/assets/{chunk-55IACEB6-QBcon4M7.js → chunk-55IACEB6-BDNKe4fa.js} +1 -1
- package/dist/core-dist/assets/{chunk-B4BG7PRW-BSf5pb79.js → chunk-B4BG7PRW-ZA-ck0YQ.js} +1 -1
- package/dist/core-dist/assets/{chunk-DI55MBZ5-DftEFpN1.js → chunk-DI55MBZ5-CnVVpZE-.js} +1 -1
- package/dist/core-dist/assets/{chunk-FMBD7UC4-4VeSB__T.js → chunk-FMBD7UC4-CwwWK8-e.js} +1 -1
- package/dist/core-dist/assets/{chunk-QN33PNHL-B8h-nEFL.js → chunk-QN33PNHL-bn39U0qP.js} +1 -1
- package/dist/core-dist/assets/{chunk-QZHKN3VN-DMYBfSug.js → chunk-QZHKN3VN-D0fSZNMo.js} +1 -1
- package/dist/core-dist/assets/{chunk-TZMSLE5B-Ct-1qAdT.js → chunk-TZMSLE5B-BTA4ulM4.js} +1 -1
- package/dist/core-dist/assets/classDiagram-2ON5EDUG-DpPeI05m.js +1 -0
- package/dist/core-dist/assets/classDiagram-v2-WZHVMYZB-DpPeI05m.js +1 -0
- package/dist/core-dist/assets/clone-Cu5G1cWz.js +1 -0
- package/dist/core-dist/assets/{code-block-IT6T5CEO-DA6hEb7Y.js → code-block-IT6T5CEO-BZv7MYo8.js} +1 -1
- package/dist/core-dist/assets/{cose-bilkent-S5V4N54A-CloLjUMy.js → cose-bilkent-S5V4N54A-DQ5fWUqZ.js} +1 -1
- package/dist/core-dist/assets/{dagre-6UL2VRFP-2A2fgc9Z.js → dagre-6UL2VRFP-C-VDHjJ-.js} +1 -1
- package/dist/core-dist/assets/{diagram-PSM6KHXK-DPA5DEpE.js → diagram-PSM6KHXK-CdPWaSoG.js} +1 -1
- package/dist/core-dist/assets/{diagram-QEK2KX5R-C4bOPS0Q.js → diagram-QEK2KX5R-CI3rBq3-.js} +1 -1
- package/dist/core-dist/assets/{diagram-S2PKOQOG-tq0GNkdW.js → diagram-S2PKOQOG-DrV1l_bS.js} +1 -1
- package/dist/core-dist/assets/{erDiagram-Q2GNP2WA-PM-4jbqi.js → erDiagram-Q2GNP2WA-DtHpaqwP.js} +1 -1
- package/dist/core-dist/assets/{flowDiagram-NV44I4VS-T1UN3giy.js → flowDiagram-NV44I4VS-CWhbqAOb.js} +1 -1
- package/dist/core-dist/assets/{ganttDiagram-JELNMOA3-BonXgJoj.js → ganttDiagram-JELNMOA3-8U2ncuQI.js} +1 -1
- package/dist/core-dist/assets/{gitGraphDiagram-NY62KEGX-BuVB_0wZ.js → gitGraphDiagram-NY62KEGX-rJlyYpVT.js} +1 -1
- package/dist/core-dist/assets/{graph-DYVP2SvU.js → graph-BhgtEUho.js} +1 -1
- package/dist/core-dist/assets/{index-CiWmRiWr.js → index-5l-GokF9.js} +1 -1
- package/dist/core-dist/assets/{index-DWavbP67.js → index-B-czu-uB.js} +1 -1
- package/dist/core-dist/assets/{index-jesypFsg.js → index-DM_G5wVs.js} +5 -5
- package/dist/core-dist/assets/index-Llx5wPe1.css +1 -0
- package/dist/core-dist/assets/{index-C6Oo3d0L.js → index-ejQaUr38.js} +1 -1
- package/dist/core-dist/assets/index-iREZCpeS.js +1 -0
- package/dist/core-dist/assets/{indexes-Bk_QNhz3.js → indexes-D8Eqj5x7.js} +1 -1
- package/dist/core-dist/assets/infoDiagram-WHAUD3N6-RphuT4VC.js +2 -0
- package/dist/core-dist/assets/{journeyDiagram-XKPGCS4Q-CCwLC7Dr.js → journeyDiagram-XKPGCS4Q-BNSrMmr7.js} +1 -1
- package/dist/core-dist/assets/{kanban-definition-3W4ZIXB7-DUawu5sK.js → kanban-definition-3W4ZIXB7-V9L96KTF.js} +1 -1
- package/dist/core-dist/assets/{layout-IC-bH2B0.js → layout-DNW_OiWL.js} +1 -1
- package/dist/core-dist/assets/{linear-ZJuqjgQK.js → linear-DqoQUU19.js} +1 -1
- package/dist/core-dist/assets/{logs-BCDaqHa5.js → logs-CjN_gOvl.js} +1 -1
- package/dist/core-dist/assets/{mermaid-VLURNSYL-CN8SKxCb.js → mermaid-VLURNSYL-F8q0N6Y-.js} +4 -4
- package/dist/core-dist/assets/{mermaid.core-CaljvboY.js → mermaid.core-Bl5zWzZD.js} +5 -5
- package/dist/core-dist/assets/{min-DmRs0sgj.js → min-DDiiHzkP.js} +1 -1
- package/dist/core-dist/assets/{mindmap-definition-VGOIOE7T-fkttDhdk.js → mindmap-definition-VGOIOE7T-_ZelwEtb.js} +1 -1
- package/dist/core-dist/assets/{pieDiagram-ADFJNKIX-ByGngzi8.js → pieDiagram-ADFJNKIX-DlnlOcS9.js} +1 -1
- package/dist/core-dist/assets/{quadrantDiagram-AYHSOK5B-DO_C9v_v.js → quadrantDiagram-AYHSOK5B-CyVFDRyR.js} +1 -1
- package/dist/core-dist/assets/{queries.store-DZ-MnOG6.js → queries.store-KdEzteJi.js} +1 -1
- package/dist/core-dist/assets/radix-ui-BypjIQUF.js +51 -0
- package/dist/core-dist/assets/{requirementDiagram-UZGBJVZJ-BDzpQlVK.js → requirementDiagram-UZGBJVZJ-jRbu5Vec.js} +1 -1
- package/dist/core-dist/assets/{runner-tab-CxwQsug8.js → runner-tab-DG4JMrIS.js} +3 -3
- package/dist/core-dist/assets/{sankeyDiagram-TZEHDZUN-HnCFDh0I.js → sankeyDiagram-TZEHDZUN-gKjFH72S.js} +1 -1
- package/dist/core-dist/assets/{schema-D_xYQwIF.js → schema-Dig80dgQ.js} +1 -1
- package/dist/core-dist/assets/{scroll-area-DP3yG54v.js → scroll-area-BZeWiQjX.js} +1 -1
- package/dist/core-dist/assets/{sequenceDiagram-WL72ISMW-ZzL5mp2w.js → sequenceDiagram-WL72ISMW-CAvLlHWG.js} +1 -1
- package/dist/core-dist/assets/{stateDiagram-FKZM4ZOC-DVgE6W5u.js → stateDiagram-FKZM4ZOC-pYmj6Lkv.js} +1 -1
- package/dist/core-dist/assets/stateDiagram-v2-4FDKWEC3-BxqBo7RT.js +1 -0
- package/dist/core-dist/assets/{tanstack-D5ysZnPZ.js → tanstack-I4NcPTsd.js} +1 -1
- package/dist/core-dist/assets/{timeline-definition-IT6M3QCI-C2z733gB.js → timeline-definition-IT6M3QCI-D9DODJhX.js} +1 -1
- package/dist/core-dist/assets/{treemap-KMMF4GRG-D-vNn6yN.js → treemap-KMMF4GRG-ClhjKA5M.js} +1 -1
- package/dist/core-dist/assets/{visualizer-BBc6FRkR.js → visualizer-CVdpIuSS.js} +1 -1
- package/dist/core-dist/assets/{xychartDiagram-PRI3JC2R-BGDvUT2K.js → xychartDiagram-PRI3JC2R-OT9Z40XT.js} +1 -1
- package/dist/core-dist/index.html +4 -4
- package/dist/index.js +35 -31
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/core-dist/assets/_queryId-DuU-RQq2.js +0 -1
- package/dist/core-dist/assets/_table-DKcTbCMo.js +0 -1
- package/dist/core-dist/assets/channel-pRz1hcM0.js +0 -1
- package/dist/core-dist/assets/classDiagram-2ON5EDUG-Dw839vW9.js +0 -1
- package/dist/core-dist/assets/classDiagram-v2-WZHVMYZB-Dw839vW9.js +0 -1
- package/dist/core-dist/assets/clone-DIzOT_B6.js +0 -1
- package/dist/core-dist/assets/index-BKhtUOFL.js +0 -1
- package/dist/core-dist/assets/index-DEXHOoGJ.css +0 -1
- package/dist/core-dist/assets/infoDiagram-WHAUD3N6-CbjR8HY4.js +0 -2
- package/dist/core-dist/assets/radix-ui-d5EbBw33.js +0 -51
- package/dist/core-dist/assets/stateDiagram-v2-4FDKWEC3-DffmOHiZ.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var vo=Object.defineProperty;var l=(t,e)=>()=>(t&&(e=t(t=0)),e);var No=(t,e)=>{for(var o in e)vo(t,o,{get:e[o],enumerable:!0})};var Ae=l(()=>{"use strict"});var j,$e=l(()=>{"use strict";j={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"http://localhost:3333",PROXY_URL:process.env.NODE_ENV==="development"?"http://localhost:8787":"https://db-studio-proxy.husamql3.workers.dev"}});var Pe=l(()=>{"use strict"});var qe,ye=l(()=>{"use strict";qe={AUTHOR:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",AUTHOR_NAME:"H\xFCsam",AUTHOR_AVATAR:"/avocado.png",AUTHOR_USERNAME:"husamql3",AUTHOR_GITHUB_LINK:"https://github.com/husamql3",SITE_DESCRIPTION:"The modern pgAdmin alternative that works with every database.",SITE_KEYWORDS:["database","management","studio","spreadsheet","ai","sql"],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_DOCS_LINK:"https://dbstudio.sh/docs",SITE_CHANGELOG_LINK:"https://dbstudio.sh/changelog",SITE_ROADMAP_LINK:"https://dbstudio.sh/roadmap",SITE_IMAGE:"/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 Le=l(()=>{"use strict"});var X=l(()=>{"use strict";Ae();$e();Pe();ye();Le()});import{z as G}from"zod";var Be,Qe=l(()=>{"use strict";Be=G.object({tableName:G.string("Table name is required"),data:G.record(G.string("Column name is required"),G.any())})});var Ye=l(()=>{"use strict"});import{z as W}from"zod";var g,Vo,te,Aa,Ge,oe,U=l(()=>{"use strict";g=W.object({db:W.string("Database name is required")}),Vo=["pg"],te=W.enum(Vo,{message:"Invalid database type"}),Aa=g.extend({dbType:te}),Ge=W.object({dbType:te}),oe=W.object({tableName:W.string("Table name is required")})});import{z as K}from"zod";var Je,Xe=l(()=>{"use strict";U();Je=K.object({messages:K.array(K.object({role:K.enum(["user","assistant"]),content:K.string("Content is required")})),conversationId:K.string().optional(),db:g.shape.db})});var Ze=l(()=>{"use strict"});import{z as x}from"zod";var Bo,Qo,q,Yo,Go,Oa,Te=l(()=>{"use strict";Bo=["text","boolean","number","enum","json","date","array"],Qo=x.enum(Bo),q={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},Yo=["int","bigint","smallint","numeric","float","double","money","boolean","text","varchar","char","json","jsonb","xml","uuid","date","time","timestamp","timestamptz","interval","bytea","inet","cidr","macaddr","macaddr8","point","line","polygon","array","enum"],Go=x.enum(Yo),Oa=x.object({columnName:x.string(),dataType:Qo,dataTypeLabel:Go,isNullable:x.boolean(),columnDefault:x.string().nullable(),isPrimaryKey:x.boolean(),isForeignKey:x.boolean(),referencedTable:x.string().nullable(),referencedColumn:x.string().nullable(),enumValues:x.array(x.string()).nullable()})});function et(t){let e=t?.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(")?q.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"?q.number:e==="boolean"||e==="bool"?q.boolean:e==="json"||e==="jsonb"?q.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?q.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"?q.text:q.text}function tt(t){if(!t)return d.text;let e=t.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?d.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?d.bigint:e==="smallint"||e==="int2"?d.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?d.numeric:e==="real"||e==="float4"?d.float:e==="double precision"||e==="float8"||e==="float"?d.double:e==="money"?d.money:e==="boolean"||e==="bool"?d.boolean:e==="text"?d.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?d.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?d.char:e==="json"?d.json:e==="jsonb"?d.jsonb:e==="xml"?d.xml:e==="uuid"?d.uuid:e==="date"?d.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?d.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?d.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?d.timestamptz:e==="interval"||e.startsWith("interval")?d.interval:e==="bytea"?d.bytea:e==="inet"?d.inet:e==="cidr"?d.cidr:e==="macaddr"?d.macaddr:e==="macaddr8"?d.macaddr8:e==="point"?d.point:e==="line"?d.line:e==="polygon"?d.polygon:e.startsWith("array")||e.includes("[]")?d.text:e.startsWith("user-defined")||e==="enum"?d.enum:d.text}var d,ot=l(()=>{"use strict";Te();d={int:"int",bigint:"bigint",smallint:"smallint",numeric:"numeric",float:"float",double:"double",money:"money",boolean:"boolean",text:"text",varchar:"varchar",char:"char",json:"json",jsonb:"jsonb",xml:"xml",uuid:"uuid",date:"date",time:"time",timestamp:"timestamp",timestamptz:"timestamptz",interval:"interval",bytea:"bytea",inet:"inet",cidr:"cidr",macaddr:"macaddr",macaddr8:"macaddr8",point:"point",line:"line",polygon:"polygon",array:"array",enum:"enum"}});import{z as S}from"zod";var Jo,rt,Xo,Zo,at,nt=l(()=>{"use strict";Jo=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],rt=S.enum(Jo),Xo=S.object({columnName:S.string("Column name is required"),columnType:S.string("Column type is required"),defaultValue:S.string().optional(),isPrimaryKey:S.boolean().default(!1),isNullable:S.boolean().default(!1),isUnique:S.boolean().default(!1),isIdentity:S.boolean().default(!1),isArray:S.boolean().default(!1)}),Zo=S.object({columnName:S.string("Column name is required"),referencedTable:S.string("Referenced table is required"),referencedColumn:S.string("Referenced column is required"),onUpdate:rt.default("NO ACTION"),onDelete:rt.default("NO ACTION")}),at=S.object({tableName:S.string("Table name is required"),fields:S.array(Xo).min(1,"At least one field is required"),foreignKeys:S.array(Zo).optional()})});import{z as D}from"zod";var er,Wa,st,it=l(()=>{"use strict";U();er=D.object({name:D.string("Name is required"),size:D.string("Size is required"),owner:D.string("Owner is required"),encoding:D.string("Encoding is required")}),Wa=D.object({databases:D.array(er),dbType:te}),st=D.object({version:D.string("Version is required"),database:D.string("Database is required"),user:D.string("User is required"),host:D.string("Host is required").nullable(),port:D.number("Port is required").nullable(),active_connections:D.coerce.number("Active connections is required"),max_connections:D.coerce.number("Max connections is required")})});var ct=l(()=>{"use strict"});import{z as v}from"zod";var lt,re,Qa,Ya,mt=l(()=>{"use strict";U();lt=g.extend({cascade:v.string().optional().transform(t=>t==="true")}),re=v.object({tableName:v.string("Table name is required"),columnName:v.string("Column name is required")}),Qa=v.object({db:g.shape.db,tableName:re.shape.tableName,columnName:re.shape.columnName,cascade:v.boolean().optional()}),Ya=v.object({message:v.string("Message is required"),tableName:v.string("Table name is required"),columnName:v.string("Column name is required"),deletedCount:v.number("Deleted count is required").default(0)})});import{z as V}from"zod";var Se,ut=l(()=>{"use strict";Se=V.object({tableName:V.string("Table name is required"),primaryKeys:V.array(V.object({columnName:V.string("Column name is required"),value:V.any()})).min(1,"At least one primary key is required")})});import{z as pt}from"zod";var dt,ft=l(()=>{"use strict";dt=pt.object({query:pt.string("Query is required")})});import{z as tr}from"zod";var or,yt,bt=l(()=>{"use strict";U();or=["csv","xlsx"],yt=g.extend({format:tr.enum(or,{message:"Invalid format. Supported formats: csv, xlsx"})})});var ht=l(()=>{"use strict"});import{z as b}from"zod";var sn,ae,cn,rr,ln,gt,Tt=l(()=>{"use strict";U();sn=b.object({columnName:b.string(),operator:b.string(),value:b.string()}),ae=["asc","desc"],cn=b.object({columnName:b.string(),direction:b.enum(ae)}),rr=b.object({limit:b.number(),total:b.number(),hasNextPage:b.boolean(),hasPreviousPage:b.boolean(),nextCursor:b.string().nullable(),prevCursor:b.string().nullable()}),ln=b.object({data:b.array(b.record(b.string(),b.unknown())),meta:rr}),gt=b.object({db:g.shape.db,cursor:b.string().optional(),limit:b.string().optional().default("50").transform(Number),direction:b.enum(ae).optional().default(ae[0]),sort:b.string().optional().transform(t=>{if(!t)return"";try{let e=JSON.parse(t);return Array.isArray(e)?e:t}catch{return t}}),order:b.enum(ae).optional(),filters:b.string().optional().transform(t=>{if(!t)return[];try{return JSON.parse(t)}catch{return[]}})})});import{z as Ee}from"zod";var pn,St=l(()=>{"use strict";pn=Ee.object({tableName:Ee.string("Table name is required"),rowCount:Ee.coerce.number("Row count is required")})});import{z as A}from"zod";var Et,Dt=l(()=>{"use strict";Et=A.object({tableName:A.string("Table name is required"),primaryKey:A.string("Primary key is required").default("id"),updates:A.array(A.object({rowData:A.record(A.string("Column name is required"),A.any()),columnName:A.string("Column name is required"),value:A.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var L=l(()=>{"use strict";Qe();Ye();Xe();Ze();ot();Te();nt();U();it();ct();mt();ut();ft();bt();ht();Tt();St();Dt()});import{HTTPException as ar}from"hono/http-exception";import{DatabaseError as nr}from"pg";import{ZodError as sr}from"zod";function wt(t,e){if(t instanceof ar)return t.getResponse();if(t instanceof sr){let o=t.issues[0];return e.json({error:"Validation error",details:o.message},400)}return t instanceof Error&&(t.message.includes("ECONNREFUSED")||t.message.includes("connection refused")||t.message.includes("timeout expired")||t.message.includes("Connection terminated")||t instanceof nr&&t.code?.startsWith("08"))?e.json({error:"Database connection failed",details:t.message},503):e.json({error:t instanceof Error?t.message:"Internal server error"},500)}var Ct,Rt=l(()=>{"use strict";Ct=(t,e)=>{if(!t.success){let o=t.error?.issues[0];return e.json({error:"Validation error",details:o?.message??"Unknown validation error"},400)}}});import{Pool as ir}from"pg";var ne,cr,De,xt=l(()=>{"use strict";ne=null,cr=()=>{if(!ne){if(!process.env.DATABASE_URL)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");try{ne=new ir({connectionString:process.env.DATABASE_URL}),ne.on("error",t=>{})}catch(t){throw t}}return ne},De=new Proxy({},{get(t,e){try{return cr()[e]}catch(o){throw o}}})});import{Pool as vt}from"pg";var we,Nt,y,Ce,C=l(()=>{"use strict";we=class{pools=new Map;baseConfig=null;constructor(){this.initializeBaseConfig()}detectDbType(e){let o=e.protocol.replace(":","");return"pg"}initializeBaseConfig(){let e=process.env.DATABASE_URL;if(!e)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");try{let o=new URL(e);this.baseConfig={url:e,host:o.hostname,port:Number.parseInt(o.port,10)||5432,user:o.username,password:o.password,dbType:this.detectDbType(o)}}catch(o){throw new Error(`Failed to parse DATABASE_URL: ${o}`)}}getDbType(){if(!this.baseConfig)throw new Error("Base configuration not initialized");return this.baseConfig.dbType}buildConnectionString(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(!e){let o=this.baseConfig.url;o&&(e=new URL(o).pathname.slice(1))}try{let o=new URL(this.baseConfig.url);return o.pathname=`/${e}`,o.toString()}catch(o){throw new Error(`Failed to build connection string for database "${e}": ${o instanceof Error?o.message:String(o)}`)}}getPool(e){let o=this.buildConnectionString(e);if(!this.pools.has(o)){let r={connectionString:o,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:2e3},a=new vt(r);a.on("error",n=>{}),this.pools.set(o,a)}return this.pools.get(o)??new vt({connectionString:o})}async closePool(e){let o=this.pools.get(e);o&&(await o.end(),this.pools.delete(e))}async closePoolByDatabase(e){let o=this.buildConnectionString(e);await this.closePool(o)}async closeAll(){let e=Array.from(this.pools.entries()).map(async([o,r])=>{await r.end()});await Promise.all(e),this.pools.clear()}getActivePools(){return Array.from(this.pools.keys())}},Nt=new we,y=t=>Nt.getPool(t),Ce=()=>Nt.getDbType()});import{HTTPException as lr}from"hono/http-exception";async function se({tableName:t,db:e}){let o=y(e),r=`
|
|
2
|
+
var qo=Object.defineProperty;var m=(t,e)=>()=>(t&&(e=t(t=0)),e);var Io=(t,e)=>{for(var o in e)qo(t,o,{get:e[o],enumerable:!0})};var Pe=m(()=>{"use strict"});var k,qe=m(()=>{"use strict";k={PORT:3333,ENV:".env",VAR_NAME:"DATABASE_URL",BASE_URL:"http://localhost:3333",PROXY_URL:process.env.NODE_ENV==="development"?"http://localhost:8787":"https://db-studio-proxy.husamql3.workers.dev"}});var Ie=m(()=>{"use strict"});var Le,he=m(()=>{"use strict";Le={AUTHOR:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",AUTHOR_NAME:"H\xFCsam",AUTHOR_AVATAR:"/avocado.png",AUTHOR_USERNAME:"husamql3",AUTHOR_GITHUB_LINK:"https://github.com/husamql3",SITE_DESCRIPTION:"The modern pgAdmin alternative that works with every database.",SITE_KEYWORDS:["database","management","studio","spreadsheet","ai","sql"],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_DOCS_LINK:"https://dbstudio.sh/docs",SITE_CHANGELOG_LINK:"https://dbstudio.sh/changelog",SITE_ROADMAP_LINK:"https://dbstudio.sh/roadmap",SITE_IMAGE:"/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 Oe=m(()=>{"use strict"});var ee=m(()=>{"use strict";Pe();qe();Ie();he();Oe()});import{z as J}from"zod";var Ye,Ge=m(()=>{"use strict";Ye=J.object({tableName:J.string("Table name is required"),data:J.record(J.string("Column name is required"),J.any())})});var Je=m(()=>{"use strict"});import{z as B}from"zod";var Xe,Ze=m(()=>{"use strict";Xe=B.object({tableName:B.string().min(1,"Table name is required"),records:B.array(B.record(B.string(),B.any())).min(1,"At least one record is required")})});import{z as W}from"zod";var T,Xo,re,ja,et,ae,j=m(()=>{"use strict";T=W.object({db:W.string("Database name is required")}),Xo=["pg"],re=W.enum(Xo,{message:"Invalid database type"}),ja=T.extend({dbType:re}),et=W.object({dbType:re}),ae=W.object({tableName:W.string("Table name is required")})});import{z as K}from"zod";var tt,ot=m(()=>{"use strict";j();tt=K.object({messages:K.array(K.object({role:K.enum(["user","assistant"]),content:K.string("Content is required")})),conversationId:K.string().optional(),db:T.shape.db})});var rt=m(()=>{"use strict"});import{z as N}from"zod";var Zo,er,I,tr,or,Ba,Ee=m(()=>{"use strict";Zo=["text","boolean","number","enum","json","date","array"],er=N.enum(Zo),I={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},tr=["int","bigint","smallint","numeric","float","double","money","boolean","text","varchar","char","json","jsonb","xml","uuid","date","time","timestamp","timestamptz","interval","bytea","inet","cidr","macaddr","macaddr8","point","line","polygon","array","enum"],or=N.enum(tr),Ba=N.object({columnName:N.string(),dataType:er,dataTypeLabel:or,isNullable:N.boolean(),columnDefault:N.string().nullable(),isPrimaryKey:N.boolean(),isForeignKey:N.boolean(),referencedTable:N.string().nullable(),referencedColumn:N.string().nullable(),enumValues:N.array(N.string()).nullable()})});function at(t){let e=t?.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(")?I.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"?I.number:e==="boolean"||e==="bool"?I.boolean:e==="json"||e==="jsonb"?I.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?I.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"?I.text:I.text}function nt(t){if(!t)return f.text;let e=t.toLowerCase().trim();return e==="integer"||e==="int"||e==="int4"||e==="serial"||e==="serial4"?f.int:e==="bigint"||e==="int8"||e==="bigserial"||e==="serial8"?f.bigint:e==="smallint"||e==="int2"?f.smallint:e==="decimal"||e.startsWith("decimal(")||e==="numeric"||e.startsWith("numeric(")?f.numeric:e==="real"||e==="float4"?f.float:e==="double precision"||e==="float8"||e==="float"?f.double:e==="money"?f.money:e==="boolean"||e==="bool"?f.boolean:e==="text"?f.text:e==="character varying"||e.startsWith("varchar")||e.startsWith("character varying(")?f.varchar:e==="character"||e.startsWith("char")||e.startsWith("character(")||e==="bpchar"?f.char:e==="json"?f.json:e==="jsonb"?f.jsonb:e==="xml"?f.xml:e==="uuid"?f.uuid:e==="date"?f.date:e==="time"||e==="time without time zone"||e.startsWith("time(")?f.time:e==="timestamp"||e==="timestamp without time zone"||e.startsWith("timestamp(")?f.timestamp:e==="timestamp with time zone"||e==="timestamptz"||e.startsWith("timestamp with time zone(")?f.timestamptz:e==="interval"||e.startsWith("interval")?f.interval:e==="bytea"?f.bytea:e==="inet"?f.inet:e==="cidr"?f.cidr:e==="macaddr"?f.macaddr:e==="macaddr8"?f.macaddr8:e==="point"?f.point:e==="line"?f.line:e==="polygon"?f.polygon:e.startsWith("array")||e.includes("[]")?f.text:e.startsWith("user-defined")||e==="enum"?f.enum:f.text}var f,st=m(()=>{"use strict";Ee();f={int:"int",bigint:"bigint",smallint:"smallint",numeric:"numeric",float:"float",double:"double",money:"money",boolean:"boolean",text:"text",varchar:"varchar",char:"char",json:"json",jsonb:"jsonb",xml:"xml",uuid:"uuid",date:"date",time:"time",timestamp:"timestamp",timestamptz:"timestamptz",interval:"interval",bytea:"bytea",inet:"inet",cidr:"cidr",macaddr:"macaddr",macaddr8:"macaddr8",point:"point",line:"line",polygon:"polygon",array:"array",enum:"enum"}});import{z as S}from"zod";var rr,it,ar,nr,ct,lt=m(()=>{"use strict";rr=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],it=S.enum(rr),ar=S.object({columnName:S.string("Column name is required"),columnType:S.string("Column type is required"),defaultValue:S.string().optional(),isPrimaryKey:S.boolean().default(!1),isNullable:S.boolean().default(!1),isUnique:S.boolean().default(!1),isIdentity:S.boolean().default(!1),isArray:S.boolean().default(!1)}),nr=S.object({columnName:S.string("Column name is required"),referencedTable:S.string("Referenced table is required"),referencedColumn:S.string("Referenced column is required"),onUpdate:it.default("NO ACTION"),onDelete:it.default("NO ACTION")}),ct=S.object({tableName:S.string("Table name is required"),fields:S.array(ar).min(1,"At least one field is required"),foreignKeys:S.array(nr).optional()})});import{z as w}from"zod";var sr,Xa,mt,ut=m(()=>{"use strict";j();sr=w.object({name:w.string("Name is required"),size:w.string("Size is required"),owner:w.string("Owner is required"),encoding:w.string("Encoding is required")}),Xa=w.object({databases:w.array(sr),dbType:re}),mt=w.object({version:w.string("Version is required"),database:w.string("Database is required"),user:w.string("User is required"),host:w.string("Host is required").nullable(),port:w.number("Port is required").nullable(),active_connections:w.coerce.number("Active connections is required"),max_connections:w.coerce.number("Max connections is required")})});var pt=m(()=>{"use strict"});import{z as v}from"zod";var dt,ne,on,rn,ft=m(()=>{"use strict";j();dt=T.extend({cascade:v.string().optional().transform(t=>t==="true")}),ne=v.object({tableName:v.string("Table name is required"),columnName:v.string("Column name is required")}),on=v.object({db:T.shape.db,tableName:ne.shape.tableName,columnName:ne.shape.columnName,cascade:v.boolean().optional()}),rn=v.object({message:v.string("Message is required"),tableName:v.string("Table name is required"),columnName:v.string("Column name is required"),deletedCount:v.number("Deleted count is required").default(0)})});import{z as V}from"zod";var we,yt=m(()=>{"use strict";we=V.object({tableName:V.string("Table name is required"),primaryKeys:V.array(V.object({columnName:V.string("Column name is required"),value:V.any()})).min(1,"At least one primary key is required")})});import{z as bt}from"zod";var ht,gt=m(()=>{"use strict";ht=bt.object({query:bt.string("Query is required")})});import{z as ir}from"zod";var cr,Tt,St=m(()=>{"use strict";j();cr=["csv","xlsx","json"],Tt=T.extend({format:ir.enum(cr,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});var Et=m(()=>{"use strict"});import{z as g}from"zod";var yn,se,bn,lr,hn,wt,Dt=m(()=>{"use strict";j();yn=g.object({columnName:g.string(),operator:g.string(),value:g.string()}),se=["asc","desc"],bn=g.object({columnName:g.string(),direction:g.enum(se)}),lr=g.object({limit:g.number(),total:g.number(),hasNextPage:g.boolean(),hasPreviousPage:g.boolean(),nextCursor:g.string().nullable(),prevCursor:g.string().nullable()}),hn=g.object({data:g.array(g.record(g.string(),g.unknown())),meta:lr}),wt=g.object({db:T.shape.db,cursor:g.string().optional(),limit:g.string().optional().default("50").transform(Number),direction:g.enum(se).optional().default(se[0]),sort:g.string().optional().transform(t=>{if(!t)return"";try{let e=JSON.parse(t);return Array.isArray(e)?e:t}catch{return t}}),order:g.enum(se).optional(),filters:g.string().optional().transform(t=>{if(!t)return[];try{return JSON.parse(t)}catch{return[]}})})});import{z as De}from"zod";var Sn,Rt=m(()=>{"use strict";Sn=De.object({tableName:De.string("Table name is required"),rowCount:De.coerce.number("Row count is required")})});import{z as A}from"zod";var Ct,xt=m(()=>{"use strict";Ct=A.object({tableName:A.string("Table name is required"),primaryKey:A.string("Primary key is required").default("id"),updates:A.array(A.object({rowData:A.record(A.string("Column name is required"),A.any()),columnName:A.string("Column name is required"),value:A.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var L=m(()=>{"use strict";Ge();Je();Ze();ot();rt();st();Ee();lt();j();ut();pt();ft();yt();gt();St();Et();Dt();Rt();xt()});import{HTTPException as mr}from"hono/http-exception";import{DatabaseError as ur}from"pg";import{ZodError as pr}from"zod";function Nt(t,e){if(t instanceof mr)return e.json({error:t.message??"Internal server error"},t.status);if(t instanceof pr){let o=t.issues[0];return e.json({error:"Validation error",details:o.message},400)}return t instanceof Error&&(t.message.includes("ECONNREFUSED")||t.message.includes("connection refused")||t.message.includes("timeout expired")||t.message.includes("Connection terminated")||t instanceof ur&&t.code?.startsWith("08"))?e.json({error:"Database connection failed",details:t.message},503):e.json({error:t instanceof Error?t.message:"Internal server error"},500)}var vt,_t=m(()=>{"use strict";vt=(t,e)=>{if(!t.success){let o=t.error?.issues[0];return e.json({error:"Validation error",details:o?.message??"Unknown validation error"},400)}}});import{Pool as dr}from"pg";var ie,fr,Re,At=m(()=>{"use strict";ie=null,fr=()=>{if(!ie){if(!process.env.DATABASE_URL)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");try{ie=new dr({connectionString:process.env.DATABASE_URL}),ie.on("error",t=>{})}catch(t){throw t}}return ie},Re=new Proxy({},{get(t,e){try{return fr()[e]}catch(o){throw o}}})});import{Pool as $t}from"pg";var Ce,Pt,y,xe,D=m(()=>{"use strict";Ce=class{pools=new Map;baseConfig=null;constructor(){this.initializeBaseConfig()}detectDbType(e){let o=e.protocol.replace(":","");return"pg"}initializeBaseConfig(){let e=process.env.DATABASE_URL;if(!e)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");try{let o=new URL(e);this.baseConfig={url:e,host:o.hostname,port:Number.parseInt(o.port,10)||5432,user:o.username,password:o.password,dbType:this.detectDbType(o)}}catch(o){throw new Error(`Failed to parse DATABASE_URL: ${o}`)}}getDbType(){if(!this.baseConfig)throw new Error("Base configuration not initialized");return this.baseConfig.dbType}buildConnectionString(e){if(!this.baseConfig)throw new Error("Base configuration not initialized");if(!e){let o=this.baseConfig.url;o&&(e=new URL(o).pathname.slice(1))}try{let o=new URL(this.baseConfig.url);return o.pathname=`/${e}`,o.toString()}catch(o){throw new Error(`Failed to build connection string for database "${e}": ${o instanceof Error?o.message:String(o)}`)}}getPool(e){let o=this.buildConnectionString(e);if(!this.pools.has(o)){let r={connectionString:o,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:2e3},a=new $t(r);a.on("error",n=>{}),this.pools.set(o,a)}return this.pools.get(o)??new $t({connectionString:o})}async closePool(e){let o=this.pools.get(e);o&&(await o.end(),this.pools.delete(e))}async closePoolByDatabase(e){let o=this.buildConnectionString(e);await this.closePool(o)}async closeAll(){let e=Array.from(this.pools.entries()).map(async([o,r])=>{await r.end()});await Promise.all(e),this.pools.clear()}getActivePools(){return Array.from(this.pools.keys())}},Pt=new Ce,y=t=>Pt.getPool(t),xe=()=>Pt.getDbType()});import{HTTPException as yr}from"hono/http-exception";async function ce({tableName:t,db:e}){let o=y(e),r=`
|
|
3
3
|
SELECT
|
|
4
4
|
c.column_name as "columnName",
|
|
5
5
|
c.data_type as "dataType",
|
|
@@ -48,18 +48,18 @@ var vo=Object.defineProperty;var l=(t,e)=>()=>(t&&(e=t(t=0)),e);var No=(t,e)=>{f
|
|
|
48
48
|
WHERE c.table_schema = 'public'
|
|
49
49
|
AND c.table_name = $1
|
|
50
50
|
ORDER BY c.ordinal_position;
|
|
51
|
-
`,{rows:a}=await o.query(r,[t]);if(!a||a.length===0)throw new
|
|
51
|
+
`,{rows:a}=await o.query(r,[t]);if(!a||a.length===0)throw new yr(404,{message:`Table "${t}" does not exist`});return a.map(n=>{let i=null;return n.enumValues&&(Array.isArray(n.enumValues)?i=n.enumValues:typeof n.enumValues=="string"&&(i=n.enumValues.replace(/[{}]/g,"").split(",").filter(Boolean))),{columnName:n.columnName,dataType:at(n.dataType),dataTypeLabel:nt(n.dataType),isNullable:n.isNullable,columnDefault:n.columnDefault,isPrimaryKey:n.isPrimaryKey,isForeignKey:n.isForeignKey,referencedTable:n.referencedTable,referencedColumn:n.referencedColumn,enumValues:i}})}var Ne=m(()=>{"use strict";L();D()});async function br(t){let e=y(t),o=`
|
|
52
52
|
SELECT table_name
|
|
53
53
|
FROM information_schema.tables
|
|
54
54
|
WHERE table_schema = 'public'
|
|
55
55
|
AND table_type = 'BASE TABLE'
|
|
56
56
|
ORDER BY table_name;
|
|
57
|
-
`,{rows:r}=await e.query(o);return r.map(a=>a.table_name)}async function
|
|
57
|
+
`,{rows:r}=await e.query(o);return r.map(a=>a.table_name)}async function hr(t){let e=await Re.connect();try{return(await e.query(`
|
|
58
58
|
SELECT obj_description(oid) as description
|
|
59
59
|
FROM pg_class
|
|
60
60
|
WHERE relname = $1
|
|
61
61
|
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');
|
|
62
|
-
`,[t])).rows[0]?.description||void 0}finally{e.release()}}async function
|
|
62
|
+
`,[t])).rows[0]?.description||void 0}finally{e.release()}}async function gr(t){let e=await Re.connect();try{return(await e.query(`SELECT * FROM "${t}" LIMIT 3`)).rows}catch{return[]}finally{e.release()}}function Tr(t){let e={name:t.columnName,type:t.dataTypeLabel,nullable:t.isNullable};return t.isPrimaryKey&&(e.isPrimaryKey=!0),t.isForeignKey&&t.referencedTable&&t.referencedColumn&&(e.foreignKey=`${t.referencedTable}.${t.referencedColumn}`),t.enumValues&&t.enumValues.length>0&&(e.enumValues=t.enumValues,e.description=`Enum values: ${t.enumValues.join(", ")}`),e}function Sr(t){let e=[];for(let o of t)for(let r of o.columns)if(r.foreignKey){let[a,n]=r.foreignKey.split(".");e.push({fromTable:o.name,fromColumn:r.name,toTable:a,toColumn:n})}return e}async function Er(t,e={}){let{includeSampleData:o=!1,includeDescriptions:r=!0}=e;try{let n=(await br(t)).map(async s=>{let[u,l,p]=await Promise.all([ce({tableName:s,db:t}),r?hr(s):Promise.resolve(void 0),o?gr(s):Promise.resolve([])]),b={name:s,columns:u.map(Tr)};return l&&(b.description=l),p.length>0&&(b.sampleData=p.map(E=>Object.fromEntries(Object.entries(E).map(([d,h])=>[d,String(h)])))),b}),i=await Promise.all(n),c=Sr(i);return{dbType:"PostgreSQL",tables:i,relationships:c}}catch(a){throw new Error(`Failed to fetch database schema: ${a instanceof Error?a.message:"Unknown error"}`)}}async function qt(t){return Er(t,{includeSampleData:!0,includeDescriptions:!0})}var It=m(()=>{"use strict";At();D();Ne()});function Lt(t){return`You are a database assistant for db-studio. Your responses must be CONCISE and FOCUSED.
|
|
63
63
|
|
|
64
64
|
**Your Role:**
|
|
65
65
|
1. Keep responses SHORT - 2-3 sentences maximum unless generating SQL
|
|
@@ -74,7 +74,7 @@ var vo=Object.defineProperty;var l=(t,e)=>()=>(t&&(e=t(t=0)),e);var No=(t,e)=>{f
|
|
|
74
74
|
6. No preamble, no apologies, get straight to the answer
|
|
75
75
|
|
|
76
76
|
**Database Context:**
|
|
77
|
-
${
|
|
77
|
+
${wr(t)}
|
|
78
78
|
|
|
79
79
|
**Guidelines:**
|
|
80
80
|
1. Always generate syntactically correct SQL for the database type (${t.dbType})
|
|
@@ -112,7 +112,7 @@ LIMIT 5;
|
|
|
112
112
|
|
|
113
113
|
This will return the 5 customers with the highest total order value. You might also want to see:
|
|
114
114
|
- Revenue trends over time for these customers
|
|
115
|
-
- Their most frequently ordered products"`}function
|
|
115
|
+
- Their most frequently ordered products"`}function wr(t){let e=`Database Type: ${t.dbType}
|
|
116
116
|
|
|
117
117
|
`;e+=`**Tables and Columns:**
|
|
118
118
|
`;for(let o of t.tables){e+=`
|
|
@@ -126,7 +126,7 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
126
126
|
`)}if(t.relationships&&t.relationships.length>0){e+=`
|
|
127
127
|
**Relationships:**
|
|
128
128
|
`;for(let o of t.relationships)e+=` - ${o.fromTable}.${o.fromColumn} -> ${o.toTable}.${o.toColumn}
|
|
129
|
-
`}return e}var
|
|
129
|
+
`}return e}var Ot=m(()=>{"use strict"});import{zValidator as Dr}from"@hono/zod-validator";import{Hono as Rr}from"hono";var kt,jt=m(()=>{"use strict";ee();L();It();Ot();kt=new Rr().basePath("/chat").post("/",Dr("json",tt),async t=>{let{messages:e,conversationId:o,db:r}=t.req.valid("json"),a=await qt(r),n=Lt(a),i={messages:e,conversationId:o,systemPrompt:n},c=await fetch(`${k.PROXY_URL}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!c.ok){let l=await c.json();return t.json({error:l.error||"Proxy request failed"},c.status)}let{readable:s,writable:u}=new TransformStream;return c.body?.pipeTo(u),new Response(s,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})})});function Ut(){let t=process.env.DATABASE_URL;if(!t)return{host:"localhost",port:5432};try{let e=new URL(t);return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||5432}}catch{return{host:"localhost",port:5432}}}var Ft=m(()=>{"use strict"});import{HTTPException as ve}from"hono/http-exception";async function Ht(){let t=y(),e=`
|
|
130
130
|
SELECT
|
|
131
131
|
d.datname as name,
|
|
132
132
|
pg_size_pretty(pg_database_size(d.datname)) as size,
|
|
@@ -135,7 +135,7 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
135
135
|
FROM pg_catalog.pg_database d
|
|
136
136
|
WHERE d.datistemplate = false
|
|
137
137
|
ORDER BY d.datname;
|
|
138
|
-
`,{rows:o}=await t.query(e);if(!o[0])throw new
|
|
138
|
+
`,{rows:o}=await t.query(e);if(!o[0])throw new ve(500,{message:"No databases returned from database"});return o}async function Mt(){let t=y(),e="SELECT current_database() as database;",{rows:o}=await t.query(e);if(!o[0])throw new ve(500,{message:"No current database returned from database"});return o[0]}async function zt(){let t=y(),e=`
|
|
139
139
|
SELECT
|
|
140
140
|
version() as version,
|
|
141
141
|
current_database() as database,
|
|
@@ -144,11 +144,15 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
144
144
|
inet_server_port() as port,
|
|
145
145
|
(SELECT count(*) FROM pg_stat_activity WHERE datname = current_database()) as active_connections,
|
|
146
146
|
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections;
|
|
147
|
-
`,{rows:o}=await t.query(e);if(!o[0])throw new
|
|
147
|
+
`,{rows:o}=await t.query(e);if(!o[0])throw new ve(500,{message:"No connection information returned from database"});let r=mt.parse(o[0]),a=Ut();return{host:r.host||a.host,port:r.port||a.port,user:r.user,database:r.database,version:r.version.toString(),active_connections:r.active_connections,max_connections:r.max_connections}}var Bt=m(()=>{"use strict";L();D();Ft()});import{Hono as Cr}from"hono";var Wt,Kt=m(()=>{"use strict";Bt();D();Wt=new Cr().basePath("/databases").get("/",async t=>{let e=await Ht(),o=xe();return t.json({data:{databases:e,dbType:o}},200)}).get("/current",async t=>{let e=await Mt(),o=xe();return t.json({data:{...e,dbType:o}},200)}).get("/connection",async t=>{let e=await zt();return t.json({data:e},200)})});import{HTTPException as xr}from"hono/http-exception";var Vt,Qt=m(()=>{"use strict";D();Vt=async({query:t,db:e})=>{let o=y(e);if(!t||!t.trim())throw new xr(400,{message:"Query is required"});let r=t.trim().replace(/;+$/,""),a=performance.now(),n=await o.query(r),i=performance.now()-a;return{columns:n.fields.map(s=>s.name),rows:n.rows,rowCount:n.rows.length,duration:i,message:n.rows.length===0?"OK":void 0}}});import{zValidator as Yt}from"@hono/zod-validator";import{Hono as Nr}from"hono";var Gt,Jt=m(()=>{"use strict";L();Qt();Gt=new Nr().basePath("/query").post("/",Yt("query",T),Yt("json",ht),async t=>{let{query:e}=t.req.valid("json"),{db:o}=t.req.valid("query"),r=await Vt({query:e,db:o});return t.json({data:r},200)})});import{HTTPException as vr}from"hono/http-exception";async function Xt({db:t,params:e}){let{tableName:o,data:r}=e,a=y(t),n=Object.keys(r),i=Object.values(r),c=n.map((p,b)=>`$${b+1}`).join(", "),s=n.map(p=>`"${p}"`).join(", "),u=`
|
|
148
148
|
INSERT INTO "${o}" (${s})
|
|
149
|
-
VALUES (${
|
|
149
|
+
VALUES (${c})
|
|
150
150
|
RETURNING *
|
|
151
|
-
`,
|
|
151
|
+
`,l=await a.query(u,i);if(l.rowCount===0)throw new vr(500,{message:`Failed to insert record into "${o}"`});return{insertedCount:l.rowCount??0}}var Zt=m(()=>{"use strict";D()});import{HTTPException as le}from"hono/http-exception";var eo,to=m(()=>{"use strict";D();eo=async({tableName:t,records:e,db:o})=>{if(!e||e.length===0)throw new le(400,{message:"At least one record is required"});let a=await y(o).connect();try{let n=Object.keys(e[0]),i=n.map(l=>`"${l}"`).join(", "),c=0,s=0,u=[];await a.query("BEGIN");for(let l=0;l<e.length;l++){let p=e[l],b=n.map(h=>p[h]),E=n.map((h,x)=>`$${x+1}`).join(", "),d=`
|
|
152
|
+
INSERT INTO "${t}" (${i})
|
|
153
|
+
VALUES (${E})
|
|
154
|
+
RETURNING *
|
|
155
|
+
`;try{await a.query(d,b),c++}catch(h){throw new le(500,{message:`Failed: ${h instanceof Error?h.message:String(h)}`})}}return await a.query("COMMIT"),{success:s===0,message:`Bulk insert completed: ${c} records inserted${s>0?`, ${s} failed`:""}`,successCount:c,failureCount:s,errors:u.length>0?u:void 0}}catch(n){throw await a.query("ROLLBACK"),n instanceof le?n:new le(500,{message:`Failed to bulk insert records into "${t}"`})}finally{a.release()}}});import{HTTPException as Q}from"hono/http-exception";async function _e(t,e){return(await y(e).query(`
|
|
152
156
|
SELECT
|
|
153
157
|
tc.constraint_name,
|
|
154
158
|
tc.table_name as referencing_table,
|
|
@@ -164,45 +168,45 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
164
168
|
AND ccu.table_schema = tc.table_schema
|
|
165
169
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
166
170
|
AND ccu.table_name = $1
|
|
167
|
-
`,[t])).rows.map(
|
|
168
|
-
SELECT * FROM "${
|
|
169
|
-
WHERE "${
|
|
171
|
+
`,[t])).rows.map(n=>({constraintName:n.constraint_name,referencingTable:n.referencing_table,referencingColumn:n.referencing_column,referencedTable:n.referenced_table,referencedColumn:n.referenced_column}))}async function _r(t,e,o){let r=await _e(t,o);if(r.length===0)return[];let a=[],n=y(o),i=new Map;for(let s of r){let u=`${s.referencingTable}.${s.referencingColumn}`;i.has(u)||i.set(u,[]),i.get(u)?.push(s)}let c=e.map(s=>s.value);for(let[s,u]of i){let l=u[0];if(!l||!e.find(h=>h.columnName===l.referencedColumn))continue;let b=c.map((h,x)=>`$${x+1}`).join(", "),E=`
|
|
172
|
+
SELECT * FROM "${l.referencingTable}"
|
|
173
|
+
WHERE "${l.referencingColumn}" IN (${b})
|
|
170
174
|
LIMIT 100
|
|
171
|
-
`,
|
|
175
|
+
`,d=await n.query(E,c);d.rows.length>0&&a.push({tableName:l.referencingTable,columnName:l.referencingColumn,constraintName:l.constraintName,records:d.rows})}return a}async function oo({tableName:t,primaryKeys:e,db:o}){let r=y(o),a=e[0]?.columnName;if(!a)throw new Q(400,{message:"Primary key column name is required"});let n=e.map(s=>s.value),i=n.map((s,u)=>`$${u+1}`).join(", "),c=`
|
|
172
176
|
DELETE FROM "${t}"
|
|
173
177
|
WHERE "${a}" IN (${i})
|
|
174
178
|
RETURNING *
|
|
175
|
-
`;await r.query("BEGIN");
|
|
176
|
-
SELECT "${O.referencedColumn}" FROM "${
|
|
177
|
-
WHERE "${
|
|
178
|
-
`,
|
|
179
|
-
DELETE FROM "${
|
|
180
|
-
WHERE "${
|
|
181
|
-
`,
|
|
179
|
+
`;try{await r.query("BEGIN");let s=await r.query(c,n);return await r.query("COMMIT"),{deletedCount:s.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(s){if(await r.query("ROLLBACK"),s.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await _r(t,e,o)};throw s instanceof Q?s:new Q(500,{message:`Failed to delete records from "${t}"`})}}async function ro({tableName:t,primaryKeys:e,db:o}){let r=y(o),a=e[0]?.columnName;if(!a)throw new Q(400,{message:"Primary key column name is required"});let n=e.map(i=>i.value);await r.query("BEGIN");try{let i=await _e(t,o),c=0,s=new Set,u=async(d,h,x)=>{let U=await _e(d,o);for(let O of U){let Y=x.map((q,G)=>`$${G+1}`).join(", "),M=`
|
|
180
|
+
SELECT "${O.referencedColumn}" FROM "${d}"
|
|
181
|
+
WHERE "${h}" IN (${Y})
|
|
182
|
+
`,C=(await r.query(M,x)).rows.map(({row:q})=>q[O.referencedColumn]);C.length>0&&await u(O.referencingTable,O.referencingColumn,C)}let F=x.map((O,Y)=>`$${Y+1}`).join(", "),H=`
|
|
183
|
+
DELETE FROM "${d}"
|
|
184
|
+
WHERE "${h}" IN (${F})
|
|
185
|
+
`,ye=await r.query(H,x);c+=ye.rowCount??0,s.add(d)};for(let d of i)s.has(d.referencingTable)||await u(d.referencingTable,d.referencingColumn,n);let l=n.map((d,h)=>`$${h+1}`).join(", "),p=`
|
|
182
186
|
DELETE FROM "${t}"
|
|
183
|
-
WHERE "${a}" IN (${
|
|
187
|
+
WHERE "${a}" IN (${l})
|
|
184
188
|
RETURNING *
|
|
185
|
-
`,
|
|
189
|
+
`,b=await r.query(p,n);return await r.query("COMMIT"),{deletedCount:(b.rowCount??0)+c}}catch(i){throw await r.query("ROLLBACK"),i instanceof Q?i:new Q(500,{message:`Failed to force delete records from "${t}"`})}}var ao=m(()=>{"use strict";D()});import{HTTPException as me}from"hono/http-exception";async function no({params:t,db:e}){let{tableName:o,updates:r,primaryKey:a}=t,n=y(e),i=new Map;for(let c of r){let s=c.rowData[a];if(s==null)throw new me(400,{message:`Primary key "${a}" not found in row data. Please ensure the row has a "${a}" column.`});i.has(s)||i.set(s,[]),i.get(s)?.push({columnName:c.columnName,value:c.value,rowData:c.rowData})}await n.query("BEGIN");try{let c=0;for(let[s,u]of i.entries()){let l=u.map((d,h)=>`"${d.columnName}" = $${h+1}`),p=u.map(d=>d.value!==null&&typeof d.value=="object"?JSON.stringify(d.value):d.value);p.push(s);let b=`
|
|
186
190
|
UPDATE "${o}"
|
|
187
|
-
SET ${
|
|
191
|
+
SET ${l.join(", ")}
|
|
188
192
|
WHERE "${a}" = $${p.length}
|
|
189
193
|
RETURNING *
|
|
190
|
-
`,E=await n.query(
|
|
194
|
+
`,E=await n.query(b,p);if(E.rowCount===0)throw new me(404,{message:`Record with ${a} = ${s} not found in table "${o}"`});c+=E.rowCount??0}return await n.query("COMMIT"),{updatedCount:c}}catch(c){throw await n.query("ROLLBACK"),c instanceof me?c:new me(500,{message:`Failed to update records in "${o}"`})}}var so=m(()=>{"use strict";D()});import{zValidator as $}from"@hono/zod-validator";import{Hono as Ar}from"hono";var io,co=m(()=>{"use strict";L();Zt();to();ao();so();io=new Ar().basePath("/records").post("/",$("query",T),$("json",Ye),async t=>{let{db:e}=t.req.valid("query"),{tableName:o,data:r}=t.req.valid("json"),{insertedCount:a}=await Xt({db:e,params:{tableName:o,data:r}});return t.json({data:`Record inserted into "${o}" with ${a} rows inserted`},200)}).patch("/",$("query",T),$("json",Ct),async t=>{let{db:e}=t.req.valid("query"),{tableName:o,primaryKey:r,updates:a}=t.req.valid("json"),{updatedCount:n}=await no({params:{tableName:o,primaryKey:r,updates:a},db:e});return t.json({data:`Updated ${n} records in "${o}"`},200)}).delete("/",$("query",T),$("json",we),async t=>{let{db:e}=t.req.valid("query"),{tableName:o,primaryKeys:r}=t.req.valid("json"),{deletedCount:a,fkViolation:n,relatedRecords:i}=await oo({tableName:o,primaryKeys:r,db:e});return n?t.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:i}},409):t.json({data:{deletedCount:a,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",$("query",T),$("json",we),async t=>{let{db:e}=t.req.valid("query"),{tableName:o,primaryKeys:r}=t.req.valid("json"),a=await ro({tableName:o,primaryKeys:r,db:e});return t.json({data:a},200)}).post("/bulk",$("query",T),$("json",Xe),async t=>{let{db:e}=t.req.valid("query"),{tableName:o,records:r}=t.req.valid("json"),a=await eo({tableName:o,records:r,db:e});return t.json({data:a},200)})});async function lo({tableData:t,db:e}){let{tableName:o,fields:r,foreignKeys:a}=t,n=y(e),i=r.map(l=>{let p=`"${l.columnName}" ${l.columnType}`;return l.isArray&&(p+="[]"),l.isPrimaryKey&&(p+=" PRIMARY KEY"),l.isUnique&&!l.isPrimaryKey&&(p+=" UNIQUE"),l.isNullable||(p+=" NOT NULL"),l.isIdentity&&(p+=" GENERATED ALWAYS AS IDENTITY"),l.defaultValue&&!l.isIdentity&&(p+=` DEFAULT ${l.defaultValue}`),p}),c=a?.map(l=>`CONSTRAINT "${`fk_${o}_${l.columnName}_${l.referencedTable}_${l.referencedColumn}`}" FOREIGN KEY ("${l.columnName}") REFERENCES "${l.referencedTable}" ("${l.referencedColumn}") ON UPDATE ${l.onUpdate} ON DELETE ${l.onDelete}`)||[],s=[...i,...c],u=`
|
|
191
195
|
CREATE TABLE "${o}" (
|
|
192
196
|
${s.join(`,
|
|
193
197
|
`)}
|
|
194
198
|
);
|
|
195
|
-
`;await n.query(u)}var
|
|
199
|
+
`;await n.query(u)}var mo=m(()=>{"use strict";D()});import{HTTPException as uo}from"hono/http-exception";async function po(t){let{tableName:e,columnName:o,cascade:r,db:a}=t,n=y(a),i=`
|
|
196
200
|
SELECT EXISTS (
|
|
197
201
|
SELECT 1 FROM information_schema.tables
|
|
198
202
|
WHERE table_name = $1 AND table_schema = 'public'
|
|
199
203
|
) as exists;
|
|
200
|
-
`,{rows:
|
|
204
|
+
`,{rows:c}=await n.query(i,[e]);if(!c[0]?.exists)throw new uo(404,{message:`Table "${e}" does not exist`});let s=`
|
|
201
205
|
SELECT EXISTS (
|
|
202
206
|
SELECT 1 FROM information_schema.columns
|
|
203
207
|
WHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'
|
|
204
208
|
) as exists;
|
|
205
|
-
`,{rows:u}=await n.query(s,[e,o]);if(!u[0]?.exists)throw new
|
|
209
|
+
`,{rows:u}=await n.query(s,[e,o]);if(!u[0]?.exists)throw new uo(404,{message:`Column "${o}" does not exist in table "${e}"`});let p=`ALTER TABLE "${e}" DROP COLUMN "${o}" ${r?"CASCADE":"RESTRICT"}`,{rowCount:b}=await n.query(p);return{deletedCount:b??0}}var fo=m(()=>{"use strict";D()});import{HTTPException as $r}from"hono/http-exception";async function yo({tableName:t,db:e}){let o=y(e),{rows:r}=await o.query(`SELECT * FROM "${t}"`);if(!r||r.length===0)throw new $r(404,{message:`Table "${t}" does not exist or has no data`});return{cols:Object.keys(r[0]),rows:r}}var bo=m(()=>{"use strict";D()});import{HTTPException as Pr}from"hono/http-exception";async function ho(t){let e=y(t),o=`
|
|
206
210
|
SELECT
|
|
207
211
|
t.table_name as "tableName",
|
|
208
212
|
CASE
|
|
@@ -217,9 +221,9 @@ LEFT JOIN pg_stat_user_tables s ON t.table_name = s.relname
|
|
|
217
221
|
WHERE t.table_schema = 'public'
|
|
218
222
|
AND t.table_type = 'BASE TABLE'
|
|
219
223
|
ORDER BY t.table_name;
|
|
220
|
-
`,{rows:r}=await e.query(o);if(!r[0])throw new
|
|
224
|
+
`,{rows:r}=await e.query(o);if(!r[0])throw new Pr(500,{message:"No tables returned from database"});return r}var go=m(()=>{"use strict";D()});function To(t){if(t.length===0)return{clause:"",values:[]};let e=[],o=[];for(let r of t){let a=o.length+1,n=`"${r.columnName}"`;switch(r.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${n} ${r.operator} $${a}`),o.push(r.value);break;case"is":r.value.toLowerCase()==="null"?e.push(`${n} IS NULL`):(e.push(`${n} = $${a}`),o.push(r.value));break;case"is not":r.value.toLowerCase()==="null"?e.push(`${n} IS NOT NULL`):(e.push(`${n} != $${a}`),o.push(r.value));break;case"like":e.push(`${n}::text LIKE $${a}`),o.push(r.value);break;case"not like":e.push(`${n}::text NOT LIKE $${a}`),o.push(r.value);break;case"ilike":e.push(`${n}::text ILIKE $${a}`),o.push(r.value);break;case"not ilike":e.push(`${n}::text NOT ILIKE $${a}`),o.push(r.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:o}}function So(t,e){return Array.isArray(t)?t.length===0?"":`ORDER BY ${t.map(r=>`"${r.columnName}" ${r.direction.toUpperCase()}`).join(", ")}`:t&&typeof t=="string"?`ORDER BY "${t}" ${e?.toUpperCase()||"ASC"}`:""}function Eo(t,e,o,r){let{values:a,sortColumns:n}=t,i=[],c=[],l=o==="asc"===(e==="asc");if(n.length>0){let p=n.map(d=>`"${d}"`).join(", "),b=n.map((d,h)=>`$${r+h}`).join(", "),E=l?">":"<";i.push(`(${p}) ${E} (${b})`);for(let d of n)c.push(a[d])}return{clause:i.length>0?`(${i.join(" AND ")})`:"",values:c}}var wo=m(()=>{"use strict"});var ue,qr,Ir,Do,Ro=m(()=>{"use strict";D();wo();ue=t=>Buffer.from(JSON.stringify(t)).toString("base64url"),qr=t=>{try{return JSON.parse(Buffer.from(t,"base64url").toString("utf-8"))}catch{return null}},Ir=async(t,e)=>{let o=`"${e}"`;return(await t.query(`SELECT a.attname as column_name
|
|
221
225
|
FROM pg_index i
|
|
222
226
|
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
223
227
|
WHERE i.indrelid = $1::regclass AND i.indisprimary
|
|
224
|
-
ORDER BY array_position(i.indkey, a.attnum)`,[o])).rows.map(a=>a.column_name)},ho=async({tableName:t,cursor:e="",limit:o=50,direction:r="asc",sort:a=[],order:n="asc",filters:i=[],db:m})=>{let s=y(m),u=await Nr(s,t),c=[],p=n;Array.isArray(a)&&a.length>0?(c=a.map(w=>w.columnName),p=a[0].direction):typeof a=="string"&&a&&(c=[a]);let h=[...c,...u.filter(w=>!c.includes(w))];h.length===0&&h.push("ctid");let{clause:E,values:f}=po(i),T="",_=[];if(e){let w=vr(e);if(w){let $=yo(w,r,p,f.length+1);T=$.clause,_=$.values}}let k="";E&&T?k=`WHERE ${E.replace(/^WHERE\s+/i,"")} AND ${T}`:E?k=E:T&&(k=`WHERE ${T}`);let F=fo((Array.isArray(a),a),n),H=F;r==="desc"?F?H=F.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):H=`ORDER BY ${h.map($=>`"${$}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!F&&h.length>0&&(H=`ORDER BY ${h.map($=>`"${$}" ${p.toUpperCase()}`).join(", ")}`);let de=await s.query(`SELECT COUNT(*) as total FROM "${t}" ${E}`,f),O=Number(de.rows[0].total),Q=f.length+_.length+1,z=await s.query(`SELECT * FROM "${t}" ${k} ${H} LIMIT $${Q}`,[...f,..._,o+1]),R=z.fields&&z.fields.length>0?z.rows.filter(w=>Object.keys(w).length>0):z.rows,P=R.length>o;P&&(R=R.slice(0,o)),r==="desc"&&(R=R.reverse());let Y=null,fe=null;if(R.length>0){let w=R[0],$=R[R.length-1],J=xo=>({values:Object.fromEntries(h.map(_e=>[_e,xo[_e]])),sortColumns:h});r==="asc"?(P&&(Y=ce(J($))),e&&(fe=ce(J(w)))):(e&&(Y=ce(J($))),P&&(fe=ce(J(w))))}return{data:R,meta:{limit:o,total:O,hasNextPage:r==="asc"?P:!!e,hasPreviousPage:r==="asc"?!!e:P,nextCursor:Y,prevCursor:fe}}}});import{utils as le,write as _r}from"xlsx";function To({cols:t,rows:e,format:o,tableName:r}){let a=[t,...e?.map(s=>t?.map(u=>s[u]))??[]],n=le.aoa_to_sheet(a),i=le.book_new();if(le.book_append_sheet(i,n,r.slice(0,31)),o==="csv"){let s=le.sheet_to_csv(n);return new Uint8Array(Buffer.from(s,"utf-8"))}let m=_r(i,{bookType:"xlsx",type:"buffer"});return new Uint8Array(m)}var So=l(()=>{"use strict"});import{zValidator as N}from"@hono/zod-validator";import{Hono as Ar}from"hono";var Eo,Do=l(()=>{"use strict";L();ao();io();lo();Re();uo();go();So();Eo=new Ar().basePath("/tables").get("/",N("query",g),async t=>{let{db:e}=t.req.valid("query"),o=await mo(e);return t.json({data:o},200)}).post("/",N("query",g),N("json",at),async t=>{let{db:e}=t.req.valid("query"),o=t.req.valid("json");return await ro({tableData:o,db:e}),t.json({data:`Table ${o.tableName} created successfully`},200)}).delete("/:tableName/columns/:columnName",N("query",lt),N("param",re),async t=>{let{db:e,cascade:o}=t.req.valid("query"),{tableName:r,columnName:a}=t.req.valid("param"),{deletedCount:n}=await so({tableName:r,columnName:a,cascade:o,db:e});return t.json({data:`Column "${a}" deleted successfully from table "${r}" with ${n} rows deleted`},200)}).get("/:tableName/columns",N("query",g),N("param",oe),async t=>{let{db:e}=t.req.valid("query"),{tableName:o}=t.req.valid("param"),r=await se({tableName:o,db:e});return t.json({data:r},200)}).get("/:tableName/data",N("param",oe),N("query",gt),async t=>{let{tableName:e}=t.req.valid("param"),{cursor:o,limit:r,direction:a,sort:n,order:i,filters:m,db:s}=t.req.valid("query"),u=await ho({tableName:e,cursor:o,limit:r,direction:a,sort:n,order:i,filters:m,db:s});return t.json({data:u},200)}).get("/:tableName/export",N("param",oe),N("query",yt),async t=>{let{tableName:e}=t.req.valid("param"),{db:o,format:r}=t.req.valid("query"),{cols:a,rows:n}=await co({tableName:e,db:o}),i=To({cols:a,rows:n,format:r,tableName:e}),m=r==="csv"?"text/csv":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";return new Response(i,{headers:{"Content-Type":m,"Content-Disposition":`attachment; filename="${e}_export.${r}"`}})})});var wo={};No(wo,{createServer:()=>jr});import pe from"path";import{fileURLToPath as $r}from"url";import{serveStatic as me}from"@hono/node-server/serve-static";import{zValidator as Pr}from"@hono/zod-validator";import{Hono as qr}from"hono";import{cors as Lr}from"hono/cors";import{logger as Ir}from"hono/logger";import{prettyJSON as Or}from"hono/pretty-json";var ue,jr,Co=l(()=>{"use strict";L();Rt();Lt();zt();Bt();oo();Do();ue=()=>{if(process.env.NODE_ENV==="development")return pe.resolve(process.cwd(),"../core/dist");let t=pe.dirname($r(import.meta.url));return pe.resolve(t,"./core-dist")},jr=()=>({app:new qr({strict:!1}).use("/*",Lr()).use(Or({space:2})).use(process.env.NODE_ENV==="development"?Ir():(e,o)=>o()).use("/favicon.ico",me({path:pe.resolve(ue(),"favicon.ico")})).use("*",async(e,o)=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),await o()}).onError(wt).route("/",Ht).use("/assets/*",me({root:ue()})).use("/image.png",me({root:ue()})).use("/:dbType/*",Pr("param",Ge,Ct)).use("/:dbType/*",async(e,o)=>{let r=e.req.param("dbType");e.set("dbType",r),await o()}).route("/:dbType",Eo).route("/:dbType",to).route("/:dbType",Vt).route("/:dbType",qt).use("/*",me({root:ue()}))})});X();import{intro as Ur,outro as kr}from"@clack/prompts";import{serve as Fr}from"@hono/node-server";import Hr from"open";import Ne from"picocolors";import{program as Ie}from"commander";var Oe=()=>(Ie.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("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv),Ie.opts());import{readFile as _o}from"fs/promises";import{resolve as Ao}from"path";import{cancel as Z,isCancel as be,note as je,select as $o,spinner as Po,text as Ue}from"@clack/prompts";import{parse as qo}from"dotenv";import he from"picocolors";var ke=async(t,e)=>{let o=e||"DATABASE_URL";if(t?.[o])return t[o];if(process.env[o])return process.env[o];let r=Po();r.start("Looking for database connection..."),t?je(he.red(`${o} not found in .env or process.env`)):je(he.red(`No .env file found and ${o} not set in process.env`));let a=await $o({message:`How do you want to provide ${o}?`,options:[{value:"manual",label:"Enter connection string manually"},{value:"other-env",label:"Use different .env file"},{value:"cancel",label:"Cancel / Exit"}],initialValue:"manual"});if((be(a)||a==="cancel")&&(Z("No database connection provided. Exiting..."),process.exit(0)),a==="other-env"){r.start("Waiting for path...");let i=await Ue({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(s){if(!s.trim())return"Path is required"}});be(i)&&(Z("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let m=Ao(i);try{let s=await _o(m,"utf-8"),u=qo(s);if(u[o])return u[o];throw new Error(`${o} still missing in custom file`)}catch(s){let u=s;Z(`Cannot read or parse file: ${he.dim(u.message)}`),process.exit(1)}}r.stop("Manual input...");let n=await Ue({message:`Paste your ${o}`,placeholder:"postgresql://user:password@localhost:5432/mydb",validate(i){if(!i.trim())return"Connection string is required!";try{new URL(i);return}catch{return"Must be a valid URL format"}}});return be(n)&&(Z("Cancelled."),process.exit(0)),n.trim()};import{access as Lo,readFile as Io}from"fs/promises";import{dirname as Oo,resolve as ge}from"path";import{parse as jo}from"dotenv";var Uo=async t=>{let e=ge(t);for(;;){let o=ge(e,".env");try{return await Lo(o),o}catch{}let r=Oo(e);if(r===e)return null;e=r}},M=async t=>{let e;if(t?e=ge(t):e=await Uo(process.cwd()),!e)return null;try{let o=await Io(e,"utf-8");return jo(o)}catch(o){if(o instanceof Error&&o.message.includes("ENOENT"))return null;throw o}};ye();import{intro as ko,outro as Fo}from"@clack/prompts";import Fe from"picocolors";var He=()=>{ko(Fe.inverse(" db-studio ")),Fo(Fe.green(`For more information, visit: ${qe.SITE_DOCS_LINK}`))};X();import{intro as Ho,note as zo,outro as ze}from"@clack/prompts";import ee from"picocolors";var Me=async(t,e,o)=>{Ho(ee.inverse(" db-studio "));let r=o||j.VAR_NAME,a=null;if(e)a=e;else{let n=t?await M(t):await M();n?.[r]?a=n[r]:process.env[r]&&(a=process.env[r]??null)}a?ze(ee.green(`\u2713 Database connection configured (using ${r})`)):(zo(ee.red(`\u2717 ${r} not found`),"Status"),ze(ee.yellow("\u26A0 No database connection configured")))};import{intro as Wo,outro as Ko}from"@clack/prompts";import Ke from"picocolors";var We={name:"db-studio",type:"module",version:"1.2.24",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","database client","postgres","postgresql","database gui","sql client","database studio","postgres gui","ai sql","sql editor","er diagram","database management","data browser","spreadsheet database","postgres admin","mysql client","sqlite client","database tool","developer tools"],author:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",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:"MIT",bin:{"db-studio":"./dist/index.js"},files:["dist"],scripts:{dev:"NODE_ENV=development tsx watch src/index.ts",build:"tsup --minify --sourcemap",prepack:"cd ../core && bun run build && cd ../server && bun run build",start:"node dist/index.js",check:"biome check --write --unsafe --verbose",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},dependencies:{"@clack/prompts":"^0.11.0","@hono/node-server":"^1.19.7","@hono/zod-validator":"^0.7.6",commander:"^12.1.0",dotenv:"^16.4.7",hono:"^4.10.4",open:"^10.0.2",pg:"^8.13.1",picocolors:"^1.1.1",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@types/node":"^20.11.17","@types/pg":"^8.16.0","@vitest/coverage-v8":"^4.0.17",shared:"workspace:*",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^5.8.3",vitest:"^4.0.17"}};var Ve=()=>{Wo(Ke.inverse(" db-studio ")),Ko(Ke.green(`\u{1F680} db-studio v${We.version}`))};var zr=async()=>{let{env:t,port:e,databaseUrl:o,varName:r,status:a,help:n,version:i}=Oe();n&&(He(),process.exit(0)),i&&(Ve(),process.exit(0)),a&&(await Me(t,o,r),process.exit(0)),Ur(Ne.inverse(" db-studio "));let m=e?parseInt(e,10):j.PORT,s=r||j.VAR_NAME,u=t?await M(t):await M(),c=o||await ke(u,s);process.env.DATABASE_URL=c;let{createServer:p}=await Promise.resolve().then(()=>(Co(),wo)),{app:h}=p();Fr({fetch:h.fetch,port:m}),kr(Ne.green(`Server running at ${Ne.cyan(`http://localhost:${m}`)}`)),process.env.NODE_ENV&&process.env.NODE_ENV!=="development"&&await Hr(`http://localhost:${m}`)};zr().catch(t=>{process.exit(1)});export{zr as main};
|
|
228
|
+
ORDER BY array_position(i.indkey, a.attnum)`,[o])).rows.map(a=>a.column_name)},Do=async({tableName:t,cursor:e="",limit:o=50,direction:r="asc",sort:a=[],order:n="asc",filters:i=[],db:c})=>{let s=y(c),u=await Ir(s,t),l=[],p=n;Array.isArray(a)&&a.length>0?(l=a.map(R=>R.columnName),p=a[0].direction):typeof a=="string"&&a&&(l=[a]);let b=[...l,...u.filter(R=>!l.includes(R))];b.length===0&&b.push("ctid");let{clause:E,values:d}=To(i),h="",x=[];if(e){let R=qr(e);if(R){let P=Eo(R,r,p,d.length+1);h=P.clause,x=P.values}}let U="";E&&h?U=`WHERE ${E.replace(/^WHERE\s+/i,"")} AND ${h}`:E?U=E:h&&(U=`WHERE ${h}`);let F=So((Array.isArray(a),a),n),H=F;r==="desc"?F?H=F.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):H=`ORDER BY ${b.map(P=>`"${P}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!F&&b.length>0&&(H=`ORDER BY ${b.map(P=>`"${P}" ${p.toUpperCase()}`).join(", ")}`);let ye=await s.query(`SELECT COUNT(*) as total FROM "${t}" ${E}`,d),O=Number(ye.rows[0].total),Y=d.length+x.length+1,M=await s.query(`SELECT * FROM "${t}" ${U} ${H} LIMIT $${Y}`,[...d,...x,o+1]),C=M.fields&&M.fields.length>0?M.rows.filter(R=>Object.keys(R).length>0):M.rows,q=C.length>o;q&&(C=C.slice(0,o)),r==="desc"&&(C=C.reverse());let G=null,be=null;if(C.length>0){let R=C[0],P=C[C.length-1],Z=Po=>({values:Object.fromEntries(b.map($e=>[$e,Po[$e]])),sortColumns:b});r==="asc"?(q&&(G=ue(Z(P))),e&&(be=ue(Z(R)))):(e&&(G=ue(Z(P))),q&&(be=ue(Z(R))))}return{data:C,meta:{limit:o,total:O,hasNextPage:r==="asc"?q:!!e,hasPreviousPage:r==="asc"?!!e:q,nextCursor:G,prevCursor:be}}}});import{utils as X,write as Lr}from"xlsx";function Co({cols:t,rows:e,format:o,tableName:r}){switch(o){case"json":{let a=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(a,"utf-8"))}case"csv":{let a=[t,...e?.map(c=>t?.map(s=>c[s]))??[]],n=X.aoa_to_sheet(a),i=X.sheet_to_csv(n);return new Uint8Array(Buffer.from(i,"utf-8"))}case"xlsx":{let a=[t,...e?.map(s=>t?.map(u=>s[u]))??[]],n=X.aoa_to_sheet(a),i=X.book_new();X.book_append_sheet(i,n,r.slice(0,31));let c=Lr(i,{bookType:"xlsx",type:"buffer"});return new Uint8Array(c)}}}var xo=m(()=>{"use strict"});import{zValidator as _}from"@hono/zod-validator";import{Hono as Or}from"hono";var No,vo=m(()=>{"use strict";L();mo();fo();bo();Ne();go();Ro();xo();No=new Or().basePath("/tables").get("/",_("query",T),async t=>{let{db:e}=t.req.valid("query"),o=await ho(e);return t.json({data:o},200)}).post("/",_("query",T),_("json",ct),async t=>{let{db:e}=t.req.valid("query"),o=t.req.valid("json");return await lo({tableData:o,db:e}),t.json({data:`Table ${o.tableName} created successfully`},200)}).delete("/:tableName/columns/:columnName",_("query",dt),_("param",ne),async t=>{let{db:e,cascade:o}=t.req.valid("query"),{tableName:r,columnName:a}=t.req.valid("param"),{deletedCount:n}=await po({tableName:r,columnName:a,cascade:o,db:e});return t.json({data:`Column "${a}" deleted successfully from table "${r}" with ${n} rows deleted`},200)}).get("/:tableName/columns",_("query",T),_("param",ae),async t=>{let{db:e}=t.req.valid("query"),{tableName:o}=t.req.valid("param"),r=await ce({tableName:o,db:e});return t.json({data:r},200)}).get("/:tableName/data",_("param",ae),_("query",wt),async t=>{let{tableName:e}=t.req.valid("param"),{cursor:o,limit:r,direction:a,sort:n,order:i,filters:c,db:s}=t.req.valid("query"),u=await Do({tableName:e,cursor:o,limit:r,direction:a,sort:n,order:i,filters:c,db:s});return t.json({data:u},200)}).get("/:tableName/export",_("param",ae),_("query",Tt),async t=>{let{tableName:e}=t.req.valid("param"),{db:o,format:r}=t.req.valid("query"),{cols:a,rows:n}=await yo({tableName:e,db:o}),i=Co({cols:a,rows:n,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(i,{headers:{"Content-Type":c??"","Content-Disposition":`attachment; filename="${e}_export.${r}"`}})})});var _o={};Io(_o,{createServer:()=>zr});import fe from"path";import{fileURLToPath as kr}from"url";import{serveStatic as pe}from"@hono/node-server/serve-static";import{zValidator as jr}from"@hono/zod-validator";import{Hono as Ur}from"hono";import{cors as Fr}from"hono/cors";import{logger as Hr}from"hono/logger";import{prettyJSON as Mr}from"hono/pretty-json";var de,zr,Ao=m(()=>{"use strict";L();_t();jt();Kt();Jt();co();vo();de=()=>{if(process.env.NODE_ENV==="development")return fe.resolve(process.cwd(),"../core/dist");let t=fe.dirname(kr(import.meta.url));return fe.resolve(t,"./core-dist")},zr=()=>({app:new Ur({strict:!1}).use("/*",Fr()).use(Mr({space:2})).use(process.env.NODE_ENV==="development"?Hr():(e,o)=>o()).use("/favicon.ico",pe({path:fe.resolve(de(),"favicon.ico")})).use("*",async(e,o)=>{e.header("Access-Control-Allow-Origin","*"),e.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"),await o()}).onError(Nt).route("/",Wt).use("/assets/*",pe({root:de()})).use("/image.png",pe({root:de()})).use("/:dbType/*",jr("param",et,vt)).use("/:dbType/*",async(e,o)=>{let r=e.req.param("dbType");e.set("dbType",r),await o()}).route("/:dbType",No).route("/:dbType",io).route("/:dbType",Gt).route("/:dbType",kt).use("/*",pe({root:de()}))})});ee();import{intro as Br,outro as Wr}from"@clack/prompts";import{serve as Kr}from"@hono/node-server";import Vr from"open";import Ae from"picocolors";import{program as ke}from"commander";var je=()=>(ke.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("-s, --status","Show status of the server").option("-h, --help","Show help").option("-v, --version","Show version").parse(process.argv),ke.opts());import{readFile as Lo}from"fs/promises";import{resolve as Oo}from"path";import{cancel as te,isCancel as ge,note as Ue,select as ko,spinner as jo,text as Fe}from"@clack/prompts";import{parse as Uo}from"dotenv";import Te from"picocolors";var He=async(t,e)=>{let o=e||"DATABASE_URL";if(t?.[o])return t[o];if(process.env[o])return process.env[o];let r=jo();r.start("Looking for database connection..."),t?Ue(Te.red(`${o} not found in .env or process.env`)):Ue(Te.red(`No .env file found and ${o} not set in process.env`));let a=await ko({message:`How do you want to provide ${o}?`,options:[{value:"manual",label:"Enter connection string manually"},{value:"other-env",label:"Use different .env file"},{value:"cancel",label:"Cancel / Exit"}],initialValue:"manual"});if((ge(a)||a==="cancel")&&(te("No database connection provided. Exiting..."),process.exit(0)),a==="other-env"){r.start("Waiting for path...");let i=await Fe({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(s){if(!s.trim())return"Path is required"}});ge(i)&&(te("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let c=Oo(i);try{let s=await Lo(c,"utf-8"),u=Uo(s);if(u[o])return u[o];throw new Error(`${o} still missing in custom file`)}catch(s){let u=s;te(`Cannot read or parse file: ${Te.dim(u.message)}`),process.exit(1)}}r.stop("Manual input...");let n=await Fe({message:`Paste your ${o}`,placeholder:"postgresql://user:password@localhost:5432/mydb",validate(i){if(!i.trim())return"Connection string is required!";try{new URL(i);return}catch{return"Must be a valid URL format"}}});return ge(n)&&(te("Cancelled."),process.exit(0)),n.trim()};import{access as Fo,readFile as Ho}from"fs/promises";import{dirname as Mo,resolve as Se}from"path";import{parse as zo}from"dotenv";var Bo=async t=>{let e=Se(t);for(;;){let o=Se(e,".env");try{return await Fo(o),o}catch{}let r=Mo(e);if(r===e)return null;e=r}},z=async t=>{let e;if(t?e=Se(t):e=await Bo(process.cwd()),!e)return null;try{let o=await Ho(e,"utf-8");return zo(o)}catch(o){if(o instanceof Error&&o.message.includes("ENOENT"))return null;throw o}};he();import{intro as Wo,outro as Ko}from"@clack/prompts";import Me from"picocolors";var ze=()=>{Wo(Me.inverse(" db-studio ")),Ko(Me.green(`For more information, visit: ${Le.SITE_DOCS_LINK}`))};ee();import{intro as Vo,note as Qo,outro as Be}from"@clack/prompts";import oe from"picocolors";var We=async(t,e,o)=>{Vo(oe.inverse(" db-studio "));let r=o||k.VAR_NAME,a=null;if(e)a=e;else{let n=t?await z(t):await z();n?.[r]?a=n[r]:process.env[r]&&(a=process.env[r]??null)}a?Be(oe.green(`\u2713 Database connection configured (using ${r})`)):(Qo(oe.red(`\u2717 ${r} not found`),"Status"),Be(oe.yellow("\u26A0 No database connection configured")))};import{intro as Go,outro as Jo}from"@clack/prompts";import Ve from"picocolors";var Ke={name:"db-studio",type:"module",version:"1.3.25",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","database client","postgres","postgresql","database gui","sql client","database studio","postgres gui","ai sql","sql editor","er diagram","database management","data browser","spreadsheet database","postgres admin","mysql client","sqlite client","database tool","developer tools"],author:"H\xFCsam \u{1F951} <devhsmq@gmail.com>",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:"MIT",bin:{"db-studio":"./dist/index.js"},files:["dist"],scripts:{dev:"NODE_ENV=development tsx watch src/index.ts",build:"tsup --minify --sourcemap",prepack:"cd ../core && bun run build && cd ../server && bun run build",start:"node dist/index.js",check:"biome check --write --unsafe",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},dependencies:{"@clack/prompts":"^0.11.0","@hono/node-server":"^1.19.7","@hono/zod-validator":"^0.7.6",commander:"^12.1.0",dotenv:"^16.4.7",hono:"^4.10.4",open:"^10.0.2",pg:"^8.13.1",picocolors:"^1.1.1",xlsx:"^0.18.5",zod:"^4.2.1"},devDependencies:{"@biomejs/biome":"^2.2.6","@types/node":"^20.11.17","@types/pg":"^8.16.0","@vitest/coverage-v8":"^4.0.17",shared:"workspace:*",tsup:"^8.5.1",tsx:"^4.7.1",typescript:"^5.8.3",vitest:"^4.0.17"}};var Qe=()=>{Go(Ve.inverse(" db-studio ")),Jo(Ve.green(`\u{1F680} db-studio v${Ke.version}`))};var Qr=async()=>{let{env:t,port:e,databaseUrl:o,varName:r,status:a,help:n,version:i}=je();n&&(ze(),process.exit(0)),i&&(Qe(),process.exit(0)),a&&(await We(t,o,r),process.exit(0)),Br(Ae.inverse(" db-studio "));let c=e?parseInt(e,10):k.PORT,s=r||k.VAR_NAME,u=t?await z(t):await z(),l=o||await He(u,s);process.env.DATABASE_URL=l;let{createServer:p}=await Promise.resolve().then(()=>(Ao(),_o)),{app:b}=p();Kr({fetch:b.fetch,port:c}),Wr(Ae.green(`Server running at ${Ae.cyan(`http://localhost:${c}`)}`)),process.env.NODE_ENV&&process.env.NODE_ENV!=="development"&&await Vr(`http://localhost:${c}`)};Qr().catch(t=>{process.exit(1)});export{Qr as main};
|
|
225
229
|
//# sourceMappingURL=index.js.map
|