@dashnex/cli 0.5.66 → 0.5.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/client.js +1 -1
- package/dist/commands/app/create.js +1 -1
- package/dist/commands/app/delete.js +1 -1
- package/dist/commands/app/deploy.js +1 -1
- package/dist/commands/app/index.js +1 -1
- package/dist/commands/app/pull.js +1 -1
- package/dist/commands/app/push.js +1 -1
- package/dist/commands/app/status.js +1 -1
- package/dist/commands/check.js +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/index.js +1 -1
- package/dist/commands/install.js +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/version.js +1 -1
- package/dist/commands/whoami.js +1 -1
- package/dist/dashnex.js +1 -0
- package/dist/lib/api.js +1 -1
- package/dist/lib/app-url.js +1 -1
- package/dist/lib/debug.js +1 -1
- package/dist/lib/errors.js +1 -1
- package/dist/lib/settings-path.js +1 -1
- package/dist/lib/spinner.js +1 -1
- package/dist/package.js +1 -0
- package/dist/server.js +1 -1
- package/dist/services/agreements.js +1 -1
- package/dist/services/auth.js +1 -1
- package/package.json +9 -9
- package/dist/dashnex.json.js +0 -1
- package/dist/package.json.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
2
|
+
import o from"./package.js";import{INTERRUPTED_MESSAGE as n,isUserInterrupt as e}from"./lib/errors.js";import{Command as s}from"commander";import c from"chalk";import t from"fs-extra";import a from"path";import{fileURLToPath as i}from"url";import{execSync as r}from"child_process";import d from"dotenv";var l=new s,{version:m,description:p}=o;l.name("dashnex").description(p).version(m).option("--ci","Disable spinner and interactive prompts (CI mode)").arguments("[command]").action(o=>{o&&(l.commands.map(o=>o.name()).includes(o)||(console.error(c.red("Invalid command")),console.log(c.green("Run `dashnex` to see available commands")),process.exit(1))),function(o){const n=[];n.push("Usage: dashnex [options] [command]"),n.push(""),n.push(o.description()),n.push(""),n.push("Options:"),o.options.forEach(o=>{const e=o.flags.padEnd(20);n.push(` ${e} ${o.description}`)}),n.push(""),n.push("Commands:"),o.commands.forEach(o=>{const e=` ${o.name().padEnd(20)} ${o.description()}`;n.push(e),o.commands.length>0&&o.commands.forEach(o=>{const e=` ${o.name().padEnd(20)} ${o.description()}`;n.push(e)})}),console.log(n.join("\n"))}(l)});var f=null;async function u(o,n){const e=[];try{const s=function(o,n){const e=a.join(n,"package.json");if(t.existsSync(e))try{if(JSON.parse(t.readFileSync(e,"utf8")).name===o)return n}catch{}const s=a.join(n,"node_modules",o);if(t.existsSync(s))return s;if(f){const n=a.join(f,o);if(t.existsSync(n))return n}return s}(o,n),c=a.join(s,"dist","commands","index.js");if(t.existsSync(c)){const o=await import(c);let n=[];o.default?n=Array.isArray(o.default)?o.default:[]:o.commands&&(n=Array.isArray(o.commands)?o.commands:[]),n.length>0&&e.push(...n)}}catch(s){if(process.env.DEBUG){const n=s instanceof Error?s.message:String(s);console.log(c.yellow(`Module ${o} has no commands or failed to load: ${n}`))}}return e}function h(o,s,t={}){const a=o.command(s.name).description(s.description);"pull"===s.name&&a.arguments("[folder]"),a.option("--ci","Disable spinner (CI mode)"),s.options&&s.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)}),s.subcommands&&s.subcommands.forEach(o=>{h(a,o,{...t,...s.options})});const i=s.subcommands&&s.subcommands.length>0;"pull"===s.name?a.action(async(o,a,i)=>{try{const n={...t,...a};o&&(n.folder=o),await s.handler.execute(n)}catch(r){if(e(r))return void console.log(c.yellow(n));console.error(c.red(`❌ Command failed in ${s.name}:`),r),process.exit(1)}}):i?a.action(async()=>{a.outputHelp()}):a.action(async(o,a)=>{try{const n={...t,...o};await s.handler.execute(n)}catch(i){if(e(i))return void console.log(c.yellow(n));console.error(c.red(`❌ Command failed in ${s.name}:`),i),process.exit(1)}})}(async function(){d.config({quiet:!0}),process.env.DASHNEX_CLI="1",function(){try{f=r("npm root -g",{encoding:"utf8"}).trim()}catch{f=null}}(),process.argv.includes("--ci")&&(process.env.DASHNEX_CI="1");let o=process.cwd();const n=a.dirname(i(import.meta.url)),e=a.resolve(n,"..");process.env.DEBUG&&(console.log(`CLI started from directory: ${o}`),console.log(`CLI package directory: ${e}`),console.log(`Global node_modules: ${f??"not found"}`));const s=await async function(o){try{const e=[],s=/* @__PURE__ */new Set,c=o=>{s.has(o)||(s.add(o),e.push(o))},i=a.join(o,"dashnex.json");if(t.existsSync(i)){const n=a.join(o,"package.json");if(t.existsSync(n)){const o=JSON.parse(t.readFileSync(n,"utf8"));o.name&&c(o.name)}}const r=a.join(o,"package.json");if(t.existsSync(r)){const n=JSON.parse(t.readFileSync(r,"utf8")),e={...n.dependencies,...n.devDependencies,...n.optionalDependencies};for(const[s]of Object.entries(e)){const n=a.join(o,"node_modules",s);t.existsSync(a.join(n,"dashnex.json"))&&c(s)}}if(f&&t.existsSync(f))try{const o=t.readdirSync(f);for(const n of o)if(n.startsWith("@")){const o=a.join(f,n);try{if(t.statSync(o).isDirectory()){const e=t.readdirSync(o);for(const o of e){const e=`${n}/${o}`,s=a.join(f,e);t.existsSync(a.join(s,"dashnex.json"))&&c(e)}}}catch{}}else{const o=a.join(f,n);t.existsSync(a.join(o,"dashnex.json"))&&c(n)}}catch(n){if(process.env.DEBUG){const o=n instanceof Error?n.message:String(n);console.log("⚠ Error scanning global node_modules:",o)}}return e}catch(n){if(process.env.DEBUG){const o=n instanceof Error?n.message:String(n);console.log("⚠ Error reading app package.json:",o)}return[]}}(o),m=e.includes("node_modules");let p=!1;try{const n=a.join(o,"package.json");if(await t.pathExists(n)){const o=JSON.parse(await t.readFile(n,"utf8"));p="@dashnex/cli"in{...o.dependencies,...o.devDependencies,...o.optionalDependencies}}}catch{}!m&&!p||s.includes("@dashnex/cli")||s.push("@dashnex/cli"),process.env.DEBUG&&(console.log(`CLI package directory: ${e}`),console.log(`Is installed package: ${m}`),console.log(`CLI in dependencies: ${p}`),console.log(`Discovered modules: ${s.join(", ")}`));for(const i of s){let n=[];if("@dashnex/cli"===i&&(m||p))try{const o=a.join(e,"dist","commands","index.js");if(process.env.DEBUG&&console.log(`Loading @dashnex/cli commands from: ${o}`),await t.pathExists(o)){const e=await import(o);e.default?n=Array.isArray(e.default)?e.default:[]:e.commands&&(n=Array.isArray(e.commands)?e.commands:[]),process.env.DEBUG&&console.log(`Loaded ${n.length} commands from @dashnex/cli`)}}catch(g){if(process.env.DEBUG){const o=g instanceof Error?g.message:String(g);console.log(c.yellow(`Failed to load @dashnex/cli commands: ${o}`))}}else n=await u(i,o);for(const o of n)h(l,o)}try{const{default:n}=await import(a.join(o,"dist","commands","index.js"));if(n&&Array.isArray(n))for(const o of n)h(l,o)}catch(g){process.env.DEBUG&&console.error(c.yellow("⚠ Failed to discover application commands"))}l.parse(process.argv)})().catch(o=>{e(o)&&(console.log(c.yellow(n)),process.exit(0)),console.error(c.red("❌ CLI failed:"),o),process.exit(1)});
|
package/dist/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"./package.js";import r from"./dashnex.js";var o={name:e.name,version:e.version,description:e.description,...r};export{o as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{INTERRUPTED_MESSAGE as e,isUserInterrupt as t}from"../../lib/errors.js";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{PullCommand as n}from"./pull.js";import{ensureAgreements as l}from"../../services/agreements.js";import c from"chalk";import p from"inquirer";var u=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,d=e=>new Promise(t=>setTimeout(t,e)),m=class{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 d(a)}return{ready:!1}}async execute(d={}){o("Create flow started");const m=await i();if(!m)return;o("Auth valid, checking if business already has application");const h=r(),f=`${a()}/business/v1/applications`;o(`GET ${f}`),h.start("Checking application status...");try{const e=await fetch(f,{headers:{Authorization:`Bearer ${m.token}`}});h.stop(),o(`Applications response: ${e.status}`),o(`Applications response body: ${await e.text()}`),404!==e.status&&(console.error(c.red("Business already has an application. Run 'dashnex app pull' to pull the existing one.")),process.exit(1))}catch(C){if(h.stop(),s(C),C instanceof Error&&C.message.startsWith("EXIT:"))throw C;if(t(C))return void console.log(c.yellow(e));console.error(c.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}o("No existing application, checking agreements");const g=void 0!==d.subdomain;if(!(await l(m.token,{ciMode:g})))return;let y;o("Agreements checked, proceeding to subdomain prompt");const b=e=>`${a()}/business/v1/applications/check-subdomain?subdomain=${encodeURIComponent(e)}`;let $=d.subdomain?.trim();for(;;){if($)y=$,$=void 0,o(`Subdomain provided via flag: ${y}`);else{if(g)return console.error(c.red("Subdomain is not available.")),void process.exit(1);{const{sub:e}=await p.prompt([{type:"input",name:"sub",message:"Pick your subdomain:",validate:e=>!!e.trim()||"Subdomain is required"}]);y=e.trim()}}o(`Checking subdomain: ${y}`);const a=b(y);o(`GET ${a}`),h.start("Checking subdomain...");try{const e=await fetch(a,{headers:{Authorization:`Bearer ${m.token}`}});h.stop(),o(`Check subdomain response: ${e.status}`);const t=await e.text();if(o(`Check subdomain response body: ${t}`),!e.ok){const s=e.headers.get("content-type")??"";let a="Failed to check subdomain availability.";if(401!==e.status&&403!==e.status||(a="Please run 'dashnex login' to authenticate.",console.error(c.red(a)),process.exit(1)),s.includes("application/json")){const e=JSON.parse(t);o(`Check subdomain error body: ${JSON.stringify(e)}`);const s=u(e);s&&(a=s)}console.error(c.red(a));continue}const s=JSON.parse(t);if(o(`Check subdomain parsed body: ${JSON.stringify(s)}`),s.available){o(`Subdomain ${y} is available`);break}console.error(c.red("Subdomain is not available. Please choose a different one."))}catch(C){if(h.stop(),s(C),C instanceof Error&&C.message.startsWith("EXIT:"))throw C;if(t(C))return void console.log(c.yellow(e));console.error(c.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}const w=`${a()}/business/v1/cli/create`;o(`POST ${w}`);const k={subdomain:y};d.template&&(k.template=d.template,o(`Template: ${d.template}`));const x=JSON.stringify(k);o(`Create request body: ${x}`),h.start("Creating application...");try{const i=await fetch(w,{method:"POST",headers:{Authorization:`Bearer ${m.token}`,"Content-Type":"application/json"},body:x});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..."),h.start("Waiting for application to be ready...");const e=`${a()}/business/v1/applications`,t=await this.pollApplicationCreated(e,m.token);h.stop(),t.ready||(console.error(c.red("Application creation is taking longer than expected. Try again later or run 'dashnex app pull' to check.")),process.exit(1)),"failed"===t.status&&(console.error(c.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 t="Failed to create application.";if(401===i.status||403===i.status)t="Please run 'dashnex login' to authenticate.";else if(e.includes("application/json")){const e=JSON.parse(r);o(`Create error body parsed: ${JSON.stringify(e)}`);const s=u(e);s&&(t=s)}console.error(c.red(t)),process.exit(1)}let l;if(o("Application created successfully"),g?(l=!1,o("CI mode (--subdomain), skipping pull")):(l=(await p.prompt([{type:"confirm",name:"pull",message:"Pull the application locally?",default:!0}])).pull,o(`User chose to pull: ${l}`)),l){o("Running pull flow");try{await(new n).execute()}catch(C){if(s(C),C instanceof Error&&C.message.startsWith("EXIT:"))throw C;if(t(C))return void console.log(c.yellow(e));console.error(c.red("Failed to pull application."))}}else console.log(c.green("Application is created successfully. Run 'dashnex app pull' to pull it to your computer or 'dashnex app deploy' to deploy it to the cloud."))}catch(C){if(h.stop(),s(C),C instanceof Error&&C.message.startsWith("EXIT:"))throw C;if(t(C))return void console.log(c.yellow(e));console.error(c.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}};export{m as CreateCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{INTERRUPTED_MESSAGE as e,isUserInterrupt as t}from"../../lib/errors.js";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 a from"chalk";import c from"inquirer";var l=class{async execute(l={}){if(o("Delete flow started"),!l.yes){const{confirm:e}=await c.prompt([{type:"confirm",name:"confirm",message:"Are you sure you want to delete this application? This action cannot be undone.",default:!1}]);if(!e)return o("User cancelled deletion"),void console.log(a.yellow("Deletion cancelled."))}const p=await i();if(!p)return;const f=`${r()}/business/v1/applications`;o(`DELETE ${f}`);const d=n();d.start("Deleting application...");try{const e=await fetch(f,{method:"DELETE",headers:{Authorization:`Bearer ${p.token}`}});if(d.stop(),o(`Response: ${e.status}`),!e.ok){const t=e.headers.get("content-type")??"";let o="Failed to delete application.";if(401===e.status||403===e.status)o="Please run 'dashnex login' to authenticate.";else if(t.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&&(o=t)}console.error(a.red(o)),process.exit(1)}const t=await e.json().catch(()=>({})),s="string"==typeof t.message?t.message:"Application deleted successfully.";o("Application deleted successfully"),console.log(a.green(s))}catch(m){if(d.stop(),s(m),m instanceof Error&&m.message.startsWith("EXIT:"))throw m;if(t(m))return void console.log(a.yellow(e));console.error(a.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}};export{l as DeleteCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"
|
|
1
|
+
import{INTERRUPTED_MESSAGE as e,isUserInterrupt as t}from"../../lib/errors.js";import{debug as o,debugError as s}from"../../lib/debug.js";import{getBusinessApiBase as r,getDeployerBase as n}from"../../lib/api.js";import{ensureLoggedIn as a}from"../../services/auth.js";import{createSpinner as i}from"../../lib/spinner.js";import{ensureAgreements as c}from"../../services/agreements.js";import{getApplicationUrl as l}from"../../lib/app-url.js";import p from"chalk";var d=3e5,m=99,f=e=>new Promise(t=>setTimeout(t,e)),u=async(e,t,r,n)=>{const a=await fetch(e,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"text/event-stream"}});if(o(`SSE connection opened: ${a.status}`),!a.ok){const e=a.status;let t="Failed to start deployment.";if(401===e||403===e)t="Please run 'dashnex login' to authenticate.";else try{const e=await a.text(),o=JSON.parse(e);"string"==typeof o.error?t=o.error:"string"==typeof o.message&&(t=o.message)}catch{}throw console.error(p.red(t)),new Error(`HTTP ${e}: ${t}`)}if(!a.body)throw new Error("Response body is null");o("SSE connection established successfully"),n?.();const i=a.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})}}(i))try{if(!e.data){o("Received empty SSE event");continue}const t=JSON.parse(e.data);o(`SSE message received: ${JSON.stringify(t)}`),r(t)}catch(c){s(c),o(`Failed to parse SSE event data: ${e.data}`)}}finally{i.releaseLock()}},y=class{async execute(){o("Deploy flow started");const r=await a();if(!r)return;if(!(await c(r.token,{ciMode:!0})))return;const l=`${n()}/business/v1/applications/deploy`;o(`GET ${l} (SSE)`);let y=0,h="",g=!1,w=0,S=!1;const $=i();let b=0,v=0,x=null;const E=(e,t)=>{const o=Math.round(e);$.text(`[${o}%] ${t}`)},D=()=>{k();const e=y,t=Date.now(),o=d*((m-e)/m);x=setInterval(()=>{const s=Date.now()-t;let r;if(v>t){const e=Date.now()-v,t=m-b,o=3030.3030303030305*t;r=Math.min(b+e/o*t,m)}else r=Math.min(e+s/o*(m-e),m);r>y&&(y=r,E(y,h))},200)},k=()=>{x&&(clearInterval(x),x=null)};let T=!1;const j=e=>{if(S=!0,"string"==typeof e.error)return k(),$.stop(),console.error(p.red(e.error)),g=!0,void(T=!0);"string"==typeof e.message&&(h=e.message),"number"==typeof e.progress&&(b=e.progress,v=Date.now(),e.progress>y&&(y=e.progress)),"string"!=typeof e.message&&"number"!=typeof e.progress||(y>=100?(k(),$.stop(),g=!0):E(y,h))};for(;w<=5;)try{return S?E(y,h):$.start("Connecting..."),D(),await u(l,r.token,j,()=>{S||($.text(`[${Math.round(y)}%] Deployment in progress...`),h="Deployment in progress...")}),k(),$.stop(),o("SSE connection closed"),T&&process.exit(1),void(g&&await this.showDeployedUrl(r.token))}catch(M){if(k(),s(M),o(`SSE connection error: ${M}`),g)return $.stop(),void(T&&process.exit(1));if(t(M))return $.stop(),void console.log(p.yellow(e));M instanceof Error&&M.message.startsWith("HTTP")&&($.stop(),console.error(p.red("Could not complete deployment. Check your connection and try again.")),process.exit(1)),w++,w>5&&($.stop(),console.error(p.red("Deployment failed. Maximum reconnection attempts exceeded.")),process.exit(1));const r=Math.min(1e3*Math.pow(2,w-1),3e4);o(`Connection error. Reconnecting in ${r/1e3}s... (attempt ${w}/5)`),await f(r)}}async showDeployedUrl(e){try{const t=`${r()}/business/v1/applications`;o(`GET ${t} (for deployed URL)`);const s=await fetch(t,{headers:{Authorization:`Bearer ${e}`}});if(!s.ok)return;const n=await s.json().catch(()=>({})),a=l({subdomain:n.subdomain,appFullCustomDomain:n.appFullCustomDomain});a&&console.log(`Application is deployed to ${p.cyan(a)}`)}catch(t){s(t)}}};export{y as DeployCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{PullCommand as e}from"./pull.js";import{CreateCommand as o}from"./create.js";import{DeployCommand as p}from"./deploy.js";import{PushCommand as a}from"./push.js";import{DeleteCommand as i}from"./delete.js";import{StatusCommand as t}from"./status.js";var s={name:"app",description:"Manage DashNex applications (should be executed in application folder)",handler:{execute:async()=>{}},options:[],subcommands:[{name:"create",description:"Create a new DashNex application",handler:new o,options:[{flags:"-t, --template <template>",description:"Template (name@branch-or-tag)",defaultValue:"webapp-base@live"},{flags:"--subdomain <subdomain>",description:"Subdomain (CI mode, skip prompts)"}]},{name:"pull",description:"Pull existing application to specified folder",handler:new e,options:[{flags:"-y, --yes",description:"Skip prompts and child commands (CI mode)"}]},{name:"push",description:"Push local application to DashNex",handler:new a,options:[{flags:"--deploy",description:"Auto-deploy after push (skip prompt)"},{flags:"--no-deploy",description:"Skip deploy prompt"},{flags:"--no-check",description:"Skip pre-push checks"}]},{name:"delete",description:"Delete application from DashNex",handler:new i,options:[{flags:"-y, --yes",description:"Skip confirmation prompt"}]},{name:"deploy",description:"Deploy application to DashNex",handler:new p,options:[]},{name:"status",description:"Show current application status",handler:new t,options:[]}]};export{s as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{INTERRUPTED_MESSAGE as e,isUserInterrupt as t}from"../../lib/errors.js";import{debug as r,debugError as o}from"../../lib/debug.js";import{getBusinessApiBase as i}from"../../lib/api.js";import{ensureLoggedIn as s}from"../../services/auth.js";import{createSpinner as a}from"../../lib/spinner.js";import{runDevInDir as n}from"../dev.js";import{runInstallInDir as l}from"../install.js";import c from"chalk";import d from"fs-extra";import p from"path";import{spawn as m}from"child_process";import f from"inquirer";import u from"os";import g from"adm-zip";var h=async(e,t)=>{const{install:i}=await f.prompt([{type:"confirm",name:"install",message:"Install dependencies?",default:!0}]);if(!i){if(p.resolve(e)!==p.resolve(t)){const r=p.relative(t,e);console.log(c.cyan(`Run "cd ${r}" to change to the application folder.`))}return}try{const t=a();t.start("Installing dependencies...");try{const o=await l(e);if(t.stop(),0!==o)return void r(`install exited with code ${o}`)}catch(u){throw t.stop(),u}}catch(u){return o(u),void console.error(c.red(u instanceof Error?u.message:"Failed to run install."))}const{migrate:s}=await f.prompt([{type:"confirm",name:"migrate",message:"Create or update database?",default:!0}]);if(!s)return;r(`Running dashnex db migrate in ${e}`);try{const t=a();t.start("Creating or updating database...");try{const i=await((e,t,r)=>new Promise((i,s)=>{const a=m(t,{cwd:e,shell:!0,stdio:"inherit",env:r?{...process.env,...r}:void 0});a.on("error",e=>{o(e),s(e)}),a.on("close",e=>{i(null===e?0:e)})}))(e,"dashnex db migrate");if(t.stop(),0!==i)return void r(`dashnex db migrate exited with code ${i}`)}catch(u){throw t.stop(),u}}catch(u){return o(u),void console.error(c.red("Failed to run dashnex db migrate."))}const{dev:d}=await f.prompt([{type:"confirm",name:"dev",message:"Run development server?",default:!0}]);if(d)try{await n(e)}catch(u){o(u),console.error(c.red(u instanceof Error?u.message:"Failed to run dev server."))}},w=(e,t)=>p.resolve(e)===p.resolve(t)?"Application is successfully pulled.":`Application is successfully pulled into ${p.relative(t,e)}.`,v=class{async execute(n={}){r("Pull flow started");const l=await s();if(!l)return;const m=process.cwd();let v;if(n.folder)v=n.folder.trim()||".",r(`Folder argument provided: ${v}`);else{r("No folder argument, prompting user");const{folder:e}=await f.prompt([{type:"input",name:"folder",message:"Which folder to pull the application to?",default:"."}]);v=e.trim()||"."}const y=p.resolve(m,v);r(`Target folder resolved: ${y}`);const x=await d.pathExists(y);let $=!1;if(x)try{$=(await d.readdir(y)).length>0,r(`Folder exists: ${x}, has files: ${$}`)}catch(F){r(`Error reading folder: ${F}`)}if($&&!n.yes){const{confirm:e}=await f.prompt([{type:"confirm",name:"confirm",message:"Existing files will be overwritten. Continue?",default:!0}]);if(!e)return r("User declined confirmation, exiting"),void console.log(c.yellow("Pull cancelled."));r("User confirmed overwrite")}await d.ensureDir(y),r(`Target folder ensured: ${y}`);const b=`${i()}/business/v1/cli/pull`;r(`GET ${b}`);const j=p.join(u.tmpdir(),`dashnex-pull-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`),E=a();E.start("Pulling application...");try{const e=await fetch(b,{headers:{Authorization:`Bearer ${l.token}`}});if(r(`Response: ${e.status}`),!e.ok){E.stop();const t=e.headers.get("content-type")??"";let r="Failed to pull application.";if(401===e.status||403===e.status)r="Please run 'dashnex login' to authenticate.";else if(404===e.status)r="Business has no application. Run 'dashnex app create' to create one.";else if(t.includes("application/json")){const t="string"==typeof(C=await e.json().catch(()=>({}))).error?C.error:"string"==typeof C.message?C.message:void 0;t&&(r=t)}console.error(c.red(r)),process.exit(1)}E.text("Downloading...");const t=Buffer.from(await e.arrayBuffer());await d.writeFile(j,t),r("Zip written to temp file"),E.text("Extracting..."),new g(j).extractAllTo(y,!0),E.stop(),r("Extracted to target folder"),p.resolve(y)!==p.resolve(m)?(console.log(c.green(w(y,m))),process.chdir(y),r(`Changed working directory to ${y}`)):console.log(c.green(w(y,m))),n.yes?r("CI mode (--yes), skipping post-pull child commands"):await h(y,m)}catch(F){if(E.stop(),o(F),F instanceof Error&&F.message.startsWith("EXIT:"))throw F;if(t(F))return void console.log(c.yellow(e));console.error(c.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}finally{await d.remove(j).catch(()=>{}),r("Temp zip removed")}var C}};export{v as PullCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{INTERRUPTED_MESSAGE as e,isUserInterrupt as o}from"../../lib/errors.js";import{debug as t,debugError as i}from"../../lib/debug.js";import{getBusinessApiBase as s}from"../../lib/api.js";import{ensureLoggedIn as r}from"../../services/auth.js";import{createSpinner as n}from"../../lib/spinner.js";import{CheckCommand as a}from"../check.js";import{DeployCommand as c}from"./deploy.js";import p from"chalk";import l from"fs-extra";import d from"path";import m from"inquirer";import f from"os";import h from"adm-zip";import u from"ignore";var g=[".dashnex",".git",".vinext",".wrangler","wrangler.jsonc"],w=async(e,o)=>{const t=[],i=await l.readdir(e,{withFileTypes:!0});for(const s of i){const i=d.relative(process.cwd(),d.join(e,s.name)).split(d.sep).join("/");if(g.some(e=>i===e||i.startsWith(`${e}/`)||i.endsWith(`/${e}`)))continue;if(o.ignores(i))continue;const r=d.join(e,s.name);if(s.isDirectory()){const e=await w(r,o);t.push(...e)}else s.isFile()&&t.push(r)}return t},y=class{async execute(y={}){if(t("Push flow started"),!1!==y.check){t("Running pre-push checks");const e=n();e.start("Running checks...");const o=await(new a).run(!0);e.stop(),o||(console.error(p.red("Push aborted: checks failed.")),process.exit(1))}else t("Skipping pre-push checks (--no-check)");const j=await r();if(!j)return;const v=process.cwd(),x=d.join(v,".gitignore"),k=u();if(k.add(g),await l.pathExists(x)){const e=await l.readFile(x,"utf8");k.add(e)}t("Building file list");const $=await w(v,k);t(`Including ${$.length} files`);const b=new h;for(const e of $){const o=d.relative(v,e).split(d.sep).join("/"),t="."===d.dirname(o)?"":d.dirname(o),i=d.basename(o);b.addLocalFile(e,t,i)}const F=d.join(f.tmpdir(),`dashnex-push-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`),P=n();try{P.start("Packaging application..."),b.writeZip(F),t(`Zip written to ${F}`);const e=`${s()}/business/v1/cli/push`;t(`POST ${e}`);const o=await l.readFile(F),i=new Blob([o],{type:"application/zip"}),r=new FormData;r.append("file",i,"archive.zip");const n=new Headers;n.set("Authorization",`Bearer ${j.token}`),P.text("Uploading...");const a=await fetch(e,{method:"POST",headers:n,body:r});if(P.stop(),t(`Response: ${a.status}`),!a.ok){const e=a.headers.get("content-type")??"";let o="Failed to push application.";if(401===a.status||403===a.status)o="Please run 'dashnex login' to authenticate.";else if(e.includes("application/json")){const e="string"==typeof(z=await a.json().catch(()=>({}))).error?z.error:"string"==typeof z.message?z.message:void 0;e&&(o=e)}console.error(p.red(o)),process.exit(1)}let d;console.log(p.green("Application pushed successfully.")),void 0!==y.deploy?(d=y.deploy,t(`Deploy decided via flag: ${d}`)):(d=(await m.prompt([{type:"confirm",name:"deploy",message:"Deploy the application?",default:!0}])).deploy,t(`User chose to deploy: ${d}`)),d&&(t("Running deploy flow"),await(new c).execute())}catch(D){if(P.stop(),i(D),D instanceof Error&&D.message.startsWith("EXIT:"))throw D;if(o(D))return void console.log(p.yellow(e));console.error(p.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}finally{await l.remove(F).catch(()=>{}),t("Temp zip removed")}var z}};export{y as PushCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"
|
|
1
|
+
import{INTERRUPTED_MESSAGE as t,isUserInterrupt as o}from"../../lib/errors.js";import{debug as s,debugError as e}from"../../lib/debug.js";import{getBusinessApiBase as r}from"../../lib/api.js";import{ensureLoggedIn as a}from"../../services/auth.js";import{createSpinner as n}from"../../lib/spinner.js";import{getApplicationUrl as i}from"../../lib/app-url.js";import c from"chalk";var l=class{async execute(){s("Status flow started");const l=await a();if(!l)return;const p=`${r()}/business/v1/applications`;s(`GET ${p}`);const u=n();u.start("Fetching application status...");try{const t=await fetch(p,{headers:{Authorization:`Bearer ${l.token}`}});if(u.stop(),s(`Response: ${t.status}`),404===t.status)return void console.log(c.yellow("Application not created"));if(!t.ok){const o=t.headers.get("content-type")??"";let s="Failed to fetch application status.";if(401===t.status||403===t.status)s="Please run 'dashnex login' to authenticate.";else if(o.includes("application/json")){const o=await t.json().catch(()=>({}));"string"==typeof o.error?s=o.error:"string"==typeof o.message&&(s=o.message)}console.error(c.red(s)),process.exit(1)}const o=await t.json().catch(()=>({}));s(`Application body: ${JSON.stringify(o)}`);const e=o.status??"unknown";console.log(`Status: ${c.cyan(e)}`);const r=i(o);r&&console.log(`URL: ${c.cyan(r)}`)}catch(f){if(u.stop(),e(f),f instanceof Error&&f.message.startsWith("EXIT:"))throw f;if(o(f))return void console.log(c.yellow(t));console.error(c.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}};export{l as StatusCommand};
|
package/dist/commands/check.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{debug as e,debugError as o}from"../lib/debug.js";import r from"chalk";import n from"fs-extra";import s from"path";import{spawn as c}from"child_process";var t="Run this command in a DashNex Web application folder.",i=e=>{const o=s.join(e,"dashnex.json");return n.pathExistsSync(o)},a=(r,n,s={})=>{const t=`${r} ${n.join(" ")}`,i=!0===s.silent;return new Promise((n,s)=>{e(`Running: ${t}`);const a=c(t,{stdio:i?["ignore","pipe","pipe"]:"inherit",cwd:process.cwd(),shell:!0});a.on("error",e=>{o(e),s(e)}),a.on("close",o=>{e(`${r} exited with code ${o}`),n(null===o?1:o)})})},l=e=>new Promise(o=>{const r=c(`${e} --version`,{stdio:"ignore",shell:!0});r.on("error",()=>o(!1)),r.on("close",e=>o(0===e))}),d=[{name:"TypeScript",command:"npx",args:["tsc","--noEmit"],notFoundMessage:"TypeScript is not available. Please install it with: npm install -D typescript"}],p=class{async execute(){e("Check flow started"),i(process.cwd())||(console.error(r.red(t)),process.exit(1)),e(`Running ${d.length} check(s)`);for(const s of d){e(`Running check: ${s.name}`),await l(s.command)||(console.error(r.red(s.notFoundMessage)),process.exit(1));try{0!==await a(s.command,s.args)&&(console.error(r.red("Check failed.")),process.exit(1))}catch(n){o(n),console.error(r.red(s.notFoundMessage)),process.exit(1)}}console.log(r.green("All checks passed."))}async run(n=!1){if(e("Running checks (called from push)"),!i(process.cwd()))return n||console.error(r.red(t)),!1;const s=n?{silent:!0}:void 0;for(const t of d){if(e(`Running check: ${t.name}`),!(await l(t.command)))return console.error(r.red(t.notFoundMessage)),!1;try{if(0!==await a(t.command,t.args,s))return!1}catch(c){return o(c),console.error(r.red(t.notFoundMessage)),!1}}return n||console.log(r.green("All checks passed.")),!0}};export{p as CheckCommand};
|
package/dist/commands/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{debug as e,debugError as r}from"../lib/debug.js";import t from"chalk";import n from"fs-extra";import o from"path";import{spawn as s}from"child_process";var i=["Using vars defined in \\.env","\\(node:\\d+\\) MaxListenersExceededWarning:","\\(Use `node --trace-warnings","\\[WARNING\\].*You have defined bindings to the following internal Durable Objects","You have defined bindings to the following internal Durable Objects",'\\{"name":".+","class_name":".+"\\}',"These will not work in local development, but they should work in production","If you want to develop these locally, you can define your DO in a separate Worker","For detailed instructions, refer to the Durable Objects section here:","developers.cloudflare.com/workers/wrangler/api#supported-bindings","workerd/server/server\\.c\\+\\+.*warning:.*DurableObjectNamespace"],a=(e,r)=>r.length>0&&r.some(r=>r.test(e)),c=(r,t)=>{let n="";return{write:o=>{const s="string"==typeof o?o:o.toString();n+=s;const i=n.split(/\r?\n/);n=i.pop()??"";for(const n of i){const o=n.trim();o?a(o,t)?e(`Filtered: ${o}`):r.write(n+"\n"):e("Filtered: <empty line>")}},flush:()=>{const o=n.trim();if(o){if(a(o,t))return e(`Filtered: ${o}`),void(n="");r.write(n),n=""}else n=""}}},l=async(t,a={})=>{const l=o.join(t,"dashnex.json"),d=o.join(t,"package.json");if(e(`Checking for dashnex.json at: ${l}`),!(await n.pathExists(l)))throw new Error("Run this command in a DashNex Web application folder.");if(e("dashnex.json found, checking for package.json"),!(await n.pathExists(d)))throw new Error("package.json is missing.");let p;e("package.json found, checking for dev script");try{p=await n.readJson(d)}catch(u){throw r(u),new Error("Failed to read package.json.")}if(!p.scripts||!p.scripts.dev)throw new Error('The "dev" script is missing from package.json. Please add a "dev" script to package.json.');e("dev script found, checking for npm availability");const h=await(async e=>new Promise(r=>{const t=s(`${e} --version`,{stdio:"ignore",shell:!0});t.on("error",()=>{r(!1)}),t.on("close",e=>{r(0===e)})}))("npm");if(e(`npm available: ${h}`),!h)throw new Error("npm is not available. Please install npm to continue.");const f=a.https?["--","--experimental-https"]:[];return e(`npm available, executing: npm run dev in ${t}${a.https?" -- --experimental-https":""}`),(async(e,t=[],n=process.cwd(),o=[])=>{const i=t.length?`${e} ${t.join(" ")}`:e,a=o.length>0;return new Promise((e,t)=>{const l=s(i,{stdio:a?["inherit","pipe","pipe"]:"inherit",cwd:n,shell:!0,env:{...process.env,NODE_ENV:"development"}});if(l.on("error",e=>{r(e),t(e)}),a&&l.stdout&&l.stderr){const r=c(process.stdout,o),t=c(process.stderr,o);l.stdout.on("data",e=>r.write(e)),l.stderr.on("data",e=>t.write(e)),l.on("close",n=>{r.flush(),t.flush(),e(null===n?0:n)})}else l.on("close",r=>{e(null===r?0:r)})})})("npm run dev",f,t,(()=>{const r=[];for(const t of i)try{r.push(new RegExp(t))}catch{e(`Invalid dev output filter pattern ignored: ${t}`)}return r})())},d=class{async execute(n={}){e("Dev flow started");try{const e=await l(process.cwd(),n);process.exit(e)}catch(o){if(o instanceof Error&&o.message.startsWith("EXIT:"))throw o;r(o),o instanceof Error?console.error(t.red(o.message)):console.error(t.red("Failed to run npm run dev")),process.exit(1)}}};export{d as DevCommand,l as runDevInDir};
|
package/dist/commands/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"./version.js";import{LoginCommand as e}from"./login.js";import{LogoutCommand as i}from"./logout.js";import{WhoamiCommand as n}from"./whoami.js";import{DevCommand as s}from"./dev.js";import{CheckCommand as r}from"./check.js";import{InstallCommand as
|
|
1
|
+
import o from"./version.js";import{LoginCommand as e}from"./login.js";import{LogoutCommand as i}from"./logout.js";import{WhoamiCommand as n}from"./whoami.js";import{DevCommand as s}from"./dev.js";import{CheckCommand as r}from"./check.js";import{InstallCommand as p}from"./install.js";import t from"./app/index.js";var a=[{name:"version",description:"Display the version of the CLI",handler:new o,options:[]},{name:"login",description:"Log in to your DashNex account",handler:new e,options:[{flags:"--email <email>",description:"Email address (skip prompt)"},{flags:"--password <password>",description:"Password (skip prompt)"},{flags:"--code <code>",description:"2FA code (skip prompt)"},{flags:"--business <id>",description:"Business ID to select (skip prompt)"}]},{name:"logout",description:"Log out and remove local credentials",handler:new i,options:[]},{name:"whoami",description:"Show current logged-in business and user",handler:new n,options:[]},{name:"dev",description:"Run the development server (run in DashNex application folder)",handler:new s,options:[{flags:"--https",description:"Run dev server with HTTPS"}]},{name:"check",description:"Run build-time validations (run in DashNex application folder)",handler:new r,options:[]},{name:"install",description:"Install dependencies using pnpm or npm (run in DashNex application folder)",handler:new p,options:[]},t];export{a as default};
|
package/dist/commands/install.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{debug as e,debugError as o}from"../lib/debug.js";import{createSpinner as r}from"../lib/spinner.js";import s from"chalk";import n from"fs-extra";import t from"path";import{spawn as i}from"child_process";var c=async e=>new Promise(o=>{const r=i(`${e} --version`,{stdio:"ignore",shell:!0});r.on("error",()=>{o(!1)}),r.on("close",e=>{o(0===e)})}),a=async r=>{const s=await(async()=>await c("pnpm")?"pnpm":await c("npm")?"npm":null)();if(!s)throw new Error("Neither pnpm nor npm is available. Please install pnpm (recommended) or npm to continue.");const n=`${s} ${["install","--ignore-scripts"].join(" ")}`;return e(`Using package manager: ${s}`),e(`Executing: ${n} in ${r}`),new Promise((e,s)=>{const t=[],c=[],a=i(n,{stdio:["ignore","pipe","pipe"],cwd:r,shell:!0,env:{...process.env,NPM_CONFIG_LOGLEVEL:"error"}});a.stdout&&a.stdout.on("data",e=>t.push(e)),a.stderr&&a.stderr.on("data",e=>c.push(e)),a.on("error",e=>{o(e),s(e)}),a.on("close",o=>{const r=null===o?0:o;0!==r&&(t.length&&process.stdout.write(Buffer.concat(t)),c.length&&process.stderr.write(Buffer.concat(c))),e(r)})})},l=class{async execute(){e("Install flow started");const c=t.join(process.cwd(),"dashnex.json");await n.pathExists(c)||(console.error(s.red("Run this command in a DashNex Web application folder.")),process.exit(1));const l=process.cwd(),p=r();p.start("Installing dependencies...");try{const r=await a(l);0!==r&&(p.stop(),process.exit(r)),p.text("Building module registry...");const n=await(async r=>new Promise((s,n)=>{e(`Running: npx dashnex build --with-config in ${r}`);const t=i("npx dashnex build --with-config",{stdio:"ignore",cwd:r,shell:!0});t.on("error",e=>{o(e),n(e)}),t.on("close",e=>{s(null===e?1:e)})}))(l);p.stop(),0!==n&&(o(/* @__PURE__ */new Error(`dashnex build --with-config exited with code ${n}`)),console.error(s.red("Install completed but module registry build failed.")),process.exit(1)),process.exit(0)}catch(d){p.stop(),o(d),d instanceof Error?console.error(s.red(d.message)):console.error(s.red("Failed to run install")),process.exit(1)}}};export{l as InstallCommand,a as runInstallInDir};
|
package/dist/commands/login.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{INTERRUPTED_MESSAGE as e,isUserInterrupt as s}from"../lib/errors.js";import{getSettingsPath as t}from"../lib/settings-path.js";import{debug as r,debugError as o,debugJson as n}from"../lib/debug.js";import{apiFetch as i,getApiBase as a,getBusinessApiBase as c}from"../lib/api.js";import{ensureLoggedIn as l}from"../services/auth.js";import{createSpinner as d}from"../lib/spinner.js";import u from"chalk";import h from"fs-extra";import p from"path";import m from"inquirer";var f=(e,s,t)=>{const r=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(s);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.":r&&(o=r),console.error(u.red(o)),process.exit(1)},g=class{async execute(c={}){r("Login flow started");const h=t(process.cwd()),p=await l({exitOnFailure:!1,dashnexPath:h});if(p)console.log(u.green(`Already logged in as ${p.userName??"user"}`));else try{let e,s;if(c.email)e=c.email.trim(),r("Email provided via flag");else{const{username:s}=await m.prompt([{type:"input",name:"username",message:"Email:",validate:e=>!!e.trim()||"Email is required"}]);e=s.trim()}if(c.password)s=c.password,r("Password provided via flag");else{const{password:e}=await m.prompt([{type:"password",name:"password",message:"Password:",mask:"*",validate:e=>!!e||"Password is required"}]);s=e}r("Email provided");const t=d();t.start("Logging in..."),r(`POST ${a()}/auth/v1/login`);const{response:l,body:p}=await i(`${a()}/auth/v1/login`,{method:"POST",body:JSON.stringify({username:e,password:s})});t.stop(),r(`Response: ${l.status}`),n("Login response",p),l.ok||(o(/* @__PURE__ */new Error(`Login failed: ${l.status} ${JSON.stringify(p)}`)),401===l.status&&(console.error(u.red("Invalid username or password.")),process.exit(1)),f(l,p,"Login failed. Please try again."));const g=p;if(g.two_fa_required&&g.token){r(`2FA required, type: ${g.type||"unknown"}`);const e=await this.handle2FA(g.token,g.type,c.code);e||process.exit(1),await this.completeLogin(e,h,c.business)}else g.token&&g.refreshToken?await this.completeLogin({token:g.token,refreshToken:g.refreshToken},h,c.business):(console.error(u.red("Invalid response from server. Please try again.")),process.exit(1))}catch(g){if(o(g),s(g))return void console.log(u.yellow(e));console.error(u.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}async handle2FA(t,c,l){if("sms"===c){r(`POST ${a()}/auth/v1/two-fa/sms`);try{const{response:e}=await i(`${a()}/auth/v1/two-fa/sms`,{method:"POST",headers:{Authorization:`Bearer ${t}`},body:JSON.stringify({})});r(`Response: ${e.status}`)}catch(p){return o(p),console.error(u.red("Could not send SMS code. Check your connection and try again.")),null}}const d="sms"===c?"Check your phone for the code":"Check your authenticator app for the code",h=l?1:3;for(let g=1;g<=h;g++){let c;l&&1===g?(c=l,r("2FA code provided via flag")):c=(await m.prompt([{type:"input",name:"auth_code",message:`Enter code (${d}):`,validate:e=>!!e.trim()||"Code is required"}])).auth_code,r(`POST ${a()}/auth/v1/2fa-check`);try{const{response:e,body:s}=await i(`${a()}/auth/v1/2fa-check`,{method:"POST",headers:{Authorization:`Bearer ${t}`},body:JSON.stringify({auth_code:c.trim()})});if(r(`Response: ${e.status}`),n("2FA check response",s),e.ok){const e=s;if(e.token&&e.refreshToken)return{token:e.token,refreshToken:e.refreshToken}}if(e.status>=400&&e.status<500){if(console.error(u.red("Invalid code. Please try again.")),g<h){const{retry:e}=await m.prompt([{type:"confirm",name:"retry",message:"Try again?",default:!0}]);if(!e)return null}continue}f(e,s,"2FA verification failed. Please try again.")}catch(p){return o(p),s(p)?(console.log(u.yellow(e)),null):(console.error(u.red("Could not reach DashNex API. Check your connection and try again.")),null)}}return null}async completeLogin(e,s,t){const l=d();l.start("Fetching businesses...");const g=a(),y={Authorization:`Bearer ${e.token}`};r(`GET ${g}/users/v1/business/my`);const{response:w,body:b}=await i(`${g}/users/v1/business/my`,{headers:y});r(`Response: ${w.status}`),n("Businesses response",b),w.ok||(l.stop(),o(/* @__PURE__ */new Error(`Business fetch failed: ${w.status}`)),f(w,b,"Failed to fetch businesses. Please try again."));const $=this.parseBusinesses(b),k=await this.fetchOtherBusinesses(e.token),v=this.mergeBusinesses($,k);let P;if(l.stop(),r(`Businesses (my: ${$.length}, other: ${k.length}, merged: ${v.length})`),0===v.length&&(console.error(u.red("No businesses or teams found for your account!")),console.log(u.green("Create your first business at https://dashnex.io")),process.exit(1)),t){const e=v.find(e=>e.id===t);e||(console.error(u.red(`Business "${t}" not found.`)),process.exit(1)),P=e,r(`Selected business via flag: ${P.id} ${P.name}`)}else if(1===v.length)P=v[0],r(`Selected business: ${P.id} ${P.name}`);else{const{businessId:e}=await m.prompt([{type:"select",name:"businessId",message:"Select business:",choices:v.map(e=>({name:e.name,value:e.id}))}]);P=v.find(s=>s.id===e)||v[0],r(`Selected business: ${P.id} ${P.name}`)}l.start("Switching business..."),r(`GET ${g}/business/v1/login?_switch_business=${P.id}`);const{response:x,body:T}=await i(`${g}/business/v1/login?_switch_business=${P.id}`,{headers:y});l.stop(),r(`Response: ${x.status}`),n("Business login response",T),x.ok||(o(/* @__PURE__ */new Error(`Business login failed: ${x.status}`)),f(x,T,"Failed to switch to business. Please try again."));const S=T;S.token&&S.refreshToken||(console.error(u.red("Invalid response from server. Please try again.")),process.exit(1));const A={token:S.token,refreshToken:S.refreshToken,businessId:P.id},B={Authorization:`Bearer ${S.token}`};try{const e=c();r(`GET ${e}/business/v1/cli/settings`);const{response:s,body:t}=await i(`${e}/business/v1/cli/settings`,{headers:B});r(`Response: ${s.status}`),n("CLI settings response",t),s.ok&&t&&"object"==typeof t&&Object.assign(A,t)}catch(O){o(O)}const E=p.dirname(s);await h.pathExists(E)&&(await h.stat(E)).isFile()&&await h.remove(E),await h.ensureDir(E),await h.writeJson(s,A,{spaces:2}),r("Saved credentials to .dashnex/settings.json"),this.ensureGitignore(),console.log(u.green(`Logged in as ${P.name}`))}async fetchOtherBusinesses(e){const s=a();let t=1;const n=[];let c=0;do{const a=`${s}/users/v1/business/other?page=${t}&perPage=100`;r(`GET ${a}`);const{response:l,body:d}=await i(a,{headers:{Authorization:`Bearer ${e}`}});l.ok||(o(/* @__PURE__ */new Error(`Other businesses fetch failed: ${l.status}`)),f(l,d,"Failed to fetch teams. Please try again."));const u=this.parseBusinesses(d),h="number"==typeof d.total?d.total:u.length;if(n.push(...u),c=h,u.length<100||n.length>=c)break;t++}while(n.length<c);return n}mergeBusinesses(e,s){const t=/* @__PURE__ */new Map;for(const r of e)t.set(r.id,r);for(const r of s)t.has(r.id)||t.set(r.id,r);return[...t.values()]}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,t=String(s.id??s.business_id??"").trim(),r=String(s.name??s.companyName??s.business_name??"Unknown").trim();if(t)return{id:t,name:r}}return null}).filter(e=>null!==e):[]}async ensureGitignore(){const e=p.join(process.cwd(),".gitignore");if(!(await h.pathExists(e)))return;let s=await h.readFile(e,"utf8");s.includes(".dashnex")||(s=s.trimEnd(),s.endsWith("\n")||(s+="\n"),s+="\n.dashnex\n",await h.writeFile(e,s))}};export{g as LoginCommand};
|
package/dist/commands/logout.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{getSettingsPath as e}from"../lib/settings-path.js";import s from"chalk";import t from"fs-extra";var o=class{async execute(){const o=e(process.cwd());if(await t.pathExists(o)){const e=await t.readJson(o);delete e.token,delete e.refreshToken,delete e.businessId,await t.writeJson(o,e,{spaces:2})}console.log(s.green("Logged out."))}};export{o as LogoutCommand};
|
package/dist/commands/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var a=class{async execute(a){const e=await import("../../package.json",{with:{type:"json"}});console.log(e.default.version)}};export{a as default};
|
package/dist/commands/whoami.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"
|
|
1
|
+
import{INTERRUPTED_MESSAGE as e,isUserInterrupt as o}from"../lib/errors.js";import{debug as t,debugError as r}from"../lib/debug.js";import{getApiBase as s}from"../lib/api.js";import{ensureLoggedIn as n}from"../services/auth.js";import{createSpinner as a}from"../lib/spinner.js";import i from"chalk";var c=class{async execute(){t("Whoami flow started");const c=await n();if(!c)return;const m=`${s()}/users/v1/`;t(`GET ${m}`);const l=a();l.start("Fetching user info...");try{const e=await fetch(m,{headers:{Authorization:`Bearer ${c.token}`}});if(l.stop(),t(`Response: ${e.status}`),!e.ok){const o=e.headers.get("content-type")??"";let t="Failed to fetch user info.";if(401===e.status||403===e.status)t="Please run 'dashnex login' to authenticate.";else if(o.includes("application/json")){const o="string"==typeof(f=await e.json().catch(()=>({}))).error?f.error:"string"==typeof f.message?f.message:void 0;o&&(t=o)}console.error(i.red(t)),process.exit(1)}const o=await e.json().catch(()=>({})),r="string"==typeof o.name?o.name:"string"==typeof o.companyName?o.companyName:"Unknown",s=o.memberUser,n=s&&"string"==typeof s.fullName?s.fullName:s&&"string"==typeof s.name?s.name:"Unknown";t(`Whoami: ${r} (${n})`),console.log(i.green(`You are logged in as ${r} (${n})`))}catch(p){if(l.stop(),r(p),p instanceof Error&&p.message.startsWith("EXIT:"))throw p;if(o(p))return void console.log(i.yellow(e));console.error(i.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}var f}};export{c as WhoamiCommand};
|
package/dist/dashnex.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a={};export{a as default};
|
package/dist/lib/api.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var s=()=>process.env.NEXT_PUBLIC_DASHNEX_API_DOMAIN||"https://api.dashnex.com",e=()=>process.env.DASHNEX_BUSINESS_API_URL||"https://api.business.dashnex.com",a={qa:"https://3atfynmu2w.us-east-1.awsapprunner.com",live:"https://rkwbzvhcwh.us-east-1.awsapprunner.com"},t=()=>a[process.env.APPLICATION_ENV||"live"]||a.live,n=async(s,e={})=>{const a=await fetch(s,{...e,headers:{"Content-Type":"application/json",...e.headers}});return{response:a,body:await a.json().catch(()=>({}))}};export{n as apiFetch,s as getApiBase,e as getBusinessApiBase,t as getDeployerBase};
|
package/dist/lib/app-url.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var a=a=>a.appFullCustomDomain?a.appFullCustomDomain:a.subdomain?"qa"===(process.env.APPLICATION_ENV??"")?`https://${a.subdomain}.dashnex.dev`:`https://${a.subdomain}.dashnexcloud.com`:null;export{a as getApplicationUrl};
|
package/dist/lib/debug.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"chalk";
|
|
1
|
+
import o from"chalk";var r=o=>{const r=o.toLowerCase();return r.includes("token")||r.includes("password")||"auth_code"===r},e=o=>{if(null===o||"object"!=typeof o)return o;if(Array.isArray(o))return o.map(e);const s={};for(const[n,t]of Object.entries(o))r(n)?s[n]="[REDACTED]":s[n]=e(t);return s},s=r=>{process.env.DEBUG&&console.log(o.dim(r))},n=(r,s)=>{if(process.env.DEBUG){const n=e(s);console.log(o.dim(`${r}: ${JSON.stringify(n,null,2)}`))}},t=r=>{process.env.DEBUG&&r instanceof Error&&(console.log(o.dim(`Error: ${r.message}`)),r.stack&&console.log(o.dim(`Stack: ${r.stack}`)))};export{s as debug,t as debugError,n as debugJson};
|
package/dist/lib/errors.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var 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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"path";
|
|
1
|
+
import o from"path";var s=process.env.DASHNEX_DIR||".dashnex",e=e=>o.join(e,s,"settings.json");export{e as getSettingsPath};
|
package/dist/lib/spinner.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var t=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],r=(r="")=>{if(process.env.DASHNEX_CI)return{start:()=>{},stop:()=>{},text:()=>{}};let e=null,s=0,n=r;const l=()=>{const r=t[s%t.length];process.stderr.write(`\r[K${r} ${n}`),s++};return{start:t=>{void 0!==t&&(n=t),e||(s=0,l(),e=setInterval(l,80))},stop:()=>{e&&(clearInterval(e),e=null),process.stderr.write("\r[K\n")},text:t=>{n=t,e&&l()}}};export{r as createSpinner};
|
package/dist/package.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e={$schema:"https://json.schemastore.org/package",name:"@dashnex/cli",version:"0.5.67",description:"Command-line interface for DashNex framework",homepage:"https://dashnex.io",type:"module",bin:{dashnex:"bin/dashnex"},exports:{".":{types:"./dist/server.d.ts",default:"./dist/server.js"},"./client":{types:"./dist/client.d.ts",default:"./dist/client.js"}},scripts:{build:"vite build",dev:"vite build --watch --mode development",test:"vitest run"},keywords:["dashnex","cli"],author:"Dashnex Team",license:"UNLICENSED",dependencies:{"adm-zip":"^0.5.16",chalk:"^5.6.2",commander:"^14.0.3",dotenv:"^17.3.1","fs-extra":"^11.3.4",ignore:"^7.0.5",inquirer:"^13.3.2"},devDependencies:{"@dashnex/types":"^1.0.0","@types/adm-zip":"^0.5.8","@types/fs-extra":"^11.0.4","@types/inquirer":"^9.0.9","@types/node":"^25.5.0",eslint:"^9.39.4","rollup-plugin-preserve-directives":"^0.4.0",terser:"^5.46.1",typescript:"^5.9.3",vite:"^8.0.2","vite-plugin-dts":"5.0.0-beta.6",vitest:"^4.1.1"},publishConfig:{registry:"https://npm.dashnex.com/"},files:["dist","bin"]};export{e as default};
|
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"./package.js";import r from"./dashnex.js";var o={name:e.name,version:e.version,description:e.description,...r};export{o as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{debug as e,debugError as t}from"../lib/debug.js";import{getBusinessApiBase as r}from"../lib/api.js";import n from"chalk";import s from"inquirer";var o=async t=>{const s=`${r()}/business/v1/agreements/payment-processing/status`;e(`GET ${s}`);const o=await fetch(s,{headers:{Authorization:`Bearer ${t}`}});if(e(`Payment agreement response: ${o.status}`),!o.ok)return!0;if((await o.json().catch(()=>({}))).hasAccepted)return!0;const a=`${await(async()=>"qa"===process.env.APPLICATION_ENV?"https://business.qa.dashnex.com":"https://business.dashnex.com")()}/money/agreement/`;return console.error(n.red(`You need to accept Master Payment Processing Agreement first by visiting this link: ${a}`)),!1},a=async(a,c={})=>{const i=c.ciMode??!1;return!!(await o(a))&&!!(await(async(o,a)=>{const c=`${r()}/business/v1/tos/latest`;e(`GET ${c}`);const i=await fetch(c,{headers:{Authorization:`Bearer ${o}`}});if(e(`TOS latest response: ${i.status}`),i.ok)return!0;if(404!==i.status)return!0;const p=`${r()}/business/v1/tos/current`;e(`GET ${p}`);const l=await fetch(p,{headers:{Authorization:`Bearer ${o}`}});if(e(`TOS current response: ${l.status}`),!l.ok)return e("Could not fetch current TOS, skipping check"),!0;const u=await l.json().catch(()=>({})),g=u.version??"unknown";if(u.text&&(console.log(n.dim("─".repeat(60))),console.log(n.bold(`Terms of Service ${g}`)),console.log(n.dim("─".repeat(60))),console.log(u.text.replace(/<br\s*\/?>/gi,"\n").replace(/<\/p>/gi,"\n\n").replace(/<\/div>/gi,"\n").replace(/<\/li>/gi,"\n").replace(/<[^>]+>/g,"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/ /g," ").replace(/\n{3,}/g,"\n\n").trim()),console.log(n.dim("─".repeat(60)))),a)return console.log(n.yellow(`By proceeding you accept the Terms of Service ${g}.`)),!0;const{accept:m}=await s.prompt([{type:"confirm",name:"accept",message:`By creating an application you accept the Terms of Service ${g}. Continue?`,default:!0}]);if(!m)return console.log(n.yellow("Cancelled.")),!1;try{const t=`${r()}/business/v1/tos/${u.id}/accept`;e(`POST ${t}`),await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify({})})}catch(h){t(h)}return!0})(a,i))};export{a as ensureAgreements};
|
package/dist/services/auth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{getSettingsPath as e}from"../lib/settings-path.js";import{debug as r,debugError as n,debugJson as s}from"../lib/debug.js";import{apiFetch as t,getApiBase as o}from"../lib/api.js";import a from"chalk";import i from"fs-extra";import u from"path";var l=()=>{console.error(a.red("Please run 'dashnex login' to authenticate.")),console.error(a.green("If you don't have an account yet, create one at https://dashnex.io"))},f=async(e,n)=>{r(`POST ${o()}/auth/v1/token/refresh`);const{response:a,body:u}=await t(`${o()}/auth/v1/token/refresh`,{method:"POST",body:JSON.stringify({refreshToken:e})});if(r(`Response: ${a.status}`),s("Refresh response",u),!a.ok)return r("Token refresh failed"),null;const l=u;if(!l.token||!l.refreshToken)return r("Refresh response missing tokens"),null;const f=await i.readJson(n);return f.token=l.token,f.refreshToken=l.refreshToken,await i.writeJson(n,f,{spaces:2}),r("Updated settings.json with new tokens"),h(l.token,l.refreshToken,n,{...f,token:l.token,refreshToken:l.refreshToken})},h=async(e,a,i,u)=>{if(((e,n=30)=>{try{const s=e.split(".");if(3!==s.length)return!1;const t=JSON.parse(Buffer.from(s[1],"base64url").toString());if("number"!=typeof t.exp)return!1;const o=Math.floor(Date.now()/1e3),a=t.exp-n<=o;return a&&r(`Token expired or expiring soon (exp: ${t.exp}, now: ${o})`),a}catch{return!1}})(e)){if(!a)return r("Token expired, no refreshToken available"),null;r("Token expired, refreshing proactively");try{return await f(a,i)}catch(l){return n(l),null}}r(`GET ${o()}/users/v1/`);try{const{response:n,body:l}=await t(`${o()}/users/v1/`,{headers:{Authorization:`Bearer ${e}`}});if(r(`Response: ${n.status}`),s("Users response",l),n.ok){const n=l;if("string"==typeof n.name&&u.businessId)return r(`Token valid, Already logged in as ${n.name}`),{token:e,businessId:u.businessId,userName:n.name}}return a?(r("Users API rejected token, refreshing"),await f(a,i)):(r("Token invalid, no refreshToken available"),null)}catch(l){return n(l),null}},c=async(n={})=>{const{exitOnFailure:s=!0,dashnexPath:t}=n,o=t??await(async r=>{let n=u.resolve(r);for(;;){const r=e(n);if(await i.pathExists(r))return r;const s=u.dirname(n);if(s===n)return null;n=s}})(process.cwd());if(!o||!(await i.pathExists(o)))return r(".dashnex/settings.json not found"),s&&(l(),process.exit(1)),null;let a;r(`Found settings at ${o}`);try{a=await i.readJson(o)}catch{return r("settings.json parse failed"),s&&(l(),process.exit(1)),null}const{token:f,refreshToken:c,businessId:p}=a;if(!f)return r("settings.json missing token"),s&&(l(),process.exit(1)),null;const d=await h(f,c,o,a);return d||(s&&(l(),process.exit(1)),null)};export{c as ensureLoggedIn};
|
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
|
+
"version": "0.5.67",
|
|
5
5
|
"description": "Command-line interface for DashNex framework",
|
|
6
6
|
"homepage": "https://dashnex.io",
|
|
7
7
|
"type": "module",
|
|
@@ -31,21 +31,21 @@
|
|
|
31
31
|
"dotenv": "^17.3.1",
|
|
32
32
|
"fs-extra": "^11.3.4",
|
|
33
33
|
"ignore": "^7.0.5",
|
|
34
|
-
"inquirer": "^13.3.
|
|
34
|
+
"inquirer": "^13.3.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@dashnex/types": "^0.
|
|
38
|
-
"@types/adm-zip": "^0.5.
|
|
37
|
+
"@dashnex/types": "^1.0.0",
|
|
38
|
+
"@types/adm-zip": "^0.5.8",
|
|
39
39
|
"@types/fs-extra": "^11.0.4",
|
|
40
40
|
"@types/inquirer": "^9.0.9",
|
|
41
|
-
"@types/node": "^25.
|
|
42
|
-
"eslint": "^9.39.
|
|
41
|
+
"@types/node": "^25.5.0",
|
|
42
|
+
"eslint": "^9.39.4",
|
|
43
43
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
44
|
-
"terser": "^5.46.
|
|
44
|
+
"terser": "^5.46.1",
|
|
45
45
|
"typescript": "^5.9.3",
|
|
46
|
-
"vite": "^
|
|
46
|
+
"vite": "^8.0.2",
|
|
47
47
|
"vite-plugin-dts": "5.0.0-beta.6",
|
|
48
|
-
"vitest": "^4.
|
|
48
|
+
"vitest": "^4.1.1"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"registry": "https://npm.dashnex.com/"
|
package/dist/dashnex.json.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const t={};export{t as default};
|
package/dist/package.json.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e="@dashnex/cli",a="0.5.66",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};
|