toad-cli
Version:
The command line interface for communicating with toad-server
4 lines (3 loc) • 5.33 kB
JavaScript
import{program as a}from"commander";import E from"conf";var f=new E({projectName:"toad-cli",projectSuffix:"",defaults:{token:"",domain:""}});import{requests as S}from"@sunney/requests";var i=o=>{let{domain:t,token:r}=o??f.store;if(t){if(!r)throw new Error("Token not set. Please run `toad setup` first.")}else throw new Error("Domain not set. Please run `toad setup` first.");let p=t.includes("0.0.0.0")?"http":"https",c=S.client({baseUrl:`${p}://${t}/api`,headers:{Authorization:`Bearer ${r}`}});return c.intercept({onResponse:(s,d,m)=>{let e=m.data;if(typeof e=="string"){!m.ok&&!e?console.log(`Request to ${s} failed with status ${m.status}`):console.log(e);return}if(e.ok)console.log(e.message);else{let u=e.message&&e.error?`${e.message}: ${e.error}`:e.message&&!e.error?e.message:e.error??"Unknown error";console.error(u)}}}),c};import P from"prompts";var k=()=>P({type:"password",name:"token",message:"Your toad token",validate:o=>o.length>0?!0:"Please provide a valid value"}).then(o=>o.token),C=()=>P({type:"text",name:"domain",message:"Your toad domain",validate:o=>o.length>0?!0:"Please provide a valid value"}).then(o=>o.domain);async function l({token:o,domain:t}){if(o||(o=await k()),t||(t=await C()),!(await i({token:o,domain:t}).get("/auth")).ok)throw new Error("Invalid token or domain");f.set("token",o),f.set("domain",t),console.log("Setup complete, succesfully authenticated! \u{1F389}")}import b from"path";import $ from"fs";var n=class{constructor(t){this.exists=!1;this.baseDirectory=t??process.cwd(),this.name=void 0,this.commands={},this.appDomain=void 0,this.env=void 0,this.load()}setName(t){return this.name=t,this}async save(t){return this.name=t.name,this.commands=t.commands,this.appDomain=t.appDomain,this.env=t.env,$.promises.writeFile(`${this.baseDirectory}/toad.config.json`,JSON.stringify(t,null,2))}load(){try{let t=$.readFileSync(`${this.baseDirectory}/toad.config.json`),r=JSON.parse(t.toString());this.exists=!0,this.name=r.name,this.commands=r.commands,this.appDomain=r.appDomain,this.env=r.env}catch{this.exists=!1}}};import D from"prompts";async function g(o,t){let r=process.cwd(),{directoryAcceptable:p}=await D({type:"confirm",name:"directoryAcceptable",message:`Would you like to create a new project in ${r}?`,initial:"y"});if(!p)throw new Error("Exiting...");let c=b.basename(r),{projectName:s}=await D({type:"text",name:"projectName",message:"What do you want to name your project?",initial:o||c,validate:e=>/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e)?!0:"Please enter a project name"});if(typeof s!="string")throw new Error("Invalid project name");let d=await i().get("/projects").then(e=>e.data.projects);if(d&&d.find(u=>u.name===s))throw new Error("A project with that name already exists");let m=new n().setName(s);if(m.exists&&s==m.name)throw new Error(`Project ${s} is already initialized`);await m.save({name:s,appDomain:t?.appDomain})}import{promises as w}from"fs";import T from"tar";import z from"os";var R=[".toad","node_modules","dist","build","coverage","__pycache__"];async function h(){let o=process.cwd(),t=new n;if(!t.exists)throw new Error("Project not initialized, please run `toad init` first");if(!t.name)throw new Error("Project name not set, please run `toad init` first");let p=`${await w.mkdtemp(`${z.tmpdir()}/.toad`)}/${t.name}-${Date.now()}.tar.gz`;console.log("Creating bundle..."),await T.c({gzip:!0,file:p,cwd:o,filter:s=>!R.some(d=>s.includes(d))},["."]),console.log("Uploading bundle...");let c=await w.readFile(p);await i().post(`/up/${t.name}`,{headers:{"Content-Type":"application/octet-stream"},body:c}).finally(()=>w.rm(p,{recursive:!0,force:!0}))}async function j(){let t=(await i().get("/projects")).data.map(r=>`${r.name} - status: ${r.process?.status}
`);console.log(t.join(""))}async function y(o){console.log("Stopping project",o);let t=new n;if(!o){if(!t.exists)throw new Error("Project not initialized, please run `toad init` first");if(!t.name)throw new Error("Project name not set, please run `toad init` first");o=t.name}await i().post(`/stop/${o}`)}async function x(o){let t=new n;if(!o){if(!t.exists)throw new Error("Project not initialized, please run `toad init` first");if(!t.name)throw new Error("Project name not set, please run `toad init` first");o=t.name}console.log("Starting project",o),await i().post(`/start/${o}`)}async function v(o){let t=new n;if(!o){if(!t.exists)throw new Error("Project not initialized, please run `toad init` first");if(!t.name)throw new Error("Project name not set, please run `toad init` first");o=t.name}await i().get(`/status/${o}`)}a.version("0.0.1").description("Toad CLI");a.command("setup").description("Setup toad CLI").option("-t, --token <token>","Your toad token").option("-d, --domain <domain>","Your toad domain").action(l);a.command("init [name]").option("-ad, --appDomain <app_domain>","Your app domain (for Caddy)").description("Initialize a new project").action(g);a.command("up").description("Upload your project").action(h);a.command("projects").description("Show all projects").action(j);a.command("status [project]").description("Show project status").action(v);a.command("stop [project]").description("Stop a project").action(y);a.command("start [project]").description("Start a project").action(x);a.parseAsync(process.argv);