mngr
Version:
Command-line cross-platform databases management TUI tool
24 lines (18 loc) • 32.2 kB
JavaScript
var Dt={focus:null,sql:"",status:"",databases:[],database:0,tables:[],table:0,count:0,cols:[],rows:[],palette:{dark0:"#282828",dark1:"#3c3836",dark2:"#504945",dark3:"#665c54",light1:"#ebdbb2",light4:"#a89984"}},Mt={setFocus(m,t=null){return{...m,focus:t}},setSql(m,t=""){return{...m,sql:t}},setStatus(m,t=""){return{...m,status:t}},setDatabases(m,t=[]){return{...m,databases:t}},setDatabase(m,t=0){return{...m,database:t}},setTables(m,t=[]){return{...m,tables:t}},setTable(m,t=0){return{...m,table:t}},setCols(m,t=[]){return{...m,cols:t}},setRows(m,t=[]){return{...m,rows:t}},setCount(m,t=0){return{...m,count:t}}};import{useSyncExternalStore as vt}from"react";var te=m=>{let t=m,e=new Set;return{getState:()=>t,dispatch:(n,r)=>{t=Mt[n](t,r),e.forEach(s=>s(t))},subscribe:n=>(e.add(n),()=>e.delete(n))}},ut=te(Dt),x=(m=t=>t)=>vt(ut.subscribe,()=>m(ut.getState())),g=ut.dispatch;import H,{useMemo as ee}from"react";import{Separator as ne,Text as J,useSize as re}from"react-curse";function bt(){let{width:m}=re(),t=x(r=>r.focus),e=x(r=>r.palette),n=ee(()=>{switch(t){case"sidebar":case"sidebar/create":case"sidebar/edit":case"sidebar/search":return[["Enter, Tab","jump to rows"],["A","create table"],["rn","rename table"],["dD","delete table"],["/","search"],["n","next occurrence"]];case"main":case"main/edit":return[["i","preview"],["Tab","jump to tables"],["E, Enter","edit selected"],["A, Y","insert, duplicate selected"],["dD","delete selected"],["[, ]","prev, next page"],["-, =, _, +","sort, add sort"],["r, Backspace","reload, reset"],["Space, uv","mark row, unmark all"],["C-a, C-x","inrement, decrement"],[".","relation jump"],["/","search"]];case"main/search":return[[":","like"],["=","equals"]]}},[t]);return n?H.createElement(J,{absolute:!0,y:`100%-${n.length+3}`,x:0,height:n.length+1,width:"100%",clear:!0},H.createElement(ne,{type:"horizontal",width:m,color:e.dark1}),H.createElement(J,{y:0,x:16,color:e.dark1,block:!0},"\u2534"),n.map(([r,s])=>H.createElement(J,{key:r,block:!0},H.createElement(J,{x:1},r.split(", ").map((i,o)=>H.createElement(J,{key:i},H.createElement(J,{dim:!0,bold:!0},i),o<r.split(", ").length-1&&", ")))," \u2192"+" ".repeat(Math.max(0,14-r.length))+s))):null}import{readFile as se,writeFile as oe}from"fs/promises";var Z=class{#n;constructor(t){this.#n=t}#r(t){return Array.isArray(t)&&(t.length===0||t.find(e=>typeof e=="object"))}async#t(){try{let t=await se(this.#n,"utf8");return JSON.parse(t)}catch(t){if(t.code==="ENOENT")return await this.#e({}),{};if(t instanceof SyntaxError)process.exit();else throw t}}#e(t){return oe(this.#n,JSON.stringify(t,null,2))}async tables(){let t=await this.#t(),e=Object.entries(t),n=e.filter(([,s])=>this.#r(s)),r=n.map(([s])=>s).sort((s,i)=>s.localeCompare(i));return e.length>n.length?[".",...r]:r}cols(t,e){let n={};return e?.forEach(r=>Object.entries(r).forEach(([s,i])=>{let o="string";typeof i=="number"?o="number":typeof i=="boolean"?o="boolean":Array.isArray(i)?o="array":typeof i=="object"&&(o="object"),n[s]===void 0&&(n[s]=o)})),Object.entries(n).map(([r,s])=>({name:r,type:s}))}async rows(t,e={},n={},r=0,s=100){if(!t)return["",0,[],[]];let i=`db.${t}(${JSON.stringify(e)}).sort(${JSON.stringify(n)})`.replace(".sort({})",""),o=await this.#t(),u;t==="."?(u=[Object.fromEntries(Object.entries(o).filter(([,a])=>!this.#r(a)))],i=i.substring(0,2)+i.substring(4)):u=o[t];let f=u.length;Object.keys(e).length>0&&Object.entries(e).forEach(([a,y])=>{u=u.filter(y.$regex?l=>new RegExp(y.$regex,"i").test(l[a]):l=>y===l[a])}),Object.keys(n).length>0&&Object.entries(n).reverse().forEach(([a,y])=>{u=u.sort((l,E)=>l[a]===E[a]?0:l[a]>E[a]?y:y*-1)}),u=u.filter((a,y)=>y>=r&&y<r+s);let b=this.cols(t,u);return[i,f,u,b]}id(){return"id"}types(){return{array:{icon:"\uEA8A",color:"Red"},boolean:{icon:"\uEAE8",color:"Red"},number:{icon:"\uEA90",color:"Magenta"},object:{icon:"\uE60B",color:"Red"},string:{icon:"\uEB69",color:"Yellow"}}}format(t,e){let n=Object.fromEntries(t.map(({name:r,type:s})=>[r,s]));return e.map(r=>Object.fromEntries(Object.entries(r).map(([s,i])=>(["object","array"].includes(n[s])&&(i=JSON.stringify(i)),[s,i]))))}#s(t,e){let n=Object.fromEntries(t.map(({name:r,type:s})=>[r,s]));return Object.fromEntries(Object.entries(e).map(([r,s])=>(n[r]==="number"?s=parseInt(s)||0:n[r]==="boolean"&&(s=s.toString().toLowerCase()==="true"),[r,s])))}async template(t,e,n){return n?n.map(r=>Object.fromEntries(Object.entries(r).filter(([s])=>s!==this.id()))):[{}]}async insert(t,e,n){if(t===".")return null;let r=await this.#t(),s=n.map(i=>{if(!i[this.id()]){let o=r[t].reduce((u,{id:f})=>Math.max(u,f),0)+1;delete i[this.id()],i={id:o,...i}}return r[t].find(({id:o})=>o.toString()===i[this.id()].toString())?null:(r[t].push(this.#s(e,i)),i[this.id()].toString())});return await this.#e(r),s}async update(t,e,n,r){let s=await this.#t();if(t==="."){let i=Object.fromEntries(Object.entries(s).filter(([,o])=>this.#r(o)));return await this.#e({...this.#s(e,n[0]),...i}),"."}else return r.forEach((i,o)=>{let u=s[t].findIndex(({id:f})=>f===i[this.id()]);if(u===-1)return!1;s[t][u]=this.#s(e,n[o])}),await this.#e(s),r.map(i=>i[this.id()].toString())}async delete(t,e,n){if(t===".")return null;Array.isArray(n)||(n=[n]);let r=await this.#t();return r[t]=r[t].filter(s=>!n.includes(s[this.id()])),await this.#e(r),n.map(s=>s.toString())}async createTable(t){if(t===".")return!1;let e=await this.#t();return e[t]!==void 0?!1:(e[t]=[],await this.#e(e),!0)}async renameTable(t,e){if(t==="."||t===e)return!1;let n=await this.#t();return n[t]===void 0||n[e]!==void 0?!1:(n[e]=n[t],delete n[t],await this.#e(n),!0)}async dropTable(t){if(t===".")return!1;let e=await this.#t();return e[t]===void 0?!1:(delete e[t],await this.#e(e),!0)}};import ie from"mariadb";var Q=class{constructor(t){this.db=ie.createPool(`mariadb://root@${t}`)}async tables(){return(await this.db.query("SHOW TABLES")).map(e=>Object.values(e)[0])}async cols(t){return(await this.db.query(`SHOW COLUMNS FROM ${t}`)).map(({Field:n,Type:r,Key:s})=>({name:n,type:r,pk:s==="PRI"?1:0}))}async rows(t,e={},n={},r=0,s=100){let i=await this.db.query(`SELECT COUNT(*) FROM ${t}`),o=parseInt(i?.[0]?.["COUNT(*)"]??0),u=`SELECT * FROM ${t}${Object.keys(e).length>0?` WHERE ${Object.entries(e).map(([b,a])=>a.$regex?`${b} LIKE '%${a.$regex}%'`:`${b} = '${a}'`).join(" AND ")}`:""}${Object.keys(n).length>0?` ORDER BY ${Object.entries(n).map(([b,a])=>`${b} ${a===1?"ASC":"DESC"}`).join(", ")}`:""}${o>s?` LIMIT ${s}`:""}${r>0?` OFFSET ${r}`:""}`,f=await this.db.query(u);return[u,o,f,void 0]}id(t){return t.find(({pk:e})=>e===1)?.name??"id"}types(){return{char:{icon:"\uEB69",color:"Yellow"},date:{icon:"\uEAB0",color:"Red"},decimal:{icon:"\uEA90",color:"Magenta"},int:{icon:"\uEA90",color:"Magenta"},tinyint:{icon:"\uEA90",color:"Magenta"},varchar:{icon:"\uEB69",color:"Yellow"}}}format(t,e){return e}async template(t,e,n){let r=this.id(e),s=await this.db.query(`SELECT ${r} FROM ${t} ORDER BY ${r} DESC LIMIT 1`),i=parseInt(s?.[0]?.[r]||0);return(n||[{}]).map(o=>Object.fromEntries(e.map(u=>[u.name,u.name===r?++i:o[u.name]])))}async insert(t,e,n){let r=[];for(let s of n){let i=await this.db.query(`INSERT INTO ${t} VALUES (${Object.keys(s).map(()=>"?").join(", ")})`,[...Object.values(s)]);r.push(i.insertId.toString())}return r}async update(t,e,n,r){let s=this.id(e),i=[];for(let o in n){let u=n[o],f=r[o],b=f[s],a=Object.keys(f).map(l=>f[l].toString()!==u[l].toString()&&[l,u[l]]).filter(l=>l),y=Object.fromEntries(a);await this.db.query(`UPDATE ${t} SET ${Object.keys(y).map(l=>l+" = ?")} WHERE ${s} = ?`,[...Object.values(y),b]),i.push(b.toString())}return i}async delete(t,e,n){let r=this.id(e);return Array.isArray(n)||(n=[n]),await this.db.query(`DELETE FROM ${t} WHERE (${r}) IN (?)`,[n]),n.map(s=>s.toString())}async createTable(t){try{return await this.db.query(`CREATE TABLE ${t} (id INT AUTO_INCREMENT PRIMARY KEY)`),!0}catch{return!1}}async renameTable(t,e){try{return await this.db.query(`ALTER TABLE ${t} RENAME TO ${e}`),!0}catch{return!1}}async dropTable(t){try{return await this.db.query(`DROP TABLE ${t}`),!0}catch{return!1}}};import{MongoClient as ae,ObjectId as It}from"mongodb";var v=class{constructor(t){let[e,n]=t.split("/",2),r=new ae(`mongodb://${e}`);r.connect(),this.db=r.db(n)}async tables(){return(await this.db.listCollections().toArray()).map(({name:e})=>e).sort((e,n)=>e.localeCompare(n))}cols(t,e){let n={};return e?.forEach(r=>Object.entries(r).forEach(([s,i])=>{let o="string";typeof i=="object"?i instanceof It?o="id":i instanceof Date?o="datetime":o="object":typeof i=="number"?o="number":typeof i=="boolean"&&(o="boolean"),n[s]===void 0&&(n[s]=o)})),Object.entries(n).map(([r,s])=>({name:r,type:s}))}async rows(t,e={},n={},r=0,s=100){if(!t)return["",0,[],[]];let i=await this.db.collection(t).countDocuments(),o=`db.${t}.find(${JSON.stringify(e)})${Object.keys(n).length>0?`.sort(${JSON.stringify(n)})`:""}${r>0?`.skip(${r})`:""}${i>s?`.limit(${s})`:""}`;e=Object.fromEntries(Object.entries(e).map(([b,a])=>(b&&(a=new It(a.$regex?a.$regex:a)),a.$regex&&(a={$regex:new RegExp(a.$regex,"i")}),[b,a])));let u=await this.db.collection(t).find(e).sort(n).skip(r).limit(s).toArray(),f=this.cols(t,u);return[o,i,u,f]}id(){return"_id"}types(){return{array:{icon:"\uEA8A",color:"Red"},boolean:{icon:"\uEAE8",color:"Red"},datetime:{icon:"\uEAB0",color:"Red"},id:{icon:"\uEA90",color:"Magenta"},number:{icon:"\uEA90",color:"Magenta"},object:{icon:"\uE60B",color:"Red"},string:{icon:"\uEB69",color:"Yellow"}}}format(t,e){let n=Object.fromEntries(t.map(({name:r,type:s})=>[r,s]));return e.map(r=>Object.fromEntries(Object.entries(r).map(([s,i])=>(n[s]==="datetime"?i=i.toISOString():n[s]==="object"&&(i=JSON.stringify(i)),[s,i]))))}#n(t,e){let n=Object.fromEntries(t.map(({name:r,type:s})=>[r,s]));return Object.fromEntries(Object.entries(e).map(([r,s])=>(n[r]==="number"?s=parseInt(s)||0:n[r]==="datetime"?s=new Date(s):n[r]==="object"?s=JSON.parse(s):n[r]==="boolean"?s=s.toString().toLowerCase()==="true":s.toString().toLowerCase()==="null"&&(s=null),[r,s])))}async template(t,e,n){return n?n.map(r=>Object.fromEntries(Object.entries(r).filter(([s])=>s!==this.id()))):[{}]}async insert(t,e,n){let{insertedIds:r}=await this.db.collection(t).insertMany(n.map(s=>this.#n(e,s)));return Object.values(r).map(s=>s.toString())}async update(t,e,n,r){let s=[];for(let i in n){let o=n[i],u=r[i],{_id:f}=u,b=this.#n(e,Object.fromEntries(Object.entries(o).filter(([y])=>y!==this.id()).map(([y,l])=>u[y]!==l&&[y,l]).filter(y=>y))),a=this.#n(e,Object.fromEntries(Object.keys(u).filter(y=>y!==this.id()).map(y=>o[y]===void 0&&[y,1]).filter(y=>y)));await this.db.collection(t).updateOne({_id:f},{$set:b,$unset:a}),s.push(f.toString())}return s}async delete(t,e,n){return Array.isArray(n)?(await this.db.collection(t).deleteMany({_id:{$in:n}}),n.map(r=>r.toString())):(await this.db.collection(t).deleteOne({_id:n}),n.toString())}async createTable(t){try{return await this.db.createCollection(t),!0}catch{return!1}}async renameTable(t,e){try{return await this.db.renameCollection(t,e),!0}catch{return!1}}async dropTable(t){try{return await this.db.dropCollection(t),!0}catch{return!1}}};import ce from"pg";var tt=class{constructor(t){let e=new URL(`postgress://${t}`),[,n]=e.pathname.split("/",3);this.db=new ce.Client({user:e.username,password:e.password,host:e.hostname,port:e.port?Number(e.port):void 0,database:n}),this.db.connect()}async databases(){let{rows:t}=await this.db.query("SELECT * FROM pg_catalog.pg_database");return t.map(e=>e.datname).sort((e,n)=>e.localeCompare(n))}async tables(){let{rows:t}=await this.db.query("SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema'");return t.map(e=>e.tablename).filter(e=>!e.startsWith("_")).sort((e,n)=>e.localeCompare(n))}async cols(t){let{rows:e}=await this.db.query("SELECT * FROM information_schema.columns WHERE table_name = $1",[t]);return e.map((n,r)=>({name:n.column_name,type:n.udt_name,pk:r===0?1:0}))}async rows(t,e={},n={},r=0,s=100){let{rows:i}=await this.db.query(`SELECT COUNT(*) FROM "${t}"`),o=parseInt(i?.[0]?.count??0),u=`SELECT * FROM "${t}"${Object.keys(e).length>0?` WHERE ${Object.entries(e).map(([b,a])=>a.$regex?`"${b}" LIKE '%${a.$regex}%'`:`"${b}" = '${a}'`).join(" AND ")}`:""}${Object.keys(n).length>0?` ORDER BY ${Object.entries(n).map(([b,a])=>`"${b}" ${a===1?"ASC":"DESC"}`).join(", ")}`:" ORDER BY 1"}${o>s?` LIMIT ${s}`:""}${r>0?` OFFSET ${r}`:""}`,f=[];try{f=(await this.db.query(u)).rows}catch{}return u=u.replace(" ORDER BY 1",""),[u,o,f,void 0]}id(t){return t.find(({pk:e})=>e===1)?.name??"id"}types(){return{_float:{icon:"\uEA8A",color:"Magenta"},_int:{icon:"\uEA8A",color:"Magenta"},_text:{icon:"\uEA8A",color:"Yellow"},bool:{icon:"\uEAE8",color:"Red"},bytea:{icon:"\uE60B",color:"Magenta"},date:{icon:"\uEAB0",color:"Red"},float:{icon:"\uEA90",color:"Magenta"},int:{icon:"\uEA90",color:"Magenta"},text:{icon:"\uEB69",color:"Yellow"},timestamp:{icon:"\uEAB0",color:"Red"},varchar:{icon:"\uEB69",color:"Yellow"}}}format(t,e){let n=Object.fromEntries(t.map(({name:r,type:s})=>[r,s]));return e.map(r=>Object.fromEntries(Object.entries(r).map(([s,i])=>(i!==null&&(["date","timestamp","timestamptz"].includes(n[s])?i=i.toISOString():n[s]==="bytea"?i=JSON.stringify(i):n[s]==="bool"&&(i=i.toString().toLowerCase()==="true")),[s,i]))))}async template(t,e,n){let r=this.id(e),{rows:s}=await this.db.query(`SELECT "${r}" FROM "${t}" ORDER BY "${r}" DESC LIMIT 1`),i=parseInt(s?.[0]?.[r]||0);return(n||[{}]).map(o=>Object.fromEntries(e.map(u=>[u.name,u.name===r?++i:o[u.name]])))}async insert(t,e,n){let r=this.id(e),s=[];for(let i of n){let{rows:o}=await this.db.query(`INSERT INTO "${t}" VALUES (${Object.keys(i).map((u,f)=>`$${f+1}`).join(", ")}) RETURNING "${r}"`,Object.values(i));s.push(o?.[0]?.[r]?.toString())}return s}async update(t,e,n,r){let s=[];for(let i in n){let o=n[i],u=r[i],f=this.id(e),b=u[f],a=Object.keys(u).map(l=>u[l]?.toString()!==o[l]?.toString()&&[l,o[l]||null]).filter(l=>l),y=Object.fromEntries(a);a.length>0&&(await this.db.query(`UPDATE "${t}" SET ${Object.keys(y).map((l,E)=>`"${l}" = $${E+1}`)} WHERE "${f}" = ${b}`,Object.values(y)),s.push(b.toString()))}return s}async delete(t,e,n){let r=this.id(e);return Array.isArray(n)||(n=[n]),await this.db.query(`DELETE FROM "${t}" WHERE "${r}" IN (${n.map((s,i)=>`$${i+1}`).join(", ")})`,n),n.map(s=>s.toString())}async createTable(t){try{return await this.db.query(`CREATE TABLE "${t}" (id SERIAL PRIMARY KEY)`),!0}catch{return!1}}async renameTable(t,e){try{return await this.db.query(`ALTER TABLE "${t}" RENAME TO ${e}`),!0}catch{return!1}}async dropTable(t){try{return await this.db.query(`DROP TABLE "${t}"`),!0}catch{return!1}}};import le from"sqlite3";var{Database:ue}=le.verbose(),et=class{constructor(t){this.db=new ue(t)}tables(){return new Promise((t,e)=>{this.db.all('SELECT name FROM sqlite_master WHERE type = "table"',(n,r)=>{if(n)return e(n);t(r.map(s=>s.name).sort((s,i)=>s.localeCompare(i)))})})}cols(t){return new Promise((e,n)=>{this.db.all(`PRAGMA table_info(${t})`,(r,s)=>{if(r)return n(r);let i=s.find(o=>o.pk===1)?[]:[{name:"rowid",type:"INTEGER",pk:1}];e([...i,...s])})})}async rows(t,e={},n={},r=0,s=100){let i=await new Promise((f,b)=>{this.db.get(`SELECT COUNT(*) FROM ${t}`,(a,y)=>{if(a)return b(a);f(y["COUNT(*)"])})}),o=`SELECT rowid, * FROM ${t}${Object.keys(e).length>0?` WHERE ${Object.entries(e).map(([f,b])=>b.$regex?`${f} LIKE '%${b.$regex}%'`:`${f} = '${b}'`).join(" AND ")}`:""}${Object.keys(n).length>0?` ORDER BY ${Object.entries(n).map(([f,b])=>`${f} ${b===1?"ASC":"DESC"}`).join(", ")}`:""}${i>s?` LIMIT ${s}`:""}${r>0?` OFFSET ${r}`:""}`,u=await new Promise(f=>{try{this.db.all(o,(b,a)=>{b&&f([]),f(a)})}catch{f([])}});return o=o.replace("SELECT rowid, ","SELECT ").replace(" ORDER BY id ASC",""),[o,i,u,void 0]}id(t){return t.find(({pk:e})=>e===1)?.name??"rowid"}types(){return{boolean:{icon:"\uEAE8",color:"Red"},datetime:{icon:"\uEAB0",color:"Red"},integer:{icon:"\uEA90",color:"Magenta"},integer_unsigned:{icon:"\uEA90",color:"Magenta"},numeric:{icon:"\uEA90",color:"Magenta"},nvarchar:{icon:"\uEB69",color:"Yellow"},text:{icon:"\uEB69",color:"Yellow"}}}format(t,e){return e}async template(t,e,n){return(n||[{}]).map(r=>Object.fromEntries(e.filter(s=>s.name!==this.id(e)).map(({name:s,type:i})=>[s,r[s]||(i==="INTEGER"?0:"")])))}async insert(t,e,n){let r=[];for(let s of n)try{let i=await new Promise(o=>{this.db.run(`INSERT INTO ${t} VALUES (${Object.keys(s).map(()=>"?").join(", ")})`,[...Object.values(s)],function(u){if(u)throw u;o(this.lastID.toString())})});r.push(i)}catch{return null}return r}async update(t,e,n,r){let s=[];for(let i in n){let o=n[i],u=r[i],f=u[Object.keys(u)[0]],b=Object.keys(u).map(a=>u[a].toString()!==o[a].toString()&&[a,o[a]]).filter(a=>a);try{let a=await new Promise(y=>{if(b.length<1)return y(null);let l=Object.fromEntries(b);this.db.run(`UPDATE ${t} SET ${Object.keys(l).map(E=>E+" = ?")} WHERE rowid = ?`,[...Object.values(l),f],E=>{if(E)throw E;y(f)})});a&&s.push(a)}catch{return null}}return s}delete(t,e,n){return Array.isArray(n)||(n=[n]),new Promise(r=>{let s=this.db.prepare(`DELETE FROM ${t} WHERE rowid = ?`);for(let i of n)s.run(i);s.finalize(i=>{if(i)return r(null);r(n.map(o=>o.toString()))})})}createTable(t){return new Promise(e=>{this.db.run(`CREATE TABLE ${t} (id INTEGER)`,n=>{if(n)return e(!1);e(!0)})})}renameTable(t,e){return new Promise(n=>{this.db.run(`ALTER TABLE ${t} RENAME TO ${e}`,r=>{if(r)return n(!1);n(!0)})})}dropTable(t){return new Promise(e=>{this.db.run(`DROP TABLE ${t}`,n=>{if(n)return e(!1);e(!0)})})}};var W={json:{db:Z,aliases:"js"},mariadb:{db:Q,aliases:"mysql"},mongodb:{db:v,aliases:"mongo"},postgresql:{db:tt,aliases:["pg","postgres"]},sqlite:{db:et,aliases:"sqlite3"}},kt,dt=m=>{let[t,e]=m.split("://",2);kt=new W[t].db(e)},nt=()=>kt;import At,{argv as mt}from"node:process";var C="";if(mt.length>2)if(C=mt[mt.length-1],!C.includes("://"))C.endsWith(".json")&&(C=`json://${C}`),(C.endsWith(".db")||C.endsWith(".sqlite")||C.endsWith("sqlite3"))&&(C=`sqlite://${C}`);else{let[m,t]=C.split("://",2);if(!Object.keys(W).includes(m)){let e=Object.values(W).findIndex(n=>n.aliases.includes(m));e>-1&&(C=`${Object.keys(W)[e]}://${t}`)}}C||(console.log(`USAGE:
mngr [URL]
EXAMPLES:
mngr db.json
mngr json://db.json
mngr mongodb:///db
mngr mongodb://localhost/db
mngr postgresql:///db
mngr postgresql://localhost/db
mngr mariadb:///db
mngr mariadb://localhost/db
mngr db.sqlite3
mngr sqlite://db.sqlite3
mngr sqlite://db.sqlite
mngr sqlite://db.db`),At.exit(0));(!C.includes("://")||!Object.keys(W).includes(C.split("://")[0]))&&(console.log("protocol not supported"),At.exit(0));var rt=C;import qt from"react";import{Text as Lt}from"react-curse";function ft(m){let t="x1b[0m"+JSON.stringify(m,(e,n)=>e.startsWith("$")?n:typeof n=="string"?{[`$${typeof n}`]:`x1b[Yellowm${n}x1b[0m`}:typeof n=="number"?{[`$${typeof n}`]:`x1b[Magentam${n}x1b[0m`}:typeof n=="boolean"?{[`$${typeof n}`]:`x1b[Magentam${n}x1b[0m`}:n,2).replace(/\{\s*"\$(string)":\s*"(.*?)"\s*\}/g,'"$2"').replace(/\{\s*"\$(number|boolean)":\s*"(.*?)"\s*\}/g,"$2").replace(/"([^"]+)":/g,"x1b[Redm$1x1b[0m:");return qt.createElement(Lt,null,t.split("x1b[").map((e,n)=>{let[r]=e.split("m",2);return qt.createElement(Lt,{key:n,color:r!=="0"?r:void 0},e.substring(r.length+1))}))}import{stat as Ft,writeFile as be,readFile as de,unlink as yt}from"node:fs/promises";import{tmpdir as me}from"node:os";import{join as fe}from"node:path";import Nt from"react-curse";var gt=m=>{let t=process.env.EDITOR||"vim",e=fe(me(),`mngr-${+new Date}.json`),n=JSON.stringify(m,void 0,2).split(`
`).map(r=>r.startsWith(" ")&&r.substring(1)).filter(r=>r).join(`
`);return new Promise(r=>{(async()=>{await be(e,n);let s=(await Ft(e)).mtimeMs,i=async()=>{let o=(await Ft(e)).mtimeMs;if(s===o)return yt(e),r([]);let u=await de(e,{encoding:"utf8"});if(u.length===0)return yt(e),r([]);try{let f=JSON.parse(`[${u.trim().replace(/},$/,"}")}]`);yt(e),r(f)}catch{Nt.spawnSync(t,[e],{stdio:"inherit"}),i()}};Nt.spawnSync(t,[e],{stdio:"inherit"}),i()})()})};import j,{useCallback as pt,useEffect as Pt,useMemo as st,useRef as ye,useState as B}from"react";import{Text as I,Input as Rt,ListTable as ge,View as pe,useClipboard as he,useInput as we,useSize as Ee,useMouse as je}from"react-curse";var ht=class{constructor(t,e={}){this.text=t,this.props=e}toString(){return this.text}},$e=({item:m,widths:t})=>j.createElement(j.Fragment,null,m.map(({text:e,props:n},r)=>j.createElement(I,{key:r,...n,width:t[r]},e))),xe=({focus:m,item:t,y:e,x:n,widths:r,index:s,pass:i})=>{let{selected:o,palette:u}=i,f=(b,a)=>b===void 0?"":b===null?"null":b.toString().length<=a?b.toString():j.createElement(I,null,b.toString().substring(0,a-1),j.createElement(I,{dim:!0},"~"));return j.createElement(I,{color:o.includes(s)?"Yellow":void 0,width:"100%"},t.map((b,a)=>j.createElement(I,{key:a,width:r[a],dim:b===null,color:e===s&&n===a?"Yellow":void 0,background:e===s&&m&&n===a?u.dark1:void 0},f(b,r[a]))))};function wt(){let{width:m,height:t}=Ee(),e=nt(),[,n]=he(),r=ye({}),s=x(c=>c.focus),i=x(c=>c.status),o=x(c=>c.tables),u=x(c=>c.table),f=x(c=>c.count),b=x(c=>c.cols),a=x(c=>c.rows),y=x(c=>c.palette),[l,E]=B({y:0,x:0,yo:0,xo:0,x1:0,x2:0}),[h,A]=B({where:{},order:{},skip:0,limit:100}),[T,N]=B([]),[P,ot]=B(null),[V,it]=B(null),[O,G]=B(""),[d,L]=B(""),q=c=>{let p=c.replace(/Id$/,"").replace(/_id$/,"").toLowerCase();return o.findIndex(w=>[p,`${p}s`,`${p}es`].includes(w.toLowerCase()))},U=st(()=>b.map(({type:c,name:p})=>{let[w,$]=c.split(/[()]/),S=w.toLowerCase().replaceAll(" ","_").replace(/_^/,""),M=Object.entries(e.types()).find(([Qt])=>S.startsWith(Qt))?.[1],at=M?.icon||c,K=$||"",lt=M?.color,X=h.order[p]!==void 0?` ${h.order[p]===1?"\uF0DE":"\uF0DD"}`:"",Zt=[-1,u].includes(q(p))?"":" \uEB15";return new ht(`${at}${K} ${p}${X}${Zt}`,{color:lt})}),[b,h.order]),_=st(()=>e.format?.(b,a)||a,[b,a]),F=st(()=>_.map(c=>b.map(({name:p})=>c[p])),[_]),St=st(()=>{let c=h.skip+F.length;return` ${f>0?`${h.skip+1}-`:""}${c}${c!==f?`/${f}`:""} `},[h.skip,F,f]),Tt=st(()=>` ${l.y+1}:${l.x+1} `,[l.y,l.x]),Y=async()=>{let[c,p,w,$]=await e.rows(o[u],h.where,h.order,h.skip,h.limit);return g("setCount",p),g("setSql",c),g("setCols",$??await e.cols(o[u])),g("setRows",w),w},Yt=pt(c=>{a[c.y]!==void 0&&(E(c),g("setFocus","main/edit"))},[a]),Ht=()=>({initialValue:_[l.y][b[l.x].name]?.toString()||"",y:l.y-l.yo,x:l.x1-l.xo,width:l.x2-l.x1}),Wt=pt(c=>{(async()=>{g("setFocus","main");let p=a[l.y],w={...p,[b[l.x].name]:c},$=await e.update(o[u],b,[w],[p]);$.length!==0&&(g("setStatus",`"${$}" written`),Y())})()},[a,l,b,o,u]),Bt=async()=>{if(a.length===0)return;let c=T.length>0?T.map($=>a[$]):[a[l.y]],p=await gt(c);if(p.length===0)return;let w=await e.update(o[u],b,p,c);w&&(g("setStatus",`"${w}" written`),Y(),T.length>0&&N([]))},Ot=async(c=!1)=>{if(c&&a.length===0)return;let p=c?T.length>0?T.map(M=>a[M]):[a[l.y]]:void 0,w=await e.template(o[u],b,p),$=await gt(w);if($.length===0)return;let S=await e.insert(o[u],b,$);S&&(g("setStatus",`"${S}" inserted`),Y(),T.length>0&&N([]))},Ut=()=>{N(T.includes(l.y)?T.filter(c=>c!==l.y):[...T,l.y]),E({...l,y:l.y+1})},Jt=()=>{if(a.length===0)return;it("dD");let c=e.id(b),p=T.length>0?T.map(w=>a[w][c]):[a[l.y][c]];g("setStatus",`Confirm deletion of: ${p.map(w=>`"${w}"`).join(", ")} ? (y/N)`)},zt=async()=>{let c=e.id(b),p=a[l.y][c],w=await e.delete(o[u],b,T.length>0?T.map(M=>a[M][c]):p);if(!w)return;g("setStatus",`"${w}" deleted`);let S=(await Y()).findIndex(M=>M[c]===p);S>-1&&S!==l.y&&E({...l,y:S}),T.length>0&&N([])},Vt=()=>{if(!b[l.x])return;let{type:c,name:p}=b[l.x],w=["text"].includes(c)?":":"=";L(p?`/${p}${w}`:""),g("setFocus","main/search")},Gt=pt(c=>{g("setFocus","main");let p=c.match(/^\/([A-Za-z_]+)([:=])(.+)$/);if(p===null)return A({...h,where:{}});let[,w,$]=p,S=p[3];parseFloat(S).toString()===S&&(S=parseFloat(S)),A({...h,where:{...h.where,[w]:$===":"?{$regex:S}:S}})},[h]),Ct=async c=>{if(a.length===0||b.length===0||a[l.y][b[l.x].name]===void 0)return;let{name:p,type:w}=b[l.x],$=a[l.y],S=$[p],M;switch(w){case"boolean":{M=!S;break}case"number":{M=S+c;break}case"string":{let K;if(K=S.match(/(-?\d+[,.]?\d*)$/)){let[,lt]=K,{index:X}=K;(X===0||!S[X-1].match(/[-\d,.]/))&&(M=S.substring(0,X)+(parseFloat(lt)+c))}break}}if(M===void 0)return;let at=await e.update(o[u],b,[{...$,[p]:M}],[$]);at&&(g("setStatus",`"${at}" written`),Y())},Kt=()=>{if(a.length===0||b.length===0||a[l.y][b[l.x].name]===void 0)return;let{name:c}=b[l.x],w=a[l.y][c],$=q(c);$!==-1&&(g("setTable",$),r.current={where:{id:w}})},Xt=()=>{if(a.length===0||b.length===0||a[l.y][b[l.x].name]===void 0)return;let c=n(a[l.y][b[l.x].name]);c&&g("setStatus",`${c.length} chars yanked`)};return Pt(()=>{E({...l,y:0,x:0}),A({order:{},where:r.current?.where||{},skip:0,limit:100}),N([]),ot(null),r.current&&(r.current={})},[o,u]),Pt(()=>{o.length!==0&&Y()},[h]),we(c=>{if(s==="main"){if(i&&g("setStatus"),V&&(it(null),["y","Y"].includes(c))){V==="dD"&&zt();return}if(c.match(/\d/)){G(O+c);return}if(c===""&&Ct(parseInt(O)||1),c===""&&Ct((parseInt(O)||1)*-1),O===""&&["u","d"].includes(c))G(c);else if(O!==""){O==="u"&&c==="v"&&N([]),O==="d"&&c==="D"&&Jt(),O.match(/^\d+$/)&&(c==="k"&&E({...l,y:l.y-parseInt(O)}),c==="j"&&E({...l,y:l.y+parseInt(O)}),["g","G"].includes(c)&&E({...l,y:parseInt(O)-1})),G("");return}c==="-"&&F.length>0&&A({...h,order:{[b[l.x].name]:-1}}),c==="_"&&F.length>0&&A({...h,order:{...h.order,[b[l.x].name]:-1}}),c==="="&&F.length>0&&A({...h,order:{[b[l.x].name]:1}}),c==="+"&&F.length>0&&A({...h,order:{...h.order,[b[l.x].name]:1}}),c==="\x7F"&&A({order:{},where:{},skip:0,limit:100}),c===" "&&g("setFocus","sidebar"),c==="E"&&Bt(),c==="r"&&Y(),c==="Y"&&Ot(!0),c==="i"&&ot(P===null?a[l.y]:null),c==="["&&h.skip>0&&A({...h,skip:Math.max(0,h.skip-h.limit)}),c==="]"&&h.skip<f-h.limit&&A({...h,skip:Math.max(0,Math.min(f-a.length,h.skip+h.limit))}),c==="A"&&Ot(),c==="/"&&Vt(),c===" "&&Ut(),c==="."&&Kt(),c==="y"&&Xt()}},[s,i,V,O,b,l,a,h,P,f]),je(c=>{["sidebar","main"].includes(s)&&["mousedown","wheeldown","wheelup"].includes(c.type)&&(c.y<1||c.y>t-3||c.x<=16||(s!=="main"&&g("setFocus","main"),c.type==="mousedown"&&E({...l,y:l.yo+Math.max(0,Math.min(t-5,c.y-2)),xm:c.x-16}),c.type==="wheelup"&&l.y>0&&E({...l,y:l.y-1}),c.type==="wheeldown"&&l.y<F.length&&E({...l,y:l.y+1})))},[s,l]),j.createElement(j.Fragment,null,!P&&F.length===0&&s==="main"&&j.createElement(I,{dim:!0},"empty"),!P&&F.length>0&&j.createElement(j.Fragment,null,j.createElement(ge,{focus:s==="main",initialPos:l,head:U,renderHead:$e,data:F,renderItem:xe,width:m-16,height:t-3,pass:{selected:T,palette:y},scrollbarBackground:y.dark1,scrollbarColor:y.light4,onChange:E,onSubmit:Yt}),s==="main/edit"&&j.createElement(I,{y:1,x:0},j.createElement(Rt,{...Ht(),height:1,background:y.dark2,color:y.light1,onSubmit:Wt,onCancel:()=>g("setFocus","main")}))),P&&j.createElement(pe,{focus:s==="main",width:m-16,height:t-3},ft(P)),j.createElement(I,{absolute:!0,y:"100%-2",x:`100%-${St.length+Tt.length+2}`,height:1,bold:!0},j.createElement(I,{background:y.dark1,color:y.dark2},"\uE0B2"),j.createElement(I,{background:y.dark2,color:y.light1},St),j.createElement(I,{background:y.dark2,color:y.light4},"\uE0B2"),j.createElement(I,{background:y.light4,color:y.dark0,bold:!0},Tt)),j.createElement(I,{absolute:!0,y:"100%-1",x:0,height:1},s!=="main/search"&&i,s==="main/search"&&j.createElement(Rt,{initialValue:d,onCancel:()=>g("setFocus","main"),onSubmit:Gt})),O&&j.createElement(I,{absolute:!0,y:"100%-1",x:"100%-11"},O))}import k,{useCallback as Et,useEffect as _t,useMemo as Se,useState as ct}from"react";import{Input as jt,Text as z,List as Te,useInput as Oe,useMouse as Ce,useSize as De}from"react-curse";function $t(){let{height:m}=De(),t=nt(),e=x(d=>d.focus),n=x(d=>d.status),r=x(d=>d.tables),s=x(d=>d.table),i=x(d=>d.palette),[o,u]=ct({y:s,x:0,yo:0,xo:0,x1:0,x2:0}),[f,b]=ct(null),[a,y]=ct(""),[l,E]=ct([]),h=Se(()=>Math.min(m-4,r.length),[m,r]),A=()=>{r.length!==0&&(s!==o.y&&g("setTable",o.y),g("setFocus","main"))},T=async()=>{g("setFocus","sidebar/create")},N=Et(d=>{(async()=>{if(g("setFocus","sidebar"),d=d.trim(),d===""||!await t.createTable(d))return;let q=await t.tables(),U=q.findIndex(_=>_===d);g("setTables",q),u({...o,y:U}),g("setTable",U),g("setFocus","main")})()},[]),P=()=>{r.length!==0&&g("setFocus","sidebar/edit")},ot=Et(d=>{(async()=>{if(g("setFocus","sidebar"),d=d.trim(),d===""||!await t.renameTable(r[o.y],d))return;let q=await t.tables();g("setTables",q),g("setTable",o.y),g("setFocus","main")})()},[r,o.y]),V=()=>{r.length!==0&&(b("dD"),g("setStatus",`Confirm deletion of: "${r[o.y]}" ? (y/N)`))},it=async()=>{if(!await t.dropTable(r[o.y]))return;let L=await t.tables();g("setTables",L),o.y===s&&(g("setCols",[]),g("setRows",[]))},O=Et(d=>{if(d==="")return;let L=r.reduce((q,U,_)=>(U.toLowerCase().includes(d.toLowerCase())&&q.push(_),q),[]);L.length!==0&&(u({...o,y:L[0]}),E(L))},[r,o]),G=()=>{if(l.length<2)return;let d=[...l.slice(1),l[0]];u({...o,y:d[0]}),E(d)};return _t(()=>{(async()=>{let d=await t.tables();g("setTables",d),e===null&&g("setFocus",d.length>0?"main":"sidebar")})()},[]),_t(()=>{u({...o,y:s})},[s]),Oe(d=>{if(e==="sidebar"){if(n&&g("setStatus"),f&&(b(null),["y","Y"].includes(d))){f==="dD"&&it();return}if(d.match(/\d/)){y(a+d);return}if(a===""&&["r","d"].includes(d))y(d);else if(a!==""){a==="r"&&d==="n"&&P(),a==="d"&&d==="D"&&V(),a.match(/^\d+$/)&&(d==="k"&&u({...o,y:o.y-parseInt(a)}),d==="j"&&u({...o,y:o.y+parseInt(a)}),["g","G"].includes(d)&&u({...o,y:parseInt(a)-1})),y("");return}[" ","\r"].includes(d)&&A(),d==="A"&&T(),d==="/"&&g("setFocus","sidebar/search"),d==="n"&&G()}},[e,n,f,a,A]),Ce(d=>{["sidebar","main"].includes(e)&&["mousedown","wheeldown","wheelup"].includes(d.type)&&(d.y<1||d.y>m-3||d.x>=16||(e!=="sidebar"&&g("setFocus","sidebar"),d.type==="mousedown"&&u({...o,y:o.yo+Math.max(0,Math.min(m-5,d.y-1))}),d.type==="wheelup"&&o.y>0&&u({...o,y:o.y-1}),d.type==="wheeldown"&&o.y<r.length&&u({...o,y:o.y+1})))},[e,o]),k.createElement(k.Fragment,null,r.length===0&&e==="sidebar"&&k.createElement(z,{dim:!0},"empty"),r.length>0&&k.createElement(k.Fragment,null,k.createElement(Te,{focus:e==="sidebar",initialPos:o,data:r,renderItem:({item:d,focus:L,selected:q})=>k.createElement(z,{color:q?"Green":void 0,background:q&&L?i.dark1:void 0,width:"100%"},"\uF0CE ",d),width:16,height:m-3,scrollbar:!1,scrollbarBackground:i.dark1,scrollbarColor:i.light4,onChange:u}),e==="sidebar/edit"&&k.createElement(jt,{y:o.y,x:2,width:14,initialValue:r[o.y],height:1,background:i.dark2,color:i.light1,onSubmit:ot,onCancel:()=>g("setFocus","sidebar")})),e==="sidebar/create"&&k.createElement(z,{y:h,x:0},k.createElement(z,null,"\uF9EB "),k.createElement(jt,{width:14,height:1,background:i.dark2,color:i.light1,onSubmit:N,onCancel:()=>g("setFocus","sidebar")})),k.createElement(z,{absolute:!0,y:"100%-1",x:0,height:1},e==="sidebar/search"&&k.createElement(jt,{onChange:O,onSubmit:()=>g("setFocus","sidebar"),onCancel:()=>g("setFocus","sidebar")})),a&&k.createElement(z,{absolute:!0,y:"100%-1",x:"100%-11"},a))}import D,{useMemo as Me,useState as Ie}from"react";import xt,{Text as R,Separator as ke,useInput as Ae,useSize as qe}from"react-curse";dt(rt);var Le=()=>{let{height:m}=qe(),t=x(o=>o.focus),e=x(o=>o.sql),n=x(o=>o.palette),[r,s]=Ie(!1),i=Me(()=>{let[o]=rt.split("://",2);return{json:"\uE60B ",mariadb:"\uE704 ",mongodb:"\uE7A4 ",postgresql:"\uE76E ",sqlite:"\uE7C4 "}[o]},[rt]);return Ae(o=>{[null,"sidebar","main"].includes(t)&&(o==="\r"&&xt.exit(),o==="q"&&xt.exit(),o==="?"&&s(u=>!u),o==="\x1B"&&r&&s(!1))},[t,r]),D.createElement(D.Fragment,null,D.createElement(R,{height:1,color:n.light4,background:n.dark1},D.createElement(R,{x:"100%-17",color:n.dark3},"press ",D.createElement(R,{bold:!0},"?")," for help"),D.createElement(R,{y:0,x:0})," "+i+rt+" "),D.createElement(R,{y:"100%-2",x:0,height:1,color:n.light4,background:n.dark1}," \uEAB6 "+e),D.createElement(R,{y:1,x:0,height:"100%-3"},D.createElement(R,{width:16},D.createElement($t,null)),D.createElement(ke,{height:m-3,color:n.dark1}),D.createElement(R,null,D.createElement(wt,null))),r&&D.createElement(bt,null))};xt.render(D.createElement(Le,null));