@dashnex/cli 0.5.62 → 0.5.64
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/commands/index.js +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/lib/settings-path.js +1 -0
- package/dist/package.json.js +1 -1
- package/dist/services/auth.js +1 -1
- package/dist/src/lib/settings-path.d.ts +3 -0
- package/package.json +2 -2
- package/dist/commands/secrets/delete.js +0 -1
- package/dist/commands/secrets/index.js +0 -1
- package/dist/commands/secrets/list.js +0 -1
- package/dist/commands/secrets/set.js +0 -1
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{fileURLToPath as a}from"url";import c from"dotenv";import t from"./package.json.js";import{isUserInterrupt as i,INTERRUPTED_MESSAGE as r}from"./lib/errors.js";const d=new o,{version:l,description:m}=t;async function p(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),t=s.join(e,"dist","commands","index.js");if(n.existsSync(t)){const o=await import(t);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(t){if(process.env.DEBUG){const n=t instanceof Error?t.message:String(t);console.log(e.yellow(`Module ${o} has no commands or failed to load: ${n}`))}}return c}function f(o,n,s={}){const a=o.command(n.name).description(n.description);"pull"===n.name&&a.arguments("[folder]"),a.option("--ci","Disable spinner (CI mode)"),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=>{f(a,o,{...s,...n.options})});const c=n.subcommands&&n.subcommands.length>0;"pull"===n.name?a.action(async(o,a,c)=>{try{const e={...s,...a};o&&(e.folder=o),await n.handler.execute(e)}catch(t){if(i(t))return void console.log(e.yellow(r));console.error(e.red(`❌ Command failed in ${n.name}:`),t),process.exit(1)}}):c?a.action(async()=>{a.outputHelp()}):a.action(async(o,a)=>{try{const e={...s,...o};await n.handler.execute(e)}catch(c){if(i(c))return void console.log(e.yellow(r));console.error(e.red(`❌ Command failed in ${n.name}:`),c),process.exit(1)}})}d.name("dashnex").description(m).version(l).option("--ci","Disable spinner and interactive prompts (CI mode)").arguments("[command]").action(o=>{if(o){d.commands.map(o=>o.name()).includes(o)||(console.error(e.red("Invalid command")),process.exit(1))}!function(o){const e=[];e.push("Usage: dashnex [options] [command]"),e.push(""),e.push(o.description()),e.push(""),e.push("Options:"),o.options.forEach(o=>{const n=o.flags.padEnd(20);e.push(` ${n} ${o.description}`)}),e.push(""),e.push("Commands:"),o.commands.forEach(o=>{const n=` ${o.name().padEnd(20)} ${o.description()}`;e.push(n),o.commands.length>0&&o.commands.forEach(o=>{const n=` ${o.name().padEnd(20)} ${o.description()}`;e.push(n)})}),console.log(e.join("\n"))}(d)}),async function(){c.config({quiet:!0}),process.env.DASHNEX_CLI="1",process.argv.includes("--ci")&&(process.env.DASHNEX_CI="1");let o=process.cwd();const t=s.dirname(a(import.meta.url)),i=s.resolve(t,"..");process.env.DEBUG&&(console.log(`CLI started from directory: ${o}`),console.log(`CLI package directory: ${i}`));const r=await async function(o){try{const e=[],a=/* @__PURE__ */new Set,c=o=>{a.has(o)||(a.add(o),e.push(o))},t=s.join(o,"dashnex.json");if(n.existsSync(t)){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 i=s.join(o,"package.json");if(!n.existsSync(i))return e;const r=JSON.parse(n.readFileSync(i,"utf8")),d={...r.dependencies,...r.devDependencies,...r.optionalDependencies};for(const[l]of Object.entries(d)){const e=s.join(o,"node_modules",l);n.existsSync(s.join(e,"dashnex.json"))&&c(l)}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),l=i.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{}!l&&!m||r.includes("@dashnex/cli")||r.push("@dashnex/cli"),process.env.DEBUG&&(console.log(`CLI package directory: ${i}`),console.log(`Is installed package: ${l}`),console.log(`CLI in dependencies: ${m}`),console.log(`Discovered modules: ${r.join(", ")}`));for(const a of r){let c=[];if("@dashnex/cli"===a&&(l||m))try{const o=s.join(i,"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(u){if(process.env.DEBUG){const o=u instanceof Error?u.message:String(u);console.log(e.yellow(`Failed to load @dashnex/cli commands: ${o}`))}}else c=await p(a,o);for(const o of c)f(d,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(d,o)}catch(u){process.env.DEBUG&&console.error(e.yellow("⚠ Failed to discover application commands"))}d.parse(process.argv)}().catch(o=>{i(o)&&(console.log(e.yellow(r)),process.exit(0)),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 t from"./package.json.js";import{isUserInterrupt as i,INTERRUPTED_MESSAGE as r}from"./lib/errors.js";const d=new o,{version:l,description:m}=t;async function p(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),t=s.join(e,"dist","commands","index.js");if(n.existsSync(t)){const o=await import(t);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(t){if(process.env.DEBUG){const n=t instanceof Error?t.message:String(t);console.log(e.yellow(`Module ${o} has no commands or failed to load: ${n}`))}}return c}function f(o,n,s={}){const a=o.command(n.name).description(n.description);"pull"===n.name&&a.arguments("[folder]"),a.option("--ci","Disable spinner (CI mode)"),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=>{f(a,o,{...s,...n.options})});const c=n.subcommands&&n.subcommands.length>0;"pull"===n.name?a.action(async(o,a,c)=>{try{const e={...s,...a};o&&(e.folder=o),await n.handler.execute(e)}catch(t){if(i(t))return void console.log(e.yellow(r));console.error(e.red(`❌ Command failed in ${n.name}:`),t),process.exit(1)}}):c?a.action(async()=>{a.outputHelp()}):a.action(async(o,a)=>{try{const e={...s,...o};await n.handler.execute(e)}catch(c){if(i(c))return void console.log(e.yellow(r));console.error(e.red(`❌ Command failed in ${n.name}:`),c),process.exit(1)}})}d.name("dashnex").description(m).version(l).option("--ci","Disable spinner and interactive prompts (CI mode)").arguments("[command]").action(o=>{if(o){d.commands.map(o=>o.name()).includes(o)||(console.error(e.red("Invalid command")),console.log(e.green("Run `dashnex` to see available commands")),process.exit(1))}!function(o){const e=[];e.push("Usage: dashnex [options] [command]"),e.push(""),e.push(o.description()),e.push(""),e.push("Options:"),o.options.forEach(o=>{const n=o.flags.padEnd(20);e.push(` ${n} ${o.description}`)}),e.push(""),e.push("Commands:"),o.commands.forEach(o=>{const n=` ${o.name().padEnd(20)} ${o.description()}`;e.push(n),o.commands.length>0&&o.commands.forEach(o=>{const n=` ${o.name().padEnd(20)} ${o.description()}`;e.push(n)})}),console.log(e.join("\n"))}(d)}),async function(){c.config({quiet:!0}),process.env.DASHNEX_CLI="1",process.argv.includes("--ci")&&(process.env.DASHNEX_CI="1");let o=process.cwd();const t=s.dirname(a(import.meta.url)),i=s.resolve(t,"..");process.env.DEBUG&&(console.log(`CLI started from directory: ${o}`),console.log(`CLI package directory: ${i}`));const r=await async function(o){try{const e=[],a=/* @__PURE__ */new Set,c=o=>{a.has(o)||(a.add(o),e.push(o))},t=s.join(o,"dashnex.json");if(n.existsSync(t)){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 i=s.join(o,"package.json");if(!n.existsSync(i))return e;const r=JSON.parse(n.readFileSync(i,"utf8")),d={...r.dependencies,...r.devDependencies,...r.optionalDependencies};for(const[l]of Object.entries(d)){const e=s.join(o,"node_modules",l);n.existsSync(s.join(e,"dashnex.json"))&&c(l)}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),l=i.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{}!l&&!m||r.includes("@dashnex/cli")||r.push("@dashnex/cli"),process.env.DEBUG&&(console.log(`CLI package directory: ${i}`),console.log(`Is installed package: ${l}`),console.log(`CLI in dependencies: ${m}`),console.log(`Discovered modules: ${r.join(", ")}`));for(const a of r){let c=[];if("@dashnex/cli"===a&&(l||m))try{const o=s.join(i,"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(u){if(process.env.DEBUG){const o=u instanceof Error?u.message:String(u);console.log(e.yellow(`Failed to load @dashnex/cli commands: ${o}`))}}else c=await p(a,o);for(const o of c)f(d,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(d,o)}catch(u){process.env.DEBUG&&console.error(e.yellow("⚠ Failed to discover application commands"))}d.parse(process.argv)}().catch(o=>{i(o)&&(console.log(e.yellow(r)),process.exit(0)),console.error(e.red("❌ CLI failed:"),o),process.exit(1)});
|
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 t}from"./install.js";import p from"./app/index.js";
|
|
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 t}from"./install.js";import p from"./app/index.js";const 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 t,options:[]},p];export{a as default};
|
package/dist/commands/login.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"inquirer";import s from"chalk";import t from"fs-extra";import r from"path";import{debug as
|
|
1
|
+
import e from"inquirer";import s from"chalk";import t from"fs-extra";import r from"path";import{getSettingsPath as o}from"../lib/settings-path.js";import{debug as n,debugJson as i,debugError as a}from"../lib/debug.js";import{getApiBase as l,apiFetch as c}from"../lib/api.js";import{ensureLoggedIn as d}from"../services/auth.js";import{createSpinner as u}from"../lib/spinner.js";import{isUserInterrupt as h,INTERRUPTED_MESSAGE as p}from"../lib/errors.js";const m=(e,t,r)=>{const o=(e=>"string"==typeof e.error?e.error:"string"==typeof e.message?e.message:void 0)(t);let n=r;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 f{async execute(t={}){n("Login flow started");const r=process.cwd(),f=o(r),g=await d({exitOnFailure:!1,dashnexPath:f});if(g)console.log(s.green(`Already logged in as ${g.userName??"user"}`));else try{let r,o;if(t.email)r=t.email.trim(),n("Email provided via flag");else{const{username:s}=await e.prompt([{type:"input",name:"username",message:"Email:",validate:e=>!!e.trim()||"Email is required"}]);r=s.trim()}if(t.password)o=t.password,n("Password provided via flag");else{const{password:s}=await e.prompt([{type:"password",name:"password",message:"Password:",mask:"*",validate:e=>!!e||"Password is required"}]);o=s}n("Email provided");const d=u();d.start("Logging in..."),n(`POST ${l()}/auth/v1/login`);const{response:h,body:p}=await c(`${l()}/auth/v1/login`,{method:"POST",body:JSON.stringify({username:r,password:o})});d.stop(),n(`Response: ${h.status}`),i("Login response",p),h.ok||(a(new Error(`Login failed: ${h.status} ${JSON.stringify(p)}`)),401===h.status&&(console.error(s.red("Invalid username or password.")),process.exit(1)),m(h,p,"Login failed. Please try again."));const g=p;if(g.two_fa_required&&g.token){n(`2FA required, type: ${g.type||"unknown"}`);const e=await this.handle2FA(g.token,g.type,t.code);e||process.exit(1),await this.completeLogin(e,f,t.business)}else g.token&&g.refreshToken?await this.completeLogin({token:g.token,refreshToken:g.refreshToken},f,t.business):(console.error(s.red("Invalid response from server. Please try again.")),process.exit(1))}catch(y){if(a(y),h(y))return void console.log(s.yellow(p));console.error(s.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}async handle2FA(t,r,o){if("sms"===r){n(`POST ${l()}/auth/v1/two-fa/sms`);try{const{response:e}=await c(`${l()}/auth/v1/two-fa/sms`,{method:"POST",headers:{Authorization:`Bearer ${t}`},body:JSON.stringify({})});n(`Response: ${e.status}`)}catch(f){return a(f),console.error(s.red("Could not send SMS code. Check your connection and try again.")),null}}const d="sms"===r?"Check your phone for the code":"Check your authenticator app for the code",u=o?1:3;for(let g=1;g<=u;g++){let r;if(o&&1===g)r=o,n("2FA code provided via flag");else{r=(await e.prompt([{type:"input",name:"auth_code",message:`Enter code (${d}):`,validate:e=>!!e.trim()||"Code is required"}])).auth_code}n(`POST ${l()}/auth/v1/2fa-check`);try{const{response:o,body:a}=await c(`${l()}/auth/v1/2fa-check`,{method:"POST",headers:{Authorization:`Bearer ${t}`},body:JSON.stringify({auth_code:r.trim()})});if(n(`Response: ${o.status}`),i("2FA check response",a),o.ok){const e=a;if(e.token&&e.refreshToken)return{token:e.token,refreshToken:e.refreshToken}}if(o.status>=400&&o.status<500){if(console.error(s.red("Invalid code. Please try again.")),g<u){const{retry:s}=await e.prompt([{type:"confirm",name:"retry",message:"Try again?",default:!0}]);if(!s)return null}continue}m(o,a,"2FA verification failed. Please try again.")}catch(f){return a(f),h(f)?(console.log(s.yellow(p)),null):(console.error(s.red("Could not reach DashNex API. Check your connection and try again.")),null)}}return null}async completeLogin(o,d,h){const p=u();p.start("Fetching businesses...");const f=l(),g={Authorization:`Bearer ${o.token}`};n(`GET ${f}/users/v1/business/my`);const{response:y,body:w}=await c(`${f}/users/v1/business/my`,{headers:g});n(`Response: ${y.status}`),i("Businesses response",w),y.ok||(p.stop(),a(new Error(`Business fetch failed: ${y.status}`)),m(y,w,"Failed to fetch businesses. Please try again."));const b=this.parseBusinesses(w),$=await this.fetchOtherBusinesses(o.token),k=this.mergeBusinesses(b,$);let v;if(p.stop(),n(`Businesses (my: ${b.length}, other: ${$.length}, merged: ${k.length})`),0===k.length&&(console.error(s.red("No businesses or teams found for your account!")),console.log(s.green("Create your first business at https://dashnex.io")),process.exit(1)),h){const e=k.find(e=>e.id===h);e||(console.error(s.red(`Business "${h}" not found.`)),process.exit(1)),v=e,n(`Selected business via flag: ${v.id} ${v.name}`)}else if(1===k.length)v=k[0],n(`Selected business: ${v.id} ${v.name}`);else{const{businessId:s}=await e.prompt([{type:"select",name:"businessId",message:"Select business:",choices:k.map(e=>({name:e.name,value:e.id}))}]);v=k.find(e=>e.id===s)||k[0],n(`Selected business: ${v.id} ${v.name}`)}p.start("Switching business..."),n(`GET ${f}/business/v1/login?_switch_business=${v.id}`);const{response:P,body:x}=await c(`${f}/business/v1/login?_switch_business=${v.id}`,{headers:g});p.stop(),n(`Response: ${P.status}`),i("Business login response",x),P.ok||(a(new Error(`Business login failed: ${P.status}`)),m(P,x,"Failed to switch to business. Please try again."));const S=x;S.token&&S.refreshToken||(console.error(s.red("Invalid response from server. Please try again.")),process.exit(1));const T={token:S.token,refreshToken:S.refreshToken,businessId:v.id},A=r.dirname(d);if(await t.pathExists(A)){(await t.stat(A)).isFile()&&await t.remove(A)}await t.ensureDir(A),await t.writeJson(d,T,{spaces:2}),n("Saved credentials to .dashnex/settings.json"),this.ensureGitignore(),console.log(s.green(`Logged in as ${v.name}`))}async fetchOtherBusinesses(e){const s=l();let t=1;const r=[];let o=0;do{const i=`${s}/users/v1/business/other?page=${t}&perPage=100`;n(`GET ${i}`);const{response:l,body:d}=await c(i,{headers:{Authorization:`Bearer ${e}`}});l.ok||(a(new Error(`Other businesses fetch failed: ${l.status}`)),m(l,d,"Failed to fetch teams. Please try again."));const u=this.parseBusinesses(d),h="number"==typeof d.total?d.total:u.length;if(r.push(...u),o=h,u.length<100||r.length>=o)break;t++}while(r.length<o);return r}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=r.join(process.cwd(),".gitignore");if(!(await t.pathExists(e)))return;let s=await t.readFile(e,"utf8");s.includes(".dashnex")||(s=s.trimEnd(),s.endsWith("\n")||(s+="\n"),s+="\n.dashnex\n",await t.writeFile(e,s))}}export{f as LoginCommand};
|
package/dist/commands/logout.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"fs-extra";import s from"chalk";import{getSettingsPath as t}from"../lib/settings-path.js";class o{async execute(){const o=t(process.cwd());if(await e.pathExists(o)){const s=await e.readJson(o);delete s.token,delete s.refreshToken,delete s.businessId,await e.writeJson(o,s,{spaces:2})}console.log(s.green("Logged out."))}}export{o as LogoutCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import o from"path";const s=process.env.DASHNEX_DIR||".dashnex",n="settings.json",t=t=>o.join(t,s,n);export{s as DASHNEX_DIR,n as SETTINGS_FILE,t as getSettingsPath};
|
package/dist/package.json.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e="@dashnex/cli",a="0.5.
|
|
1
|
+
const e="@dashnex/cli",a="0.5.64",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};
|
package/dist/services/auth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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
|
|
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";import{getSettingsPath as u}from"../lib/settings-path.js";const l=()=>{console.error(e.red("Please run 'dashnex login' to authenticate.")),console.error(e.green("If you don't have an account yet, create one at https://dashnex.io"))},f=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 l=u;if(!l.token||!l.refreshToken)return s("Refresh response missing tokens"),null;const f=await n.readJson(r);return f.token=l.token,f.refreshToken=l.refreshToken,await n.writeJson(r,f,{spaces:2}),s("Updated settings.json with new tokens"),c(l.token,l.refreshToken,r,{...f,token:l.token,refreshToken:l.refreshToken})},c=async(e,n,r,u)=>{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 f(n,r)}catch(l){return t(l),null}}s(`GET ${a()}/users/v1/`);try{const{response:t,body:l}=await i(`${a()}/users/v1/`,{headers:{Authorization:`Bearer ${e}`}});if(s(`Response: ${t.status}`),o("Users response",l),t.ok){const n=l;if("string"==typeof n.name&&u.businessId)return s(`Token valid, Already logged in as ${n.name}`),{token:e,businessId:u.businessId,userName:n.name}}return n?(s("Users API rejected token, refreshing"),await f(n,r)):(s("Token invalid, no refreshToken available"),null)}catch(l){return t(l),null}},h=async(e={})=>{const{exitOnFailure:t=!0,dashnexPath:o}=e,a=o??await(async e=>{let s=r.resolve(e);for(;;){const e=u(s);if(await n.pathExists(e))return e;const t=r.dirname(s);if(t===s)return null;s=t}})(process.cwd());if(!a||!(await n.pathExists(a)))return s(".dashnex/settings.json not found"),t&&(l(),process.exit(1)),null;let i;s(`Found settings at ${a}`);try{i=await n.readJson(a)}catch{return s("settings.json parse failed"),t&&(l(),process.exit(1)),null}const{token:f,refreshToken:h,businessId:p}=i;if(!f)return s("settings.json missing token"),t&&(l(),process.exit(1)),null;const d=await c(f,h,a,i);return d||(t&&(l(),process.exit(1)),null)};export{h 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.64",
|
|
5
5
|
"description": "Command-line interface for DashNex framework",
|
|
6
6
|
"homepage": "https://dashnex.io",
|
|
7
7
|
"type": "module",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"chalk": "^5.6.2",
|
|
30
30
|
"commander": "^14.0.3",
|
|
31
31
|
"dotenv": "^17.3.1",
|
|
32
|
-
"fs-extra": "^11.3.
|
|
32
|
+
"fs-extra": "^11.3.4",
|
|
33
33
|
"ignore": "^7.0.5",
|
|
34
34
|
"inquirer": "^13.3.0"
|
|
35
35
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"inquirer";import t from"chalk";import{debug as r,debugError as o}from"../../lib/debug.js";import{getBusinessApiBase as s}from"../../lib/api.js";import{ensureLoggedIn as i}from"../../services/auth.js";import{createSpinner as a}from"../../lib/spinner.js";import{isUserInterrupt as n,INTERRUPTED_MESSAGE as c}from"../../lib/errors.js";class l{async execute(l={}){r("Secrets delete flow started");let{name:m}=l;if(!m){m=(await e.prompt([{type:"input",name:"name",message:"Secret name:",validate:e=>""!==e.trim()||"Name is required"}])).name.trim()}const d=await i();if(!d)return;const u=`${s()}/business/v1/cli/secrets/${encodeURIComponent(m)}`;r(`DELETE ${u}`);const p=a();p.start(`Deleting secret '${m}'...`);try{const e=await fetch(u,{method:"DELETE",headers:{Authorization:`Bearer ${d.token}`}});if(p.stop(),r(`Response: ${e.status}`),!e.ok){let r="Failed to delete secret.";401===e.status||403===e.status?r="Please run 'dashnex login' to authenticate.":404===e.status?r=`Secret '${m}' not found.`:502===e.status&&(r="Error deleting secret. Make sure your application is deployed."),console.error(t.red(r)),process.exit(1)}r(`Secret '${m}' deleted successfully`),console.log(t.green(`Secret '${m}' deleted.`))}catch(f){if(p.stop(),o(f),f instanceof Error&&f.message.startsWith("EXIT:"))throw f;if(n(f))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 DeleteSecretCommand};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ListSecretsCommand as e}from"./list.js";import{SetSecretCommand as t}from"./set.js";import{DeleteSecretCommand as s}from"./delete.js";const n={name:"secrets",description:"Manage DashNex secrets",handler:{execute:async()=>{}},options:[],subcommands:[{name:"list",description:"List all secret names bound to the worker",handler:new e,options:[]},{name:"set",description:"Create or update a secret",handler:new t,options:[{flags:"--name <name>",description:"Secret name"},{flags:"--value <value>",description:"Secret value"}]},{name:"delete",description:"Delete a secret",handler:new s,options:[{flags:"--name <name>",description:"Secret name"}]}]};export{n as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"chalk";import{debug as s,debugError as o}from"../../lib/debug.js";import{getBusinessApiBase as t}from"../../lib/api.js";import{ensureLoggedIn as r}from"../../services/auth.js";import{createSpinner as n}from"../../lib/spinner.js";import{isUserInterrupt as i,INTERRUPTED_MESSAGE as a}from"../../lib/errors.js";class c{async execute(){s("Secrets list flow started");const c=await r();if(!c)return;const l=`${t()}/business/v1/cli/secrets`;s(`GET ${l}`);const h=n();h.start("Fetching secrets...");try{const o=await fetch(l,{headers:{Authorization:`Bearer ${c.token}`}});if(h.stop(),s(`Response: ${o.status}`),!o.ok){let s="Failed to fetch secrets.";401===o.status||403===o.status?s="Please run 'dashnex login' to authenticate.":404===o.status?s="Business has no application.":502===o.status&&(s="Error fetching secrets. Make sure your application is deployed."),console.error(e.red(s)),process.exit(1)}const t=(await o.json()).secrets??[];if(0===t.length)return void console.log(e.yellow("No secrets set."));console.log(e.bold(`\nSecrets (${t.length}):\n`)),t.forEach(({name:s})=>{console.log(` ${e.cyan(s)}`)}),console.log("")}catch(u){if(h.stop(),o(u),u instanceof Error&&u.message.startsWith("EXIT:"))throw u;if(i(u))return void console.log(e.yellow(a));console.error(e.red("Could not reach DashNex API. Check your connection and try again.")),process.exit(1)}}}export{c as ListSecretsCommand};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"inquirer";import t from"chalk";import{debug as s,debugError as r}from"../../lib/debug.js";import{getBusinessApiBase as o}from"../../lib/api.js";import{ensureLoggedIn as a}from"../../services/auth.js";import{createSpinner as i}from"../../lib/spinner.js";import{isUserInterrupt as n,INTERRUPTED_MESSAGE as c}from"../../lib/errors.js";class l{async execute(l={}){s("Secrets set flow started");let{name:u,value:m}=l;if(!u){u=(await e.prompt([{type:"input",name:"name",message:"Secret name:",validate:e=>""!==e.trim()||"Name is required"}])).name.trim()}if(!m){m=(await e.prompt([{type:"password",name:"value",message:`Enter value for ${u}:`,mask:"*",validate:e=>""!==e||"Value is required"}])).value}const p=await a();if(!p)return;const f=`${o()}/business/v1/cli/secrets`;s(`PUT ${f}`);const d=i();d.start(`Setting secret '${u}'...`);try{const e=await fetch(f,{method:"PUT",headers:{Authorization:`Bearer ${p.token}`,"Content-Type":"application/json"},body:JSON.stringify({name:u,value:m})});if(d.stop(),s(`Response: ${e.status}`),!e.ok){let s="Failed to set secret.";401===e.status||403===e.status?s="Please run 'dashnex login' to authenticate.":400===e.status?s="Missing or empty name / value.":404===e.status?s="Business has no application.":502===e.status&&(s="Error setting secret. Make sure your application is deployed."),console.error(t.red(s)),process.exit(1)}s(`Secret '${u}' set successfully`),console.log(t.green(`Secret '${u}' set successfully.`))}catch(h){if(d.stop(),r(h),h instanceof Error&&h.message.startsWith("EXIT:"))throw h;if(n(h))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 SetSecretCommand};
|