db-studio 1.3.30 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core-dist/assets/{_baseUniq-UWFgpItC.js → _baseUniq-C7A7fsQ-.js} +1 -1
- package/dist/core-dist/assets/{_pathlessLayout-CpBL0aj6.js → _pathlessLayout-BErOoJBf.js} +2 -2
- package/dist/core-dist/assets/{_queryId-B1avt5xd.js → _queryId-B1LaFAmm.js} +1 -1
- package/dist/core-dist/assets/_table-4nxpgHEz.js +8 -0
- package/dist/core-dist/assets/{arc-CYmQe9AE.js → arc-Clvi5rzR.js} +1 -1
- package/dist/core-dist/assets/{architectureDiagram-VXUJARFQ-BG9RglDV.js → architectureDiagram-VXUJARFQ-DkipSmLb.js} +1 -1
- package/dist/core-dist/assets/{blockDiagram-VD42YOAC-Bt0kVS2s.js → blockDiagram-VD42YOAC-DV8KUj94.js} +1 -1
- package/dist/core-dist/assets/{c4Diagram-YG6GDRKO-BPGcnb0p.js → c4Diagram-YG6GDRKO-CIKSfaF1.js} +1 -1
- package/dist/core-dist/assets/{cdoe-editor-CCElZ8xs.js → cdoe-editor-BCFPgj4h.js} +1 -1
- package/dist/core-dist/assets/channel-B2Rh1omC.js +1 -0
- package/dist/core-dist/assets/{chunk-4BX2VUAB-DDI4iDp3.js → chunk-4BX2VUAB-DcvB4_uV.js} +1 -1
- package/dist/core-dist/assets/{chunk-55IACEB6-CbXHwtl3.js → chunk-55IACEB6-EG9AyKaq.js} +1 -1
- package/dist/core-dist/assets/{chunk-B4BG7PRW-CwngaFew.js → chunk-B4BG7PRW-KK8IJqzV.js} +1 -1
- package/dist/core-dist/assets/{chunk-DI55MBZ5-DhP_kO2r.js → chunk-DI55MBZ5-TpII66YZ.js} +1 -1
- package/dist/core-dist/assets/{chunk-FMBD7UC4-SVBax3JO.js → chunk-FMBD7UC4-IEg5SEkW.js} +1 -1
- package/dist/core-dist/assets/{chunk-QN33PNHL-Co_dl0i3.js → chunk-QN33PNHL-DOQqAhwZ.js} +1 -1
- package/dist/core-dist/assets/{chunk-QZHKN3VN-DnBN-dFo.js → chunk-QZHKN3VN-CQD63wVo.js} +1 -1
- package/dist/core-dist/assets/{chunk-TZMSLE5B-LqiNMaf7.js → chunk-TZMSLE5B-Ck8unx9M.js} +1 -1
- package/dist/core-dist/assets/classDiagram-2ON5EDUG-yB0lDqQ_.js +1 -0
- package/dist/core-dist/assets/classDiagram-v2-WZHVMYZB-yB0lDqQ_.js +1 -0
- package/dist/core-dist/assets/clone-DMtL-4i6.js +1 -0
- package/dist/core-dist/assets/{code-block-IT6T5CEO-B_iutjGv.js → code-block-IT6T5CEO-BkhPLTN-.js} +1 -1
- package/dist/core-dist/assets/{cose-bilkent-S5V4N54A-C29AFgeB.js → cose-bilkent-S5V4N54A-BU01uPeb.js} +1 -1
- package/dist/core-dist/assets/{dagre-6UL2VRFP-CRw-rmhP.js → dagre-6UL2VRFP-DgGR46yM.js} +1 -1
- package/dist/core-dist/assets/{diagram-PSM6KHXK-ilk5FbYN.js → diagram-PSM6KHXK-D_opTgTY.js} +1 -1
- package/dist/core-dist/assets/{diagram-QEK2KX5R-FAmyHLy2.js → diagram-QEK2KX5R-C8q65IvQ.js} +1 -1
- package/dist/core-dist/assets/{diagram-S2PKOQOG-CszVht6-.js → diagram-S2PKOQOG-DideTxM7.js} +1 -1
- package/dist/core-dist/assets/{erDiagram-Q2GNP2WA-BmOkDGWs.js → erDiagram-Q2GNP2WA-CRAdUMHH.js} +1 -1
- package/dist/core-dist/assets/{flowDiagram-NV44I4VS-Da9X1RuW.js → flowDiagram-NV44I4VS-BZhEr3Uj.js} +1 -1
- package/dist/core-dist/assets/{ganttDiagram-JELNMOA3-C696L8ZB.js → ganttDiagram-JELNMOA3-v6QMKJx4.js} +1 -1
- package/dist/core-dist/assets/{gitGraphDiagram-NY62KEGX-LTfBzWOC.js → gitGraphDiagram-NY62KEGX-A1MEr8uU.js} +1 -1
- package/dist/core-dist/assets/{graph-DuK9pMjF.js → graph-C6dXmhID.js} +1 -1
- package/dist/core-dist/assets/index-B7-ICZ0j.js +1 -0
- package/dist/core-dist/assets/index-BMkY85Cs.js +58 -0
- package/dist/core-dist/assets/index-CI-PCTpD.css +1 -0
- package/dist/core-dist/assets/{index-Dji_PlAM.js → index-DVnhzasD.js} +1 -1
- package/dist/core-dist/assets/{infoDiagram-WHAUD3N6-BGath1CP.js → infoDiagram-WHAUD3N6-CJkR0w30.js} +1 -1
- package/dist/core-dist/assets/{journeyDiagram-XKPGCS4Q-BIAqcWKP.js → journeyDiagram-XKPGCS4Q-SAEhBpzZ.js} +1 -1
- package/dist/core-dist/assets/{kanban-definition-3W4ZIXB7-DohAAdP-.js → kanban-definition-3W4ZIXB7-CTjwDgKD.js} +1 -1
- package/dist/core-dist/assets/{layout-Buqi3-6U.js → layout-BC4bIyCj.js} +1 -1
- package/dist/core-dist/assets/{linear-CGcP08V8.js → linear-aOQP6b5O.js} +1 -1
- package/dist/core-dist/assets/{mermaid-VLURNSYL-Dmq-1uzC.js → mermaid-VLURNSYL-Bk83Yp1q.js} +4 -4
- package/dist/core-dist/assets/{mermaid.core-BbW_ZtiH.js → mermaid.core-VvKZ2mCx.js} +5 -5
- package/dist/core-dist/assets/{min-lqfKr2zD.js → min-BiqQDxvT.js} +1 -1
- package/dist/core-dist/assets/{mindmap-definition-VGOIOE7T-Dy2JB381.js → mindmap-definition-VGOIOE7T-DjjEGOvH.js} +1 -1
- package/dist/core-dist/assets/{pieDiagram-ADFJNKIX--R2CEHc7.js → pieDiagram-ADFJNKIX-AUM01WmV.js} +1 -1
- package/dist/core-dist/assets/{quadrantDiagram-AYHSOK5B--lH98DZf.js → quadrantDiagram-AYHSOK5B-MpcGOIDU.js} +1 -1
- package/dist/core-dist/assets/{queries.store-HQzrytMz.js → queries.store-DjOPk8vF.js} +1 -1
- package/dist/core-dist/assets/{requirementDiagram-UZGBJVZJ-D2c3MoLI.js → requirementDiagram-UZGBJVZJ-DTgvy-oh.js} +1 -1
- package/dist/core-dist/assets/{runner-tab-BmW2SYWu.js → runner-tab-2NkPdwaD.js} +3 -3
- package/dist/core-dist/assets/{sankeyDiagram-TZEHDZUN-hmMC-wMg.js → sankeyDiagram-TZEHDZUN-Coy7Jnu4.js} +1 -1
- package/dist/core-dist/assets/{scroll-area-BN9Yzs7i.js → scroll-area-DuacQlkg.js} +1 -1
- package/dist/core-dist/assets/{sequenceDiagram-WL72ISMW-DjM_8aLZ.js → sequenceDiagram-WL72ISMW-DWol0BxA.js} +1 -1
- package/dist/core-dist/assets/{stateDiagram-FKZM4ZOC-6QGXRXcC.js → stateDiagram-FKZM4ZOC-B4qm6ej0.js} +1 -1
- package/dist/core-dist/assets/stateDiagram-v2-4FDKWEC3-BuP2exNa.js +1 -0
- package/dist/core-dist/assets/{timeline-definition-IT6M3QCI-7u-NYugE.js → timeline-definition-IT6M3QCI-DZ5Afuno.js} +1 -1
- package/dist/core-dist/assets/{treemap-KMMF4GRG-C_ijS9xc.js → treemap-KMMF4GRG-Cxy-aurk.js} +1 -1
- package/dist/core-dist/assets/{xychartDiagram-PRI3JC2R-Dutd9f_F.js → xychartDiagram-PRI3JC2R-yhq_s0e5.js} +1 -1
- package/dist/core-dist/index.html +2 -2
- package/dist/index.js +168 -60
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/core-dist/assets/_table-Dq6idgBf.js +0 -8
- package/dist/core-dist/assets/channel-DKAZYnGL.js +0 -1
- package/dist/core-dist/assets/classDiagram-2ON5EDUG-BhFmd1vH.js +0 -1
- package/dist/core-dist/assets/classDiagram-v2-WZHVMYZB-BhFmd1vH.js +0 -1
- package/dist/core-dist/assets/clone-BGEOsFgb.js +0 -1
- package/dist/core-dist/assets/index-BXRBzRx2.css +0 -1
- package/dist/core-dist/assets/index-Ccs95aMC.js +0 -1
- package/dist/core-dist/assets/index-JaaW_vfS.js +0 -58
- package/dist/core-dist/assets/stateDiagram-v2-4FDKWEC3-BGBFh8rH.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var zo=Object.defineProperty;var m=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ko=(t,e)=>{for(var o in e)zo(t,o,{get:e[o],enumerable:!0})};var qe=m(()=>{"use strict"});var M,Ie=m(()=>{"use strict";M={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 Oe=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:"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 ke=m(()=>{"use strict"});var oe=m(()=>{"use strict";qe();Ie();Oe();he();ke()});import{z as Z}from"zod";var Ge,Je=m(()=>{"use strict";Ge=Z.object({tableName:Z.string("Table name is required"),data:Z.record(Z.string("Column name is required"),Z.any())})});var Xe=m(()=>{"use strict"});import{z as W}from"zod";var Ze,et=m(()=>{"use strict";Ze=W.object({tableName:W.string().min(1,"Table name is required"),records:W.array(W.record(W.string(),W.any())).min(1,"At least one record is required")})});import{z as B}from"zod";var S,cr,ne,Za,tt,V,j=m(()=>{"use strict";S=B.object({db:B.string("Database name is required")}),cr=["pg"],ne=B.enum(cr,{message:"Invalid database type"}),Za=S.extend({dbType:ne}),tt=B.object({dbType:ne}),V=B.object({tableName:B.string("Table name is required")})});import{z as Q}from"zod";var ot,rt=m(()=>{"use strict";j();ot=Q.object({messages:Q.array(Q.object({role:Q.enum(["user","assistant"]),content:Q.string("Content is required")})),conversationId:Q.string().optional(),db:S.shape.db})});var at=m(()=>{"use strict"});import{z as A}from"zod";var lr,mr,U,ur,pr,nn,Ee=m(()=>{"use strict";lr=["text","boolean","number","enum","json","date","array"],mr=A.enum(lr),U={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},ur=["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"],pr=A.enum(ur),nn=A.object({columnName:A.string(),dataType:mr,dataTypeLabel:pr,isNullable:A.boolean(),columnDefault:A.string().nullable(),isPrimaryKey:A.boolean(),isForeignKey:A.boolean(),referencedTable:A.string().nullable(),referencedColumn:A.string().nullable(),enumValues:A.array(A.string()).nullable()})});function nt(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(")?U.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"?U.number:e==="boolean"||e==="bool"?U.boolean:e==="json"||e==="jsonb"?U.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?U.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"?U.text:U.text}function st(t){if(!t)return b.text;let e=t.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}var b,it=m(()=>{"use strict";Ee();b={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 R}from"zod";var dr,ct,fr,br,lt,mt=m(()=>{"use strict";dr=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],ct=R.enum(dr),fr=R.object({columnName:R.string("Column name is required"),columnType:R.string("Column type is required"),defaultValue:R.string().optional(),isPrimaryKey:R.boolean().default(!1),isNullable:R.boolean().default(!1),isUnique:R.boolean().default(!1),isIdentity:R.boolean().default(!1),isArray:R.boolean().default(!1)}),br=R.object({columnName:R.string("Column name is required"),referencedTable:R.string("Referenced table is required"),referencedColumn:R.string("Referenced column is required"),onUpdate:ct.default("NO ACTION"),onDelete:ct.default("NO ACTION")}),lt=R.object({tableName:R.string("Table name is required"),fields:R.array(fr).min(1,"At least one field is required"),foreignKeys:R.array(br).optional()})});import{z as C}from"zod";var yr,fn,ut,pt=m(()=>{"use strict";j();yr=C.object({name:C.string("Name is required"),size:C.string("Size is required"),owner:C.string("Owner is required"),encoding:C.string("Encoding is required")}),fn=C.object({databases:C.array(yr),dbType:ne}),ut=C.object({version:C.string("Version is required"),database:C.string("Database is required"),user:C.string("User is required"),host:C.string("Host is required").nullable(),port:C.number("Port is required").nullable(),active_connections:C.coerce.number("Active connections is required"),max_connections:C.coerce.number("Max connections is required")})});var dt=m(()=>{"use strict"});import{z as $}from"zod";var ft,se,gn,Tn,bt=m(()=>{"use strict";j();ft=S.extend({cascade:$.string().optional().transform(t=>t==="true")}),se=$.object({tableName:$.string("Table name is required"),columnName:$.string("Column name is required")}),gn=$.object({db:S.shape.db,tableName:se.shape.tableName,columnName:se.shape.columnName,cascade:$.boolean().optional()}),Tn=$.object({message:$.string("Message is required"),tableName:$.string("Table name is required"),columnName:$.string("Column name is required"),deletedCount:$.number("Deleted count is required").default(0)})});import{z as Y}from"zod";var Re,yt=m(()=>{"use strict";Re=Y.object({tableName:Y.string("Table name is required"),primaryKeys:Y.array(Y.object({columnName:Y.string("Column name is required"),value:Y.any()})).min(1,"At least one primary key is required")})});import{z as hr}from"zod";var ht,gt=m(()=>{"use strict";j();ht=S.extend({cascade:hr.string().optional().transform(t=>t==="true")})});import{z as Tt}from"zod";var St,Et=m(()=>{"use strict";St=Tt.object({query:Tt.string("Query is required")})});import{z as gr}from"zod";var Tr,Rt,wt=m(()=>{"use strict";j();Tr=["csv","xlsx","json"],Rt=S.extend({format:gr.enum(Tr,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});var _t=m(()=>{"use strict"});import{z as T}from"zod";var qn,ie,In,Sr,On,Dt,Ct=m(()=>{"use strict";j();qn=T.object({columnName:T.string(),operator:T.string(),value:T.string()}),ie=["asc","desc"],In=T.object({columnName:T.string(),direction:T.enum(ie)}),Sr=T.object({limit:T.number(),total:T.number(),hasNextPage:T.boolean(),hasPreviousPage:T.boolean(),nextCursor:T.string().nullable(),prevCursor:T.string().nullable()}),On=T.object({data:T.array(T.record(T.string(),T.unknown())),meta:Sr}),Dt=T.object({db:S.shape.db,cursor:T.string().optional(),limit:T.string().optional().default("50").transform(Number),direction:T.enum(ie).optional().default(ie[0]),sort:T.string().optional().transform(t=>{if(!t)return"";try{let e=JSON.parse(t);return Array.isArray(e)?e:t}catch{return t}}),order:T.enum(ie).optional(),filters:T.string().optional().transform(t=>{if(!t)return[];try{return JSON.parse(t)}catch{return[]}})})});import{z as we}from"zod";var jn,xt=m(()=>{"use strict";jn=we.object({tableName:we.string("Table name is required"),rowCount:we.coerce.number("Row count is required")})});import{z as Nt}from"zod";var Hn,vt=m(()=>{"use strict";Hn=Nt.object({schema:Nt.string()})});import{z as q}from"zod";var At,$t=m(()=>{"use strict";At=q.object({tableName:q.string("Table name is required"),primaryKey:q.string("Primary key is required").default("id"),updates:q.array(q.object({rowData:q.record(q.string("Column name is required"),q.any()),columnName:q.string("Column name is required"),value:q.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var F=m(()=>{"use strict";Je();Xe();et();rt();at();it();Ee();mt();j();pt();dt();bt();yt();gt();Et();wt();_t();Ct();xt();vt();$t()});import{HTTPException as Er}from"hono/http-exception";import{DatabaseError as Rr}from"pg";import{ZodError as wr}from"zod";function Pt(t,e){if(t instanceof Er)return e.json({error:t.message??"Internal server error"},t.status);if(t instanceof wr){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 Rr&&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 qt,It=m(()=>{"use strict";qt=(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 _r}from"pg";var ce,Dr,_e,Ot=m(()=>{"use strict";ce=null,Dr=()=>{if(!ce){if(!process.env.DATABASE_URL)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");try{ce=new _r({connectionString:process.env.DATABASE_URL}),ce.on("error",t=>{})}catch(t){throw t}}return ce},_e=new Proxy({},{get(t,e){try{return Dr()[e]}catch(o){throw o}}})});import{Pool as Lt}from"pg";var De,kt,f,Ce,_=m(()=>{"use strict";De=class{pools=new Map;baseConfig=null;constructor(){this.initializeBaseConfig()}detectDbType(e){let o=e.protocol.replace(":","");if(o==="postgres"||o==="postgresql")return"pg";throw new Error(`Unsupported database type: ${o}. Currently only PostgreSQL is supported. Please use a PostgreSQL connection string (postgres:// or postgresql://).`)}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(o instanceof Error?o.message:String(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},n=new Lt(r);n.on("error",a=>{}),this.pools.set(o,n)}return this.pools.get(o)??new Lt({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())}},kt=new De,f=t=>kt.getPool(t),Ce=()=>kt.getDbType()});import{HTTPException as Cr}from"hono/http-exception";async function le({tableName:t,db:e}){let o=f(e),r=`
|
|
2
|
+
var Fo=Object.defineProperty;var p=(a,e)=>()=>(a&&(e=a(a=0)),e);var Uo=(a,e)=>{for(var t in e)Fo(a,t,{get:e[t],enumerable:!0})};var Ye=p(()=>{"use strict"});var Qe=p(()=>{"use strict"});var Ge=p(()=>{"use strict"});var Q,Je=p(()=>{"use strict";Q={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 Xe=p(()=>{"use strict"});var Ze,_e=p(()=>{"use strict";Ze={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:"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 et=p(()=>{"use strict"});var ce=p(()=>{"use strict";Ye();Qe();Ge();Je();Xe();_e();et()});import{z as ne}from"zod";var dt,ft=p(()=>{"use strict";dt=ne.object({tableName:ne.string("Table name is required"),data:ne.record(ne.string("Column name is required"),ne.any())})});var bt=p(()=>{"use strict"});import{z as X}from"zod";var yt,gt=p(()=>{"use strict";yt=X.object({tableName:X.string().min(1,"Table name is required"),records:X.array(X.record(X.string(),X.any())).min(1,"At least one record is required")})});import{z as Z}from"zod";var w,rr,pe,bs,ht,ee,z=p(()=>{"use strict";w=Z.object({db:Z.string("Database name is required")}),rr=["pg","mysql"],pe=Z.enum(rr,{message:"Invalid database type"}),bs=w.extend({dbType:pe}),ht=Z.object({dbType:pe}),ee=Z.object({tableName:Z.string("Table name is required")})});import{z as te}from"zod";var Tt,Et=p(()=>{"use strict";z();Tt=te.object({messages:te.array(te.object({role:te.enum(["user","assistant"]),content:te.string("Content is required")})),conversationId:te.string().optional(),db:w.shape.db})});var St=p(()=>{"use strict"});import{z as F}from"zod";var nr,sr,v,ir,lr,Ss,Le=p(()=>{"use strict";nr=["text","boolean","number","enum","json","date","array"],sr=F.enum(nr),v={text:"text",boolean:"boolean",number:"number",enum:"enum",json:"json",date:"date",array:"array"},ir=["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"],lr=F.enum(ir),Ss=F.object({columnName:F.string(),dataType:sr,dataTypeLabel:lr,isNullable:F.boolean(),columnDefault:F.string().nullable(),isPrimaryKey:F.boolean(),isForeignKey:F.boolean(),referencedTable:F.string().nullable(),referencedColumn:F.string().nullable(),enumValues:F.array(F.string()).nullable()})});function Rt(a){let e=a?.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(")?v.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"?v.number:e==="boolean"||e==="bool"?v.boolean:e==="json"||e==="jsonb"?v.json:e.startsWith("user-defined")||e==="enum"||e==="text"||e==="xml"?v.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"?v.text:v.text}function Ct(a){if(!a)return b.text;let e=a.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 wt(a,e){let t=a?.toLowerCase().trim()||"",o=e?.toLowerCase().trim()||"";return t==="tinyint"&&o==="tinyint(1)"?v.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"?v.number:t==="boolean"||t==="bool"?v.boolean:t==="date"||t==="datetime"||t==="timestamp"||t==="time"||t==="year"?v.date:t==="json"?v.json:t==="enum"||t==="set"?v.enum:v.text}function Nt(a,e){if(!a)return b.text;let t=a.toLowerCase().trim(),o=e?.toLowerCase().trim()||"";return t==="tinyint"&&o==="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}var b,Dt=p(()=>{"use strict";Le();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 _}from"zod";var cr,At,mr,ur,_t,xt=p(()=>{"use strict";cr=["CASCADE","SET NULL","SET DEFAULT","RESTRICT","NO ACTION"],At=_.enum(cr),mr=_.object({columnName:_.string("Column name is required"),columnType:_.string("Column type is required"),defaultValue:_.string().optional(),isPrimaryKey:_.boolean().default(!1),isNullable:_.boolean().default(!1),isUnique:_.boolean().default(!1),isIdentity:_.boolean().default(!1),isArray:_.boolean().default(!1)}),ur=_.object({columnName:_.string("Column name is required"),referencedTable:_.string("Referenced table is required"),referencedColumn:_.string("Referenced column is required"),onUpdate:At.default("NO ACTION"),onDelete:At.default("NO ACTION")}),_t=_.object({tableName:_.string("Table name is required"),fields:_.array(mr).min(1,"At least one field is required"),foreignKeys:_.array(ur).optional()})});import{z as L}from"zod";var pr,xs,Pt,vt=p(()=>{"use strict";z();pr=L.object({name:L.string("Name is required"),size:L.string("Size is required"),owner:L.string("Owner is required"),encoding:L.string("Encoding is required")}),xs=L.object({databases:L.array(pr),dbType:pe}),Pt=L.object({version:L.string("Version is required"),database:L.string("Database is required"),user:L.string("User is required"),host:L.string("Host is required").nullable(),port:L.number("Port is required").nullable(),active_connections:L.coerce.number("Active connections is required"),max_connections:L.coerce.number("Max connections is required")})});var Lt=p(()=>{"use strict"});import{z as H}from"zod";var $t,de,$s,Os,Ot=p(()=>{"use strict";z();$t=w.extend({cascade:H.string().optional().transform(a=>a==="true")}),de=H.object({tableName:H.string("Table name is required"),columnName:H.string("Column name is required")}),$s=H.object({db:w.shape.db,tableName:de.shape.tableName,columnName:de.shape.columnName,cascade:H.boolean().optional()}),Os=H.object({message:H.string("Message is required"),tableName:H.string("Table name is required"),columnName:H.string("Column name is required"),deletedCount:H.number("Deleted count is required").default(0)})});import{z as ae}from"zod";var $e,qt=p(()=>{"use strict";$e=ae.object({tableName:ae.string("Table name is required"),primaryKeys:ae.array(ae.object({columnName:ae.string("Column name is required"),value:ae.any()})).min(1,"At least one primary key is required")})});import{z as dr}from"zod";var It,Mt=p(()=>{"use strict";z();It=w.extend({cascade:dr.string().optional().transform(a=>a==="true")})});import{z as kt}from"zod";var Ft,Ut=p(()=>{"use strict";Ft=kt.object({query:kt.string("Query is required")})});import{z as fr}from"zod";var br,Ht,jt=p(()=>{"use strict";z();br=["csv","xlsx","json"],Ht=w.extend({format:fr.enum(br,{message:"Invalid format. Supported formats: csv, xlsx, json"})})});var Bt=p(()=>{"use strict"});import{z as C}from"zod";var Ys,fe,Qs,yr,Gs,Kt,Wt=p(()=>{"use strict";z();Ys=C.object({columnName:C.string(),operator:C.string(),value:C.string()}),fe=["asc","desc"],Qs=C.object({columnName:C.string(),direction:C.enum(fe)}),yr=C.object({limit:C.number(),total:C.number(),hasNextPage:C.boolean(),hasPreviousPage:C.boolean(),nextCursor:C.string().nullable(),prevCursor:C.string().nullable()}),Gs=C.object({data:C.array(C.record(C.string(),C.unknown())),meta:yr}),Kt=C.object({db:w.shape.db,cursor:C.string().optional(),limit:C.string().optional().default("50").transform(Number),direction:C.enum(fe).optional().default(fe[0]),sort:C.string().optional().transform(a=>{if(!a)return"";try{let e=JSON.parse(a);return Array.isArray(e)?e:a}catch{return a}}),order:C.enum(fe).optional(),filters:C.string().optional().transform(a=>{if(!a)return[];try{return JSON.parse(a)}catch{return[]}})})});import{z as Oe}from"zod";var Zs,Vt=p(()=>{"use strict";Zs=Oe.object({tableName:Oe.string("Table name is required"),rowCount:Oe.coerce.number("Row count is required")})});import{z as zt}from"zod";var ai,Yt=p(()=>{"use strict";ai=zt.object({schema:zt.string()})});import{z as B}from"zod";var Qt,Gt=p(()=>{"use strict";Qt=B.object({tableName:B.string("Table name is required"),primaryKey:B.string("Primary key is required").default("id"),updates:B.array(B.object({rowData:B.record(B.string("Column name is required"),B.any()),columnName:B.string("Column name is required"),value:B.any()},{message:"Each update must have a row data, column name, and value."})).min(1,"At least one update is required")})});var V=p(()=>{"use strict";ft();bt();gt();Et();St();Dt();Le();xt();z();vt();Lt();Ot();qt();Mt();Ut();jt();Bt();Wt();Vt();Yt();Gt()});import{HTTPException as gr}from"hono/http-exception";import{DatabaseError as hr}from"pg";import{ZodError as Tr}from"zod";function Jt(a,e){if(a instanceof gr)return e.json({error:a.message??"Internal server error"},a.status);if(a instanceof Tr){let t=a.issues[0];return e.json({error:"Validation error",details:t.message},400)}if(a instanceof Error){let t=a;if(t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"||t.code==="ETIMEDOUT"||t.code==="ER_ACCESS_DENIED_ERROR"||t.code==="ER_BAD_HOST_ERROR"||t.code==="ECONNRESET"||t.errno===1045||t.errno===2003||t.errno===2002||a.message.includes("ECONNREFUSED")||a.message.includes("connection refused")||a.message.includes("timeout expired")||a.message.includes("Connection terminated")||a instanceof hr&&a.code?.startsWith("08"))return e.json({error:"Database connection failed",details:a.message},503)}return e.json({error:a instanceof Error?a.message:"Internal server error"},500)}var Xt,Zt=p(()=>{"use strict";Xt=(a,e)=>{if(!a.success){let t=a.error?.issues[0];return e.json({error:"Validation error",details:t?.message??"Unknown validation error"},400)}}});import{Pool as Er}from"pg";var be,Sr,qe,ea=p(()=>{"use strict";be=null,Sr=()=>{if(!be){if(!process.env.DATABASE_URL)throw new Error("DATABASE_URL is not set. Please provide a database connection string.");try{be=new Er({connectionString:process.env.DATABASE_URL}),be.on("error",a=>{})}catch(a){throw a}}return be},qe=new Proxy({},{get(a,e){try{return Sr()[e]}catch(t){throw t}}})});import{createPool as Rr}from"mysql2/promise";import{Pool as ta}from"pg";var Ie,Me,T,S,ye,R=p(()=>{"use strict";Ie=class{pgPools=new Map;mysqlPools=new Map;baseConfig=null;constructor(){this.initializeBaseConfig()}detectDbType(e){let t=e.protocol.replace(":","");if(t==="postgres"||t==="postgresql")return"pg";if(t==="mysql"||t==="mysql2")return"mysql";throw new Error(`Unsupported database type: ${t}. Supported types: PostgreSQL (postgres://) and MySQL (mysql://).`)}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 t=new URL(e);this.baseConfig={url:e,host:t.hostname,port:Number.parseInt(t.port,10)||(this.detectDbType(t)==="mysql"?3306:5432),user:t.username,password:t.password,dbType:this.detectDbType(t)}}catch(t){throw new Error(t instanceof Error?t.message:String(t))}}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");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)}`)}}getPgPool(e){let t=this.buildConnectionString(e);if(!this.pgPools.has(t)){let o={connectionString:t,max:10,idleTimeoutMillis:3e4,connectionTimeoutMillis:2e3},r=new ta(o);r.on("error",n=>{}),this.pgPools.set(t,r)}return this.pgPools.get(t)??new ta({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 r=new URL(t).pathname.slice(1),n=Rr({host:this.baseConfig.host,port:this.baseConfig.port,user:this.baseConfig.user,password:this.baseConfig.password,database:r||void 0,waitForConnections:!0,connectionLimit:10,idleTimeout:3e4,connectTimeout:2e3,multipleStatements:!1});this.mysqlPools.set(t,n)}return this.mysqlPools.get(t)}getPool(e){return this.getPgPool(e)}async closePgPool(e){let t=this.pgPools.get(e);t&&(await t.end(),this.pgPools.delete(e))}async closeMysqlPool(e){let t=this.mysqlPools.get(e);t&&(await t.end(),this.mysqlPools.delete(e))}async closePool(e){await this.closePgPool(e),await this.closeMysqlPool(e)}async closePoolByDatabase(e){let t=this.buildConnectionString(e);await this.closePool(t)}async closeAll(){let e=Array.from(this.pgPools.entries()).map(async([o,r])=>{await r.end()}),t=Array.from(this.mysqlPools.entries()).map(async([o,r])=>{await r.end()});await Promise.all([...e,...t]),this.pgPools.clear(),this.mysqlPools.clear()}getActivePools(){return[...Array.from(this.pgPools.keys()),...Array.from(this.mysqlPools.keys())]}},Me=new Ie,T=a=>Me.getPgPool(a),S=a=>Me.getMysqlPool(a),ye=()=>Me.getDbType()});import{HTTPException as Cr}from"hono/http-exception";async function ge({tableName:a,db:e}){let t=T(e),o=`
|
|
3
3
|
SELECT
|
|
4
4
|
c.column_name as "columnName",
|
|
5
5
|
c.data_type as "dataType",
|
|
@@ -48,18 +48,18 @@ var zo=Object.defineProperty;var m=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ko=(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:
|
|
51
|
+
`,{rows:r}=await t.query(o,[a]);if(!r||r.length===0)throw new Cr(404,{message:`Table "${a}" does not exist`});return r.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:Rt(n.dataType),dataTypeLabel:Ct(n.dataType),isNullable:n.isNullable,columnDefault:n.columnDefault,isPrimaryKey:n.isPrimaryKey,isForeignKey:n.isForeignKey,referencedTable:n.referencedTable,referencedColumn:n.referencedColumn,enumValues:i}})}var ke=p(()=>{"use strict";V();R()});async function wr(a){let e=T(a),t=`
|
|
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:
|
|
57
|
+
`,{rows:o}=await e.query(t);return o.map(r=>r.table_name)}async function Nr(a){let e=await qe.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
|
-
`,[
|
|
62
|
+
`,[a])).rows[0]?.description||void 0}finally{e.release()}}async function Dr(a){let e=await qe.connect();try{return(await e.query(`SELECT * FROM "${a}" LIMIT 3`)).rows}catch{return[]}finally{e.release()}}function Ar(a){let e={name:a.columnName,type:a.dataTypeLabel,nullable:a.isNullable};return a.isPrimaryKey&&(e.isPrimaryKey=!0),a.isForeignKey&&a.referencedTable&&a.referencedColumn&&(e.foreignKey=`${a.referencedTable}.${a.referencedColumn}`),a.enumValues&&a.enumValues.length>0&&(e.enumValues=a.enumValues,e.description=`Enum values: ${a.enumValues.join(", ")}`),e}function _r(a){let e=[];for(let t of a)for(let o of t.columns)if(o.foreignKey){let[r,n]=o.foreignKey.split(".");e.push({fromTable:t.name,fromColumn:o.name,toTable:r,toColumn:n})}return e}async function xr(a,e={}){let{includeSampleData:t=!1,includeDescriptions:o=!0}=e;try{let n=(await wr(a)).map(async s=>{let[m,c,f]=await Promise.all([ge({tableName:s,db:a}),o?Nr(s):Promise.resolve(void 0),t?Dr(s):Promise.resolve([])]),u={name:s,columns:m.map(Ar)};return c&&(u.description=c),f.length>0&&(u.sampleData=f.map(y=>Object.fromEntries(Object.entries(y).map(([d,g])=>[d,String(g)])))),u}),i=await Promise.all(n),l=_r(i);return{dbType:"PostgreSQL",tables:i,relationships:l}}catch(r){throw new Error(`Failed to fetch database schema: ${r instanceof Error?r.message:"Unknown error"}`)}}async function aa(a){return xr(a,{includeSampleData:!0,includeDescriptions:!0})}var oa=p(()=>{"use strict";ea();R();ke()});function ra(a){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
|
|
@@ -69,15 +69,15 @@ var zo=Object.defineProperty;var m=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ko=(t,e)=>{f
|
|
|
69
69
|
- 1 sentence about expected results
|
|
70
70
|
- NO verbose explanations
|
|
71
71
|
3. Use exact table/column names from the schema
|
|
72
|
-
4. Generate valid ${
|
|
72
|
+
4. Generate valid ${a.dbType} syntax
|
|
73
73
|
5. If query is unclear, ask ONE specific clarifying question
|
|
74
74
|
6. No preamble, no apologies, get straight to the answer
|
|
75
75
|
|
|
76
76
|
**Database Context:**
|
|
77
|
-
${
|
|
77
|
+
${Pr(a)}
|
|
78
78
|
|
|
79
79
|
**Guidelines:**
|
|
80
|
-
1. Always generate syntactically correct SQL for the database type (${
|
|
80
|
+
1. Always generate syntactically correct SQL for the database type (${a.dbType})
|
|
81
81
|
2. Use proper table/column names exactly as defined in the schema
|
|
82
82
|
3. When generating queries, wrap them in \`\`\`sql code blocks
|
|
83
83
|
4. Explain what the query does in plain language
|
|
@@ -112,21 +112,21 @@ 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 Pr(a){let e=`Database Type: ${a.dbType}
|
|
116
116
|
|
|
117
117
|
`;e+=`**Tables and Columns:**
|
|
118
|
-
`;for(let
|
|
119
|
-
### ${
|
|
120
|
-
`,
|
|
118
|
+
`;for(let t of a.tables){e+=`
|
|
119
|
+
### ${t.name}
|
|
120
|
+
`,t.description&&(e+=`Description: ${t.description}
|
|
121
121
|
`),e+=`Columns:
|
|
122
|
-
`;for(let
|
|
123
|
-
`,
|
|
124
|
-
`)}
|
|
125
|
-
`,e+=`${JSON.stringify(
|
|
126
|
-
`)}if(
|
|
122
|
+
`;for(let o of t.columns){let r=o.isPrimaryKey?" [PRIMARY KEY]":"",n=o.foreignKey?` [FK -> ${o.foreignKey}]`:"",i=o.nullable?"NULL":"NOT NULL";e+=` - ${o.name}: ${o.type} ${i}${r}${n}
|
|
123
|
+
`,o.description&&(e+=` ${o.description}
|
|
124
|
+
`)}t.sampleData&&t.sampleData.length>0&&(e+=`Sample data (${t.sampleData.length} rows):
|
|
125
|
+
`,e+=`${JSON.stringify(t.sampleData.slice(0,3),null,2)}
|
|
126
|
+
`)}if(a.relationships&&a.relationships.length>0){e+=`
|
|
127
127
|
**Relationships:**
|
|
128
|
-
`;for(let
|
|
129
|
-
`}return e}var
|
|
128
|
+
`;for(let t of a.relationships)e+=` - ${t.fromTable}.${t.fromColumn} -> ${t.toTable}.${t.toColumn}
|
|
129
|
+
`}return e}var na=p(()=>{"use strict"});import{zValidator as vr}from"@hono/zod-validator";import{Hono as Lr}from"hono";var sa,ia=p(()=>{"use strict";ce();V();oa();na();sa=new Lr().basePath("/chat").post("/",vr("json",Tt),async a=>{let{messages:e,conversationId:t,db:o}=a.req.valid("json"),r=await aa(o),n=ra(r),i={messages:e,conversationId:t,systemPrompt:n},l=await fetch(`${Q.PROXY_URL}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!l.ok){let c=await l.json();return a.json({error:c.error||"Proxy request failed"},l.status)}let{readable:s,writable:m}=new TransformStream;return l.body?.pipeTo(m),new Response(s,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})})});function he(){let a=process.env.DATABASE_URL;if(!a)return{host:"localhost",port:5432};try{let e=new URL(a);return{host:e.hostname||"localhost",port:Number.parseInt(e.port,10)||5432}}catch{return{host:"localhost",port:5432}}}var Fe=p(()=>{"use strict"});import{HTTPException as Ue}from"hono/http-exception";async function la(){let a=T(),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:
|
|
138
|
+
`,{rows:t}=await a.query(e);if(!t[0])throw new Ue(500,{message:"No databases returned from database"});return t}async function ca(){let a=T(),e="SELECT current_database() as database;",{rows:t}=await a.query(e);if(!t[0])throw new Ue(500,{message:"No current database returned from database"});return t[0]}async function ma(){let a=T(),e=`
|
|
139
139
|
SELECT
|
|
140
140
|
version() as version,
|
|
141
141
|
current_database() as database,
|
|
@@ -144,15 +144,40 @@ 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:
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
`,{rows:t}=await a.query(e);if(!t[0])throw new Ue(500,{message:"No connection information returned from database"});let o=Pt.parse(t[0]),r=he();return{host:o.host||r.host,port:o.port||r.port,user:o.user,database:o.database,version:o.version.toString(),active_connections:o.active_connections,max_connections:o.max_connections}}var ua=p(()=>{"use strict";V();R();Fe()});import{HTTPException as He}from"hono/http-exception";async function pa(){let a=S(),[e]=await a.execute(`
|
|
148
|
+
SELECT
|
|
149
|
+
s.SCHEMA_NAME AS name,
|
|
150
|
+
CONCAT(
|
|
151
|
+
ROUND(
|
|
152
|
+
COALESCE(SUM(t.data_length + t.index_length), 0) / 1024 / 1024,
|
|
153
|
+
2
|
|
154
|
+
),
|
|
155
|
+
' MB'
|
|
156
|
+
) AS size,
|
|
157
|
+
CURRENT_USER() AS owner,
|
|
158
|
+
s.DEFAULT_CHARACTER_SET_NAME AS encoding
|
|
159
|
+
FROM information_schema.SCHEMATA s
|
|
160
|
+
LEFT JOIN information_schema.TABLES t
|
|
161
|
+
ON t.TABLE_SCHEMA = s.SCHEMA_NAME
|
|
162
|
+
GROUP BY s.SCHEMA_NAME, s.DEFAULT_CHARACTER_SET_NAME
|
|
163
|
+
ORDER BY s.SCHEMA_NAME
|
|
164
|
+
`);if(!e[0])throw new He(500,{message:"No databases returned from server"});return e}async function da(){let a=S(),[e]=await a.execute("SELECT DATABASE() AS db");if(!e[0])throw new He(500,{message:"No current database returned from server"});return e[0]}async function fa(){let a=S(),[e]=await a.execute(`
|
|
165
|
+
SELECT
|
|
166
|
+
VERSION() AS version,
|
|
167
|
+
DATABASE() AS database_name,
|
|
168
|
+
CURRENT_USER() AS user,
|
|
169
|
+
@@hostname AS host,
|
|
170
|
+
@@port AS port,
|
|
171
|
+
@@max_connections AS max_connections
|
|
172
|
+
`),[t]=await a.execute("SELECT COUNT(*) AS cnt FROM information_schema.PROCESSLIST");if(!e[0])throw new He(500,{message:"No connection information returned from server"});let o=e[0],r=Number(t[0]?.cnt??0),n=he();return{host:String(o.host||n.host),port:Number(o.port||n.port),user:String(o.user),database:String(o.database_name??""),version:String(o.version),active_connections:r,max_connections:Number(o.max_connections)}}var ba=p(()=>{"use strict";R();Fe()});import{Hono as $r}from"hono";var ya,ga=p(()=>{"use strict";ua();ba();R();ya=new $r().basePath("/databases").get("/",async a=>{let e=ye(),t=e==="mysql"?await pa():await la();return a.json({data:{databases:t,dbType:e}},200)}).get("/current",async a=>{let e=ye(),t=e==="mysql"?await da():await ca();return a.json({data:{db:t.db,dbType:e}},200)}).get("/connection",async a=>{let t=ye()==="mysql"?await fa():await ma();return a.json({data:t},200)})});import{HTTPException as Or}from"hono/http-exception";var ha,Ta=p(()=>{"use strict";R();ha=async({query:a,db:e})=>{let t=S(e);if(!a||!a.trim())throw new Or(400,{message:"Query is required"});let o=a.trim().replace(/;+$/,""),r=performance.now(),[n,i]=await t.execute(o),l=performance.now()-r;if(Array.isArray(n)){let m=n;return{columns:i?i.map(f=>f.name):Object.keys(m[0]??{}),rows:m,rowCount:m.length,duration:l,message:m.length===0?"OK":void 0}}let s=n;return{columns:[],rows:[],rowCount:s.affectedRows,duration:l,message:`OK \u2014 ${s.affectedRows} row(s) affected`}}});import{HTTPException as qr}from"hono/http-exception";var Ea,Sa=p(()=>{"use strict";R();Ea=async({query:a,db:e})=>{let t=T(e);if(!a||!a.trim())throw new qr(400,{message:"Query is required"});let o=a.trim().replace(/;+$/,""),r=performance.now(),n=await t.query(o),i=performance.now()-r;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 Ra}from"@hono/zod-validator";import{Hono as Ir}from"hono";var Ca,wa=p(()=>{"use strict";V();Ta();Sa();Ca=new Ir().basePath("/query").post("/",Ra("query",w),Ra("json",Ft),async a=>{let{query:e}=a.req.valid("json"),{db:t}=a.req.valid("query"),r=a.get("dbType")==="mysql"?await ha({query:e,db:t}):await Ea({query:e,db:t});return a.json({data:r},200)})});import{HTTPException as Mr}from"hono/http-exception";async function Na({db:a,params:e}){let{tableName:t,data:o}=e,r=T(a),n=Object.keys(o),i=Object.values(o),l=n.map((f,u)=>`$${u+1}`).join(", "),s=n.map(f=>`"${f}"`).join(", "),m=`
|
|
173
|
+
INSERT INTO "${t}" (${s})
|
|
174
|
+
VALUES (${l})
|
|
150
175
|
RETURNING *
|
|
151
|
-
`,
|
|
152
|
-
INSERT INTO "${
|
|
153
|
-
VALUES (${
|
|
176
|
+
`,c=await r.query(m,i);if(c.rowCount===0)throw new Mr(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:c.rowCount??0}}var Da=p(()=>{"use strict";R()});import{HTTPException as Te}from"hono/http-exception";var Aa,_a=p(()=>{"use strict";R();Aa=async({tableName:a,records:e,db:t})=>{if(!e||e.length===0)throw new Te(400,{message:"At least one record is required"});let r=await T(t).connect();try{let n=Object.keys(e[0]),i=n.map(c=>`"${c}"`).join(", "),l=0,s=0,m=[];await r.query("BEGIN");for(let c=0;c<e.length;c++){let f=e[c],u=n.map(g=>f[g]),y=n.map((g,h)=>`$${h+1}`).join(", "),d=`
|
|
177
|
+
INSERT INTO "${a}" (${i})
|
|
178
|
+
VALUES (${y})
|
|
154
179
|
RETURNING *
|
|
155
|
-
`;try{await
|
|
180
|
+
`;try{await r.query(d,u),l++}catch(g){throw new Te(500,{message:`Failed: ${g instanceof Error?g.message:String(g)}`})}}return await r.query("COMMIT"),{success:s===0,message:`Bulk insert completed: ${l} records inserted${s>0?`, ${s} failed`:""}`,successCount:l,failureCount:s,errors:m.length>0?m:void 0}}catch(n){throw await r.query("ROLLBACK"),n instanceof Te?n:new Te(500,{message:`Failed to bulk insert records into "${a}"`})}finally{r.release()}}});import{HTTPException as oe}from"hono/http-exception";async function je(a,e){return(await T(e).query(`
|
|
156
181
|
SELECT
|
|
157
182
|
tc.constraint_name,
|
|
158
183
|
tc.table_name as referencing_table,
|
|
@@ -168,45 +193,91 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
168
193
|
AND ccu.table_schema = tc.table_schema
|
|
169
194
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
170
195
|
AND ccu.table_name = $1
|
|
171
|
-
`,[
|
|
172
|
-
SELECT * FROM "${
|
|
173
|
-
WHERE "${
|
|
196
|
+
`,[a])).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 kr(a,e,t){let o=await je(a,t);if(o.length===0)return[];let r=[],n=T(t),i=new Map;for(let s of o){let m=`${s.referencingTable}.${s.referencingColumn}`;i.has(m)||i.set(m,[]),i.get(m)?.push(s)}let l=e.map(s=>s.value);for(let[s,m]of i){let c=m[0];if(!c||!e.find(g=>g.columnName===c.referencedColumn))continue;let u=l.map((g,h)=>`$${h+1}`).join(", "),y=`
|
|
197
|
+
SELECT * FROM "${c.referencingTable}"
|
|
198
|
+
WHERE "${c.referencingColumn}" IN (${u})
|
|
174
199
|
LIMIT 100
|
|
175
|
-
`,d=await
|
|
176
|
-
DELETE FROM "${
|
|
177
|
-
WHERE "${
|
|
200
|
+
`,d=await n.query(y,l);d.rows.length>0&&r.push({tableName:c.referencingTable,columnName:c.referencingColumn,constraintName:c.constraintName,records:d.rows})}return r}async function xa({tableName:a,primaryKeys:e,db:t}){let o=T(t),r=e[0]?.columnName;if(!r)throw new oe(400,{message:"Primary key column name is required"});let n=e.map(s=>s.value),i=n.map((s,m)=>`$${m+1}`).join(", "),l=`
|
|
201
|
+
DELETE FROM "${a}"
|
|
202
|
+
WHERE "${r}" IN (${i})
|
|
178
203
|
RETURNING *
|
|
179
|
-
`;try{await
|
|
180
|
-
SELECT "${
|
|
181
|
-
WHERE "${g}" IN (${
|
|
182
|
-
`,
|
|
204
|
+
`;try{await o.query("BEGIN");let s=await o.query(l,n);return await o.query("COMMIT"),{deletedCount:s.rowCount??0,fkViolation:!1,relatedRecords:[]}}catch(s){if(await o.query("ROLLBACK"),s.code==="23503")return{deletedCount:0,fkViolation:!0,relatedRecords:await kr(a,e,t)};throw s instanceof oe?s:new oe(500,{message:`Failed to delete records from "${a}"`})}}async function Pa({tableName:a,primaryKeys:e,db:t}){let o=T(t),r=e[0]?.columnName;if(!r)throw new oe(400,{message:"Primary key column name is required"});let n=e.map(i=>i.value);await o.query("BEGIN");try{let i=await je(a,t),l=0,s=new Set,m=async(d,g,h)=>{let E=await je(d,t);for(let M of E){let k=h.map((q,W)=>`$${W+1}`).join(", "),j=`
|
|
205
|
+
SELECT "${M.referencedColumn}" FROM "${d}"
|
|
206
|
+
WHERE "${g}" IN (${k})
|
|
207
|
+
`,A=(await o.query(j,h)).rows.map(({row:q})=>q[M.referencedColumn]);A.length>0&&await m(M.referencingTable,M.referencingColumn,A)}let D=h.map((M,k)=>`$${k+1}`).join(", "),x=`
|
|
183
208
|
DELETE FROM "${d}"
|
|
184
209
|
WHERE "${g}" IN (${D})
|
|
185
|
-
`,
|
|
186
|
-
DELETE FROM "${
|
|
187
|
-
WHERE "${
|
|
210
|
+
`,U=await o.query(x,h);l+=U.rowCount??0,s.add(d)};for(let d of i)s.has(d.referencingTable)||await m(d.referencingTable,d.referencingColumn,n);let c=n.map((d,g)=>`$${g+1}`).join(", "),f=`
|
|
211
|
+
DELETE FROM "${a}"
|
|
212
|
+
WHERE "${r}" IN (${c})
|
|
188
213
|
RETURNING *
|
|
189
|
-
`,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
214
|
+
`,u=await o.query(f,n);return await o.query("COMMIT"),{deletedCount:(u.rowCount??0)+l}}catch(i){throw await o.query("ROLLBACK"),i instanceof oe?i:new oe(500,{message:`Failed to force delete records from "${a}"`})}}var va=p(()=>{"use strict";R()});import{HTTPException as Fr}from"hono/http-exception";function Ur(a){let e=a.match(/^(?:enum|set)\((.+)\)$/i);return e?.[1]?e[1].split(",").map(t=>t.trim().replace(/^'|'$/g,"")):null}async function Y({tableName:a,db:e}){let t=S(e),o=`
|
|
215
|
+
SELECT
|
|
216
|
+
c.COLUMN_NAME AS columnName,
|
|
217
|
+
c.DATA_TYPE AS dataType,
|
|
218
|
+
c.COLUMN_TYPE AS columnType,
|
|
219
|
+
(c.IS_NULLABLE = 'YES') AS isNullable,
|
|
220
|
+
c.COLUMN_DEFAULT AS columnDefault,
|
|
221
|
+
(c.COLUMN_KEY = 'PRI') AS isPrimaryKey,
|
|
222
|
+
(kcu.REFERENCED_TABLE_NAME IS NOT NULL) AS isForeignKey,
|
|
223
|
+
kcu.REFERENCED_TABLE_NAME AS referencedTable,
|
|
224
|
+
kcu.REFERENCED_COLUMN_NAME AS referencedColumn
|
|
225
|
+
FROM information_schema.COLUMNS c
|
|
226
|
+
LEFT JOIN information_schema.KEY_COLUMN_USAGE kcu
|
|
227
|
+
ON c.TABLE_SCHEMA = kcu.TABLE_SCHEMA
|
|
228
|
+
AND c.TABLE_NAME = kcu.TABLE_NAME
|
|
229
|
+
AND c.COLUMN_NAME = kcu.COLUMN_NAME
|
|
230
|
+
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
231
|
+
WHERE c.TABLE_SCHEMA = DATABASE()
|
|
232
|
+
AND c.TABLE_NAME = ?
|
|
233
|
+
ORDER BY c.ORDINAL_POSITION
|
|
234
|
+
`,[r]=await t.execute(o,[a]);if(!r||r.length===0)throw new Fr(404,{message:`Table "${a}" does not exist`});return r.map(n=>{let i=n.dataType,l=n.columnType,m=i==="enum"||i==="set"?Ur(l):null;return{columnName:n.columnName,dataType:wt(i,l),dataTypeLabel:Nt(i,l),isNullable:!!n.isNullable,columnDefault:n.columnDefault??null,isPrimaryKey:!!n.isPrimaryKey,isForeignKey:!!n.isForeignKey,referencedTable:n.referencedTable??null,referencedColumn:n.referencedColumn??null,enumValues:m}})}var se=p(()=>{"use strict";V();R()});import{HTTPException as Hr}from"hono/http-exception";async function La({db:a,params:e}){let{tableName:t,data:o}=e,r=S(a),n=await Y({tableName:t,db:a}),i=new Set(n.filter(y=>y.dataTypeLabel==="boolean").map(y=>y.columnName)),l=Object.keys(o),s=Object.values(o).map((y,d)=>{let g=l[d];return i.has(g)&&typeof y=="string"?y==="true"?1:0:y}),m=l.map(()=>"?").join(", "),c=l.map(y=>`\`${y}\``).join(", "),f=`
|
|
235
|
+
INSERT INTO \`${t}\` (${c})
|
|
236
|
+
VALUES (${m})
|
|
237
|
+
`,[u]=await r.execute(f,s);if(u.affectedRows===0)throw new Hr(500,{message:`Failed to insert record into "${t}"`});return{insertedCount:u.affectedRows}}var $a=p(()=>{"use strict";R();se()});import{HTTPException as Ee}from"hono/http-exception";var Oa,qa=p(()=>{"use strict";R();se();Oa=async({tableName:a,records:e,db:t})=>{if(!e||e.length===0)throw new Ee(400,{message:"At least one record is required"});let r=await S(t).getConnection();try{let n=Object.keys(e[0]),i=n.map(m=>`\`${m}\``).join(", "),l=await Y({tableName:a,db:t}),s=new Set(l.filter(m=>m.dataTypeLabel==="boolean").map(m=>m.columnName));await r.beginTransaction();for(let m=0;m<e.length;m++){let c=e[m],f=n.map(d=>{let g=c[d];return s.has(d)&&typeof g=="string"?g==="true"?1:0:g}),u=n.map(()=>"?").join(", "),y=`
|
|
238
|
+
INSERT INTO \`${a}\` (${i})
|
|
239
|
+
VALUES (${u})
|
|
240
|
+
`;try{await r.execute(y,f)}catch(d){throw new Ee(500,{message:`Failed to insert record ${m+1}: ${d instanceof Error?d.message:String(d)}`})}}return await r.commit(),{success:!0,message:`Successfully inserted ${e.length} record${e.length!==1?"s":""}`,successCount:e.length,failureCount:0}}catch(n){throw await r.rollback(),n instanceof Ee?n:new Ee(500,{message:`Failed to bulk insert records into "${a}"`})}finally{r.release()}}});import{HTTPException as re}from"hono/http-exception";async function Be(a,e){let t=S(e),[o]=await t.execute(`SELECT
|
|
241
|
+
kcu.CONSTRAINT_NAME AS constraint_name,
|
|
242
|
+
kcu.TABLE_NAME AS referencing_table,
|
|
243
|
+
kcu.COLUMN_NAME AS referencing_column,
|
|
244
|
+
kcu.REFERENCED_TABLE_NAME AS referenced_table,
|
|
245
|
+
kcu.REFERENCED_COLUMN_NAME AS referenced_column
|
|
246
|
+
FROM information_schema.KEY_COLUMN_USAGE kcu
|
|
247
|
+
JOIN information_schema.TABLE_CONSTRAINTS tc
|
|
248
|
+
ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
|
|
249
|
+
AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
|
|
250
|
+
AND kcu.TABLE_NAME = tc.TABLE_NAME
|
|
251
|
+
WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
|
252
|
+
AND kcu.TABLE_SCHEMA = DATABASE()
|
|
253
|
+
AND kcu.REFERENCED_TABLE_NAME = ?`,[a]);return o.map(r=>({constraintName:r.constraint_name,referencingTable:r.referencing_table,referencingColumn:r.referencing_column,referencedTable:r.referenced_table,referencedColumn:r.referenced_column}))}async function Br(a,e,t){let o=await Be(a,t);if(o.length===0)return[];let r=[],n=S(t),i=e.map(s=>s.value),l=new Map;for(let s of o){let m=`${s.referencingTable}.${s.referencingColumn}`;l.has(m)||l.set(m,[]),l.get(m)?.push(s)}for(let[s,m]of l){let c=m[0];if(!c||!e.find(d=>d.columnName===c.referencedColumn))continue;let u=i.map(()=>"?").join(", "),[y]=await n.execute(`SELECT * FROM \`${c.referencingTable}\`
|
|
254
|
+
WHERE \`${c.referencingColumn}\` IN (${u})
|
|
255
|
+
LIMIT 100`,i);y.length>0&&r.push({tableName:c.referencingTable,columnName:c.referencingColumn,constraintName:c.constraintName,records:y})}return r}async function Ia({tableName:a,primaryKeys:e,db:t}){let o=S(t),r=e[0]?.columnName;if(!r)throw new re(400,{message:"Primary key column name is required"});let n=e.map(s=>s.value),i=n.map(()=>"?").join(", "),l=await o.getConnection();await l.beginTransaction();try{let[s]=await l.execute(`DELETE FROM \`${a}\` WHERE \`${r}\` IN (${i})`,n);return await l.commit(),{deletedCount:s.affectedRows,fkViolation:!1,relatedRecords:[]}}catch(s){if(await l.rollback(),s.errno===jr)return{deletedCount:0,fkViolation:!0,relatedRecords:await Br(a,e,t)};throw s instanceof re?s:new re(500,{message:`Failed to delete records from "${a}"`})}finally{l.release()}}async function Ma({tableName:a,primaryKeys:e,db:t}){let o=S(t),r=e[0]?.columnName;if(!r)throw new re(400,{message:"Primary key column name is required"});let n=e.map(l=>l.value),i=await o.getConnection();await i.beginTransaction();try{await i.execute("SET FOREIGN_KEY_CHECKS = 0");let l=await Be(a,t),s=0,m=new Set,c=new Set,f=async(d,g,h,E)=>{let D=`${d}.${g}`;if(E.has(D))return;E.add(D);let x=await Be(d,t);for(let k of x){let j=h.map(()=>"?").join(", "),[O]=await i.execute(`SELECT \`${k.referencedColumn}\` FROM \`${d}\`
|
|
256
|
+
WHERE \`${g}\` IN (${j})`,h),A=O.map(q=>q[k.referencedColumn]);A.length>0&&await f(k.referencingTable,k.referencingColumn,A,E)}let U=h.map(()=>"?").join(", "),[M]=await i.execute(`DELETE FROM \`${d}\` WHERE \`${g}\` IN (${U})`,h);s+=M.affectedRows,m.add(d)};for(let d of l)m.has(d.referencingTable)||await f(d.referencingTable,d.referencingColumn,n,c);let u=n.map(()=>"?").join(", "),[y]=await i.execute(`DELETE FROM \`${a}\` WHERE \`${r}\` IN (${u})`,n);return await i.execute("SET FOREIGN_KEY_CHECKS = 1"),await i.commit(),{deletedCount:y.affectedRows+s}}catch(l){throw await i.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{}),await i.rollback(),l instanceof re?l:new re(500,{message:`Failed to force delete records from "${a}"`})}finally{i.release()}}var jr,ka=p(()=>{"use strict";R();jr=1451});import{HTTPException as Se}from"hono/http-exception";async function Fa({params:a,db:e}){let{tableName:t,updates:o,primaryKey:r}=a,n=S(e),i=await Y({tableName:t,db:e}),l=new Set(i.filter(c=>c.dataTypeLabel==="boolean").map(c=>c.columnName)),s=new Map;for(let c of o){let f=c.rowData[r];if(f==null)throw new Se(400,{message:`Primary key "${r}" not found in row data.`});s.has(f)||s.set(f,[]),s.get(f)?.push({columnName:c.columnName,value:c.value,rowData:c.rowData})}let m=await n.getConnection();await m.beginTransaction();try{let c=0;for(let[f,u]of s.entries()){let y=u.map(E=>`\`${E.columnName}\` = ?`),d=u.map(E=>E.value!==null&&typeof E.value=="object"?JSON.stringify(E.value):l.has(E.columnName)&&typeof E.value=="string"?E.value==="true"?1:0:E.value);d.push(f);let g=`
|
|
257
|
+
UPDATE \`${t}\`
|
|
258
|
+
SET ${y.join(", ")}
|
|
259
|
+
WHERE \`${r}\` = ?
|
|
260
|
+
`,[h]=await m.execute(g,d);if(h.affectedRows===0)throw new Se(404,{message:`Record with ${r} = ${f} not found in table "${t}"`});c+=h.affectedRows}return await m.commit(),{updatedCount:c}}catch(c){throw await m.rollback(),c instanceof Se?c:new Se(500,{message:`Failed to update records in "${t}"`})}finally{m.release()}}var Ua=p(()=>{"use strict";R();se()});import{HTTPException as Re}from"hono/http-exception";async function Ha({params:a,db:e}){let{tableName:t,updates:o,primaryKey:r}=a,n=T(e),i=new Map;for(let l of o){let s=l.rowData[r];if(s==null)throw new Re(400,{message:`Primary key "${r}" not found in row data. Please ensure the row has a "${r}" column.`});i.has(s)||i.set(s,[]),i.get(s)?.push({columnName:l.columnName,value:l.value,rowData:l.rowData})}await n.query("BEGIN");try{let l=0;for(let[s,m]of i.entries()){let c=m.map((d,g)=>`"${d.columnName}" = $${g+1}`),f=m.map(d=>d.value!==null&&typeof d.value=="object"?JSON.stringify(d.value):d.value);f.push(s);let u=`
|
|
261
|
+
UPDATE "${t}"
|
|
262
|
+
SET ${c.join(", ")}
|
|
263
|
+
WHERE "${r}" = $${f.length}
|
|
193
264
|
RETURNING *
|
|
194
|
-
`,
|
|
195
|
-
CREATE TABLE "${
|
|
265
|
+
`,y=await n.query(u,f);if(y.rowCount===0)throw new Re(404,{message:`Record with ${r} = ${s} not found in table "${t}"`});l+=y.rowCount??0}return await n.query("COMMIT"),{updatedCount:l}}catch(l){throw await n.query("ROLLBACK"),l instanceof Re?l:new Re(500,{message:`Failed to update records in "${t}"`})}}var ja=p(()=>{"use strict";R()});import{zValidator as K}from"@hono/zod-validator";import{Hono as Kr}from"hono";var Ba,Ka=p(()=>{"use strict";V();Da();_a();va();$a();qa();ka();Ua();ja();Ba=new Kr().basePath("/records").post("/",K("query",w),K("json",dt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,data:o}=a.req.valid("json"),r=a.get("dbType"),{insertedCount:n}=r==="mysql"?await La({db:e,params:{tableName:t,data:o}}):await Na({db:e,params:{tableName:t,data:o}});return a.json({data:`Record inserted into "${t}" with ${n} rows inserted`},200)}).patch("/",K("query",w),K("json",Qt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKey:o,updates:r}=a.req.valid("json"),n=a.get("dbType"),{updatedCount:i}=n==="mysql"?await Fa({params:{tableName:t,primaryKey:o,updates:r},db:e}):await Ha({params:{tableName:t,primaryKey:o,updates:r},db:e});return a.json({data:`Updated ${i} records in "${t}"`},200)}).delete("/",K("query",w),K("json",$e),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:o}=a.req.valid("json"),r=a.get("dbType"),{deletedCount:n,fkViolation:i,relatedRecords:l}=r==="mysql"?await Ia({tableName:t,primaryKeys:o,db:e}):await xa({tableName:t,primaryKeys:o,db:e});return i?a.json({data:{deletedCount:0,fkViolation:!0,relatedRecords:l}},409):a.json({data:{deletedCount:n,fkViolation:!1,relatedRecords:[]}},200)}).delete("/force",K("query",w),K("json",$e),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,primaryKeys:o}=a.req.valid("json"),n=a.get("dbType")==="mysql"?await Ma({tableName:t,primaryKeys:o,db:e}):await Pa({tableName:t,primaryKeys:o,db:e});return a.json({data:n},200)}).post("/bulk",K("query",w),K("json",yt),async a=>{let{db:e}=a.req.valid("query"),{tableName:t,records:o}=a.req.valid("json"),n=a.get("dbType")==="mysql"?await Oa({tableName:t,records:o,db:e}):await Aa({tableName:t,records:o,db:e});return a.json({data:n},200)})});async function Wa({tableData:a,db:e}){let{tableName:t,fields:o,foreignKeys:r}=a,n=T(e),i=o.map(c=>{let f=`"${c.columnName}" ${c.columnType}`;return c.isArray&&(f+="[]"),c.isPrimaryKey&&(f+=" PRIMARY KEY"),c.isUnique&&!c.isPrimaryKey&&(f+=" UNIQUE"),c.isNullable||(f+=" NOT NULL"),c.isIdentity&&(f+=" GENERATED ALWAYS AS IDENTITY"),c.defaultValue&&!c.isIdentity&&(f+=` DEFAULT ${c.defaultValue}`),f}),l=r?.map(c=>`CONSTRAINT "${`fk_${t}_${c.columnName}_${c.referencedTable}_${c.referencedColumn}`}" FOREIGN KEY ("${c.columnName}") REFERENCES "${c.referencedTable}" ("${c.referencedColumn}") ON UPDATE ${c.onUpdate} ON DELETE ${c.onDelete}`)||[],s=[...i,...l],m=`
|
|
266
|
+
CREATE TABLE "${t}" (
|
|
196
267
|
${s.join(`,
|
|
197
268
|
`)}
|
|
198
269
|
);
|
|
199
|
-
`;await
|
|
270
|
+
`;await n.query(m)}var Va=p(()=>{"use strict";R()});import{HTTPException as za}from"hono/http-exception";async function Ya(a){let{tableName:e,columnName:t,cascade:o,db:r}=a,n=T(r),i=`
|
|
200
271
|
SELECT EXISTS (
|
|
201
272
|
SELECT 1 FROM information_schema.tables
|
|
202
273
|
WHERE table_name = $1 AND table_schema = 'public'
|
|
203
274
|
) as exists;
|
|
204
|
-
`,{rows:
|
|
275
|
+
`,{rows:l}=await n.query(i,[e]);if(!l[0]?.exists)throw new za(404,{message:`Table "${e}" does not exist`});let s=`
|
|
205
276
|
SELECT EXISTS (
|
|
206
277
|
SELECT 1 FROM information_schema.columns
|
|
207
278
|
WHERE table_name = $1 AND column_name = $2 AND table_schema = 'public'
|
|
208
279
|
) as exists;
|
|
209
|
-
`,{rows:
|
|
280
|
+
`,{rows:m}=await n.query(s,[e,t]);if(!m[0]?.exists)throw new za(404,{message:`Column "${t}" does not exist in table "${e}"`});let f=`ALTER TABLE "${e}" DROP COLUMN "${t}" ${o?"CASCADE":"RESTRICT"}`,{rowCount:u}=await n.query(f);return{deletedCount:u??0}}var Qa=p(()=>{"use strict";R()});import{HTTPException as Ke}from"hono/http-exception";async function Wr(a,e){return(await T(e).query(`
|
|
210
281
|
SELECT
|
|
211
282
|
tc.constraint_name,
|
|
212
283
|
tc.table_name as referencing_table,
|
|
@@ -222,26 +293,63 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
222
293
|
AND ccu.table_schema = tc.table_schema
|
|
223
294
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
224
295
|
AND ccu.table_name = $1
|
|
225
|
-
`,[
|
|
226
|
-
SELECT * FROM "${
|
|
296
|
+
`,[a])).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 Ga(a,e){let t=await Wr(a,e);if(t.length===0)return[];let o=[],r=T(e);for(let n of t){let i=`
|
|
297
|
+
SELECT * FROM "${n.referencingTable}"
|
|
227
298
|
LIMIT 100
|
|
228
|
-
`,
|
|
299
|
+
`,l=await r.query(i);l.rows.length>0&&o.push({tableName:n.referencingTable,columnName:n.referencingColumn,constraintName:n.constraintName,records:l.rows})}return o}async function Vr(a,e){let o=await T(e).query(`SELECT COUNT(*) as count FROM "${a}"`);return Number.parseInt(o.rows[0]?.count??"0",10)}async function Ja(a){let{tableName:e,db:t,cascade:o}=a,r=T(t),n=`
|
|
229
300
|
SELECT EXISTS (
|
|
230
301
|
SELECT 1 FROM information_schema.tables
|
|
231
302
|
WHERE table_name = $1 AND table_schema = 'public'
|
|
232
303
|
) as exists;
|
|
233
|
-
`,{rows:i}=await
|
|
304
|
+
`,{rows:i}=await r.query(n,[e]);if(!i[0]?.exists)throw new Ke(404,{message:`Table "${e}" does not exist`});let l=await Vr(e,t);if(!o){let s=await Ga(e,t);if(s.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:s}}try{let m=`DROP TABLE "${e}" ${o?"CASCADE":"RESTRICT"}`;return await r.query(m),{deletedCount:l,fkViolation:!1,relatedRecords:[]}}catch(s){if(s.code==="2BP01")return{deletedCount:0,fkViolation:!0,relatedRecords:await Ga(e,t)};throw s instanceof Ke?s:new Ke(500,{message:`Failed to delete table "${e}"`})}}var Xa=p(()=>{"use strict";R()});import{HTTPException as zr}from"hono/http-exception";async function Za({tableName:a,db:e}){let t=T(e),{rows:o}=await t.query(`SELECT * FROM "${a}"`);if(!o||o.length===0)throw new zr(404,{message:`Table "${a}" does not exist or has no data`});return{cols:Object.keys(o[0]),rows:o}}var eo=p(()=>{"use strict";R()});function Yr(a,e){let t=a.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)":`(${a.trim()})`:t==="null"?"NULL":t==="true"||t==="false"?t==="true"?"1":"0":a.trim()}function Qr(a,e){if(e)return"JSON";let t=a.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]||a.toUpperCase()}async function to({tableData:a,db:e}){let{tableName:t,fields:o,foreignKeys:r}=a,n=S(e),i=o.map(u=>{let y=Qr(u.columnType,u.isArray??!1),d=`\`${u.columnName}\` ${y}`;if(!u.isNullable&&!u.isPrimaryKey&&(d+=" NOT NULL"),u.defaultValue&&!y.includes("AUTO_INCREMENT")){let g=Yr(u.defaultValue,y);g!==null&&(d+=` DEFAULT ${g}`)}return u.isIdentity&&!y.includes("AUTO_INCREMENT")&&(d+=" AUTO_INCREMENT"),d}),l=o.filter(u=>u.isPrimaryKey),s=[];if(l.length>0){let u=l.map(y=>`\`${y.columnName}\``).join(", ");s.push(`PRIMARY KEY (${u})`)}for(let u of o)u.isUnique&&!u.isPrimaryKey&&s.push(`UNIQUE KEY \`uq_${t}_${u.columnName}\` (\`${u.columnName}\`)`);let m=r?.map(u=>`CONSTRAINT \`${`fk_${t}_${u.columnName}_${u.referencedTable}_${u.referencedColumn}`}\` FOREIGN KEY (\`${u.columnName}\`) REFERENCES \`${u.referencedTable}\` (\`${u.referencedColumn}\`) ON UPDATE ${u.onUpdate} ON DELETE ${u.onDelete}`)||[],c=[...i,...s,...m],f=`
|
|
305
|
+
CREATE TABLE \`${t}\` (
|
|
306
|
+
${c.join(`,
|
|
307
|
+
`)}
|
|
308
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
309
|
+
`;await n.execute(f)}var ao=p(()=>{"use strict";R()});import{HTTPException as oo}from"hono/http-exception";async function ro(a){let{tableName:e,columnName:t,db:o}=a,r=S(o),[n]=await r.execute(`SELECT COUNT(*) as cnt
|
|
310
|
+
FROM information_schema.TABLES
|
|
311
|
+
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,[e]);if(!(Number(n[0]?.cnt??0)>0))throw new oo(404,{message:`Table "${e}" does not exist`});let[l]=await r.execute(`SELECT COUNT(*) as cnt
|
|
312
|
+
FROM information_schema.COLUMNS
|
|
313
|
+
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,[e,t]);if(!(Number(l[0]?.cnt??0)>0))throw new oo(404,{message:`Column "${t}" does not exist in table "${e}"`});let[m]=await r.execute(`ALTER TABLE \`${e}\` DROP COLUMN \`${t}\``);return{deletedCount:m.affectedRows}}var no=p(()=>{"use strict";R()});import{HTTPException as We}from"hono/http-exception";async function Xr(a,e){let t=S(e),[o]=await t.execute(`SELECT
|
|
314
|
+
kcu.CONSTRAINT_NAME AS constraint_name,
|
|
315
|
+
kcu.TABLE_NAME AS referencing_table,
|
|
316
|
+
kcu.COLUMN_NAME AS referencing_column,
|
|
317
|
+
kcu.REFERENCED_TABLE_NAME AS referenced_table,
|
|
318
|
+
kcu.REFERENCED_COLUMN_NAME AS referenced_column
|
|
319
|
+
FROM information_schema.KEY_COLUMN_USAGE kcu
|
|
320
|
+
JOIN information_schema.TABLE_CONSTRAINTS tc
|
|
321
|
+
ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
|
|
322
|
+
AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
|
|
323
|
+
AND kcu.TABLE_NAME = tc.TABLE_NAME
|
|
324
|
+
WHERE tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
|
325
|
+
AND kcu.TABLE_SCHEMA = DATABASE()
|
|
326
|
+
AND kcu.REFERENCED_TABLE_NAME = ?`,[a]);return o.map(r=>({constraintName:r.constraint_name,referencingTable:r.referencing_table,referencingColumn:r.referencing_column,referencedTable:r.referenced_table,referencedColumn:r.referenced_column}))}async function so(a,e){let t=await Xr(a,e);if(t.length===0)return[];let o=[],r=S(e);for(let n of t){let[i]=await r.execute(`SELECT * FROM \`${n.referencingTable}\` LIMIT 100`);i.length>0&&o.push({tableName:n.referencingTable,columnName:n.referencingColumn,constraintName:n.constraintName,records:i})}return o}async function Zr(a,e){let t=S(e),[o]=await t.execute(`SELECT COUNT(*) as count FROM \`${a}\``);return Number(o[0]?.count??0)}async function io(a){let{tableName:e,db:t,cascade:o}=a,r=S(t),[n]=await r.execute(`SELECT COUNT(*) as cnt
|
|
327
|
+
FROM information_schema.TABLES
|
|
328
|
+
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,[e]);if(!(Number(n[0]?.cnt??0)>0))throw new We(404,{message:`Table "${e}" does not exist`});let l=await Zr(e,t);if(!o){let s=await so(e,t);if(s.length>0)return{deletedCount:0,fkViolation:!0,relatedRecords:s}}try{if(o){let s=await r.getConnection();try{await s.execute("SET FOREIGN_KEY_CHECKS = 0"),await s.execute(`DROP TABLE \`${e}\``),await s.execute("SET FOREIGN_KEY_CHECKS = 1")}finally{s.release()}}else await r.execute(`DROP TABLE \`${e}\``);return{deletedCount:l,fkViolation:!1,relatedRecords:[]}}catch(s){await r.execute("SET FOREIGN_KEY_CHECKS = 1").catch(()=>{});let m=s;if(m.errno===Gr||m.errno===Jr)return{deletedCount:0,fkViolation:!0,relatedRecords:await so(e,t)};throw s instanceof We?s:new We(500,{message:`Failed to delete table "${e}"`})}}var Gr,Jr,lo=p(()=>{"use strict";R();Gr=1217,Jr=1451});import{HTTPException as en}from"hono/http-exception";async function co({tableName:a,db:e}){let t=S(e),[o]=await t.execute(`SELECT * FROM \`${a}\``);if(!o||o.length===0)throw new en(404,{message:`Table "${a}" does not exist or has no data`});return{cols:Object.keys(o[0]),rows:o}}var mo=p(()=>{"use strict";R()});async function uo(a){let e=S(a),t=`
|
|
329
|
+
SELECT table_name as tableName
|
|
330
|
+
FROM information_schema.tables
|
|
331
|
+
WHERE table_schema = DATABASE()
|
|
332
|
+
AND table_type = 'BASE TABLE'
|
|
333
|
+
ORDER BY table_name
|
|
334
|
+
`,[o]=await e.execute(t);return!o||o.length===0?[]:await Promise.all(o.map(async n=>{let[i]=await e.execute(`SELECT COUNT(*) as count FROM \`${n.tableName}\``),l=i[0];return{tableName:n.tableName,rowCount:l?.count??0}}))}var po=p(()=>{"use strict";R()});import{HTTPException as fo}from"hono/http-exception";async function bo({tableName:a,db:e}){let t=S(e),[o]=await t.execute(`SELECT COUNT(*) as cnt
|
|
335
|
+
FROM information_schema.TABLES
|
|
336
|
+
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?`,[a]);if(!(Number(o[0]?.cnt??0)>0))throw new fo(404,{message:`Table "${a}" does not exist`});let[n]=await t.execute(`SHOW CREATE TABLE \`${a}\``),i=n[0],l=i?.["Create Table"]??i?.create_table??"";if(!l)throw new fo(500,{message:`Failed to retrieve schema for table "${a}"`});return l}var yo=p(()=>{"use strict";R()});function go(a){if(a.length===0)return{clause:"",values:[]};let e=[],t=[];for(let o of a){let r=`\`${o.columnName}\``;switch(o.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${r} ${o.operator} ?`),t.push(o.value);break;case"is":o.value.toLowerCase()==="null"?e.push(`${r} IS NULL`):(e.push(`${r} = ?`),t.push(o.value));break;case"is not":o.value.toLowerCase()==="null"?e.push(`${r} IS NOT NULL`):(e.push(`${r} != ?`),t.push(o.value));break;case"like":case"ilike":e.push(`${r} LIKE ?`),t.push(o.value);break;case"not like":case"not ilike":e.push(`${r} NOT LIKE ?`),t.push(o.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function ho(a,e){return Array.isArray(a)?a.length===0?"":`ORDER BY ${a.map(o=>`\`${o.columnName}\` ${o.direction.toUpperCase()}`).join(", ")}`:a&&typeof a=="string"?`ORDER BY \`${a}\` ${e?.toUpperCase()||"ASC"}`:""}function To(a,e,t){let{values:o,sortColumns:r}=a,n=[],i=[],m=t==="asc"===(e==="asc");if(r.length>0){let c=r.map(y=>`\`${y}\``).join(", "),f=r.map(()=>"?").join(", "),u=m?">":"<";n.push(`(${c}) ${u} (${f})`);for(let y of r)i.push(o[y])}return{clause:n.length>0?`(${n.join(" AND ")})`:"",values:i}}var Eo=p(()=>{"use strict"});var Ce,tn,an,So,Ro=p(()=>{"use strict";R();Eo();Ce=a=>Buffer.from(JSON.stringify(a)).toString("base64url"),tn=a=>{try{return JSON.parse(Buffer.from(a,"base64url").toString("utf-8"))}catch{return null}},an=async(a,e)=>{let[t]=await a.execute(`SELECT COLUMN_NAME as column_name
|
|
337
|
+
FROM information_schema.COLUMNS
|
|
338
|
+
WHERE TABLE_SCHEMA = DATABASE()
|
|
339
|
+
AND TABLE_NAME = ?
|
|
340
|
+
AND COLUMN_KEY = 'PRI'
|
|
341
|
+
ORDER BY ORDINAL_POSITION`,[e]);return t.map(o=>o.column_name)},So=async({tableName:a,cursor:e="",limit:t=50,direction:o="asc",sort:r=[],order:n="asc",filters:i=[],db:l})=>{let s=S(l),m=await an(s,a),c=[],f=n;Array.isArray(r)&&r.length>0?(c=r.map(P=>P.columnName),f=r[0].direction):typeof r=="string"&&r&&(c=[r]);let u=[...c,...m.filter(P=>!c.includes(P))],{clause:y,values:d}=go(i),g="",h=[];if(e){let P=tn(e);if(P){let N=To(P,o,f);g=N.clause,h=N.values}}let E="";y&&g?E=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${g}`:y?E=y:g&&(E=`WHERE ${g}`);let D=ho((Array.isArray(r),r),n),x=D;o==="desc"?D?x=D.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):u.length>0&&(x=`ORDER BY ${u.map(N=>`\`${N}\` ${f==="asc"?"DESC":"ASC"}`).join(", ")}`):!D&&u.length>0&&(x=`ORDER BY ${u.map(N=>`\`${N}\` ${f.toUpperCase()}`).join(", ")}`);let[U]=await s.execute(`SELECT COUNT(*) as total FROM \`${a}\` ${y}`,d),M=Number(U[0]?.total??0),k=Math.floor(t)+1,[j]=await s.execute(`SELECT * FROM \`${a}\` ${E} ${x} LIMIT ${k}`,[...d,...h]),O=j,A=O.length>t;A&&(O=O.slice(0,t)),o==="desc"&&(O=O.reverse());let q=null,W=null;if(O.length>0&&u.length>0){let P=O[0],N=O[O.length-1],I=G=>({values:Object.fromEntries(u.map(le=>[le,G[le]])),sortColumns:u});o==="asc"?(A&&(q=Ce(I(N))),e&&(W=Ce(I(P)))):(e&&(q=Ce(I(N))),A&&(W=Ce(I(P))))}return{data:O,meta:{limit:t,total:M,hasNextPage:o==="asc"?A:!!e,hasPreviousPage:o==="asc"?!!e:A,nextCursor:q,prevCursor:W}}}});import{HTTPException as on}from"hono/http-exception";async function Co(a){let e=T(a),t=`
|
|
234
342
|
SELECT table_name as "tableName"
|
|
235
343
|
FROM information_schema.tables
|
|
236
344
|
WHERE table_schema = 'public'
|
|
237
345
|
AND table_type = 'BASE TABLE'
|
|
238
346
|
ORDER BY table_name;
|
|
239
|
-
`,{rows:
|
|
347
|
+
`,{rows:o}=await e.query(t);if(!o[0])throw new on(500,{message:"No tables returned from database"});return await Promise.all(o.map(async n=>{let i=`SELECT COUNT(*)::integer as count FROM "${n.tableName}"`,{rows:l}=await e.query(i);return{tableName:n.tableName,rowCount:l[0]?.count??0}}))}var wo=p(()=>{"use strict";R()});import{HTTPException as rn}from"hono/http-exception";async function No({tableName:a,db:e}){let t=T(e),o=`
|
|
240
348
|
SELECT EXISTS (
|
|
241
349
|
SELECT 1 FROM information_schema.tables
|
|
242
350
|
WHERE table_schema = 'public' AND table_name = $1
|
|
243
351
|
) as exists
|
|
244
|
-
`,{rows:
|
|
352
|
+
`,{rows:r}=await t.query(o,[a]);if(!r[0]?.exists)throw new rn(404,{message:`Table "${a}" does not exist`});let n=`
|
|
245
353
|
SELECT
|
|
246
354
|
column_name,
|
|
247
355
|
data_type,
|
|
@@ -254,7 +362,7 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
254
362
|
FROM information_schema.columns
|
|
255
363
|
WHERE table_schema = 'public' AND table_name = $1
|
|
256
364
|
ORDER BY ordinal_position
|
|
257
|
-
`,{rows:i}=await
|
|
365
|
+
`,{rows:i}=await t.query(n,[a]),l=`
|
|
258
366
|
SELECT
|
|
259
367
|
tc.constraint_name,
|
|
260
368
|
tc.constraint_type,
|
|
@@ -271,7 +379,7 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
271
379
|
AND tc.constraint_type = 'FOREIGN KEY'
|
|
272
380
|
WHERE tc.table_schema = 'public' AND tc.table_name = $1
|
|
273
381
|
ORDER BY tc.constraint_type, tc.constraint_name
|
|
274
|
-
`,{rows:s}=await
|
|
382
|
+
`,{rows:s}=await t.query(l,[a]),m=`
|
|
275
383
|
SELECT indexname, indexdef
|
|
276
384
|
FROM pg_indexes
|
|
277
385
|
WHERE schemaname = 'public' AND tablename = $1
|
|
@@ -280,11 +388,11 @@ This will return the 5 customers with the highest total order value. You might a
|
|
|
280
388
|
FROM information_schema.table_constraints
|
|
281
389
|
WHERE table_schema = 'public' AND table_name = $1 AND constraint_type = 'PRIMARY KEY'
|
|
282
390
|
)
|
|
283
|
-
`,{rows:
|
|
284
|
-
`)),
|
|
285
|
-
`)}function
|
|
391
|
+
`,{rows:c}=await t.query(m,[a]),f=[];f.push(`create table public.${a} (`);let u=[];for(let h of i){let E=` ${h.column_name} ${nn(h)}`;h.is_nullable==="NO"&&(E+=" not null"),h.column_default!==null&&(E+=` default ${h.column_default}`),u.push(E)}let y=new Map;for(let h of s){let E=y.get(h.constraint_name)||[];E.push(h),y.set(h.constraint_name,E)}let d=[];for(let[h,E]of y){let D=E[0],x=E.map(U=>U.column_name).join(", ");if(D.constraint_type==="PRIMARY KEY")d.push(` constraint ${h} primary key (${x})`);else if(D.constraint_type==="FOREIGN KEY"){let U=D.foreign_table_name,M=D.foreign_column_name;d.push(` constraint ${h} foreign key (${x}) references ${U} (${M})`)}else D.constraint_type==="UNIQUE"&&d.push(` constraint ${h} unique (${x})`)}let g=[...u,...d];f.push(g.join(`,
|
|
392
|
+
`)),f.push(") tablespace pg_default;");for(let h of c)Array.from(y.values()).some(D=>D[0].constraint_type==="UNIQUE"&&D[0].constraint_name===h.indexname)||(f.push(""),f.push(`${h.indexdef};`));return f.join(`
|
|
393
|
+
`)}function nn(a){let{data_type:e,udt_name:t,character_maximum_length:o,numeric_precision:r,numeric_scale:n}=a;return e==="USER-DEFINED"?t:e==="ARRAY"?`${t.replace(/^_/,"")}[]`:(e==="character varying"||e==="varchar")&&o?`varchar(${o})`:e==="character"&&o?`char(${o})`:e==="numeric"&&r!==null?n!==null&&n>0?`numeric(${r}, ${n})`:`numeric(${r})`:e==="timestamp with time zone"?"timestamp with time zone":e==="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"}[e]||e}var Do=p(()=>{"use strict";R()});function Ao(a){if(a.length===0)return{clause:"",values:[]};let e=[],t=[];for(let o of a){let r=t.length+1,n=`"${o.columnName}"`;switch(o.operator){case"=":case"!=":case">":case">=":case"<":case"<=":e.push(`${n} ${o.operator} $${r}`),t.push(o.value);break;case"is":o.value.toLowerCase()==="null"?e.push(`${n} IS NULL`):(e.push(`${n} = $${r}`),t.push(o.value));break;case"is not":o.value.toLowerCase()==="null"?e.push(`${n} IS NOT NULL`):(e.push(`${n} != $${r}`),t.push(o.value));break;case"like":e.push(`${n}::text LIKE $${r}`),t.push(o.value);break;case"not like":e.push(`${n}::text NOT LIKE $${r}`),t.push(o.value);break;case"ilike":e.push(`${n}::text ILIKE $${r}`),t.push(o.value);break;case"not ilike":e.push(`${n}::text NOT ILIKE $${r}`),t.push(o.value);break;default:break}}return e.length===0?{clause:"",values:[]}:{clause:`WHERE ${e.join(" AND ")}`,values:t}}function _o(a,e){return Array.isArray(a)?a.length===0?"":`ORDER BY ${a.map(o=>`"${o.columnName}" ${o.direction.toUpperCase()}`).join(", ")}`:a&&typeof a=="string"?`ORDER BY "${a}" ${e?.toUpperCase()||"ASC"}`:""}function xo(a,e,t,o){let{values:r,sortColumns:n}=a,i=[],l=[],c=t==="asc"===(e==="asc");if(n.length>0){let f=n.map(d=>`"${d}"`).join(", "),u=n.map((d,g)=>`$${o+g}`).join(", "),y=c?">":"<";i.push(`(${f}) ${y} (${u})`);for(let d of n)l.push(r[d])}return{clause:i.length>0?`(${i.join(" AND ")})`:"",values:l}}var Po=p(()=>{"use strict"});var we,sn,ln,vo,Lo=p(()=>{"use strict";R();Po();we=a=>Buffer.from(JSON.stringify(a)).toString("base64url"),sn=a=>{try{return JSON.parse(Buffer.from(a,"base64url").toString("utf-8"))}catch{return null}},ln=async(a,e)=>{let t=`"${e}"`;return(await a.query(`SELECT a.attname as column_name
|
|
286
394
|
FROM pg_index i
|
|
287
395
|
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
288
396
|
WHERE i.indrelid = $1::regclass AND i.indisprimary
|
|
289
|
-
ORDER BY array_position(i.indkey, a.attnum)`,[o])).rows.map(n=>n.column_name)},qo=async({tableName:t,cursor:e="",limit:o=50,direction:r="asc",sort:n=[],order:a="asc",filters:i=[],db:c})=>{let s=f(c),u=await Yr(s,t),l=[],p=a;Array.isArray(n)&&n.length>0?(l=n.map(N=>N.columnName),p=n[0].direction):typeof n=="string"&&n&&(l=[n]);let y=[...l,...u.filter(N=>!l.includes(N))];y.length===0&&y.push("ctid");let{clause:E,values:d}=vo(i),g="",h=[];if(e){let N=Qr(e);if(N){let L=$o(N,r,p,d.length+1);g=L.clause,h=L.values}}let w="";E&&g?w=`WHERE ${E.replace(/^WHERE\s+/i,"")} AND ${g}`:E?w=E:g&&(w=`WHERE ${g}`);let D=Ao((Array.isArray(n),n),a),P=D;r==="desc"?D?P=D.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):P=`ORDER BY ${y.map(L=>`"${L}" ${p==="asc"?"DESC":"ASC"}`).join(", ")}`:!D&&y.length>0&&(P=`ORDER BY ${y.map(L=>`"${L}" ${p.toUpperCase()}`).join(", ")}`);let H=await s.query(`SELECT COUNT(*) as total FROM "${t}" ${E}`,d),O=Number(H.rows[0].total),J=d.length+h.length+1,z=await s.query(`SELECT * FROM "${t}" ${w} ${P} LIMIT $${J}`,[...d,...h,o+1]),v=z.fields&&z.fields.length>0?z.rows.filter(N=>Object.keys(N).length>0):z.rows,k=v.length>o;k&&(v=v.slice(0,o)),r==="desc"&&(v=v.reverse());let X=null,ye=null;if(v.length>0){let N=v[0],L=v[v.length-1],te=Mo=>({values:Object.fromEntries(y.map(Pe=>[Pe,Mo[Pe]])),sortColumns:y});r==="asc"?(k&&(X=pe(te(L))),e&&(ye=pe(te(N)))):(e&&(X=pe(te(L))),k&&(ye=pe(te(N))))}return{data:v,meta:{limit:o,total:O,hasNextPage:r==="asc"?k:!!e,hasPreviousPage:r==="asc"?!!e:k,nextCursor:X,prevCursor:ye}}}});import{utils as ee,write as Gr}from"xlsx";function Oo({cols:t,rows:e,format:o,tableName:r}){switch(o){case"json":{let n=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(n,"utf-8"))}case"csv":{let n=[t,...e?.map(c=>t?.map(s=>c[s]))??[]],a=ee.aoa_to_sheet(n),i=ee.sheet_to_csv(a);return new Uint8Array(Buffer.from(i,"utf-8"))}case"xlsx":{let n=[t,...e?.map(s=>t?.map(u=>s[u]))??[]],a=ee.aoa_to_sheet(n),i=ee.book_new();ee.book_append_sheet(i,a,r.slice(0,31));let c=Gr(i,{bookType:"xlsx",type:"buffer"});return new Uint8Array(c)}}}var Lo=m(()=>{"use strict"});import{zValidator as x}from"@hono/zod-validator";import{Hono as Jr}from"hono";var ko,jo=m(()=>{"use strict";F();yo();To();Ro();_o();xe();Co();No();Io();Lo();ko=new Jr().basePath("/tables").get("/",x("query",S),async t=>{let{db:e}=t.req.valid("query"),o=await Do(e);return t.json({data:o},200)}).post("/",x("query",S),x("json",lt),async t=>{let{db:e}=t.req.valid("query"),o=t.req.valid("json");return await bo({tableData:o,db:e}),t.json({data:`Table ${o.tableName} created successfully`},200)}).delete("/:tableName",x("query",ht),x("param",V),async t=>{let{db:e,cascade:o}=t.req.valid("query"),{tableName:r}=t.req.valid("param"),n=await Eo({tableName:r,db:e,cascade:o});return t.json({data:n},200)}).delete("/:tableName/columns/:columnName",x("query",ft),x("param",se),async t=>{let{db:e,cascade:o}=t.req.valid("query"),{tableName:r,columnName:n}=t.req.valid("param"),{deletedCount:a}=await go({tableName:r,columnName:n,cascade:o,db:e});return t.json({data:`Column "${n}" deleted successfully from table "${r}" with ${a} rows deleted`},200)}).get("/:tableName/columns",x("query",S),x("param",V),async t=>{let{db:e}=t.req.valid("query"),{tableName:o}=t.req.valid("param"),r=await le({tableName:o,db:e});return t.json({data:r},200)}).get("/:tableName/schema",x("query",S),x("param",V),async t=>{let{db:e}=t.req.valid("query"),{tableName:o}=t.req.valid("param"),r=await xo({tableName:o,db:e});return t.json({data:{schema:r}},200)}).get("/:tableName/data",x("param",V),x("query",Dt),async t=>{let{tableName:e}=t.req.valid("param"),{cursor:o,limit:r,direction:n,sort:a,order:i,filters:c,db:s}=t.req.valid("query"),u=await qo({tableName:e,cursor:o,limit:r,direction:n,sort:a,order:i,filters:c,db:s});return t.json({data:u},200)}).get("/:tableName/export",x("param",V),x("query",Rt),async t=>{let{tableName:e}=t.req.valid("param"),{db:o,format:r}=t.req.valid("query"),{cols:n,rows:a}=await wo({tableName:e,db:o}),i=Oo({cols:n,rows:a,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 Uo={};Ko(Uo,{createServer:()=>aa});import be from"path";import{fileURLToPath as Xr}from"url";import{serveStatic as de}from"@hono/node-server/serve-static";import{zValidator as Zr}from"@hono/zod-validator";import{Hono as ea}from"hono";import{cors as ta}from"hono/cors";import{logger as oa}from"hono/logger";import{prettyJSON as ra}from"hono/pretty-json";var fe,aa,Fo=m(()=>{"use strict";F();It();zt();Jt();oo();fo();jo();fe=()=>{if(process.env.NODE_ENV==="development")return be.resolve(process.cwd(),"../core/dist");let t=be.dirname(Xr(import.meta.url));return be.resolve(t,"./core-dist")},aa=()=>({app:new ea({strict:!1}).use("/*",ta()).use(ra({space:2})).use(process.env.NODE_ENV==="development"?oa():(e,o)=>o()).use("/favicon.ico",de({path:be.resolve(fe(),"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(Pt).route("/",Gt).use("/assets/*",de({root:fe()})).use("/image.png",de({root:fe()})).use("/:dbType/*",Zr("param",tt,qt)).use("/:dbType/*",async(e,o)=>{let r=e.req.param("dbType");e.set("dbType",r),await o()}).route("/:dbType",ko).route("/:dbType",po).route("/:dbType",to).route("/:dbType",Mt).use("/*",de({root:fe()}))})});oe();import{intro as na,outro as sa}from"@clack/prompts";import{serve as ia}from"@hono/node-server";import ca from"open";import $e from"picocolors";import{program as je}from"commander";var Ue=()=>(je.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),je.opts());import{readFile as Wo}from"fs/promises";import{resolve as Bo}from"path";import{cancel as re,isCancel as ge,note as Fe,select as Vo,spinner as Qo,text as He}from"@clack/prompts";import{parse as Yo}from"dotenv";import Te from"picocolors";var Me=async(t,e)=>{let o=e||"DATABASE_URL";if(t?.[o])return t[o];if(process.env[o])return process.env[o];let r=Qo();r.start("Looking for database connection..."),t?Fe(Te.red(`${o} not found in .env or process.env`)):Fe(Te.red(`No .env file found and ${o} not set in process.env`));let n=await Vo({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(n)||n==="cancel")&&(re("No database connection provided. Exiting..."),process.exit(0)),n==="other-env"){r.start("Waiting for path...");let i=await He({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)&&(re("Cancelled."),process.exit(0)),r.stop("Trying custom .env...");let c=Bo(i);try{let s=await Wo(c,"utf-8"),u=Yo(s);if(u[o])return u[o];throw new Error(`${o} still missing in custom file`)}catch(s){let u=s;re(`Cannot read or parse file: ${Te.dim(u.message)}`),process.exit(1)}}r.stop("Manual input...");let a=await He({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(a)&&(re("Cancelled."),process.exit(0)),a.trim()};import{access as Go,readFile as Jo}from"fs/promises";import{dirname as Xo,resolve as Se}from"path";import{parse as Zo}from"dotenv";var er=async t=>{let e=Se(t);for(;;){let o=Se(e,".env");try{return await Go(o),o}catch{}let r=Xo(e);if(r===e)return null;e=r}},K=async t=>{let e;if(t?e=Se(t):e=await er(process.cwd()),!e)return null;try{let o=await Jo(e,"utf-8");return Zo(o)}catch(o){if(o instanceof Error&&o.message.includes("ENOENT"))return null;throw o}};he();import{intro as tr,outro as or}from"@clack/prompts";import ze from"picocolors";var Ke=()=>{tr(ze.inverse(" db-studio ")),or(ze.green(`For more information, visit: ${Le.SITE_DOCS_LINK}`))};oe();import{intro as rr,note as ar,outro as We}from"@clack/prompts";import ae from"picocolors";var Be=async(t,e,o)=>{rr(ae.inverse(" db-studio "));let r=o||M.VAR_NAME,n=null;if(e)n=e;else{let a=t?await K(t):await K();a?.[r]?n=a[r]:process.env[r]&&(n=process.env[r]??null)}n?We(ae.green(`\u2713 Database connection configured (using ${r})`)):(ar(ae.red(`\u2717 ${r} not found`),"Status"),We(ae.yellow("\u26A0 No database connection configured")))};import{intro as sr,outro as ir}from"@clack/prompts";import Qe from"picocolors";var Ve={name:"db-studio",type:"module",version:"1.3.30",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":"^1.0.1","@hono/node-server":"^1.19.7","@hono/zod-validator":"^0.7.6",commander:"^14.0.3",dotenv:"^17.3.1",hono:"^4.10.4",open:"^11.0.0",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 Ye=()=>{sr(Qe.inverse(" db-studio ")),ir(Qe.green(`\u{1F680} db-studio v${Ve.version}`))};var la=async()=>{let{env:t,port:e,databaseUrl:o,varName:r,status:n,help:a,version:i}=Ue();a&&(Ke(),process.exit(0)),i&&(Ye(),process.exit(0)),n&&(await Be(t,o,r),process.exit(0)),na($e.inverse(" db-studio "));let c=e?parseInt(e,10):M.PORT,s=r||M.VAR_NAME,u=t?await K(t):await K(),l=o||await Me(u,s);process.env.DATABASE_URL=l;let{createServer:p}=await Promise.resolve().then(()=>(Fo(),Uo)),{app:y}=p();ia({fetch:y.fetch,port:c}),sa($e.green(`Server running at ${$e.cyan(`http://localhost:${c}`)}`)),process.env.NODE_ENV&&process.env.NODE_ENV!=="development"&&await ca(`http://localhost:${c}`)};la().catch(t=>{process.exit(1)});export{la as main};
|
|
397
|
+
ORDER BY array_position(i.indkey, a.attnum)`,[t])).rows.map(r=>r.column_name)},vo=async({tableName:a,cursor:e="",limit:t=50,direction:o="asc",sort:r=[],order:n="asc",filters:i=[],db:l})=>{let s=T(l),m=await ln(s,a),c=[],f=n;Array.isArray(r)&&r.length>0?(c=r.map(N=>N.columnName),f=r[0].direction):typeof r=="string"&&r&&(c=[r]);let u=[...c,...m.filter(N=>!c.includes(N))];u.length===0&&u.push("ctid");let{clause:y,values:d}=Ao(i),g="",h=[];if(e){let N=sn(e);if(N){let I=xo(N,o,f,d.length+1);g=I.clause,h=I.values}}let E="";y&&g?E=`WHERE ${y.replace(/^WHERE\s+/i,"")} AND ${g}`:y?E=y:g&&(E=`WHERE ${g}`);let D=_o((Array.isArray(r),r),n),x=D;o==="desc"?D?x=D.replace(/\bASC\b/gi,"TEMP_DESC").replace(/\bDESC\b/gi,"ASC").replace(/TEMP_DESC/g,"DESC"):x=`ORDER BY ${u.map(I=>`"${I}" ${f==="asc"?"DESC":"ASC"}`).join(", ")}`:!D&&u.length>0&&(x=`ORDER BY ${u.map(I=>`"${I}" ${f.toUpperCase()}`).join(", ")}`);let U=await s.query(`SELECT COUNT(*) as total FROM "${a}" ${y}`,d),M=Number(U.rows[0].total),k=d.length+h.length+1,j=await s.query(`SELECT * FROM "${a}" ${E} ${x} LIMIT $${k}`,[...d,...h,t+1]),A=j.fields&&j.fields.length>0?j.rows.filter(N=>Object.keys(N).length>0):j.rows,q=A.length>t;q&&(A=A.slice(0,t)),o==="desc"&&(A=A.reverse());let W=null,P=null;if(A.length>0){let N=A[0],I=A[A.length-1],G=le=>({values:Object.fromEntries(u.map(ze=>[ze,le[ze]])),sortColumns:u});o==="asc"?(q&&(W=we(G(I))),e&&(P=we(G(N)))):(e&&(W=we(G(I))),q&&(P=we(G(N))))}return{data:A,meta:{limit:t,total:M,hasNextPage:o==="asc"?q:!!e,hasPreviousPage:o==="asc"?!!e:q,nextCursor:W,prevCursor:P}}}});import{utils as ie,write as cn}from"xlsx";function $o({cols:a,rows:e,format:t,tableName:o}){switch(t){case"json":{let r=JSON.stringify(e??[],null,2);return new Uint8Array(Buffer.from(r,"utf-8"))}case"csv":{let r=[a,...e?.map(l=>a?.map(s=>l[s]))??[]],n=ie.aoa_to_sheet(r),i=ie.sheet_to_csv(n);return new Uint8Array(Buffer.from(i,"utf-8"))}case"xlsx":{let r=[a,...e?.map(s=>a?.map(m=>s[m]))??[]],n=ie.aoa_to_sheet(r),i=ie.book_new();ie.book_append_sheet(i,n,o.slice(0,31));let l=cn(i,{bookType:"xlsx",type:"buffer"});return new Uint8Array(l)}}}var Oo=p(()=>{"use strict"});import{zValidator as $}from"@hono/zod-validator";import{Hono as mn}from"hono";var qo,Io=p(()=>{"use strict";V();Va();Qa();Xa();eo();ao();no();lo();mo();se();po();yo();Ro();ke();wo();Do();Lo();Oo();qo=new mn().basePath("/tables").get("/",$("query",w),async a=>{let{db:e}=a.req.valid("query"),o=a.get("dbType")==="mysql"?await uo(e):await Co(e);return a.json({data:o},200)}).post("/",$("query",w),$("json",_t),async a=>{let{db:e}=a.req.valid("query"),t=a.req.valid("json");return a.get("dbType")==="mysql"?await to({tableData:t,db:e}):await Wa({tableData:t,db:e}),a.json({data:`Table ${t.tableName} created successfully`},200)}).delete("/:tableName",$("query",It),$("param",ee),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:o}=a.req.valid("param"),n=a.get("dbType")==="mysql"?await io({tableName:o,db:e,cascade:t}):await Ja({tableName:o,db:e,cascade:t});return a.json({data:n},200)}).delete("/:tableName/columns/:columnName",$("query",$t),$("param",de),async a=>{let{db:e,cascade:t}=a.req.valid("query"),{tableName:o,columnName:r}=a.req.valid("param"),n=a.get("dbType"),{deletedCount:i}=n==="mysql"?await ro({tableName:o,columnName:r,cascade:t,db:e}):await Ya({tableName:o,columnName:r,cascade:t,db:e});return a.json({data:`Column "${r}" deleted successfully from table "${o}" with ${i} rows deleted`},200)}).get("/:tableName/columns",$("query",w),$("param",ee),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType")==="mysql"?await Y({tableName:t,db:e}):await ge({tableName:t,db:e});return a.json({data:r},200)}).get("/:tableName/schema",$("query",w),$("param",ee),async a=>{let{db:e}=a.req.valid("query"),{tableName:t}=a.req.valid("param"),r=a.get("dbType")==="mysql"?await bo({tableName:t,db:e}):await No({tableName:t,db:e});return a.json({data:{schema:r}},200)}).get("/:tableName/data",$("param",ee),$("query",Kt),async a=>{let{tableName:e}=a.req.valid("param"),{cursor:t,limit:o,direction:r,sort:n,order:i,filters:l,db:s}=a.req.valid("query"),c=a.get("dbType")==="mysql"?await So({tableName:e,cursor:t,limit:o,direction:r,sort:n,order:i,filters:l,db:s}):await vo({tableName:e,cursor:t,limit:o,direction:r,sort:n,order:i,filters:l,db:s});return a.json({data:c},200)}).get("/:tableName/export",$("param",ee),$("query",Ht),async a=>{let{tableName:e}=a.req.valid("param"),{db:t,format:o}=a.req.valid("query"),r=a.get("dbType"),{cols:n,rows:i}=r==="mysql"?await co({tableName:e,db:t}):await Za({tableName:e,db:t}),l=$o({cols:n,rows:i,format:o,tableName:e}),s;switch(o){case"csv":s="text/csv";break;case"xlsx":s="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";break;case"json":s="application/json";break}return new Response(l,{headers:{"Content-Type":s??"","Content-Disposition":`attachment; filename="${e}_export.${o}"`}})})});var Mo={};Uo(Mo,{createServer:()=>gn});import Ae from"path";import{fileURLToPath as un}from"url";import{serveStatic as Ne}from"@hono/node-server/serve-static";import{zValidator as pn}from"@hono/zod-validator";import{Hono as dn}from"hono";import{cors as fn}from"hono/cors";import{logger as bn}from"hono/logger";import{prettyJSON as yn}from"hono/pretty-json";var De,gn,ko=p(()=>{"use strict";V();Zt();ia();ga();wa();Ka();Io();De=()=>{if(process.env.NODE_ENV==="development")return Ae.resolve(process.cwd(),"../core/dist");let a=Ae.dirname(un(import.meta.url));return Ae.resolve(a,"./core-dist")},gn=()=>({app:new dn({strict:!1}).use("/*",fn()).use(yn({space:2})).use(process.env.NODE_ENV==="development"?bn():(e,t)=>t()).use("/favicon.ico",Ne({path:Ae.resolve(De(),"favicon.ico")})).use("*",async(e,t)=>{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 t()}).onError(Jt).route("/",ya).use("/assets/*",Ne({root:De()})).use("/image.png",Ne({root:De()})).use("/:dbType/*",pn("param",ht,Xt)).use("/:dbType/*",async(e,t)=>{let o=e.req.param("dbType");e.set("dbType",o),await t()}).route("/:dbType",qo).route("/:dbType",Ba).route("/:dbType",Ca).route("/:dbType",sa).use("/*",Ne({root:De()}))})});ce();import{intro as hn,outro as Tn}from"@clack/prompts";import{serve as En}from"@hono/node-server";import Ve from"picocolors";import{program as tt}from"commander";var at=()=>(tt.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),tt.opts());import{readFile as Ho}from"fs/promises";import{resolve as jo}from"path";import{cancel as me,isCancel as xe,note as ot,select as Bo,spinner as Ko,text as rt}from"@clack/prompts";import{parse as Wo}from"dotenv";import Pe from"picocolors";var nt=async(a,e)=>{let t=e||"DATABASE_URL";if(a?.[t])return a[t];if(process.env[t])return process.env[t];let o=Ko();o.start("Looking for database connection..."),a?ot(Pe.red(`${t} not found in .env or process.env`)):ot(Pe.red(`No .env file found and ${t} not set in process.env`));let r=await Bo({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((xe(r)||r==="cancel")&&(me("No database connection provided. Exiting..."),process.exit(0)),r==="other-env"){o.start("Waiting for path...");let i=await rt({message:"Enter path to .env file",placeholder:"~/projects/myapp/.env.local or ./special.env",validate(s){if(!s?.trim())return"Path is required"}});xe(i)&&(me("Cancelled."),process.exit(0)),o.stop("Trying custom .env...");let l=jo(i);try{let s=await Ho(l,"utf-8"),m=Wo(s);if(m[t])return m[t];throw new Error(`${t} still missing in custom file`)}catch(s){let m=s;me(`Cannot read or parse file: ${Pe.dim(m.message)}`),process.exit(1)}}o.stop("Manual input...");let n=await rt({message:`Paste your ${t}`,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 xe(n)&&(me("Cancelled."),process.exit(0)),n.trim()};import{access as Vo,readFile as zo}from"fs/promises";import{dirname as Yo,resolve as ve}from"path";import{parse as Qo}from"dotenv";var Go=async a=>{let e=ve(a);for(;;){let t=ve(e,".env");try{return await Vo(t),t}catch{}let o=Yo(e);if(o===e)return null;e=o}},J=async a=>{let e;if(a?e=ve(a):e=await Go(process.cwd()),!e)return null;try{let t=await zo(e,"utf-8");return Qo(t)}catch(t){if(t instanceof Error&&t.message.includes("ENOENT"))return null;throw t}};_e();import{intro as Jo,outro as Xo}from"@clack/prompts";import st from"picocolors";var it=()=>{Jo(st.inverse(" db-studio ")),Xo(st.green(`For more information, visit: ${Ze.SITE_DOCS_LINK}`))};ce();import{intro as Zo,note as er,outro as lt}from"@clack/prompts";import ue from"picocolors";var ct=async(a,e,t)=>{Zo(ue.inverse(" db-studio "));let o=t||Q.VAR_NAME,r=null;if(e)r=e;else{let n=a?await J(a):await J();n?.[o]?r=n[o]:process.env[o]&&(r=process.env[o]??null)}r?lt(ue.green(`\u2713 Database connection configured (using ${o})`)):(er(ue.red(`\u2717 ${o} not found`),"Status"),lt(ue.yellow("\u26A0 No database connection configured")))};import{intro as ar,outro as or}from"@clack/prompts";import ut from"picocolors";var mt={name:"db-studio",type:"module",version:"1.4.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","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":"^1.0.1","@hono/node-server":"^1.19.7","@hono/zod-validator":"^0.7.6",commander:"^14.0.3",dotenv:"^17.3.1",hono:"^4.10.4",mysql2:"^3.18.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 pt=()=>{ar(ut.inverse(" db-studio ")),or(ut.green(`\u{1F680} db-studio v${mt.version}`))};var Sn=async()=>{let{env:a,port:e,databaseUrl:t,varName:o,status:r,help:n,version:i}=at();n&&(it(),process.exit(0)),i&&(pt(),process.exit(0)),r&&(await ct(a,t,o),process.exit(0)),hn(Ve.inverse(" db-studio "));let l=e?parseInt(e,10):Q.PORT,s=o||Q.VAR_NAME,m=a?await J(a):await J(),c=t||await nt(m,s);process.env.DATABASE_URL=c;let{createServer:f}=await Promise.resolve().then(()=>(ko(),Mo)),{app:u}=f();En({fetch:u.fetch,port:l}),Tn(Ve.green(`Server running at ${Ve.cyan(`http://localhost:${l}`)}`))};Sn().catch(a=>{process.exit(1)});export{Sn as main};
|
|
290
398
|
//# sourceMappingURL=index.js.map
|