@dashnex/cli 0.5.4 → 0.5.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +2 -1
  2. package/dist/cli.js +1 -1
  3. package/dist/commands/create.js +1 -1
  4. package/dist/commands/delete.js +1 -1
  5. package/dist/commands/deploy.js +1 -0
  6. package/dist/commands/dev.js +1 -0
  7. package/dist/commands/index.js +1 -1
  8. package/dist/commands/install.js +1 -0
  9. package/dist/commands/login.js +1 -1
  10. package/dist/commands/pull.js +1 -1
  11. package/dist/commands/push.js +1 -1
  12. package/dist/commands/whoami.js +1 -1
  13. package/dist/lib/api.js +1 -1
  14. package/dist/lib/errors.js +1 -0
  15. package/dist/lib/spinner.js +1 -0
  16. package/dist/package.json.js +1 -1
  17. package/dist/services/auth.js +1 -1
  18. package/dist/{commands → src/commands}/create.d.ts +4 -0
  19. package/dist/src/commands/deploy.d.ts +4 -0
  20. package/dist/src/commands/dev.d.ts +4 -0
  21. package/dist/src/commands/install.d.ts +4 -0
  22. package/dist/{commands → src/commands}/pull.d.ts +3 -1
  23. package/dist/{lib → src/lib}/api.d.ts +2 -1
  24. package/dist/src/lib/errors.d.ts +2 -0
  25. package/dist/src/lib/spinner.d.ts +6 -0
  26. package/package.json +5 -6
  27. /package/dist/{cli.d.ts → src/cli.d.ts} +0 -0
  28. /package/dist/{client.d.ts → src/client.d.ts} +0 -0
  29. /package/dist/{commands → src/commands}/delete.d.ts +0 -0
  30. /package/dist/{commands → src/commands}/index.d.ts +0 -0
  31. /package/dist/{commands → src/commands}/login.d.ts +0 -0
  32. /package/dist/{commands → src/commands}/logout.d.ts +0 -0
  33. /package/dist/{commands → src/commands}/push.d.ts +0 -0
  34. /package/dist/{commands → src/commands}/version.d.ts +0 -0
  35. /package/dist/{commands → src/commands}/whoami.d.ts +0 -0
  36. /package/dist/{lib → src/lib}/debug.d.ts +0 -0
  37. /package/dist/{server.d.ts → src/server.d.ts} +0 -0
  38. /package/dist/{services → src/services}/auth.d.ts +0 -0
package/README.md CHANGED
@@ -30,6 +30,7 @@ npx @dashnex/cli <command> [options]
30
30
  | `delete` | Delete application from DashNex |
31
31
  | `whoami` | Show current logged-in business and user |
32
32
 
33
+
33
34
  ### Options
34
35
 
35
- - **create**: `-t, --template <template>` — Template (name@branch-or-tag, default: webapp-base@live)
36
+ - **create**: `-t, --template <template>` — Template (name@branch-or-tag, default: webapp-base@live)
package/dist/cli.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{Command as o}from"commander";import e from"chalk";import n from"fs-extra";import s from"path";import t from"dotenv";import r from"./package.json.js";const c=new o,{name:a,version:i,description:d}=r;async function p(o,t){const r=[];try{const e=function(o,e){const t=s.join(e,"package.json");if(n.existsSync(t))try{if(JSON.parse(n.readFileSync(t,"utf8")).name===o)return e}catch{}return s.join(e,"node_modules",o)}(o,t),c=s.join(e,"dist","commands","index.js");if(n.existsSync(c)){const o=await import(c);let e=[];o.default?e=Array.isArray(o.default)?o.default:[]:o.commands&&(e=Array.isArray(o.commands)?o.commands:[]),e.length>0&&r.push(...e)}}catch(c){if(process.env.DEBUG){const n=c instanceof Error?c.message:String(c);console.log(e.yellow(`Module ${o} has no commands or failed to load: ${n}`))}}return r}function f(o,n,s={}){const t=o.command(n.name).description(n.description);n.options&&n.options.forEach(o=>{void 0!==o.defaultValue?"number"==typeof o.defaultValue?t.option(o.flags,o.description,String(o.defaultValue)):t.option(o.flags,o.description,o.defaultValue):t.option(o.flags,o.description)}),n.subcommands&&n.subcommands.forEach(o=>{f(t,o,{...s,...n.options})}),t.action(async(o,t)=>{try{const e={...s,...o};await n.handler.execute(e)}catch(r){console.error(e.red(`❌ Command failed in ${n.name}:`),r),process.exit(1)}})}c.name(a).description(d).version(i),async function(){t.config({quiet:!0}),process.env.DASHNEX_CLI="1";let o=process.cwd();process.env.DEBUG&&console.log(`CLI started from directory: ${o}`);const r=await async function(o){try{const e=[],t=/* @__PURE__ */new Set,r=o=>{t.has(o)||(t.add(o),e.push(o))},c=s.join(o,"dashnex.json");if(n.existsSync(c)){const e=s.join(o,"package.json");if(n.existsSync(e)){const o=JSON.parse(n.readFileSync(e,"utf8"));o.name&&r(o.name)}}const a=s.join(o,"package.json");if(!n.existsSync(a))return e;const i=JSON.parse(n.readFileSync(a,"utf8")),d={...i.dependencies,...i.devDependencies,...i.optionalDependencies};for(const[p]of Object.entries(d)){const e=s.join(o,"node_modules",p);n.existsSync(s.join(e,"dashnex.json"))&&r(p)}return e}catch(e){if(process.env.DEBUG){const o=e instanceof Error?e.message:String(e);console.log("⚠ Error reading app package.json:",o)}return[]}}(o);process.env.DEBUG&&console.log(`Discovered modules: ${r.join(", ")}`);for(const e of r){const n=await p(e,o);for(const o of n)f(c,o)}try{const{default:e}=await import(s.join(o,"dist","commands","index.js"));if(e&&Array.isArray(e))for(const o of e)f(c,o)}catch(a){process.env.DEBUG&&console.error(e.yellow("⚠ Failed to discover application commands"))}c.parse(process.argv),process.argv.slice(2).length||c.outputHelp()}().catch(o=>{console.error(e.red("❌ CLI failed:"),o),process.exit(1)});
2
+ import{Command as o}from"commander";import e from"chalk";import n from"fs-extra";import s from"path";import{fileURLToPath as a}from"url";import c from"dotenv";import r from"./package.json.js";import{isUserInterrupt as t,INTERRUPTED_MESSAGE as i}from"./lib/errors.js";const l=new o,{name:d,version:m,description:p}=r;async function f(o,a){const c=[];try{const e=function(o,e){const a=s.join(e,"package.json");if(n.existsSync(a))try{if(JSON.parse(n.readFileSync(a,"utf8")).name===o)return e}catch{}return s.join(e,"node_modules",o)}(o,a),r=s.join(e,"dist","commands","index.js");if(n.existsSync(r)){const o=await import(r);let e=[];o.default?e=Array.isArray(o.default)?o.default:[]:o.commands&&(e=Array.isArray(o.commands)?o.commands:[]),e.length>0&&c.push(...e)}}catch(r){if(process.env.DEBUG){const n=r instanceof Error?r.message:String(r);console.log(e.yellow(`Module ${o} has no commands or failed to load: ${n}`))}}return c}function u(o,n,s={}){const a=o.command(n.name).description(n.description);"pull"===n.name&&a.arguments("[folder]"),n.options&&n.options.forEach(o=>{void 0!==o.defaultValue?"number"==typeof o.defaultValue?a.option(o.flags,o.description,String(o.defaultValue)):a.option(o.flags,o.description,o.defaultValue):a.option(o.flags,o.description)}),n.subcommands&&n.subcommands.forEach(o=>{u(a,o,{...s,...n.options})}),"pull"===n.name?a.action(async(o,a,c)=>{try{const e={...s,...a};o&&(e.folder=o),await n.handler.execute(e)}catch(r){if(t(r))return void console.log(e.yellow(i));console.error(e.red(`❌ Command failed in ${n.name}:`),r),process.exit(1)}}):a.action(async(o,a)=>{try{const e={...s,...o};await n.handler.execute(e)}catch(c){if(t(c))return void console.log(e.yellow(i));console.error(e.red(`❌ Command failed in ${n.name}:`),c),process.exit(1)}})}l.name(d).description(p).version(m),async function(){c.config({quiet:!0}),process.env.DASHNEX_CLI="1";let o=process.cwd();const r=s.dirname(a(import.meta.url)),t=s.resolve(r,"..");process.env.DEBUG&&(console.log(`CLI started from directory: ${o}`),console.log(`CLI package directory: ${t}`));const i=await async function(o){try{const e=[],a=/* @__PURE__ */new Set,c=o=>{a.has(o)||(a.add(o),e.push(o))},r=s.join(o,"dashnex.json");if(n.existsSync(r)){const e=s.join(o,"package.json");if(n.existsSync(e)){const o=JSON.parse(n.readFileSync(e,"utf8"));o.name&&c(o.name)}}const t=s.join(o,"package.json");if(!n.existsSync(t))return e;const i=JSON.parse(n.readFileSync(t,"utf8")),l={...i.dependencies,...i.devDependencies,...i.optionalDependencies};for(const[d]of Object.entries(l)){const e=s.join(o,"node_modules",d);n.existsSync(s.join(e,"dashnex.json"))&&c(d)}return e}catch(e){if(process.env.DEBUG){const o=e instanceof Error?e.message:String(e);console.log("⚠ Error reading app package.json:",o)}return[]}}(o),d=t.includes("node_modules");let m=!1;try{const e=s.join(o,"package.json");if(await n.pathExists(e)){const o=JSON.parse(await n.readFile(e,"utf8"));m="@dashnex/cli"in{...o.dependencies,...o.devDependencies,...o.optionalDependencies}}}catch{}!d&&!m||i.includes("@dashnex/cli")||i.push("@dashnex/cli"),process.env.DEBUG&&(console.log(`CLI package directory: ${t}`),console.log(`Is installed package: ${d}`),console.log(`CLI in dependencies: ${m}`),console.log(`Discovered modules: ${i.join(", ")}`));for(const a of i){let c=[];if("@dashnex/cli"===a&&(d||m))try{const o=s.join(t,"dist","commands","index.js");if(process.env.DEBUG&&console.log(`Loading @dashnex/cli commands from: ${o}`),await n.pathExists(o)){const e=await import(o);e.default?c=Array.isArray(e.default)?e.default:[]:e.commands&&(c=Array.isArray(e.commands)?e.commands:[]),process.env.DEBUG&&console.log(`Loaded ${c.length} commands from @dashnex/cli`)}}catch(p){if(process.env.DEBUG){const o=p instanceof Error?p.message:String(p);console.log(e.yellow(`Failed to load @dashnex/cli commands: ${o}`))}}else c=await f(a,o);for(const o of c)u(l,o)}try{const{default:e}=await import(s.join(o,"dist","commands","index.js"));if(e&&Array.isArray(e))for(const o of e)u(l,o)}catch(p){process.env.DEBUG&&console.error(e.yellow("⚠ Failed to discover application commands"))}l.parse(process.argv),process.argv.slice(2).length||l.outputHelp()}().catch(o=>{t(o)&&(console.log(e.yellow(i)),process.exit(0)),console.error(e.red("❌ CLI failed:"),o),process.exit(1)});
@@ -1 +1 @@
1
- import e from"inquirer";import t from"chalk";import{debug as o,debugError as s}from"../lib/debug.js";import{getBusinessApiBase as a}from"../lib/api.js";import{ensureLoggedIn as n}from"../services/auth.js";const i=e=>Array.isArray(e.message)&&e.message.length>0?e.message.join(" "):"string"==typeof e.message?e.message:"string"==typeof e.error?e.error:void 0;class r{async execute(r={}){o("Create flow started");const c=await n();if(!c)return;o("Auth valid, checking if business already has application");const l=`${a()}/business/v1/applications`;o(`GET ${l}`);try{const e=await fetch(l,{headers:{Authorization:`Bearer ${c.token}`}});o(`Applications response: ${e.status}`),404!==e.status&&(console.error(t.red("Business already has an application. Run 'npx dashnex pull' to pull the existing one.")),process.exit(1))}catch(m){if(s(m),m instanceof Error&&m.message.startsWith("EXIT:"))throw m;console.error(t.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}let p;o("No existing application, proceeding to subdomain prompt");const u=e=>`${a()}/business/v1/applications/check-subdomain?subdomain=${encodeURIComponent(e)}`;for(;;){const{sub:a}=await e.prompt([{type:"input",name:"sub",message:"Pick your subdomain:",validate:e=>!!e.trim()||"Subdomain is required"}]);p=a.trim(),o(`Checking subdomain: ${p}`);try{const e=await fetch(u(p),{headers:{Authorization:`Bearer ${c.token}`}});if(o(`Check subdomain response: ${e.status}`),!e.ok){const o=e.headers.get("content-type")??"";let s="Failed to check subdomain availability.";if(401!==e.status&&403!==e.status||(s="Please run 'npx dashnex login' to authenticate.",console.error(t.red(s)),process.exit(1)),o.includes("application/json")){const t=await e.json().catch(()=>({})),o=i(t);o&&(s=o)}console.error(t.red(s));continue}if((await e.json()).available){o(`Subdomain ${p} is available`);break}console.error(t.red("Subdomain is not available. Please choose a different one."))}catch(m){if(s(m),m instanceof Error&&m.message.startsWith("EXIT:"))throw m;console.error(t.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}const d=`${a()}/business/v1/cli/create`;o(`POST ${d}`);const h={subdomain:p};r.template&&(h.template=r.template,o(`Template: ${r.template}`));try{const e=await fetch(d,{method:"POST",headers:{Authorization:`Bearer ${c.token}`,"Content-Type":"application/json"},body:JSON.stringify(h)});if(o(`Create response: ${e.status}`),!e.ok){const s=e.headers.get("content-type")??"";let a="Failed to create application.";if(401===e.status||403===e.status)a="Please run 'npx dashnex login' to authenticate.";else if(s.includes("application/json")){const t=await e.json().catch(()=>({}));o(`Create response body: ${JSON.stringify(t)}`);const s=i(t);s&&(a=s)}console.error(t.red(a)),process.exit(1)}o("Application created successfully"),console.log(t.green("Application is created successfully. Use 'npx dashnex pull' to pull it to your computer or 'npx dashnex deploy' to deploy it to the cloud."))}catch(m){if(s(m),m instanceof Error&&m.message.startsWith("EXIT:"))throw m;console.error(t.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}}export{r as CreateCommand};
1
+ import e from"inquirer";import t from"chalk";import{debug as o,debugError as s}from"../lib/debug.js";import{getBusinessApiBase as a}from"../lib/api.js";import{ensureLoggedIn as i}from"../services/auth.js";import{createSpinner as r}from"../lib/spinner.js";import{isUserInterrupt as n,INTERRUPTED_MESSAGE as l}from"../lib/errors.js";import{PullCommand as c}from"./pull.js";const p=e=>Array.isArray(e.message)&&e.message.length>0?e.message.join("\n"):"string"==typeof e.message?e.message:"string"==typeof e.error?e.error:void 0,u=e=>new Promise(t=>setTimeout(t,e));class d{async pollApplicationCreated(e,t,a=5e3,i=6e4){const r=Date.now();let n=0;for(;Date.now()-r<i;){n++,o(`Polling application status (attempt ${n})...`);try{const s=await fetch(e,{headers:{Authorization:`Bearer ${t}`}});if(o(`Poll response: ${s.status}`),200===s.status){const e=await s.json();if(o(`Poll response body status: ${e.status}`),"creating"!==e.status)return o(`Application status is "${e.status}", creation complete`),{ready:!0,status:e.status};o('Application status is still "creating", continuing to poll...')}}catch(l){s(l),o(`Poll attempt ${n} failed with network error`)}await u(a)}return{ready:!1}}async execute(u={}){o("Create flow started");const d=await i();if(!d)return;o("Auth valid, checking if business already has application");const h=r(),m=`${a()}/business/v1/applications`;o(`GET ${m}`),h.start("Checking application status...");try{const e=await fetch(m,{headers:{Authorization:`Bearer ${d.token}`}});h.stop(),o(`Applications response: ${e.status}`);const s=await e.text();o(`Applications response body: ${s}`),404!==e.status&&(console.error(t.red("Business already has an application. Run 'npx dashnex pull' to pull the existing one.")),process.exit(1))}catch($){if(h.stop(),s($),$ instanceof Error&&$.message.startsWith("EXIT:"))throw $;if(n($))return void console.log(t.yellow(l));console.error(t.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}let f;o("No existing application, proceeding to subdomain prompt");const y=e=>`${a()}/business/v1/applications/check-subdomain?subdomain=${encodeURIComponent(e)}`;for(;;){const{sub:a}=await e.prompt([{type:"input",name:"sub",message:"Pick your subdomain:",validate:e=>!!e.trim()||"Subdomain is required"}]);f=a.trim(),o(`Checking subdomain: ${f}`);const i=y(f);o(`GET ${i}`),h.start("Checking subdomain...");try{const e=await fetch(i,{headers:{Authorization:`Bearer ${d.token}`}});h.stop(),o(`Check subdomain response: ${e.status}`);const s=await e.text();if(o(`Check subdomain response body: ${s}`),!e.ok){const a=e.headers.get("content-type")??"";let i="Failed to check subdomain availability.";if(401!==e.status&&403!==e.status||(i="Please run 'npx dashnex login' to authenticate.",console.error(t.red(i)),process.exit(1)),a.includes("application/json")){const e=JSON.parse(s);o(`Check subdomain error body: ${JSON.stringify(e)}`);const t=p(e);t&&(i=t)}console.error(t.red(i));continue}const a=JSON.parse(s);if(o(`Check subdomain parsed body: ${JSON.stringify(a)}`),a.available){o(`Subdomain ${f} is available`);break}console.error(t.red("Subdomain is not available. Please choose a different one."))}catch($){if(h.stop(),s($),$ instanceof Error&&$.message.startsWith("EXIT:"))throw $;if(n($))return void console.log(t.yellow(l));console.error(t.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}const g=`${a()}/business/v1/cli/create`;o(`POST ${g}`);const b={subdomain:f};u.template&&(b.template=u.template,o(`Template: ${u.template}`));const w=JSON.stringify(b);o(`Create request body: ${w}`),h.start("Creating application...");try{const i=await fetch(g,{method:"POST",headers:{Authorization:`Bearer ${d.token}`,"Content-Type":"application/json"},body:w});h.stop(),o(`Create response: ${i.status}`);const r=await i.text();if(o(`Create response body: ${r}`),503===i.status){o("Create returned 503, polling for application creation..."),console.log(t.yellow("Application is being created, please wait..."));const e=`${a()}/business/v1/applications`,s=await this.pollApplicationCreated(e,d.token);s.ready||(console.error(t.red("Application creation is taking longer than expected. Try again later or run 'npx dashnex pull' to check.")),process.exit(1)),"failed"===s.status&&(console.error(t.red("Application creation failed. Please try again.")),process.exit(1)),o("Application found after polling")}else if(!i.ok){const e=i.headers.get("content-type")??"";let s="Failed to create application.";if(401===i.status||403===i.status)s="Please run 'npx dashnex login' to authenticate.";else if(e.includes("application/json")){const e=JSON.parse(r);o(`Create error body parsed: ${JSON.stringify(e)}`);const t=p(e);t&&(s=t)}console.error(t.red(s)),process.exit(1)}o("Application created successfully");const{pull:u}=await e.prompt([{type:"confirm",name:"pull",message:"Pull the application locally?",default:!0}]);if(o(`User chose to pull: ${u}`),u){o("Running pull flow");try{const e=new c;await e.execute()}catch($){if(s($),$ instanceof Error&&$.message.startsWith("EXIT:"))throw $;if(n($))return void console.log(t.yellow(l));console.error(t.red("Failed to pull application."))}}else console.log(t.green("Application is created successfully. Run 'dashnex pull' to pull it to your computer or 'dashnex deploy' to deploy it to the cloud."))}catch($){if(h.stop(),s($),$ instanceof Error&&$.message.startsWith("EXIT:"))throw $;if(n($))return void console.log(t.yellow(l));console.error(t.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}}export{d as CreateCommand};
@@ -1 +1 @@
1
- import e from"chalk";import{debug as t,debugError as s}from"../lib/debug.js";import{getBusinessApiBase as o}from"../lib/api.js";import{ensureLoggedIn as a}from"../services/auth.js";class r{async execute(){t("Delete flow started");const r=await a();if(!r)return;const i=`${o()}/business/v1/applications`;t(`DELETE ${i}`);try{const s=await fetch(i,{method:"DELETE",headers:{Authorization:`Bearer ${r.token}`}});if(t(`Response: ${s.status}`),!s.ok){const t=s.headers.get("content-type")??"";let o="Failed to delete application.";if(401===s.status||403===s.status)o="Please run 'npx dashnex login' to authenticate.";else if(t.includes("application/json")){const e=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await s.json().catch(()=>({})));e&&(o=e)}console.error(e.red(o)),process.exit(1)}const o=await s.json().catch(()=>({})),a="string"==typeof o.message?o.message:"Application deleted successfully.";t("Application deleted successfully"),console.log(e.green(a))}catch(n){if(s(n),n instanceof Error&&n.message.startsWith("EXIT:"))throw n;console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}}export{r as DeleteCommand};
1
+ import e from"inquirer";import t from"chalk";import{debug as o,debugError as s}from"../lib/debug.js";import{getBusinessApiBase as r}from"../lib/api.js";import{ensureLoggedIn as i}from"../services/auth.js";import{createSpinner as n}from"../lib/spinner.js";import{isUserInterrupt as a,INTERRUPTED_MESSAGE as c}from"../lib/errors.js";class l{async execute(){o("Delete flow started");const{confirm:l}=await e.prompt([{type:"confirm",name:"confirm",message:"Are you sure you want to delete this application? This action cannot be undone.",default:!1}]);if(!l)return o("User cancelled deletion"),void console.log(t.yellow("Deletion cancelled."));const p=await i();if(!p)return;const d=`${r()}/business/v1/applications`;o(`DELETE ${d}`);const f=n();f.start("Deleting application...");try{const e=await fetch(d,{method:"DELETE",headers:{Authorization:`Bearer ${p.token}`}});if(f.stop(),o(`Response: ${e.status}`),!e.ok){const o=e.headers.get("content-type")??"";let s="Failed to delete application.";if(401===e.status||403===e.status)s="Please run 'npx dashnex login' to authenticate.";else if(o.includes("application/json")){const t=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await e.json().catch(()=>({})));t&&(s=t)}console.error(t.red(s)),process.exit(1)}const s=await e.json().catch(()=>({})),r="string"==typeof s.message?s.message:"Application deleted successfully.";o("Application deleted successfully"),console.log(t.green(r))}catch(m){if(f.stop(),s(m),m instanceof Error&&m.message.startsWith("EXIT:"))throw m;if(a(m))return void console.log(t.yellow(c));console.error(t.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}}export{l as DeleteCommand};
@@ -0,0 +1 @@
1
+ import e from"chalk";import{debug as t,debugError as o}from"../lib/debug.js";import{getDeployerBase as s}from"../lib/api.js";import{ensureLoggedIn as r}from"../services/auth.js";import{createSpinner as n}from"../lib/spinner.js";import{isUserInterrupt as a,INTERRUPTED_MESSAGE as i}from"../lib/errors.js";const c=3e5,l=99,p=e=>new Promise(t=>setTimeout(t,e)),d=async(s,r,n,a)=>{const i=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${r}`,Accept:"text/event-stream"}});if(t(`SSE connection opened: ${i.status}`),!i.ok){const t=i.status;let o="Failed to start deployment.";if(401===t||403===t)o="Please run 'npx dashnex login' to authenticate.";else try{const e=await i.text(),t=JSON.parse(e);"string"==typeof t.error?o=t.error:"string"==typeof t.message&&(o=t.message)}catch{}throw console.error(e.red(o)),new Error(`HTTP ${t}: ${o}`)}if(!i.body)throw new Error("Response body is null");t("SSE connection established successfully"),a?.();const c=i.body.getReader();try{for await(const e of async function*(e){const t=new TextDecoder("utf-8");let o="";for(;;){const{value:s,done:r}=await e.read();if(r)break;o+=t.decode(s,{stream:!0});const n=o.split("\n");o=n.pop()||"";let a="";for(const e of n)e.startsWith("data: ")?a=e.slice(6):""===e&&a&&(yield{data:a},a="")}if(o.startsWith("data: ")){const e=o.slice(6);e&&(yield{data:e})}}(c))try{if(!e.data){t("Received empty SSE event");continue}const o=JSON.parse(e.data);t(`SSE message received: ${JSON.stringify(o)}`),n(o)}catch(l){o(l),t(`Failed to parse SSE event data: ${e.data}`)}}finally{c.releaseLock()}};class f{async execute(){t("Deploy flow started");const f=await r();if(!f)return;const m=`${s()}/business/v1/applications/deploy`;t(`GET ${m} (SSE)`);let y=0,u="",g=!1,h=0,w=!1;const S=n();let x=0,$=0,v=null;const b=(e,t)=>{const o=Math.round(e);S.text(`[${o}%] ${t}`)},E=()=>{D();const e=y,t=Date.now(),o=c*((l-e)/l);v=setInterval(()=>{const s=Date.now()-t;let r;if($>t){const e=Date.now()-$,t=l-x,o=t*3030.3030303030305;r=Math.min(x+e/o*t,l)}else r=Math.min(e+s/o*(l-e),l);r>y&&(y=r,b(y,u))},200)},D=()=>{v&&(clearInterval(v),v=null)};let T=!1;const M=t=>{if(w=!0,"string"==typeof t.error)return D(),S.stop(),console.error(e.red(t.error)),g=!0,void(T=!0);if("string"==typeof t.message&&(u=t.message),"number"==typeof t.progress&&(x=t.progress,$=Date.now(),t.progress>y&&(y=t.progress)),"string"==typeof t.message||"number"==typeof t.progress)if(y>=100){D(),S.stop();const t=u||"Application is deployed";process.stdout.write(`${e.green(t)}\n`),g=!0}else b(y,u)};for(;h<=5;)try{return w?b(y,u):S.start("Connecting..."),E(),await d(m,f.token,M,()=>{w||(S.text(`[${Math.round(y)}%] Deployment in progress...`),u="Deployment in progress...")}),D(),S.stop(),t("SSE connection closed"),void(T&&process.exit(1))}catch(k){if(D(),o(k),t(`SSE connection error: ${k}`),g)return S.stop(),void(T&&process.exit(1));if(a(k))return S.stop(),void console.log(e.yellow(i));k instanceof Error&&k.message.startsWith("HTTP")&&(S.stop(),console.error(e.red("Could not complete deployment. Check your connection and try again.")),process.exit(1)),h++,h>5&&(S.stop(),console.error(e.red("Deployment failed. Maximum reconnection attempts exceeded.")),process.exit(1));const s=Math.min(1e3*Math.pow(2,h-1),3e4);t(`Connection error. Reconnecting in ${s/1e3}s... (attempt ${h}/5)`),await p(s)}}}export{f as DeployCommand};
@@ -0,0 +1 @@
1
+ import{spawn as e}from"child_process";import o from"path";import s from"fs-extra";import r from"chalk";import{debug as n,debugError as a}from"../lib/debug.js";class i{async execute(){n("Dev flow started");const i=process.cwd(),c=o.join(i,"dashnex.json"),t=o.join(i,"package.json");let p;n(`Checking for dashnex.json at: ${c}`),await s.pathExists(c)||(console.error(r.red("This is not a DashNex project.")),process.exit(1)),n("dashnex.json found, checking for package.json"),await s.pathExists(t)||(console.error(r.red("package.json is missing.")),process.exit(1)),n("package.json found, checking for dev script");try{p=await s.readJson(t)}catch(m){a(m),console.error(r.red("Failed to read package.json.")),process.exit(1)}p.scripts&&p.scripts.dev||(console.error(r.red('The "dev" script is missing from package.json. Please add a "dev" script to package.json.')),process.exit(1)),n("dev script found, checking for npm availability");const d=await(async o=>new Promise(s=>{const r=e(`${o} --version`,{stdio:"ignore",shell:!0});r.on("error",()=>{s(!1)}),r.on("close",e=>{s(0===e)})}))("npm");let l;n(`npm available: ${d}`),d||(console.error(r.red("npm is not available. Please install npm to continue.")),process.exit(1)),n("npm available, executing: npm run dev");try{l=await(async o=>new Promise((s,r)=>{const n=e(o,{stdio:"inherit",cwd:process.cwd(),shell:!0});n.on("error",e=>{a(e),r(e)}),n.on("close",e=>{s(null===e?0:e)})}))("npm run dev")}catch(m){return a(m),m instanceof Error?console.error(r.red(`Failed to run npm run dev: ${m.message}`)):console.error(r.red("Failed to run npm run dev")),void process.exit(1)}process.exit(l)}}export{i as DevCommand};
@@ -1 +1 @@
1
- import e from"./version.js";import{LoginCommand as o}from"./login.js";import{LogoutCommand as n}from"./logout.js";import{CreateCommand as t}from"./create.js";import{PullCommand as i}from"./pull.js";import{PushCommand as a}from"./push.js";import{DeleteCommand as r}from"./delete.js";import{WhoamiCommand as s}from"./whoami.js";const p=[{name:"version",description:"Display the version of the CLI",handler:new e,options:[]},{name:"login",description:"Log in to your DashNex account",handler:new o,options:[]},{name:"logout",description:"Log out and remove local credentials",handler:new n,options:[]},{name:"create",description:"Create a new DashNex application",handler:new t,options:[{flags:"-t, --template <template>",description:"Template (name@branch-or-tag)",defaultValue:"webapp-base@live"}]},{name:"pull",description:"Pull existing application to current folder",handler:new i,options:[]},{name:"push",description:"Push local application to DashNex",handler:new a,options:[]},{name:"delete",description:"Delete application from DashNex",handler:new r,options:[]},{name:"whoami",description:"Show current logged-in business and user",handler:new s,options:[]}];export{p as default};
1
+ import e from"./version.js";import{LoginCommand as o}from"./login.js";import{LogoutCommand as n}from"./logout.js";import{CreateCommand as i}from"./create.js";import{PullCommand as t}from"./pull.js";import{PushCommand as a}from"./push.js";import{DeleteCommand as r}from"./delete.js";import{WhoamiCommand as p}from"./whoami.js";import{DeployCommand as s}from"./deploy.js";import{InstallCommand as l}from"./install.js";import{DevCommand as m}from"./dev.js";const d=[{name:"version",description:"Display the version of the CLI",handler:new e,options:[]},{name:"login",description:"Log in to your DashNex account",handler:new o,options:[]},{name:"logout",description:"Log out and remove local credentials",handler:new n,options:[]},{name:"create",description:"Create a new DashNex application",handler:new i,options:[{flags:"-t, --template <template>",description:"Template (name@branch-or-tag)",defaultValue:"webapp-base@live"}]},{name:"pull",description:"Pull existing application to specified folder",handler:new t,options:[]},{name:"push",description:"Push local application to DashNex",handler:new a,options:[]},{name:"delete",description:"Delete application from DashNex",handler:new r,options:[]},{name:"whoami",description:"Show current logged-in business and user",handler:new p,options:[]},{name:"deploy",description:"Deploy application to DashNex",handler:new s,options:[]},{name:"install",description:"Install dependencies using pnpm or npm",handler:new l,options:[]},{name:"dev",description:"Run the development server",handler:new m,options:[]}];export{d as default};
@@ -0,0 +1 @@
1
+ import{spawn as e}from"child_process";import n from"chalk";import{debug as o,debugError as r}from"../lib/debug.js";const s=async n=>new Promise(o=>{const r=e(`${n} --version`,{stdio:"ignore",shell:!0});r.on("error",()=>{o(!1)}),r.on("close",e=>{o(0===e)})});class l{async execute(){o("Install flow started");let l=null,a=null;o("Checking for pnpm availability");const i=await s("pnpm");if(o(`pnpm available: ${i}`),i)l="pnpm",a="pnpm";else{o("pnpm not available, checking for npm");const e=await s("npm");o(`npm available: ${e}`),e&&(l="npm",a="npm")}l&&a||(console.error(n.red("Neither pnpm nor npm is available. Please install pnpm (recommended) or npm to continue.")),process.exit(1)),o(`Using package manager: ${l}`),o(`Executing: ${a} install`);try{const n=await(async n=>new Promise((o,s)=>{const l=e(`${n} install`,{stdio:"inherit",cwd:process.cwd(),shell:!0});l.on("error",e=>{r(e),s(e)}),l.on("close",e=>{o(null===e?0:e)})}))(a);process.exit(n)}catch(t){r(t),t instanceof Error?console.error(n.red(`Failed to run ${a} install: ${t.message}`)):console.error(n.red(`Failed to run ${a} install`)),process.exit(1)}}}export{l as InstallCommand};
@@ -1 +1 @@
1
- import e from"inquirer";import s from"chalk";import r from"fs-extra";import t from"path";import{debug as n,debugJson as o,debugError as a}from"../lib/debug.js";import{getApiBase as i,apiFetch as c}from"../lib/api.js";import{ensureLoggedIn as d}from"../services/auth.js";const u=(e,r,t)=>{const n=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(r);let o=t;429===e.status?o="Too many requests. Please wait a moment and try again.":e.status>=500?o="DashNex API is temporarily unavailable. Please try again later.":n&&(o=n),console.error(s.red(o)),process.exit(1)};class l{async execute(){n("Login flow started");const r=process.cwd(),l=t.join(r,".dashnex"),m=await d({exitOnFailure:!1,dashnexPath:l});if(m)console.log(s.green(`Already logged in as ${m.userName??"user"}`));else try{const{username:r,password:t}=await e.prompt([{type:"input",name:"username",message:"Email:",validate:e=>!!e.trim()||"Email is required"},{type:"password",name:"password",message:"Password:",mask:"*",validate:e=>!!e||"Password is required"}]),d=r.trim();n("Email provided"),n(`POST ${i()}/auth/v1/login`);const{response:m,body:h}=await c(`${i()}/auth/v1/login`,{method:"POST",body:JSON.stringify({username:d,password:t})});n(`Response: ${m.status}`),o("Login response",h),m.ok||(a(new Error(`Login failed: ${m.status} ${JSON.stringify(h)}`)),401===m.status&&(console.error(s.red("Invalid username or password.")),process.exit(1)),u(m,h,"Login failed. Please try again."));const p=h;if(p.two_fa_required&&p.token){n(`2FA required, type: ${p.type||"unknown"}`);const e=await this.handle2FA(p.token,p.type);e||process.exit(1),await this.completeLogin(e,l)}else p.token&&p.refreshToken?await this.completeLogin({token:p.token,refreshToken:p.refreshToken},l):(console.error(s.red("Invalid response from server. Please try again.")),process.exit(1))}catch(h){a(h),console.error(s.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}async handle2FA(r,t){if("sms"===t){n(`POST ${i()}/auth/v1/two-fa/sms`);try{const{response:e}=await c(`${i()}/auth/v1/two-fa/sms`,{method:"POST",headers:{Authorization:`Bearer ${r}`},body:JSON.stringify({})});n(`Response: ${e.status}`)}catch(l){return a(l),console.error(s.red("Could not send SMS code. Check your connection and try again.")),null}}const d="sms"===t?"Check your phone for the code":"Check your authenticator app for the code";for(let m=1;m<=3;m++){const{auth_code:t}=await e.prompt([{type:"input",name:"auth_code",message:`Enter code (${d}):`,validate:e=>!!e.trim()||"Code is required"}]);n(`POST ${i()}/auth/v1/2fa-check`);try{const{response:a,body:d}=await c(`${i()}/auth/v1/2fa-check`,{method:"POST",headers:{Authorization:`Bearer ${r}`},body:JSON.stringify({auth_code:t.trim()})});if(n(`Response: ${a.status}`),o("2FA check response",d),a.ok){const e=d;if(e.token&&e.refreshToken)return{token:e.token,refreshToken:e.refreshToken}}if(a.status>=400&&a.status<500){if(console.error(s.red("Invalid code. Please try again.")),m<3){const{retry:s}=await e.prompt([{type:"confirm",name:"retry",message:"Try again?",default:!0}]);if(!s)return null}continue}u(a,d,"2FA verification failed. Please try again.")}catch(l){return a(l),console.error(s.red("Could not reach DashNex API. Check your connection and try again.")),null}}return null}async completeLogin(t,d){n(`GET ${i()}/users/v1/business/my`);const{response:l,body:m}=await c(`${i()}/users/v1/business/my`,{headers:{Authorization:`Bearer ${t.token}`}});n(`Response: ${l.status}`),o("Businesses response",m),l.ok||(a(new Error(`Business fetch failed: ${l.status}`)),u(l,m,"Failed to fetch businesses. Please try again."));const h=this.parseBusinesses(m);let p;if(n(`Businesses: ${h.length}`),0===h.length&&(console.error(s.red("No businesses found for your account.")),process.exit(1)),1===h.length)p=h[0],n(`Selected business: ${p.id} ${p.name}`);else{const{businessId:s}=await e.prompt([{type:"select",name:"businessId",message:"Select business:",choices:h.map(e=>({name:e.name,value:e.id}))}]);p=h.find(e=>e.id===s)||h[0],n(`Selected business: ${p.id} ${p.name}`)}n(`GET ${i()}/business/v1/login?_switch_business=${p.id}`);const{response:f,body:y}=await c(`${i()}/business/v1/login?_switch_business=${p.id}`,{headers:{Authorization:`Bearer ${t.token}`}});n(`Response: ${f.status}`),o("Business login response",y),f.ok||(a(new Error(`Business login failed: ${f.status}`)),u(f,y,"Failed to switch to business. Please try again."));const g=y;g.token&&g.refreshToken||(console.error(s.red("Invalid response from server. Please try again.")),process.exit(1));const w={token:g.token,refreshToken:g.refreshToken,businessId:p.id};await r.writeJson(d,w,{spaces:2}),n("Saved credentials to .dashnex"),this.ensureGitignore(),console.log(s.green(`Logged in as ${p.name}`))}parseBusinesses(e){const s=Array.isArray(e)?e:e.items??e.data??e.businesses??[];return Array.isArray(s)?s.map(e=>{if(e&&"object"==typeof e){const s=e,r=String(s.id??s.business_id??"").trim(),t=String(s.name??s.companyName??s.business_name??"Unknown").trim();if(r)return{id:r,name:t}}return null}).filter(e=>null!==e):[]}async ensureGitignore(){const e=t.join(process.cwd(),".gitignore");if(!(await r.pathExists(e)))return;let s=await r.readFile(e,"utf8");s.includes(".dashnex")||(s=s.trimEnd(),s.endsWith("\n")||(s+="\n"),s+="\n.dashnex\n",await r.writeFile(e,s))}}export{l as LoginCommand};
1
+ import e from"inquirer";import s from"chalk";import r from"fs-extra";import t from"path";import{debug as o,debugJson as n,debugError as a}from"../lib/debug.js";import{getApiBase as i,apiFetch as c}from"../lib/api.js";import{ensureLoggedIn as u}from"../services/auth.js";import{createSpinner as l}from"../lib/spinner.js";import{isUserInterrupt as d,INTERRUPTED_MESSAGE as m}from"../lib/errors.js";const p=(e,r,t)=>{const o=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(r);let n=t;429===e.status?n="Too many requests. Please wait a moment and try again.":e.status>=500?n="DashNex API is temporarily unavailable. Please try again later.":o&&(n=o),console.error(s.red(n)),process.exit(1)};class h{async execute(){o("Login flow started");const r=process.cwd(),h=t.join(r,".dashnex"),f=await u({exitOnFailure:!1,dashnexPath:h});if(f)console.log(s.green(`Already logged in as ${f.userName??"user"}`));else try{const{username:r,password:t}=await e.prompt([{type:"input",name:"username",message:"Email:",validate:e=>!!e.trim()||"Email is required"},{type:"password",name:"password",message:"Password:",mask:"*",validate:e=>!!e||"Password is required"}]),u=r.trim();o("Email provided");const d=l();d.start("Logging in..."),o(`POST ${i()}/auth/v1/login`);const{response:m,body:f}=await c(`${i()}/auth/v1/login`,{method:"POST",body:JSON.stringify({username:u,password:t})});d.stop(),o(`Response: ${m.status}`),n("Login response",f),m.ok||(a(new Error(`Login failed: ${m.status} ${JSON.stringify(f)}`)),401===m.status&&(console.error(s.red("Invalid username or password.")),process.exit(1)),p(m,f,"Login failed. Please try again."));const g=f;if(g.two_fa_required&&g.token){o(`2FA required, type: ${g.type||"unknown"}`);const e=await this.handle2FA(g.token,g.type);e||process.exit(1),await this.completeLogin(e,h)}else g.token&&g.refreshToken?await this.completeLogin({token:g.token,refreshToken:g.refreshToken},h):(console.error(s.red("Invalid response from server. Please try again.")),process.exit(1))}catch(g){if(a(g),d(g))return void console.log(s.yellow(m));console.error(s.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}async handle2FA(r,t){if("sms"===t){o(`POST ${i()}/auth/v1/two-fa/sms`);try{const{response:e}=await c(`${i()}/auth/v1/two-fa/sms`,{method:"POST",headers:{Authorization:`Bearer ${r}`},body:JSON.stringify({})});o(`Response: ${e.status}`)}catch(l){return a(l),console.error(s.red("Could not send SMS code. Check your connection and try again.")),null}}const u="sms"===t?"Check your phone for the code":"Check your authenticator app for the code";for(let h=1;h<=3;h++){const{auth_code:t}=await e.prompt([{type:"input",name:"auth_code",message:`Enter code (${u}):`,validate:e=>!!e.trim()||"Code is required"}]);o(`POST ${i()}/auth/v1/2fa-check`);try{const{response:a,body:u}=await c(`${i()}/auth/v1/2fa-check`,{method:"POST",headers:{Authorization:`Bearer ${r}`},body:JSON.stringify({auth_code:t.trim()})});if(o(`Response: ${a.status}`),n("2FA check response",u),a.ok){const e=u;if(e.token&&e.refreshToken)return{token:e.token,refreshToken:e.refreshToken}}if(a.status>=400&&a.status<500){if(console.error(s.red("Invalid code. Please try again.")),h<3){const{retry:s}=await e.prompt([{type:"confirm",name:"retry",message:"Try again?",default:!0}]);if(!s)return null}continue}p(a,u,"2FA verification failed. Please try again.")}catch(l){return a(l),d(l)?(console.log(s.yellow(m)),null):(console.error(s.red("Could not reach DashNex API. Check your connection and try again.")),null)}}return null}async completeLogin(t,u){const d=l();d.start("Fetching businesses..."),o(`GET ${i()}/users/v1/business/my`);const{response:m,body:h}=await c(`${i()}/users/v1/business/my`,{headers:{Authorization:`Bearer ${t.token}`}});d.stop(),o(`Response: ${m.status}`),n("Businesses response",h),m.ok||(a(new Error(`Business fetch failed: ${m.status}`)),p(m,h,"Failed to fetch businesses. Please try again."));const f=this.parseBusinesses(h);let g;if(o(`Businesses: ${f.length}`),0===f.length&&(console.error(s.red("No businesses found for your account.")),process.exit(1)),1===f.length)g=f[0],o(`Selected business: ${g.id} ${g.name}`);else{const{businessId:s}=await e.prompt([{type:"select",name:"businessId",message:"Select business:",choices:f.map(e=>({name:e.name,value:e.id}))}]);g=f.find(e=>e.id===s)||f[0],o(`Selected business: ${g.id} ${g.name}`)}d.start("Switching business..."),o(`GET ${i()}/business/v1/login?_switch_business=${g.id}`);const{response:y,body:w}=await c(`${i()}/business/v1/login?_switch_business=${g.id}`,{headers:{Authorization:`Bearer ${t.token}`}});d.stop(),o(`Response: ${y.status}`),n("Business login response",w),y.ok||(a(new Error(`Business login failed: ${y.status}`)),p(y,w,"Failed to switch to business. Please try again."));const k=w;k.token&&k.refreshToken||(console.error(s.red("Invalid response from server. Please try again.")),process.exit(1));const b={token:k.token,refreshToken:k.refreshToken,businessId:g.id};await r.writeJson(u,b,{spaces:2}),o("Saved credentials to .dashnex"),this.ensureGitignore(),console.log(s.green(`Logged in as ${g.name}`))}parseBusinesses(e){const s=Array.isArray(e)?e:e.items??e.data??e.businesses??[];return Array.isArray(s)?s.map(e=>{if(e&&"object"==typeof e){const s=e,r=String(s.id??s.business_id??"").trim(),t=String(s.name??s.companyName??s.business_name??"Unknown").trim();if(r)return{id:r,name:t}}return null}).filter(e=>null!==e):[]}async ensureGitignore(){const e=t.join(process.cwd(),".gitignore");if(!(await r.pathExists(e)))return;let s=await r.readFile(e,"utf8");s.includes(".dashnex")||(s=s.trimEnd(),s.endsWith("\n")||(s+="\n"),s+="\n.dashnex\n",await r.writeFile(e,s))}}export{h as LoginCommand};
@@ -1 +1 @@
1
- import e from"chalk";import t from"fs-extra";import o from"path";import s from"os";import n from"inquirer";import r from"adm-zip";import{debug as a,debugError as i}from"../lib/debug.js";import{getBusinessApiBase as l}from"../lib/api.js";import{ensureLoggedIn as p}from"../services/auth.js";class c{async execute(){a("Pull flow started");const c=await p();if(!c)return;const d=process.cwd(),f=o.join(d,"dashnex.json"),u=await t.pathExists(f);let m;if(a("Application check (dashnex.json): "+(u?"present":"absent")),u)m=d;else{a("No application yet, prompting for folder");const{folder:e}=await n.prompt([{type:"input",name:"folder",message:"Which folder to pull the application to?",default:"."}]);m=o.resolve(d,e.trim()||"."),await t.ensureDir(m),a(`Target folder created/resolved: ${m}`)}const h=`${l()}/business/v1/cli/pull`;a(`GET ${h}`);const x=o.join(s.tmpdir(),`dashnex-pull-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`);try{const s=await fetch(h,{headers:{Authorization:`Bearer ${c.token}`}});if(a(`Response: ${s.status}`),!s.ok){const t=s.headers.get("content-type")??"";let o="Failed to pull application.";if(401===s.status||403===s.status)o="Please run 'npx dashnex login' to authenticate.";else if(404===s.status)o="Business has no application. Run 'npx dashnex create' to create one.";else if(t.includes("application/json")){const e=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await s.json().catch(()=>({})));e&&(o=e)}console.error(e.red(o)),process.exit(1)}const n=Buffer.from(await s.arrayBuffer());await t.writeFile(x,n),a("Zip written to temp file");new r(x).extractAllTo(m,!0),a("Extracted to target folder"),u?console.log(e.green(`Application pulled to ${m}`)):console.log(e.green(((e,t)=>o.resolve(e)===o.resolve(t)?'Application is successfully pulled. Run "npm install" or "pnpm install" to install dependencies and then "npx dashnex dev" to run it':`Application is successfully pulled. Run 'cd ${o.relative(t,e)}' then "pnpm install" or "npm install" to install dependencies and then "npx dashnex dev" to run it`)(m,d)))}catch(g){if(i(g),g instanceof Error&&g.message.startsWith("EXIT:"))throw g;console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}finally{await t.remove(x).catch(()=>{}),a("Temp zip removed")}}}export{c as PullCommand};
1
+ import e from"chalk";import t from"fs-extra";import o from"path";import r from"os";import{spawn as n}from"child_process";import i from"inquirer";import a from"adm-zip";import{debug as s,debugError as l}from"../lib/debug.js";import{getBusinessApiBase as c}from"../lib/api.js";import{ensureLoggedIn as d}from"../services/auth.js";import{createSpinner as p}from"../lib/spinner.js";import{isUserInterrupt as m,INTERRUPTED_MESSAGE as f}from"../lib/errors.js";const u=(e,t)=>new Promise((o,r)=>{const i=n(t,{cwd:e,shell:!0,stdio:"inherit"});i.on("error",e=>{l(e),r(e)}),i.on("close",e=>{o(null===e?0:e)})}),g=async(t,r)=>{const{install:a}=await i.prompt([{type:"confirm",name:"install",message:"Install dependencies?",default:!0}]);if(!a){if(o.resolve(t)!==o.resolve(r)){const n=o.relative(r,t);console.log(e.cyan(`Run "cd ${n}" to change to the application folder.`))}return}if(a){const o=await(async()=>{const e=e=>new Promise(t=>{const o=n(e,["--version"],{stdio:"ignore",shell:!0});o.on("error",()=>t(!1)),o.on("close",e=>t(0===e))});return await e("pnpm")?"pnpm":(await e("npm"),"npm")})();s(`Running ${o} install in ${t}`);try{const e=await u(t,`${o} install`);if(0!==e)return void s(`${o} install exited with code ${e}`)}catch(p){return l(p),void console.error(e.red(`Failed to run ${o} install.`))}}const{migrate:c}=await i.prompt([{type:"confirm",name:"migrate",message:"Create local database?",default:!0}]);if(c){s(`Running npx dashnex db migrate in ${t}`);try{const e=await u(t,"npx dashnex db migrate");if(0!==e)return void s(`dashnex db migrate exited with code ${e}`)}catch(p){return l(p),void console.error(e.red("Failed to run dashnex db migrate."))}}const{dev:d}=await i.prompt([{type:"confirm",name:"dev",message:"Run development server?",default:!0}]);if(d){s(`Running npm run dev in ${t}`);try{await u(t,"npm run dev")}catch(p){l(p),console.error(e.red("Failed to run dev server."))}}},h='Application is successfully pulled. Run "npm install" or "pnpm install" to install dependencies and then "npx dashnex dev" to run it';class w{async execute(n={}){s("Pull flow started");const u=await d();if(!u)return;const w=process.cwd();let v;if(n.folder)v=n.folder.trim()||".",s(`Folder argument provided: ${v}`);else{s("No folder argument, prompting user");const{folder:e}=await i.prompt([{type:"input",name:"folder",message:"Which folder to pull the application to?",default:"."}]);v=e.trim()||"."}const x=o.resolve(w,v);s(`Target folder resolved: ${x}`);const y=await t.pathExists(x);let $=!1;if(y)try{$=(await t.readdir(x)).length>0,s(`Folder exists: ${y}, has files: ${$}`)}catch(R){s(`Error reading folder: ${R}`)}if($){const{confirm:t}=await i.prompt([{type:"confirm",name:"confirm",message:"Existing files will be overwritten. Continue?",default:!0}]);if(!t)return s("User declined confirmation, exiting"),void console.log(e.yellow("Pull cancelled."));s("User confirmed overwrite")}await t.ensureDir(x),s(`Target folder ensured: ${x}`);const b=`${c()}/business/v1/cli/pull`;s(`GET ${b}`);const j=o.join(r.tmpdir(),`dashnex-pull-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`),E=p();E.start("Pulling application...");try{const r=await fetch(b,{headers:{Authorization:`Bearer ${u.token}`}});if(s(`Response: ${r.status}`),!r.ok){E.stop();const t=r.headers.get("content-type")??"";let o="Failed to pull application.";if(401===r.status||403===r.status)o="Please run 'npx dashnex login' to authenticate.";else if(404===r.status)o="Business has no application. Run 'npx dashnex create' to create one.";else if(t.includes("application/json")){const e=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await r.json().catch(()=>({})));e&&(o=e)}console.error(e.red(o)),process.exit(1)}E.text("Downloading...");const n=Buffer.from(await r.arrayBuffer());await t.writeFile(j,n),s("Zip written to temp file"),E.text("Extracting...");new a(j).extractAllTo(x,!0),E.stop(),s("Extracted to target folder"),o.resolve(x)!==o.resolve(w)?(console.log(e.green(((e,t)=>o.resolve(e)===o.resolve(t)?h:`Application is successfully pulled into ${o.relative(t,e)}.`)(x,w))),process.chdir(x),s(`Changed working directory to ${x}`)):console.log(e.green(h)),await g(x,w)}catch(R){if(E.stop(),l(R),R instanceof Error&&R.message.startsWith("EXIT:"))throw R;if(m(R))return void console.log(e.yellow(f));console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}finally{await t.remove(j).catch(()=>{}),s("Temp zip removed")}}}export{w as PullCommand};
@@ -1 +1 @@
1
- import e from"chalk";import t from"fs-extra";import o from"path";import i from"os";import s from"adm-zip";import a from"ignore";import{debug as n,debugError as r}from"../lib/debug.js";import{getBusinessApiBase as c}from"../lib/api.js";import{ensureLoggedIn as p}from"../services/auth.js";const l=[".dashnex",".git"],d=async(e,i)=>{const s=[],a=await t.readdir(e,{withFileTypes:!0});for(const t of a){const a=o.relative(process.cwd(),o.join(e,t.name)).split(o.sep).join("/");if(l.some(e=>a===e||a.startsWith(`${e}/`)))continue;if(i.ignores(a))continue;const n=o.join(e,t.name);if(t.isDirectory()){const e=await d(n,i);s.push(...e)}else t.isFile()&&s.push(n)}return s};class m{async execute(){n("Push flow started");const m=await p();if(!m)return;const f=process.cwd(),h=o.join(f,".gitignore"),u=a();if(u.add(l),await t.pathExists(h)){const e=await t.readFile(h,"utf8");u.add(e)}n("Building file list");const w=await d(f,u);n(`Including ${w.length} files`);const g=new s;for(const e of w){const t=o.relative(f,e).split(o.sep).join("/"),i="."===o.dirname(t)?"":o.dirname(t),s=o.basename(t);g.addLocalFile(e,i,s)}const y=o.join(i.tmpdir(),`dashnex-push-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`);try{g.writeZip(y),n(`Zip written to ${y}`);const o=`${c()}/business/v1/cli/push`;n(`POST ${o}`);const i=new FormData;i.append("file",new Blob([await t.readFile(y)]),"archive.zip");const s=await fetch(o,{method:"POST",headers:{Authorization:`Bearer ${m.token}`},body:i});if(n(`Response: ${s.status}`),!s.ok){const t=s.headers.get("content-type")??"";let o="Failed to push application.";if(401===s.status||403===s.status)o="Please run 'npx dashnex login' to authenticate.";else if(t.includes("application/json")){const e=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await s.json().catch(()=>({})));e&&(o=e)}console.error(e.red(o)),process.exit(1)}console.log(e.green("Application pushed successfully."))}catch(j){if(r(j),j instanceof Error&&j.message.startsWith("EXIT:"))throw j;console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}finally{await t.remove(y).catch(()=>{}),n("Temp zip removed")}}}export{m as PushCommand};
1
+ import e from"chalk";import t from"fs-extra";import o from"path";import i from"os";import s from"adm-zip";import r from"ignore";import n from"inquirer";import{debug as a,debugError as p}from"../lib/debug.js";import{getBusinessApiBase as c}from"../lib/api.js";import{ensureLoggedIn as l}from"../services/auth.js";import{createSpinner as d}from"../lib/spinner.js";import{isUserInterrupt as m,INTERRUPTED_MESSAGE as f}from"../lib/errors.js";import{DeployCommand as h}from"./deploy.js";const u=[".dashnex",".git"],w=async(e,i)=>{const s=[],r=await t.readdir(e,{withFileTypes:!0});for(const t of r){const r=o.relative(process.cwd(),o.join(e,t.name)).split(o.sep).join("/");if(u.some(e=>r===e||r.startsWith(`${e}/`)))continue;if(i.ignores(r))continue;const n=o.join(e,t.name);if(t.isDirectory()){const e=await w(n,i);s.push(...e)}else t.isFile()&&s.push(n)}return s};class g{async execute(){a("Push flow started");const g=await l();if(!g)return;const y=process.cwd(),j=o.join(y,".gitignore"),x=r();if(x.add(u),await t.pathExists(j)){const e=await t.readFile(j,"utf8");x.add(e)}a("Building file list");const $=await w(y,x);a(`Including ${$.length} files`);const b=new s;for(const e of $){const t=o.relative(y,e).split(o.sep).join("/"),i="."===o.dirname(t)?"":o.dirname(t),s=o.basename(t);b.addLocalFile(e,i,s)}const v=o.join(i.tmpdir(),`dashnex-push-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`),F=d();try{F.start("Packaging application..."),b.writeZip(v),a(`Zip written to ${v}`);const o=`${c()}/business/v1/cli/push`;a(`POST ${o}`);const i=await t.readFile(v),s=new Blob([i],{type:"application/zip"}),r=new FormData;r.append("file",s,"archive.zip");const p=new Headers;p.set("Authorization",`Bearer ${g.token}`),F.text("Uploading...");const l=await fetch(o,{method:"POST",headers:p,body:r});if(F.stop(),a(`Response: ${l.status}`),!l.ok){const t=l.headers.get("content-type")??"";let o="Failed to push application.";if(401===l.status||403===l.status)o="Please run 'npx dashnex login' to authenticate.";else if(t.includes("application/json")){const e=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await l.json().catch(()=>({})));e&&(o=e)}console.error(e.red(o)),process.exit(1)}console.log(e.green("Application pushed successfully."));const{deploy:d}=await n.prompt([{type:"confirm",name:"deploy",message:"Deploy the application?",default:!0}]);if(a(`User chose to deploy: ${d}`),d){a("Running deploy flow");const e=new h;await e.execute()}}catch(z){if(F.stop(),p(z),z instanceof Error&&z.message.startsWith("EXIT:"))throw z;if(m(z))return void console.log(e.yellow(f));console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}finally{await t.remove(v).catch(()=>{}),a("Temp zip removed")}}}export{g as PushCommand};
@@ -1 +1 @@
1
- import e from"chalk";import{debug as t,debugError as o}from"../lib/debug.js";import{getApiBase as s}from"../lib/api.js";import{ensureLoggedIn as r}from"../services/auth.js";class a{async execute(){t("Whoami flow started");const a=await r();if(!a)return;const n=`${s()}/users/v1/`;t(`GET ${n}`);try{const o=await fetch(n,{headers:{Authorization:`Bearer ${a.token}`}});if(t(`Response: ${o.status}`),!o.ok){const t=o.headers.get("content-type")??"";let s="Failed to fetch user info.";if(401===o.status||403===o.status)s="Please run 'npx dashnex login' to authenticate.";else if(t.includes("application/json")){const e=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await o.json().catch(()=>({})));e&&(s=e)}console.error(e.red(s)),process.exit(1)}const s=await o.json().catch(()=>({})),r="string"==typeof s.name?s.name:"string"==typeof s.companyName?s.companyName:"Unknown",i=s.memberUser,c=i&&"string"==typeof i.fullName?i.fullName:i&&"string"==typeof i.name?i.name:"Unknown";t(`Whoami: ${r} (${c})`),console.log(e.green(`You are logged in as ${r} (${c})`))}catch(i){if(o(i),i instanceof Error&&i.message.startsWith("EXIT:"))throw i;console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}}export{a as WhoamiCommand};
1
+ import e from"chalk";import{debug as o,debugError as t}from"../lib/debug.js";import{getApiBase as s}from"../lib/api.js";import{ensureLoggedIn as r}from"../services/auth.js";import{createSpinner as n}from"../lib/spinner.js";import{isUserInterrupt as a,INTERRUPTED_MESSAGE as i}from"../lib/errors.js";class c{async execute(){o("Whoami flow started");const c=await r();if(!c)return;const m=`${s()}/users/v1/`;o(`GET ${m}`);const l=n();l.start("Fetching user info...");try{const t=await fetch(m,{headers:{Authorization:`Bearer ${c.token}`}});if(l.stop(),o(`Response: ${t.status}`),!t.ok){const o=t.headers.get("content-type")??"";let s="Failed to fetch user info.";if(401===t.status||403===t.status)s="Please run 'npx dashnex login' to authenticate.";else if(o.includes("application/json")){const e=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(await t.json().catch(()=>({})));e&&(s=e)}console.error(e.red(s)),process.exit(1)}const s=await t.json().catch(()=>({})),r="string"==typeof s.name?s.name:"string"==typeof s.companyName?s.companyName:"Unknown",n=s.memberUser,a=n&&"string"==typeof n.fullName?n.fullName:n&&"string"==typeof n.name?n.name:"Unknown";o(`Whoami: ${r} (${a})`),console.log(e.green(`You are logged in as ${r} (${a})`))}catch(f){if(l.stop(),t(f),f instanceof Error&&f.message.startsWith("EXIT:"))throw f;if(a(f))return void console.log(e.yellow(i));console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}}export{c as WhoamiCommand};
package/dist/lib/api.js CHANGED
@@ -1 +1 @@
1
- const s=()=>process.env.NEXT_PUBLIC_DASHNEX_API_DOMAIN||"https://api.dashnex.com",e=()=>process.env.DASHNEX_BUSINESS_API_URL||"https://api.business.dashnex.com",n=async(s,e={})=>{const n=await fetch(s,{...e,headers:{"Content-Type":"application/json",...e.headers}}),t=await n.json().catch(()=>({}));return{response:n,body:t}};export{n as apiFetch,s as getApiBase,e as getBusinessApiBase};
1
+ const s=()=>process.env.NEXT_PUBLIC_DASHNEX_API_DOMAIN||"https://api.dashnex.com",e=()=>process.env.DASHNEX_BUSINESS_API_URL||"https://api.business.dashnex.com",t={qa:"https://3atfynmu2w.us-east-1.awsapprunner.com",live:"https://rkwbzvhcwh.us-east-1.awsapprunner.com"},n=()=>{const s=process.env.APPLICATION_ENV||"live";return t[s]||t.live},a=async(s,e={})=>{const t=await fetch(s,{...e,headers:{"Content-Type":"application/json",...e.headers}}),n=await t.json().catch(()=>({}));return{response:t,body:n}};export{a as apiFetch,s as getApiBase,e as getBusinessApiBase,n as getDeployerBase};
@@ -0,0 +1 @@
1
+ const r=r=>r instanceof Error&&("ExitPromptError"===r.name||("AbortError"===r.name||("User force closed the prompt"===r.message||!!r.message.includes("prompt was closed")))),e="Command interrupted.";export{e as INTERRUPTED_MESSAGE,r as isUserInterrupt};
@@ -0,0 +1 @@
1
+ const t=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],r=(r="")=>{let e=null,s=0,l=r;const n=()=>{const r=t[s%t.length];process.stderr.write(`\r${r} ${l}`),s++};return{start:t=>{void 0!==t&&(l=t),e||(s=0,n(),e=setInterval(n,80))},stop:()=>{e&&(clearInterval(e),e=null),process.stderr.write("\r")},text:t=>{l=t,e&&n()}}};export{r as createSpinner};
@@ -1 +1 @@
1
- const e="@dashnex/cli",a="0.5.4",n="Command-line interface for DashNex framework",o={name:e,version:a,description:n};export{o as default,n as description,e as name,a as version};
1
+ const e="@dashnex/cli",a="0.5.23",n="Command-line interface for DashNex framework",o={name:e,version:a,description:n};export{o as default,n as description,e as name,a as version};
@@ -1 +1 @@
1
- import e from"chalk";import n from"fs-extra";import s from"path";import{debug as r,debugJson as t,debugError as o}from"../lib/debug.js";import{getApiBase as a,apiFetch as i}from"../lib/api.js";const l=async(e,s,u,h)=>{r(`GET ${a()}/users/v1/`);try{const{response:o,body:d}=await i(`${a()}/users/v1/`,{headers:{Authorization:`Bearer ${e}`}});if(r(`Response: ${o.status}`),t("Users response",d),o.ok){const n=d;if("string"==typeof n.name&&h.businessId)return r(`Token valid, Already logged in as ${n.name}`),{token:e,businessId:h.businessId,userName:n.name}}if(!s)return r("Token invalid, no refreshToken available"),null;r(`POST ${a()}/auth/v1/token/refresh`);const{response:c,body:f}=await i(`${a()}/auth/v1/token/refresh`,{method:"POST",body:JSON.stringify({refreshToken:s})});if(r(`Response: ${c.status}`),t("Refresh response",f),!c.ok)return r("Token refresh failed"),null;const p=f;if(!p.token||!p.refreshToken)return r("Refresh response missing tokens"),null;const k=await n.readJson(u);return k.token=p.token,k.refreshToken=p.refreshToken,await n.writeJson(u,k,{spaces:2}),r("Updated .dashnex with new tokens, retrying session check"),l(p.token,p.refreshToken,u,{...k,token:p.token,refreshToken:p.refreshToken})}catch(d){return o(d),null}},u=async(t={})=>{const{exitOnFailure:o=!0,dashnexPath:a}=t,i=a??await(async e=>{let r=s.resolve(e);for(;;){const e=s.join(r,".dashnex");if(await n.pathExists(e))return e;const t=s.dirname(r);if(t===r)return null;r=t}})(process.cwd());if(!i||!(await n.pathExists(i)))return r(".dashnex not found"),o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null;let u;try{u=await n.readJson(i)}catch{return r(".dashnex parse failed"),o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null}const{token:h,refreshToken:d,businessId:c}=u;if(!h)return r(".dashnex missing token"),o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null;const f=await l(h,d,i,u);return f||(o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null)};export{u as ensureLoggedIn};
1
+ import e from"chalk";import n from"fs-extra";import r from"path";import{debug as s,debugError as t,debugJson as o}from"../lib/debug.js";import{getApiBase as a,apiFetch as i}from"../lib/api.js";const u=async(e,r)=>{s(`POST ${a()}/auth/v1/token/refresh`);const{response:t,body:u}=await i(`${a()}/auth/v1/token/refresh`,{method:"POST",body:JSON.stringify({refreshToken:e})});if(s(`Response: ${t.status}`),o("Refresh response",u),!t.ok)return s("Token refresh failed"),null;const h=u;if(!h.token||!h.refreshToken)return s("Refresh response missing tokens"),null;const f=await n.readJson(r);return f.token=h.token,f.refreshToken=h.refreshToken,await n.writeJson(r,f,{spaces:2}),s("Updated .dashnex with new tokens"),l(h.token,h.refreshToken,r,{...f,token:h.token,refreshToken:h.refreshToken})},l=async(e,n,r,l)=>{if(((e,n=30)=>{try{const r=e.split(".");if(3!==r.length)return!1;const t=JSON.parse(Buffer.from(r[1],"base64url").toString());if("number"!=typeof t.exp)return!1;const o=Math.floor(Date.now()/1e3),a=t.exp-n<=o;return a&&s(`Token expired or expiring soon (exp: ${t.exp}, now: ${o})`),a}catch{return!1}})(e)){if(!n)return s("Token expired, no refreshToken available"),null;s("Token expired, refreshing proactively");try{return await u(n,r)}catch(h){return t(h),null}}s(`GET ${a()}/users/v1/`);try{const{response:t,body:h}=await i(`${a()}/users/v1/`,{headers:{Authorization:`Bearer ${e}`}});if(s(`Response: ${t.status}`),o("Users response",h),t.ok){const n=h;if("string"==typeof n.name&&l.businessId)return s(`Token valid, Already logged in as ${n.name}`),{token:e,businessId:l.businessId,userName:n.name}}return n?(s("Users API rejected token, refreshing"),await u(n,r)):(s("Token invalid, no refreshToken available"),null)}catch(h){return t(h),null}},h=async(t={})=>{const{exitOnFailure:o=!0,dashnexPath:a}=t,i=a??await(async e=>{let s=r.resolve(e);for(;;){const e=r.join(s,".dashnex");if(await n.pathExists(e))return e;const t=r.dirname(s);if(t===s)return null;s=t}})(process.cwd());if(!i||!(await n.pathExists(i)))return s(".dashnex not found"),o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null;let u;s(`Found .dashnex at ${i}`);try{u=await n.readJson(i)}catch{return s(".dashnex parse failed"),o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null}const{token:h,refreshToken:f,businessId:c}=u;if(!h)return s(".dashnex missing token"),o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null;const d=await l(h,f,i,u);return d||(o&&(console.error(e.red("Please run 'npx dashnex login' to authenticate.")),process.exit(1)),null)};export{h as ensureLoggedIn};
@@ -3,5 +3,9 @@ export interface CreateCommandOptions {
3
3
  template?: string;
4
4
  }
5
5
  export declare class CreateCommand implements CliCommand {
6
+ pollApplicationCreated(applicationsUrl: string, token: string, interval?: number, timeout?: number): Promise<{
7
+ ready: boolean;
8
+ status?: string;
9
+ }>;
6
10
  execute(options?: CreateCommandOptions): Promise<void>;
7
11
  }
@@ -0,0 +1,4 @@
1
+ import { CliCommand } from '@dashnex/types';
2
+ export declare class DeployCommand implements CliCommand {
3
+ execute(): Promise<void>;
4
+ }
@@ -0,0 +1,4 @@
1
+ import { CliCommand } from '@dashnex/types';
2
+ export declare class DevCommand implements CliCommand {
3
+ execute(): Promise<void>;
4
+ }
@@ -0,0 +1,4 @@
1
+ import { CliCommand } from '@dashnex/types';
2
+ export declare class InstallCommand implements CliCommand {
3
+ execute(): Promise<void>;
4
+ }
@@ -1,4 +1,6 @@
1
1
  import { CliCommand } from '@dashnex/types';
2
2
  export declare class PullCommand implements CliCommand {
3
- execute(): Promise<void>;
3
+ execute(options?: {
4
+ folder?: string;
5
+ }): Promise<void>;
4
6
  }
@@ -1,7 +1,8 @@
1
1
  declare const getApiBase: () => string;
2
2
  declare const getBusinessApiBase: () => string;
3
+ declare const getDeployerBase: () => string;
3
4
  declare const apiFetch: (url: string, options?: RequestInit) => Promise<{
4
5
  response: Response;
5
6
  body: Record<string, unknown>;
6
7
  }>;
7
- export { getApiBase, getBusinessApiBase, apiFetch };
8
+ export { getApiBase, getBusinessApiBase, getDeployerBase, apiFetch };
@@ -0,0 +1,2 @@
1
+ export declare const isUserInterrupt: (error: unknown) => boolean;
2
+ export declare const INTERRUPTED_MESSAGE = "Command interrupted.";
@@ -0,0 +1,6 @@
1
+ export interface Spinner {
2
+ start: (text?: string) => void;
3
+ stop: () => void;
4
+ text: (text: string) => void;
5
+ }
6
+ export declare const createSpinner: (initialText?: string) => Spinner;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@dashnex/cli",
4
- "version": "0.5.4",
4
+ "version": "0.5.23",
5
5
  "description": "Command-line interface for DashNex framework",
6
6
  "homepage": "https://dashnex.io",
7
7
  "type": "module",
@@ -28,13 +28,13 @@
28
28
  "adm-zip": "^0.5.16",
29
29
  "chalk": "^5.6.2",
30
30
  "commander": "^14.0.3",
31
- "dotenv": "^17.3.0",
31
+ "dotenv": "^17.3.1",
32
32
  "fs-extra": "^11.3.3",
33
33
  "ignore": "^7.0.5",
34
- "inquirer": "^13.2.2"
34
+ "inquirer": "^13.2.5"
35
35
  },
36
36
  "devDependencies": {
37
- "@dashnex/types": "^0.5.11",
37
+ "@dashnex/types": "^0.5.14",
38
38
  "@types/adm-zip": "^0.5.7",
39
39
  "@types/fs-extra": "^11.0.4",
40
40
  "@types/inquirer": "^9.0.9",
@@ -48,8 +48,7 @@
48
48
  "vitest": "^4.0.18"
49
49
  },
50
50
  "publishConfig": {
51
- "access": "public",
52
- "registry": "https://registry.npmjs.org/"
51
+ "registry": "https://npm.dashnex.com/"
53
52
  },
54
53
  "files": [
55
54
  "dist",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes