@zenovay/cli 0.1.67 → 0.1.68
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/{agency-BxYMejNb.js → agency-BRTQMQko.js} +1 -1
- package/dist/{ai-DbtIo6k2.js → ai-RVuD47iX.js} +1 -1
- package/dist/{alerts-DKQa_K77.js → alerts-B65b9jWl.js} +1 -1
- package/dist/{analytical-screen-B_wWUnT4.js → analytical-screen-DM7SBY5U.js} +1 -1
- package/dist/{analytics-BO22Zeas.js → analytics-CBP38R6T.js} +2 -2
- package/dist/{annotation-CL1q8mjr.js → annotation-CdqECkB6.js} +1 -1
- package/dist/api-hWp9s3Y8.js +1 -0
- package/dist/{api-keys-lfjOVUIe.js → api-keys-BmmNLpjG.js} +1 -1
- package/dist/api-v2-C6bvRBzw.js +1 -0
- package/dist/{api-v2-CPUUcP1i.js → api-v2-C82L-ZOL.js} +1 -1
- package/dist/{audit-DfKQdrug.js → audit-D_NXQFBa.js} +1 -1
- package/dist/bin.js +6 -6
- package/dist/{chat-panel-ZlKZ0W6J.js → chat-panel-DS-FxXoL.js} +1 -1
- package/dist/{commands-NsH5CS-H.js → commands-BJQxwCUl.js} +1 -1
- package/dist/{companies-CtZ2vGQs.js → companies-DNay1Xrh.js} +1 -1
- package/dist/{completions-Bem7-lcb.js → completions-D-Esx72b.js} +1 -1
- package/dist/{deploys-CUbSa8S5.js → deploys-BnByoalt.js} +1 -1
- package/dist/{devices-CrkIxfde.js → devices-Di7NUUmM.js} +1 -1
- package/dist/{doctor-D5HWdhgv.js → doctor-B_C_zJQh.js} +1 -1
- package/dist/{domains-V4sD09io.js → domains-xWz-syku.js} +1 -1
- package/dist/{emit-C9vAopcy.js → emit-NkY7PE3R.js} +1 -1
- package/dist/{error-codes-C5caZH9p.js → error-codes-D4XO4okw.js} +1 -1
- package/dist/{error-codes-fnm-9MRL.js → error-codes-DpKbL-uM.js} +1 -1
- package/dist/{errors-D3fS1kYu.js → errors-DhQE6fJQ.js} +1 -1
- package/dist/{events-tail-DGRZewwc.js → events-tail-CSHCH77I.js} +1 -1
- package/dist/{export-FjEyji8r.js → export-CmypMMjU.js} +1 -1
- package/dist/{funnel-C7DmrdUC.js → funnel-DwBZVMGB.js} +1 -1
- package/dist/{geo-C9OcRStg.js → geo-hKUpyWuw.js} +1 -1
- package/dist/globe-8qdyNUN-.js +2 -0
- package/dist/{goals-CVRryIri.js → goals-cNoELf2s.js} +1 -1
- package/dist/{health-DMiTjQ9Z.js → health-BJwKEdIp.js} +1 -1
- package/dist/{health-vxoiMF8G.js → health-CbaNXgdP.js} +1 -1
- package/dist/heatmaps-SCfq5M8H.js +1 -0
- package/dist/{home-CXwRtMge.js → home-DAEqaTOD.js} +1 -1
- package/dist/init-C7zAAhfS.js +79 -0
- package/dist/init-DOrkLxxe.js +1 -0
- package/dist/insights-Bshy_7Ln.js +1 -0
- package/dist/{integrations-CWPrMJfZ.js → integrations-m8rSzn3o.js} +1 -1
- package/dist/journeys-DZvlQiCz.js +1 -0
- package/dist/live-3YVbBo2f.js +1 -0
- package/dist/login-COMo5KUL.js +2 -0
- package/dist/login-W7wIGtyL.js +1 -0
- package/dist/logout-D89CET3S.js +2 -0
- package/dist/{notes-C8cba6QA.js → notes-IHtGD1hp.js} +1 -1
- package/dist/{pages-CKs5X38q.js → pages-BD1BmfgN.js} +1 -1
- package/dist/{plans-oxxMSOdB.js → plans-BjApr8oD.js} +1 -1
- package/dist/{profile-CD9QVZ2I.js → profile-u9G8Sxdv.js} +1 -1
- package/dist/{projects-hIQqeDYq.js → projects-DK9ZO7qd.js} +1 -1
- package/dist/{query-BLHvu1IF.js → query-BhtiMkwf.js} +1 -1
- package/dist/{resolve-site-DQVcWhjG.js → resolve-site-GDYx0__E.js} +1 -1
- package/dist/retention-BA59Mo79.js +1 -0
- package/dist/{revenue-BiViSloE.js → revenue-vHyW8Ypm.js} +1 -1
- package/dist/secrets-BBaEWu03.js +1 -0
- package/dist/{self-test-CSST_zHj.js → self-test-QdQWJ7tK.js} +2 -2
- package/dist/sessions-DN4j8OEV.js +1 -0
- package/dist/{settings-CFFiWmGO.js → settings-HSntEG-D.js} +1 -1
- package/dist/{share-Cx62AEP-.js → share-CQwuZtgh.js} +1 -1
- package/dist/{sources-D-KqX0Sg.js → sources-CSFQi-V7.js} +1 -1
- package/dist/{stats-BzTqFpJL.js → stats-DCzM0MeA.js} +1 -1
- package/dist/{status-agent-TIyEIKOj.js → status-agent-C2-h8fKK.js} +1 -1
- package/dist/{team-BRebgNMO.js → team-_SMC_yFx.js} +1 -1
- package/dist/{teams-DhrkUkt8.js → teams-C_eV1rXM.js} +1 -1
- package/dist/{telemetry-DRh10SvO.js → telemetry-BJbpxgIp.js} +1 -1
- package/dist/{telemetry-DC0Jw3JD.js → telemetry-BwXO7Z83.js} +1 -1
- package/dist/telemetry-CZhEbFqI.js +1 -0
- package/dist/{themes-gluHmb6E.js → themes-D5A3e_mg.js} +1 -1
- package/dist/update-DoOjZZNm.js +1 -0
- package/dist/uptime-Da9_QYPm.js +1 -0
- package/dist/{usage-BFCTeA8E.js → usage-beKJ1HbM.js} +1 -1
- package/dist/{use-baQFldqI.js → use-DbUqNyZk.js} +1 -1
- package/dist/{visitors-BtriXh9k.js → visitors-CJ2FfgSL.js} +1 -1
- package/dist/{vitals-BgAwONID.js → vitals-Cczahuhy.js} +1 -1
- package/dist/watch-6c4jbLbR.js +1 -0
- package/dist/{webhooks-PRWhMVgS.js → webhooks-CFtGBoJm.js} +1 -1
- package/dist/{webhooks-forward-BDxi2TcF.js → webhooks-forward-D-erVn8S.js} +1 -1
- package/dist/wizard-bin.js +1 -1
- package/package.json +1 -1
- package/dist/api-FCanTxsb.js +0 -1
- package/dist/api-v2-D9N_2hdW.js +0 -1
- package/dist/globe-PiPL3Bei.js +0 -2
- package/dist/heatmaps-G3Nf95tV.js +0 -1
- package/dist/init-BuyESMBj.js +0 -79
- package/dist/init-WmEUW4Em.js +0 -1
- package/dist/insights-J99-8Rcu.js +0 -1
- package/dist/journeys-BLxqoeFu.js +0 -1
- package/dist/live-CWSLgkC2.js +0 -1
- package/dist/login-CaDs2Peq.js +0 -2
- package/dist/login-wpGuU_Zm.js +0 -1
- package/dist/logout-BkeT6Hke.js +0 -2
- package/dist/retention-B8bgiVux.js +0 -1
- package/dist/secrets-M60NENIa.js +0 -1
- package/dist/sessions-lUUiiNYc.js +0 -1
- package/dist/telemetry-C1045t6Q.js +0 -1
- package/dist/update-BCgHj5O4.js +0 -1
- package/dist/uptime-CwG6bqir.js +0 -1
- package/dist/watch-Cv4FtwSJ.js +0 -1
- /package/dist/{client-Dm8uGVCy.js → client-I4GTcUcm.js} +0 -0
- /package/dist/{open-url-BxXbZzWS.js → open-url-CTfSApWl.js} +0 -0
- /package/dist/{prompt-B4s3o9G7.js → prompt-CJw_Mqo2.js} +0 -0
- /package/dist/{secrets-DPf_7SkN.js → secrets-DzueUVGL.js} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-D4XO4okw.js";import"./telemetry-BJbpxgIp.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-I4GTcUcm.js";import"./theme-BuGrQHax.js";import{useTheme as a}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-CJw_Mqo2.js";import"./keybar-QgnmSion.js";import"./chat-panel-DS-FxXoL.js";import{resolveSiteId as o}from"./resolve-site-GDYx0__E.js";import{DataTable as s}from"./data-table-DJzT7bAr.js";import{runAnalyticalScreen as c}from"./analytical-screen-DM7SBY5U.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e){return`${(e*100).toFixed(1)}%`}function p(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}const m=({data:e})=>{let{theme:t}=a();return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.visitors.toLocaleString()),d.createElement(u,{color:t.muted},` visitors `),d.createElement(u,{bold:!0},e.pageviews.toLocaleString()),d.createElement(u,{color:t.muted},` pageviews `),d.createElement(u,{bold:!0},e.sessions.toLocaleString()),d.createElement(u,{color:t.muted},` sessions`)),d.createElement(u,{color:t.muted},`bounce `,f(e.bounceRate),` · avg session `,p(e.avgSessionSec)))},h=({label:e})=>{let{theme:t}=a();return d.createElement(u,{color:t.dim},e)};async function g(a){let l=await e(),u=await t({strict:!1}),g=new n({config:l,cliVersion:a.cliVersion,token:u}),_,v;try{({siteId:_,site:v}=await o(g,{explicit:a.siteId,headless:!!(a.json||a.csv||a.tsv||a.ndjson),cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(a),b=a.range??`24h`,x=[{key:`url`,label:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,label:`views`,width:8,align:`right`}],S=[{key:`country`,label:`country`,width:8},{key:`visitors`,label:`visitors`,width:8,align:`right`}];return c({cliVersion:a.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,ai:{api:g,siteId:_,siteLabel:v?.url?v.url.replace(/^https?:\/\//,``).replace(/\/$/,``):v?.name??_},authToken:u?.accessToken??null,refreshIntervalMs:a.watch?6e4:0,fetcher:e=>g.getStats(_,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
2
|
`);return}process.stdout.write(r([{range:b,visitors:e.visitors,pageviews:e.pageviews,sessions:e.sessions,bounceRate:f(e.bounceRate),avgSession:p(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>d.createElement(m,{data:e})},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?d.createElement(h,{label:`— no pages —`}):d.createElement(s,{data:e.topPages.slice(0,10),columns:x,headerStyle:`accent`})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?d.createElement(h,{label:`— no country data —`}):d.createElement(s,{data:e.topCountries.slice(0,10),columns:S,headerStyle:`accent`})}]})}export{g as statsCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{configPath as e,readConfig as t,writeConfig as n}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{configPath as e,readConfig as t,writeConfig as n}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import{emit$1 as i}from"./telemetry-BJbpxgIp.js";import{ApiV2Client as a}from"./api-v2-C82L-ZOL.js";import{spawn as o}from"node:child_process";import s from"node:path";import{existsSync as c,mkdirSync as l,readFileSync as u,renameSync as d,unlinkSync as f,writeFileSync as p}from"node:fs";import{homedir as m}from"node:os";const h=6e4;function g(){return s.join(m(),`.zenovay`)}function _(){return s.join(g(),`status-agent.pid`)}function v(){return s.join(g(),`tmux-status`)}function y(){l(g(),{recursive:!0,mode:448})}function b(e){let t=_(),n=`${t}.tmp.${process.pid}`;p(n,String(e),{mode:384}),d(n,t)}function x(e){try{return process.kill(e,0),!0}catch{return!1}}function S(e){if(!e)return[];let t=[];for(let n of e.split(`,`).map(e=>e.trim()).filter(Boolean)){let e=n.match(/^([a-z_]+)\s*(>|<)\s*(-?\d+(?:\.\d+)?)$/i);if(!e)continue;t.push({key:(e[1]??``).toLowerCase(),op:e[2]??`>`,value:Number(e[3]??0)})}return t}function C(e,t,n,r=!1){let i=(t/1e5).toFixed(1),a=[`#[fg=colour141]● ${e} live`,`#[fg=colour114]▲ MRR $${i}k`,`#[fg=colour203]✗ ${n.toFixed(0)} err/s`].join(` `);return r?`#[reverse]${a}#[noreverse]`:a}const w=3e4,T=5*60*1e3,E=new Map;function D(e,t){let n=Math.floor(t/10),r=`${e}:${n}`,i=Date.now(),a=E.get(r);return a&&i-a<T?!1:(E.set(r,i),!0)}async function O(e,t){let n=process.platform;try{if(n===`darwin`){await new Promise((n,r)=>{let i=o(`terminal-notifier`,[`-title`,e,`-message`,t,`-group`,`zenovay`],{stdio:`ignore`});i.on(`error`,r),i.on(`exit`,()=>n())});return}if(n===`linux`){await new Promise((n,r)=>{let i=o(`notify-send`,[e,t],{stdio:`ignore`});i.on(`error`,r),i.on(`exit`,()=>n())});return}}catch{}process.stdout.write(`\x1b]9;${e} — ${t}\x07`)}function k(e,t){let n=[];for(let r of e){let e=t[r.key];if(typeof e!=`number`)continue;r.op===`>`&&e>r.value&&n.push({rule:r,actual:e}),r.op===`<`&&e<r.value&&n.push({rule:r,actual:e})}return n}async function A(e){let n=await t(),o=await r({strict:!1});if(!o)return process.stderr.write(`status-agent: not logged in
|
|
2
2
|
`),2;let s=new a({config:n,cliVersion:e.cliVersion,token:o}),c=e.siteId??n.defaultSiteId??``;if(!c)return process.stderr.write("status-agent: no site selected — pass --site-id or run `zenovay use <site>`\n"),2;y();let l=n.statusAgent?.notifyOn,u=n.statusAgent?.refreshIntervalMs,d=S(e.notifyOn??l),m=e.intervalMs??u??h,g=Date.now(),b=0;i(`status_agent.start`,{properties:{rule_count:d.length,interval_ms:m}});let x=null,T=!1,E=0,A=null,j=()=>{T=!0,A&&A()};for(process.on(`SIGTERM`,j),process.on(`SIGINT`,j);!T;){try{let[e,t,n]=await Promise.all([s.getLive(c).catch(()=>({activeVisitors:0,recentEvents:[]})),s.getErrors(c,{window:`24h`}).catch(()=>({errors:[],total:0})),s.getRevenue(c,`24h`).catch(()=>null)]),r=e.activeVisitors,a=n?.mrr??n?.totalAmount??0,o=t.total/86400,l=x&&x>0?(x-a)/x*100:0,u=k(d,{error_rate:o,revenue_drop:l}),f=!1;for(let e of u){if(!D(e.rule.key,e.actual))continue;f=!0,i(`status_agent.alert_fired`,{properties:{rule_key:e.rule.key,op:e.rule.op}}),await O(`Zenovay alert`,`${e.rule.key} ${e.rule.op} ${e.rule.value} (got ${e.actual.toFixed(2)})`)}f&&(E=Date.now());let m=E>0&&Date.now()-E<w;p(v(),C(r,a,o,m),{mode:420}),b+=1,b%10==0&&i(`status_agent.tick`,{properties:{tick:b,has_revenue:a>0,has_visitors:r>0,had_errors:o>0}}),x=a}catch(e){process.stderr.write(`status-agent tick failed: ${e.message}\n`)}await new Promise(e=>{let t=setTimeout(e,m);A=()=>{clearTimeout(t),e()}}),A=null}i(`status_agent.stop`,{duration_ms:Date.now()-g,properties:{ticks:b}});try{f(_())}catch{}return 0}function j(){return[`# Add to ~/.tmux.conf:`,`set -g status-right "#(cat ~/.zenovay/tmux-status) %H:%M"`,``,`# Then reload:`,`# $ tmux source ~/.tmux.conf`].join(`
|
|
3
3
|
`)}function M(){let e=process.argv[0]??`zenovay`;return[`[Unit]`,`Description=Zenovay status agent`,`After=network.target`,``,`[Service]`,`Type=simple`,`ExecStart=${e} status-agent --child`,`Restart=on-failure`,`RestartSec=10`,``,`[Install]`,`WantedBy=default.target`,``,`# Save as ~/.config/systemd/user/zenovay-status.service`,`# systemctl --user enable --now zenovay-status`].join(`
|
|
4
4
|
`)}function N(){let e=process.argv[0]??`zenovay`;return[`<?xml version="1.0" encoding="UTF-8"?>`,`<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">`,`<plist version="1.0">`,`<dict>`,` <key>Label</key><string>com.zenovay.status-agent</string>`,` <key>ProgramArguments</key>`,` <array>`,` <string>${e}</string>`,` <string>status-agent</string>`,` <string>--child</string>`,` </array>`,` <key>RunAtLoad</key><true/>`,` <key>KeepAlive</key><true/>`,`</dict>`,`</plist>`,``,`<!-- Save as ~/Library/LaunchAgents/com.zenovay.status-agent.plist -->`,`<!-- launchctl load ~/Library/LaunchAgents/com.zenovay.status-agent.plist -->`].join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import{confirmDestructive as i}from"./confirm-CIdxMt7N.js";import{fmtDate as a,formatTable as o,shortId as s}from"./fmt-xxIPQJX-.js";async function c(c){let l=await e(),u=await t({strict:!1}),d=new n({config:l,cliVersion:c.cliVersion,token:u});try{await r(d,`pro`)}catch(e){return process.stderr.write(`✗ ${e.message}\n`),2}try{switch(c.action){case`list`:{let e=await d.listTeam();if(c.json)return process.stdout.write(JSON.stringify(e,null,2)+`
|
|
2
2
|
`),0;let t=[{key:`userId`,header:`user id`,width:14,format:e=>s(String(e))},{key:`email`,header:`email`,width:32,format:e=>String(e??`—`)},{key:`role`,header:`role`,width:8},{key:`joinedAt`,header:`joined`,width:10,format:e=>a(e)}],n=[{key:`id`,header:`invite id`,width:14,format:e=>s(String(e))},{key:`email`,header:`email`,width:32},{key:`role`,header:`role`,width:8},{key:`expiresAt`,header:`expires`,width:10,format:e=>a(e)}];return process.stdout.write(`\nMEMBERS (${e.members.length})\n`),e.members.length===0?process.stdout.write(` — none —
|
|
3
3
|
`):process.stdout.write(o({rows:e.members,cols:t})),process.stdout.write(`\nPENDING INVITES (${e.invites.length})\n`),e.invites.length===0?process.stdout.write(` — none —
|
|
4
4
|
`):process.stdout.write(o({rows:e.invites,cols:n})),process.stdout.write(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as n}from"./token-store-BQuGH0z2.js";import{ApiV2Client as r}from"./api-v2-C82L-ZOL.js";function i(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}async function a(a){let o=await e(),s=await n({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new r({config:o,cliVersion:a.cliVersion,token:s});try{switch(a.action){case`reset`:{let e=await t({currentTeamId:void 0,currentTeamName:void 0});return a.json?(process.stdout.write(JSON.stringify({reset:!0,currentTeamId:e.currentTeamId??null})+`
|
|
2
2
|
`),0):(process.stdout.write(`✔ Team override cleared. Future commands use the API key's default team.
|
|
3
3
|
`),0)}case`current`:{let e=await c.me(),t=e.teams?.find(e=>e.isCurrent)??(e.team?{id:e.team.id,name:e.team.name,plan:e.team.plan,role:`?`,siteCount:0,isCurrent:!0}:null);return a.json?(process.stdout.write(JSON.stringify({current:t,override:o.currentTeamId??null},null,2)+`
|
|
4
4
|
`),0):t?(process.stdout.write(`\n current team: ${t.name} (${i(t.id)})\n plan: ${t.plan}\n override? ${o.currentTeamId?"yes — set via `teams switch`":`no — using API key default`}\n\n`),0):(process.stdout.write(`No team currently bound.
|
|
@@ -2,4 +2,4 @@ import{configDir as e,readConfig as t,writeConfig as n}from"./config--JRu_jFq.js
|
|
|
2
2
|
No site data, file contents, or chat messages are included.
|
|
3
3
|
Disable: \`zenovay telemetry off\` or set ZENOVAY_TELEMETRY=0 / DO_NOT_TRACK=1
|
|
4
4
|
|
|
5
|
-
`),r={...r,telemetry:{enabled:!0,disclosed_at:Date.now()}};try{await n(r)}catch{}}w=D(r),await j().catch(()=>void 0),process.on(`exit`,()=>{_.length>0&&A(_.splice(0))});for(let e of[`SIGINT`,`SIGTERM`])process.on(e,()=>{k()})}}function E(){let e=process.env.ZENOVAY_TELEMETRY;if(e===`0`||e===`false`||e===`off`||e===`no`)return!0;let t=process.env.DO_NOT_TRACK;return t===`1`||t===`true`}function D(e){let t=e.telemetry;return typeof t==`boolean`?t:t&&typeof t==`object`&&`enabled`in t?!!t.enabled:!0}function O(e,t={}){w!==!1&&(_.length>=f||(_.push({ts:Date.now(),event:e,cli_version:b,node_version:process.versions.node,os:process.platform,arch:process.arch,session_id:h,...t}),_.length>=d?k():v||=setTimeout(()=>{v=null,k()},u)))}async function k(){if(y)return y;if(_.length===0)return;if(w===!1){_.length=0;return}v&&(clearTimeout(v),v=null);let e=_.splice(0);return y=(async()=>{try{let t=x.replace(/\/$/,``)+l;await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...S?{Authorization:`Bearer ${S}`}:{}},body:JSON.stringify({events:e}),signal:AbortSignal.timeout(p)})}catch{try{A(e.slice(0,f))}catch{}}finally{y=null}})(),y}function A(t){try{i(e(),{recursive:!0,mode:448})}catch{}let n=[];try{let e=o(m,`utf8`),t=JSON.parse(e);Array.isArray(t)&&(n=t.slice(0,f))}catch{}let r=[...n,...t].slice(-f);try{s(m,JSON.stringify(r),{mode:384})}catch{}}async function j(){let e=[];try{let t=await a.readFile(m,`utf8`),n=JSON.parse(t);Array.isArray(n)&&(e=n)}catch{return}if(e.length===0)return;let t=e.slice(-f);try{let e=x.replace(/\/$/,``)+l,n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,...S?{Authorization:`Bearer ${S}`}:{}},body:JSON.stringify({events:t}),signal:AbortSignal.timeout(p)});if(n.ok)try{await a.unlink(m)}catch{}}catch{}}async function M(){if(E())return{enabled:!1,source:`env`,endpoint:x.replace(/\/$/,``)+l,pending_count:await N()};let e=await t().catch(()=>null),n=e?.telemetry,r=!0,i,a=`default`;return typeof n==`boolean`?(r=n,a=`config`):n&&typeof n==`object`&&(r=!!n.enabled,i=n.disclosed_at,a=`config`),{enabled:r,source:a,disclosed_at:i,endpoint:x.replace(/\/$/,``)+l,pending_count:await N()}}async function N(){try{let e=await a.readFile(m,`utf8`),t=JSON.parse(e);return Array.isArray(t)?t.length:0}catch{return 0}}async function P(e){let r=await t();await n({...r,telemetry:{enabled:e,disclosed_at:Date.now()}}),w=e}function F(){return Date.now()-g}export{O as emit,k as flush,F as getProcessUptimeMs,M as getTelemetryStatus,T as initTelemetry,P as setTelemetry};
|
|
5
|
+
`),r={...r,telemetry:{enabled:!0,disclosed_at:Date.now()}};try{await n(r)}catch{}}w=D(r),await j().catch(()=>void 0),process.on(`exit`,()=>{_.length>0&&A(_.splice(0))});for(let e of[`SIGINT`,`SIGTERM`])process.on(e,()=>{k()})}}function E(){let e=process.env.ZENOVAY_TELEMETRY;if(e===`0`||e===`false`||e===`off`||e===`no`)return!0;let t=process.env.DO_NOT_TRACK;return t===`1`||t===`true`}function D(e){let t=e.telemetry;return typeof t==`boolean`?t:t&&typeof t==`object`&&`enabled`in t?!!t.enabled:!0}function O(e,t={}){w!==!1&&(_.length>=f||(_.push({ts:Date.now(),event:e,cli_version:b,node_version:process.versions.node,os:process.platform,arch:process.arch,session_id:h,...t}),_.length>=d?k():v||=setTimeout(()=>{v=null,k()},u)))}async function k(){if(y)return y;if(_.length===0)return;if(w===!1){_.length=0;return}v&&(clearTimeout(v),v=null);let e=_.splice(0);return y=(async()=>{try{let t=x.replace(/\/$/,``)+l;await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...S?{Authorization:`Bearer ${S}`}:{}},body:JSON.stringify({events:e}),signal:AbortSignal.timeout(p)})}catch{try{A(e.slice(0,f))}catch{}}finally{y=null}})(),y}function A(t){try{i(e(),{recursive:!0,mode:448})}catch{}let n=[];try{let e=o(m,`utf8`),t=JSON.parse(e);Array.isArray(t)&&(n=t.slice(0,f))}catch{}let r=[...n,...t].slice(-f);try{s(m,JSON.stringify(r),{mode:384})}catch{}}async function j(){let e=[];try{let t=await a.readFile(m,`utf8`),n=JSON.parse(t);Array.isArray(n)&&(e=n)}catch{return}if(e.length===0)return;let t=e.slice(-f);try{let e=x.replace(/\/$/,``)+l,n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,...S?{Authorization:`Bearer ${S}`}:{}},body:JSON.stringify({events:t}),signal:AbortSignal.timeout(p)});if(n.ok)try{await a.unlink(m)}catch{}}catch{}}async function M(){if(E())return{enabled:!1,source:`env`,endpoint:x.replace(/\/$/,``)+l,pending_count:await N()};let e=await t().catch(()=>null),n=e?.telemetry,r=!0,i,a=`default`;return typeof n==`boolean`?(r=n,a=`config`):n&&typeof n==`object`&&(r=!!n.enabled,i=n.disclosed_at,a=`config`),{enabled:r,source:a,disclosed_at:i,endpoint:x.replace(/\/$/,``)+l,pending_count:await N()}}async function N(){try{let e=await a.readFile(m,`utf8`),t=JSON.parse(e);return Array.isArray(t)?t.length:0}catch{return 0}}async function P(e){let r=await t();await n({...r,telemetry:{enabled:e,disclosed_at:Date.now()}}),w=e}function F(){return Date.now()-g}export{O as emit$1,k as flush,F as getProcessUptimeMs,M as getTelemetryStatus,T as initTelemetry,P as setTelemetry};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"./config--JRu_jFq.js";import{getTelemetryStatus as e,setTelemetry as t}from"./telemetry-
|
|
1
|
+
import"./config--JRu_jFq.js";import{getTelemetryStatus as e,setTelemetry as t}from"./telemetry-BJbpxgIp.js";async function n(n){let r=n.action??`status`;if(r===`on`)return await t(!0),n.json?process.stdout.write(JSON.stringify({ok:!0,enabled:!0})+`
|
|
2
2
|
`):process.stdout.write(`Telemetry enabled.
|
|
3
3
|
`),0;if(r===`off`)return await t(!1),n.json?process.stdout.write(JSON.stringify({ok:!0,enabled:!1})+`
|
|
4
4
|
`):process.stdout.write(`Telemetry disabled. Existing pending events on disk will not be sent.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./config--JRu_jFq.js";import{emit$1 as e,flush as t,getProcessUptimeMs as n,getTelemetryStatus as r,initTelemetry as i,setTelemetry as a}from"./telemetry-BJbpxgIp.js";export{e as emit,t as flush,n as getProcessUptimeMs,r as getTelemetryStatus,i as initTelemetry,a as setTelemetry};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./theme-BuGrQHax.js";import{useTheme as a}from"./panel-B-XxdP-N.js";import{Banner as o}from"./banner-DdgwXGzt.js";import"./progress-row-5ns2IsFh.js";import"./prompt-
|
|
1
|
+
import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./theme-BuGrQHax.js";import{useTheme as a}from"./panel-B-XxdP-N.js";import{Banner as o}from"./banner-DdgwXGzt.js";import"./progress-row-5ns2IsFh.js";import"./prompt-CJw_Mqo2.js";import"./keybar-QgnmSion.js";import"./sparkline-CpoBjjlc.js";import"./data-table-DJzT7bAr.js";import"./bar-C1Zrfe9H.js";import"./ui-whccLLRv.js";import{promises as s}from"node:fs";import{Box as c,Text as l,render as u}from"ink";import d from"react";const f=[{name:`mocha`,theme:n,mode:`dark`},{name:`latte`,theme:t,mode:`light`},{name:`dracula`,theme:e,mode:`dark`},{name:`tokyoNight`,theme:i,mode:`dark`},{name:`nord`,theme:r,mode:`dark`}],p=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function m({name:e,theme:t,mode:n}){let{theme:r}=a(),i=[t.accent,t.accent2,t.success,t.warn,t.error];return d.createElement(c,{flexDirection:`row`},d.createElement(l,{bold:!0},e.padEnd(14)),d.createElement(l,{color:r.muted},n.padEnd(7)),i.map((e,t)=>d.createElement(l,{key:t,color:e},`████`,` `)),d.createElement(l,{color:r.muted},t.bg))}function h({themes:e}){let{theme:t}=a();return d.createElement(c,{flexDirection:`column`},d.createElement(o,{version:`themes`}),d.createElement(c,{marginTop:1,marginBottom:1},d.createElement(l,{color:t.muted},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),d.createElement(c,{flexDirection:`column`},d.createElement(c,null,d.createElement(l,{bold:!0},`name`.padEnd(14)),d.createElement(l,{bold:!0},`mode`.padEnd(7)),d.createElement(l,{bold:!0},`swatch`.padEnd(28)),d.createElement(l,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>d.createElement(m,{key:e,name:e,theme:t,mode:n}))))}async function g(e){if(e.validate){let t;try{let n=await s.readFile(e.validate,`utf8`);t=JSON.parse(n)}catch(t){return process.stderr.write(`✗ Failed to read ${e.validate}: ${t.message}\n`),1}let n=p.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
|
|
2
2
|
`),1):(process.stdout.write(`✔ Valid theme (${p.length} tokens present).\n`),e.json&&process.stdout.write(JSON.stringify({ok:!0,theme:t},null,2)+`
|
|
3
3
|
`),0)}if(e.json)return process.stdout.write(JSON.stringify({themes:f.map(({name:e,theme:t,mode:n})=>({name:e,mode:n,background:t.bg,foreground:t.fg,accent:t.accent}))},null,2)+`
|
|
4
4
|
`),0;let{waitUntilExit:t}=u(d.createElement(h,{themes:f}));return await t(),0}export{g as themesCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import{classifyBump as t,fetchManifest as n}from"./check-D9G0N7NB.js";import{applyUpdate as r}from"./apply-B19bFTz0.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";async function o(o){let s=await e(),c=await n({cliBase:s.cliBase}),l=t(o.cliVersion,c.latest);if(o.check)return a({json:o.json})?i({type:`info`,message:`latest=${c.latest} current=${o.cliVersion} bump=${l}`}):process.stdout.write(`Current: ${o.cliVersion}\nLatest: ${c.latest}\nBump: ${l}\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`none`)return a({json:o.json})||process.stdout.write(`Already on latest (${o.cliVersion}).\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`downgrade`&&!o.forceDowngrade)throw Error(`Refused to downgrade ${o.cliVersion} → ${c.latest}. Pass --force-downgrade if you really want this.`);let u=await r({currentVersion:o.cliVersion,cliBase:s.cliBase,binaryPath:o.binaryPath,forceDowngrade:o.forceDowngrade});return a({json:o.json})?u.updated&&i({type:`update.applied`,from:u.from,to:u.to}):u.updated?process.stdout.write(`Updated ${u.from} → ${u.to}\n`):process.stdout.write(`Not updated (${u.reason??`unknown`}).\n`),u}export{o as updateCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{openInBrowser as o}from"./open-url-CTfSApWl.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-CJw_Mqo2.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{resolveSiteId as d}from"./resolve-site-GDYx0__E.js";import{DataTable as f}from"./data-table-DJzT7bAr.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";function w(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function T(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function E(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let u,f;try{({siteId:u,site:f}=await d(l,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(a(o)){let e=await l.getUptime(u);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(D,{api:l,siteId:u,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const D=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=v(),{theme:d}=c(),[_,E]=S(null),[D,O]=S(!0),[k,A]=S(null);if(y(e=>{if(e===`o`||e===`O`){o(m(`uptime`,{siteId:t}));return}e===`q`&&(a(),i(0))}),x(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(E(r.monitors),O(!1))}catch(e){n||(A(e.message),O(!1))}})(),()=>{n=!0}},[e,t]),D)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(s,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:d.accent},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Fetching monitors…`))));if(k)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(p,{reason:`error`,headline:`Failed to load`,hint:k}));if(!_||_.length===0)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(p,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let j=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>w(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>T(e)}];return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(s,{title:`Monitors (${_.length})`},b.createElement(f,{columns:j,data:_,zebra:!0})),b.createElement(u,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{E as uptimeCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import{fmtDate as r,fmtNumber as i}from"./fmt-xxIPQJX-.js";const a=1e8,o=e=>e<=0||e>=a;function s(e,t,n=24){if(o(t))return`─`.repeat(n);let r=Math.min(1,e/t),i=Math.round(r*n);return`█`.repeat(i)+`░`.repeat(Math.max(0,n-i))}function c(e,t){if(o(t))return`—`;let n=e/t*100;return`${n.toFixed(0)}%`}function l(e,t){if(o(t))return``;let n=e/t;return n>=1?`⚠ over limit`:n>=.8?`⚠ near limit`:``}function u(e,t){return o(e)?`∞`:t(e)}async function d(a){let o=await e(),d=await t({strict:!1});if(!d)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let f=new n({config:o,cliVersion:a.cliVersion,token:d}),p;try{p=await f.getUsage()}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}if(a.json)return process.stdout.write(JSON.stringify(p,null,2)+`
|
|
2
2
|
`),0;let m=[{label:`events this month`,used:p.events.thisMonth,limit:p.events.monthlyLimit,format:i},{label:`events today`,used:p.events.today,limit:p.events.dailyLimit,format:i},{label:`websites`,used:p.websites.used,limit:p.websites.limit},{label:`team members`,used:p.teamMembers.used,limit:p.teamMembers.limit}],h=18,g=8,_=9,v=[];v.push(``),v.push(` plan: ${p.plan}`),v.push(``);for(let e of m){let t=e.format??i,n=t(e.used).padStart(g),r=u(e.limit,t).padStart(_),a=s(e.used,e.limit),o=c(e.used,e.limit).padStart(5),d=l(e.used,e.limit);v.push(` ${e.label.padEnd(h)} ${n} / ${r} ${a} ${o} ${d}`.trimEnd())}return v.push(` ${`api keys`.padEnd(h)} ${i(p.apiKeys.used).padStart(g)} / ${`—`.padStart(_)} ${`─`.repeat(24)} ${`—`.padStart(5)}`),v.push(``),v.push(` data retention: ${p.dataRetentionDays} days`),v.push(` last event: ${r(p.events.lastEventAt,`datetime`)}`),v.push(``),process.stdout.write(v.join(`
|
|
3
3
|
`)),0}export{d as usageCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import{ApiClient as n}from"./api-
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import{ApiClient as n}from"./api-hWp9s3Y8.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import"./formatter-DDG2TSOz.js";import{emitEnvelope as i,wrapSnapshot as a}from"./emit-NkY7PE3R.js";async function o(o){if(o.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),o.json?(i(a({reset:!0,defaultSiteId:null},`use.reset`)),0):(process.stdout.write(`Default site cleared.
|
|
2
2
|
`),0);if(!o.match||!o.match.trim()){let t=await e();if(t.defaultSiteId){let e={siteId:t.defaultSiteId,name:t.defaultSiteName??null,domain:t.defaultSiteName??null};return o.json?(i(a(e,`use.current`,{siteId:t.defaultSiteId})),0):(process.stdout.write(`Default site: ${e.name??e.siteId} (${t.defaultSiteId})\n`),0)}return o.json?(i(a(null,`use.current`,{})),0):(process.stdout.write("No default site set. Run `zenovay use <domain>` to set one.\n"),0)}let c=await e(),l=await r({strict:!1});if(!l&&!process.env.ZENOVAY_API_TOKEN)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:c,cliVersion:o.cliVersion,token:l}),d=o.match.trim().toLowerCase(),f=await u.getSites(),p=f.find(e=>e.id===o.match||e.trackingCode===o.match||e.url===o.match),m=p??f.find(e=>s(e.url).includes(d)||e.name.toLowerCase().includes(d));return m?(await t({defaultSiteId:m.id,defaultSiteName:m.name}),o.json?(i(a({siteId:m.id,name:m.name,domain:s(m.url)},`use.set`,{siteId:m.id})),0):(process.stdout.write(`Default site → ${m.name} (${m.url})\n`),0)):(process.stderr.write(`No site matched "${o.match}". Your sites:\n${f.map(e=>` ${e.name} — ${e.url} — ${e.id}`).join(`
|
|
3
3
|
`)}\n`),2)}function s(e){return e.toLowerCase().replace(/^https?:\/\//,``).replace(/\/.*$/,``)}export{o as useCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-D4XO4okw.js";import"./telemetry-BJbpxgIp.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import{openInBrowser as a}from"./open-url-CTfSApWl.js";import"./client-I4GTcUcm.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-CJw_Mqo2.js";import"./keybar-QgnmSion.js";import{brailleSpark as s,spark as c}from"./sparkline-CpoBjjlc.js";import"./chat-panel-DS-FxXoL.js";import{resolveSiteId as l}from"./resolve-site-GDYx0__E.js";import{DataTable as u}from"./data-table-DJzT7bAr.js";import{deepLinkFor as d}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as f}from"./analytical-screen-DM7SBY5U.js";import{Box as p,Text as m}from"ink";import h from"react";function g(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function _(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?c(n,8):`▁▁▁▁▁▁▁▁`}function v(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function y(o){let s=await e(),c=await t({strict:!1}),u=new n({config:s,cliVersion:o.cliVersion,token:c}),p,m;try{({siteId:p,site:m}=await l(u,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(o),S=o.limit??50,C=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,w=e=>C<=0?e:e.filter(e=>v(e)>=C),T=6e4,E=e=>{let t=Date.parse(e.startedAt);return Number.isFinite(t)&&Date.now()-t<T},D=[{key:`startedAt`,label:``,width:5,format:(e,t)=>E(t)?`● new`:``},{key:`startedAt`,label:`when`,width:6,format:e=>g(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>_(t)}];return f({cliVersion:o.cliVersion,title:`visitors · ${p}`,commandName:`visitors`,ai:{api:u,siteId:p,siteLabel:m?.url?m.url.replace(/^https?:\/\//,``).replace(/\/$/,``):m?.name??p},authToken:c?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>u.getVisitors(p,{limit:S},e),format:y,keybindings:{o:{label:`open in browser`,handler:()=>{a(d(`visitors`,{siteId:p}))}}},headlessEmit:(e,t)=>{let n={...e,visitors:w(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
2
|
`);return}let i=[`startedAt`,`country`,`city`,`device`,`page`];process.stdout.write(r(n.visitors,i,t))},panels:[{id:`live`,title:`Now`,render:e=>h.createElement(b,{visitors:w(e.visitors)})},{id:`visitors`,title:`Active sessions`,render:e=>h.createElement(x,{visitors:w(e.visitors),limit:S,columns:D})}]})}const b=({visitors:e})=>{let{theme:t}=o(),n=[...e].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)),r=n[0],i=Array(24*6).fill(0),a=Date.now();for(let t of e){let e=a-new Date(t.startedAt).getTime(),n=Math.floor(e/(10*60*1e3));n>=0&&n<i.length&&(i[i.length-1-n]+=1)}return h.createElement(p,{flexDirection:`column`},h.createElement(m,{bold:!0},e.length,` live`),h.createElement(m,{color:t.muted},s(i,40)),r?h.createElement(m,{color:t.muted},`top: `,r.city??r.country??`—`,` · `,r.page??`—`):null)},x=({visitors:e,limit:t,columns:n})=>{let{theme:r}=o(),i=[...e].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)).slice(0,t);return i.length===0?h.createElement(m,{color:r.dim},`— no visitors yet —`):h.createElement(u,{columns:n,data:i,headerStyle:`accent`})};export{y as visitorsCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-D4XO4okw.js";import"./telemetry-BJbpxgIp.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import{openInBrowser as a}from"./open-url-CTfSApWl.js";import"./client-I4GTcUcm.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-CJw_Mqo2.js";import"./keybar-QgnmSion.js";import"./chat-panel-DS-FxXoL.js";import{resolveSiteId as s}from"./resolve-site-GDYx0__E.js";import{DataTable as c}from"./data-table-DJzT7bAr.js";import{deepLinkFor as l}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as u}from"./analytical-screen-DM7SBY5U.js";import{Box as d,Text as f}from"ink";import p from"react";const m={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function h(e,t){let n=m[e];return t<=n.good?{label:`good`,tone:`good`}:t<=n.poor?{label:`needs`,tone:`needs`}:{label:`poor`,tone:`poor`}}function g(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}function _({data:e}){let{theme:t}=o(),n={good:t.success,needs:t.warn,poor:t.error},r=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},i=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return p.createElement(d,{flexDirection:`column`},i.map(e=>{let t=r(e),i=h(e,t);return p.createElement(f,{key:e},p.createElement(f,{color:n[i.tone]},`● `),p.createElement(f,{bold:!0},e.toUpperCase().padEnd(5)),` `,p.createElement(f,null,g(e,t).padStart(8)),` `,p.createElement(f,{color:n[i.tone]},i.label))}))}function v({data:e,columns:t}){let{theme:n}=o();return e.vitals.length===0?p.createElement(f,{color:n.muted},`— no vitals data yet —`):p.createElement(c,{data:e.vitals.slice(0,15),columns:t,headerStyle:`accent`})}async function y(o){let c=await e(),d=await t({strict:!1}),f=new n({config:c,cliVersion:o.cliVersion,token:d}),m,h;try{({siteId:m,site:h}=await s(f,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(o),b=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return u({cliVersion:o.cliVersion,title:`vitals · ${m}`,commandName:`vitals`,ai:{api:f,siteId:m,siteLabel:h?.url?h.url.replace(/^https?:\/\//,``).replace(/\/$/,``):h?.name??m},authToken:d?.accessToken??null,refreshIntervalMs:o.watch?5*6e4:0,fetcher:e=>f.getVitals(m,{url:o.url,device:o.device,window:o.window},e),format:y,keybindings:{o:{label:`open in browser`,handler:()=>{a(l(`vitals`,{siteId:m}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
2
|
`);return}process.stdout.write(r(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>p.createElement(_,{data:e})},{id:`pages`,title:`Per-page`,render:e=>p.createElement(v,{data:e,columns:b})}]})}export{y as vitalsCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import"./formatter-DDG2TSOz.js";import{emit as r,isHeadless as i}from"./emit-NkY7PE3R.js";import{openInBrowser as a}from"./open-url-CTfSApWl.js";import{parseSseStream as o}from"./client-I4GTcUcm.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-CJw_Mqo2.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{spark as d}from"./sparkline-CpoBjjlc.js";import{resolveSiteId as f}from"./resolve-site-GDYx0__E.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{z as h}from"zod";import{Box as g,Text as _,render as v,useApp as y,useInput as b}from"ink";import x,{useEffect as S,useState as C}from"react";import w from"ink-spinner";import T from"ink-text-input";const E=Math.PI*2;function D(e){let t=e,n=Math.PI*Math.sin(e);for(let e=0;e<6;e++){let e=2*t+Math.sin(2*t)-n,r=2+2*Math.cos(2*t);if(r===0)break;t-=e/r}return t}function O(e,t){if(e<-90||e>90||t<-180||t>180)return null;let n=e*Math.PI/180,r=t*Math.PI/180,i=D(n),a=r*Math.cos(i)/Math.PI,o=Math.sin(i);return{x:a,y:o}}function k(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function A(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function j(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function M(e){let t=e.dw/2,n=e.dh/2,r=e.dw/2-1,i=e.dh/2-1,a=Math.max(e.dw,e.dh)*2;for(let o=0;o<a;o++){let s=o/a*E,c=Math.round(t+r*Math.cos(s)),l=Math.round(n+i*Math.sin(s));j(e,c,l)}}function N(e){let t=Math.floor(e.dh/2);for(let n=0;n<e.dw;n+=4)j(e,n,t)}function P(e,t){let n=e.dw/2,r=e.dh/2,i=e.dw/2-1,a=e.dh/2-1;for(let o of t){let t=O(o.lat,o.lng);if(!t)continue;let s=Math.round(n+t.x*i),c=Math.round(r-t.y*a);j(e,s,c),j(e,s+1,c),j(e,s,c+1),j(e,s+1,c+1)}}const F=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function I(e,t,n){let r=0;for(let i=0;i<F.length;i++){let[a,o]=F[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function L(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`.`:r<=4?`:`:r<=6?`*`:`#`}function R({data:e,width:t=80,height:n=20,asciiOnly:r}){let{theme:i}=c(),a=k(r),o=A(t,n);M(o),N(o),P(o,e);let s=[];for(let e=0;e<n;e++){let n=``;for(let r=0;r<t;r++)n+=a?L(o,r,e):I(o,r,e);s.push(n)}return x.createElement(g,{flexDirection:`column`},s.map((e,t)=>x.createElement(_,{key:t,color:i.accent},e)),x.createElement(_,{color:i.muted},e.length,` live · `,a?`ascii mode`:`braille mode`))}const z=h.object({siteId:h.string().optional(),window:h.string().optional(),totalVisitors:h.number().optional(),visitors:h.object({count:h.number().optional(),series:h.array(h.number()).optional()}).optional(),topPages:h.array(h.object({path:h.string(),views:h.number().optional(),count:h.number().optional()})).optional(),sources:h.array(h.object({source:h.string(),visitors:h.number()})).optional()}).passthrough();async function B(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),l;try{({siteId:l}=await f(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(a)){let e=await c.getDashboardSnapshot(l);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=v(x.createElement(V,{api:c,siteId:l,intervalMs:a.intervalMs??15e3,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const V=({api:e,siteId:t,intervalMs:n,cliVersion:r,onExit:i})=>{let{theme:d}=c(),{exit:f}=y(),[h,v]=C(null),[T,E]=C(null),[D,O]=C(null),[k,A]=C([]),[j,M]=C(!0),[N,P]=C(null),[F,I]=C(1),[L,B]=C(!1),[V,Y]=C(!1);b((e,n)=>{if(e===`o`||e===`O`){a(m(`watch`,{siteId:t}));return}if(e===`q`){f(),i(0);return}if(e===`?`||e===`/`){Y(e=>!e);return}if(e===`g`){B(e=>!e);return}if(n.tab){I(e=>{let t=n.shift?(e+4)%6+1:e%6+1;return t});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&I(Number(e))});let[X,Z]=C(!1);if(S(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=z.safeParse(n);if(!i.success){Z(!0),M(!1);return}Z(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};v(o),e.getVitals(t).then(e=>{r||E(e)},()=>{}),e.getGoals(t).then(e=>{r||O(e)},()=>{}),M(!1),P(null)}catch(e){r||P(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),S(()=>{let n=new AbortController;return(async()=>{try{let r=await e.openEventsStream(t,n.signal);for await(let e of o(r))e.type===`error`&&A(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),j)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Loading`,state:`busy`},x.createElement(g,null,x.createElement(_,{color:d.accent},x.createElement(w,{type:`dots`})),x.createElement(_,null,` Fetching snapshot…`))));if(N&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Error`,state:`err`},x.createElement(_,{color:d.error},N)));if(X&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(p,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let Q=process.stdout.columns??80,$=Math.max(20,Math.floor(Q/3)-1),ee=[];return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}${L?` · globe`:``}`}),x.createElement(g,{flexDirection:`row`},x.createElement(g,{flexDirection:`column`},L?x.createElement(s,{title:`Live globe`,focused:F===1,width:$},x.createElement(R,{data:ee,width:Math.max(40,$-4),height:12})):x.createElement(U,{snapshot:h,focused:F===1,width:$}),x.createElement(K,{events:k,focused:F===4,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(W,{snapshot:h,focused:F===2,width:$}),x.createElement(q,{vitals:T,focused:F===5,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(G,{snapshot:h,focused:F===3,width:$}),x.createElement(J,{goals:D,focused:F===6,width:$}))),V?x.createElement(H,{api:e,siteId:t,width:Q-2}):null,x.createElement(u,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:L?`panels`:`globe`},{key:`?/`,label:V?`close chat`:`ai chat`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))},H=({api:e,siteId:t,width:n})=>{let{theme:r}=c(),[i,a]=C(``),[l,u]=C([]),[d,f]=C(!1),[p,m]=C(``),[h,v]=C(null),y=async n=>{let r=n.trim();if(!r||d)return;v(null),a(``);let i=[...l,{role:`user`,content:r}];u(i),f(!0),m(``);try{let n=i.map(e=>({role:e.role,content:e.content})),r=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),a=``;for await(let e of o(r))if(e.type===`delta`)a+=e.content,m(a);else if(e.type===`error`)v(`${e.code}: ${e.message}`);else if(e.type===`done`)break;u([...i,{role:`assistant`,content:a}]),m(``)}catch(e){v(e instanceof Error?e.message:`chat failed`)}finally{f(!1)}};return x.createElement(g,{marginTop:1},x.createElement(s,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},x.createElement(g,{flexDirection:`column`},l.slice(-6).map((e,t)=>x.createElement(g,{key:t,flexDirection:`column`,marginBottom:1},x.createElement(_,{color:e.role===`user`?r.accent:r.info,bold:!0},e.role===`user`?`you`:`zenovay`),x.createElement(_,null,e.content))),d&&p?x.createElement(g,{flexDirection:`column`,marginBottom:1},x.createElement(_,{color:r.info,bold:!0},`zenovay`),x.createElement(_,null,p)):null,h?x.createElement(_,{color:r.error},`✗ `,h):null,x.createElement(g,null,x.createElement(_,{color:r.accent},d?`⠋ `:`▸ `),x.createElement(T,{value:i,onChange:a,onSubmit:y,placeholder:d?`streaming…`:`ask anything about your analytics`})))))},U=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.visitors?.count??0,a=e?.visitors?.series??[];return x.createElement(s,{title:`Visitors`,focused:t,width:n},x.createElement(_,{bold:!0},i.toString()),x.createElement(_,{color:r.muted},a.length>0?d(a,Math.max(8,n-6)):`— no data —`))},W=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.topPages?.slice(0,5)??[];return x.createElement(s,{title:`Top pages`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.path},x.createElement(_,null,e.path.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.views))))},G=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.sources?.slice(0,5)??[];return x.createElement(s,{title:`Sources`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.source},x.createElement(_,null,e.source.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.visitors))))},K=({events:e,focused:t,width:n})=>{let{theme:r}=c();return x.createElement(s,{title:`Events`,focused:t,width:n},e.length===0?x.createElement(_,{color:r.muted},`— waiting —`):e.slice(-10).map((e,t)=>x.createElement(_,{key:t},e.slice(0,n-4))))},q=({vitals:e,focused:t,width:n})=>{let{theme:r}=c(),i=(e,t,n)=>x.createElement(g,{key:e},x.createElement(_,{bold:!0},e.padEnd(6)),x.createElement(_,{color:r.muted},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return x.createElement(s,{title:`Vitals`,focused:t,width:n},i(`LCP`,e?.lcpP75,`ms`),i(`INP`,e?.inpP75,`ms`),i(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),i(`TTFB`,e?.ttfbP75,`ms`),i(`FCP`,e?.fcpP75,`ms`))},J=({goals:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.goals?.slice(0,5)??[];return x.createElement(s,{title:`Goals`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.name},x.createElement(_,null,e.name.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.completions))))};export{B as watchCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{emitErrorEnvelope as n}from"./error-codes-D4XO4okw.js";import{ApiV2Client as r}from"./api-v2-C82L-ZOL.js";import{confirmDestructive as i}from"./confirm-CIdxMt7N.js";import"./formatter-DDG2TSOz.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-NkY7PE3R.js";function c(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function l(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function u(u){let d=await e(),f=await t({strict:!1}),p=new r({config:d,cliVersion:u.cliVersion,token:f});try{switch(u.action){case`list`:{let{webhooks:e}=await p.listWebhooks();if(u.json)return a(s(e,`webhooks.list`),{legacyKey:`webhooks`,legacyValue:e}),0;if(e.length===0)return process.stdout.write("No webhooks yet. Add one with `zenovay webhooks add <https-url> --events <e1,e2>`.\n"),0;let t=[``,`id`,`url`,`events`,`created`],n=[1,14,40,28,10],r=e=>e.map((e,t)=>(e??``).padEnd(n[t])).join(` `);process.stdout.write(r(t)+`
|
|
2
2
|
`),process.stdout.write(r(n.map(e=>`─`.repeat(e)))+`
|
|
3
3
|
`);for(let t of e){let e=t.status===`disabled`?`○`:`●`,i=t.url.length>n[2]?`${t.url.slice(0,n[2]-1)}…`:t.url,a=t.events.join(`,`),o=a.length>n[3]?`${a.slice(0,n[3]-1)}…`:a;process.stdout.write(r([e,c(t.id),i,o,l(t.createdAt)])+`
|
|
4
4
|
`)}return process.stdout.write(`
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-hWp9s3Y8.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-C82L-ZOL.js";import"./theme-BuGrQHax.js";import{Panel as r,useTheme as i}from"./panel-B-XxdP-N.js";import{Banner as a}from"./banner-DdgwXGzt.js";import"./progress-row-5ns2IsFh.js";import"./prompt-CJw_Mqo2.js";import"./keybar-QgnmSion.js";import"./sparkline-CpoBjjlc.js";import"./data-table-DJzT7bAr.js";import"./bar-C1Zrfe9H.js";import"./ui-whccLLRv.js";import{Box as o,Text as s,render as c,useApp as l,useInput as u}from"ink";import d,{useEffect as f,useState as p}from"react";async function m(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function h({stats:e}){let{theme:t}=i();return d.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},d.createElement(o,{flexDirection:`column`},d.createElement(s,null,d.createElement(s,{color:t.muted},`public URL `),d.createElement(s,{color:t.accent},e.publicUrl)),d.createElement(s,null,d.createElement(s,{color:t.muted},`→ forwarding to `),d.createElement(s,{color:t.accent},e.wsUrl)),d.createElement(s,null,e.connected?d.createElement(s,{color:t.success},`● connected`):d.createElement(s,{color:t.warn},`○ connecting…`),d.createElement(s,{color:t.muted},` · `,e.total,` requests · `,e.ok,` ok · `),d.createElement(s,{color:e.err>0?t.error:t.muted},e.err,` err`),e.lastStatus===null?null:d.createElement(s,{color:t.muted},` · last: HTTP `,e.lastStatus)),e.lastError?d.createElement(s,{color:t.error},`last error: `,e.lastError.slice(0,80)):null))}async function g(r){let g=await e(),_=await t({strict:!1});if(!_?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let v=r.siteId??_.teamId??``;if(!v)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
|
|
2
2
|
`),2;if(!r.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
|
|
3
3
|
`),2;let y=r.to.match(/^https?:\/\//)?r.to:`http://${r.to}`,b=new n({config:g,cliVersion:r.cliVersion,token:_}),x;try{x=await b.createTunnel(v,r.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let S=r.sign?r.secret??x.tunnelKey:null,C=()=>{let{theme:e}=i(),{exit:t}=l(),[n,c]=p({total:0,ok:0,err:0,lastStatus:null,lastError:null,publicUrl:x.publicUrl,wsUrl:x.wsUrl,connected:!1});return u((e,n)=>{(e===`q`||n.escape)&&t()}),f(()=>{let e=new AbortController,t=async e=>{try{let t={...e.headers};delete t.host,delete t[`content-length`],S&&(t[`X-Zenovay-Signature`]=`sha256=${await m(S,e.body)}`);let n=await fetch(y,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),r=await n.text(),i={};return n.headers.forEach((e,t)=>{i[t]=e}),c(e=>({...e,total:e.total+1,ok:e.ok+(n.ok?1:0),err:e.err+(n.ok?0:1),lastStatus:n.status,lastError:n.ok?null:`HTTP ${n.status}`})),{status:n.status,headers:i,body:r}}catch(e){let t=e instanceof Error?e.message:String(e);return c(e=>({...e,total:e.total+1,err:e.err+1,lastError:t})),{status:502,body:JSON.stringify({error:`cli_local_failed`,detail:t})}}};return(async()=>{let n=b.tunnelClient(x.wsUrl);c(e=>({...e,connected:!0}));try{await n.start(t,e.signal)}catch(e){c(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),d.createElement(o,{flexDirection:`column`},d.createElement(a,{version:`webhooks forward`}),d.createElement(h,{stats:n}),d.createElement(s,{color:e.muted},`target: `,y,` `,r.sign?`· HMAC-signed`:``),d.createElement(s,{color:e.muted},`[q | Esc] quit`))},{waitUntilExit:w}=c(d.createElement(C,null));return await w(),0}export{g as webhooksForwardCommand};
|
package/dist/wizard-bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import(`./init-
|
|
2
|
+
import(`./init-DOrkLxxe.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
|
package/package.json
CHANGED
package/dist/api-FCanTxsb.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{clearToken as e,isExpired as t,readToken as n,writeToken as r}from"./token-store-BQuGH0z2.js";import{z as i}from"zod";const a=i.object({device_code:i.string(),user_code:i.string(),verification_uri:i.string().url(),verification_uri_complete:i.string().url().optional(),expires_in:i.number().int().positive(),interval:i.number().int().positive().default(5)}),o=i.object({access_token:i.string(),refresh_token:i.string(),token_type:i.literal(`Bearer`).default(`Bearer`),expires_in:i.number().int().positive(),scope:i.string().optional()}),s=i.object({error:i.enum([`authorization_pending`,`slow_down`,`access_denied`,`expired_token`,`invalid_client`,`invalid_grant`,`invalid_scope`]),error_description:i.string().optional()});async function c(e){let{apiBase:t,clientId:n=`cli-zenovay`,scope:r=`cli:full`}=e,i=e.fetchImpl??fetch,o=new URLSearchParams({client_id:n,scope:r}),s=await i(`${t}/oauth/device_authorization`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:o.toString()});if(!s.ok){let e=await s.text();throw Error(`Device authorization failed: ${s.status} ${e}`)}let c=await s.json();return a.parse(c)}async function l(e){let{apiBase:t,deviceCode:n,clientId:r=`cli-zenovay`,expiresIn:i}=e,a=e.fetchImpl??fetch,c=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),l=e.interval,u=Date.now(),d=u+i*1e3;for(;Date.now()<d;){if(e.signal?.aborted)throw Error(`Polling aborted`);await c(l*1e3),e.onTick?.(Date.now()-u);let i=new URLSearchParams({grant_type:`urn:ietf:params:oauth:grant-type:device_code`,device_code:n,client_id:r}),d=await a(`${t}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:i.toString()}),f=await d.json().catch(()=>({}));if(d.ok){let e=o.parse(f);return{accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:Date.now()+e.expires_in*1e3,tokenType:`Bearer`,scope:e.scope}}let p=s.safeParse(f);if(!p.success)throw Error(`Token poll failed (${d.status}): ${JSON.stringify(f)}`);let{error:m}=p.data;if(m!==`authorization_pending`){if(m===`slow_down`){l=Math.min(l*2,30);continue}throw m===`access_denied`?Error(`Device authorization denied by user.`):m===`expired_token`?Error("Device code expired — run `zenovay login` again."):Error(`Device token error: ${m}`)}}throw Error("Device code expired — run `zenovay login` again.")}async function u(e){let r=await n({strict:!0});return r?t(r)?d(r,e):r:null}async function d(t,n){let{apiBase:i,clientId:a=`cli-zenovay`}=n,s=n.fetchImpl??fetch,c=new URLSearchParams({grant_type:`refresh_token`,refresh_token:t.refreshToken,client_id:a}),l=await s(`${i}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:c.toString()}),u=await l.json().catch(()=>({}));if(!l.ok){let t=u&&typeof u==`object`&&`error`in u?u.error:String(u);throw t===`invalid_grant`?(await e(),Error("Refresh token rejected by server — your session has been revoked. Run `zenovay login` again.")):Error(`Token refresh failed (${l.status}): ${JSON.stringify(u)}`)}let d=o.parse(u),f={...t,accessToken:d.access_token,refreshToken:d.refresh_token,expiresAt:Date.now()+d.expires_in*1e3,tokenType:`Bearer`,scope:d.scope??t.scope};return await r(f),f}const f=i.object({id:i.string(),name:i.string(),url:i.string().url(),trackingCode:i.string().optional(),lastActiveAt:i.string().nullable().optional()}),p=i.object({user:i.object({id:i.string(),email:i.string().email(),name:i.string().optional().nullable()}),team:i.object({id:i.string(),name:i.string(),plan:i.string()}).optional().nullable(),teams:i.array(i.object({id:i.string(),name:i.string(),plan:i.string(),role:i.string(),siteCount:i.number().int(),isCurrent:i.boolean()})).optional()});var m=class extends Error{constructor(e,t,n){super(n),this.status=e,this.body=t,this.name=`ApiError`}},h=class{fetchImpl;token;constructor(e){this.opts=e,this.fetchImpl=e.fetchImpl??fetch,this.token=e.token??null}get apiBase(){return this.opts.config.apiBase}async authedHeaders(e={}){let t=process.env.ZENOVAY_TEAM_ID,n=t&&t.trim()?{"X-Zenovay-Team-Id":t.trim()}:{},r=process.env.ZENOVAY_API_TOKEN;if(r&&r.trim())return{Accept:`application/json`,"User-Agent":`zenovay-cli/${this.opts.cliVersion}`,"X-Zenovay-CLI-Version":this.opts.cliVersion,Authorization:`Bearer ${r.trim()}`,...n,...e};this.token||=await u({apiBase:this.apiBase});let i={Accept:`application/json`,"User-Agent":`zenovay-cli/${this.opts.cliVersion}`,"X-Zenovay-CLI-Version":this.opts.cliVersion,...n,...e};return this.token&&(i.Authorization=`${this.token.tokenType} ${this.token.accessToken}`),i}async request(e,t){let n=`${this.apiBase}${e}`,r=await this.fetchImpl(n,{...t,headers:{...await this.authedHeaders(),...t.headers}});if(r.status===401&&this.token&&(this.token=null,r=await this.fetchImpl(n,{...t,headers:{...await this.authedHeaders(),...t.headers}})),!r.ok){let n=await r.text().catch(()=>``);throw new m(r.status,n,`${t.method??`GET`} ${e} → ${r.status}`)}let i=await r.json();return t.schema.parse(i)}async getSites(){return this.request(`/v1/cli/sites`,{schema:i.array(f)})}async createSite(e){return this.request(`/v1/cli/sites`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),schema:i.object({id:i.string()})})}async getFirstEvent(e){let t=new URLSearchParams({site_id:e.siteId,since:String(e.since)});return this.request(`/v1/cli/first-event?${t.toString()}`,{schema:i.object({received:i.boolean(),event:i.unknown().optional()})})}async me(){return this.request(`/v1/cli/me`,{schema:p})}async revokeCurrentToken(){this.token&&await this.fetchImpl(`${this.apiBase}/oauth/revoke`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,...await this.authedHeaders()},body:new URLSearchParams({token:this.token.refreshToken,token_type_hint:`refresh_token`,client_id:`cli-zenovay`}).toString()})}async openAiStream(e,t,n){let r=await this.authedHeaders({"Content-Type":`application/json`,Accept:`text/event-stream`}),i=await this.fetchImpl(`${this.apiBase}/ai/cli/${e}`,{method:`POST`,headers:r,body:JSON.stringify(t),signal:n});if(!i.ok){let t=await i.text().catch(()=>``);throw new m(i.status,t,`POST /ai/cli/${e} → ${i.status}`)}return i}async openEventsStream(e,t){let n=await this.authedHeaders({Accept:`text/event-stream`}),r=await this.fetchImpl(`${this.apiBase}/v1/cli/events/tail?site_id=${e}`,{method:`GET`,headers:n,signal:t});if(!r.ok){let e=await r.text().catch(()=>``);throw new m(r.status,e,`GET events tail → ${r.status}`)}return r}async getDashboardSnapshot(e){return this.request(`/v1/cli/dashboard?site_id=${e}`,{schema:i.unknown()})}async ping(){let e=Date.now(),t=await this.fetchImpl(`${this.apiBase}/v1/cli/ping`,{headers:await this.authedHeaders()});if(!t.ok)throw new m(t.status,await t.text().catch(()=>``),`ping failed`);return{ok:!0,latencyMs:Date.now()-e}}};export{h as ApiClient,m as ApiError,u as ensureFreshToken,l as pollDeviceToken,c as startDeviceAuthorization};
|
package/dist/api-v2-D9N_2hdW.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./config--JRu_jFq.js";import{ApiError as e}from"./api-FCanTxsb.js";import"./token-store-BQuGH0z2.js";import{ApiV2Client as t}from"./api-v2-CPUUcP1i.js";export{t as ApiV2Client};
|
package/dist/globe-PiPL3Bei.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import"./formatter-DDG2TSOz.js";import{emit$1 as r,isHeadless as i}from"./emit-C9vAopcy.js";import"./client-Dm8uGVCy.js";import{openInBrowser as a}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{Panel as o,useTheme as s}from"./panel-B-XxdP-N.js";import{Banner as c}from"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{Keybar as l}from"./keybar-QgnmSion.js";import{ChatPanel as u}from"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as d}from"./resolve-site-DQVcWhjG.js";import{EmptyState as f}from"./empty-state-DbToIL5T.js";import{Bar as p}from"./bar-C1Zrfe9H.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useMemo as ee,useRef as te,useState as S}from"react";import ne from"ink-spinner";const C={DZ:{lat:28.0339,lng:1.6596,name:`Algeria`,spread:8},EG:{lat:26.8206,lng:30.8025,name:`Egypt`,spread:6},ET:{lat:9.145,lng:40.4897,name:`Ethiopia`,spread:6},GH:{lat:7.9465,lng:-1.0232,name:`Ghana`,spread:3},KE:{lat:-.0236,lng:37.9062,name:`Kenya`,spread:4},MA:{lat:31.7917,lng:-7.0926,name:`Morocco`,spread:5},NG:{lat:9.082,lng:8.6753,name:`Nigeria`,spread:5},ZA:{lat:-30.5595,lng:22.9375,name:`South Africa`,spread:7},TZ:{lat:-6.369,lng:34.8888,name:`Tanzania`,spread:5},UG:{lat:1.3733,lng:32.2903,name:`Uganda`,spread:3},TN:{lat:33.8869,lng:9.5375,name:`Tunisia`,spread:3},SN:{lat:14.4974,lng:-14.4524,name:`Senegal`,spread:3},CI:{lat:7.54,lng:-5.5471,name:`Côte d'Ivoire`,spread:3},CM:{lat:7.3697,lng:12.3547,name:`Cameroon`,spread:4},AO:{lat:-11.2027,lng:17.8739,name:`Angola`,spread:6},MZ:{lat:-18.6657,lng:35.5296,name:`Mozambique`,spread:6},ZW:{lat:-19.0154,lng:29.1549,name:`Zimbabwe`,spread:4},ZM:{lat:-13.1339,lng:27.8493,name:`Zambia`,spread:5},RW:{lat:-1.9403,lng:29.8739,name:`Rwanda`,spread:1.5},MG:{lat:-18.7669,lng:46.8691,name:`Madagascar`,spread:5},LY:{lat:26.3351,lng:17.2283,name:`Libya`,spread:8},SD:{lat:12.8628,lng:30.2176,name:`Sudan`,spread:7},US:{lat:39.0902,lng:-98.5795,name:`United States`,spread:18},CA:{lat:56.1304,lng:-106.3468,name:`Canada`,spread:22},MX:{lat:23.6345,lng:-102.5528,name:`Mexico`,spread:9},BR:{lat:-10.235,lng:-51.9253,name:`Brazil`,spread:18},AR:{lat:-38.4161,lng:-63.6167,name:`Argentina`,spread:11},CL:{lat:-35.6751,lng:-71.543,name:`Chile`,spread:11},CO:{lat:4.5709,lng:-74.2973,name:`Colombia`,spread:6},PE:{lat:-9.19,lng:-75.0152,name:`Peru`,spread:7},VE:{lat:6.4238,lng:-66.5897,name:`Venezuela`,spread:6},EC:{lat:-1.8312,lng:-78.1834,name:`Ecuador`,spread:3},BO:{lat:-16.2902,lng:-63.5887,name:`Bolivia`,spread:6},UY:{lat:-32.5228,lng:-55.7658,name:`Uruguay`,spread:2.5},PY:{lat:-23.4425,lng:-58.4438,name:`Paraguay`,spread:4},GT:{lat:15.7835,lng:-90.2308,name:`Guatemala`,spread:2},CU:{lat:21.5218,lng:-77.7812,name:`Cuba`,spread:3},DO:{lat:18.7357,lng:-70.1627,name:`Dominican Republic`,spread:1.5},CR:{lat:9.7489,lng:-83.7534,name:`Costa Rica`,spread:1.2},PA:{lat:8.538,lng:-80.7821,name:`Panama`,spread:1.5},HN:{lat:15.2,lng:-86.2419,name:`Honduras`,spread:2},PR:{lat:18.2208,lng:-66.5901,name:`Puerto Rico`,spread:.6},JM:{lat:18.1096,lng:-77.2975,name:`Jamaica`,spread:.7},TT:{lat:10.6918,lng:-61.2225,name:`Trinidad and Tobago`,spread:.6},GB:{lat:55.3781,lng:-3.436,name:`United Kingdom`,spread:3},IE:{lat:53.4129,lng:-8.2439,name:`Ireland`,spread:2},FR:{lat:46.6034,lng:1.8883,name:`France`,spread:4},DE:{lat:51.1657,lng:10.4515,name:`Germany`,spread:3.5},IT:{lat:41.8719,lng:12.5674,name:`Italy`,spread:3.5},ES:{lat:40.4637,lng:-3.7492,name:`Spain`,spread:4},PT:{lat:39.3999,lng:-8.2245,name:`Portugal`,spread:2},NL:{lat:52.1326,lng:5.2913,name:`Netherlands`,spread:1.2},BE:{lat:50.5039,lng:4.4699,name:`Belgium`,spread:1},CH:{lat:46.8182,lng:8.2275,name:`Switzerland`,spread:1.4},AT:{lat:47.5162,lng:14.5501,name:`Austria`,spread:2},PL:{lat:51.9194,lng:19.1451,name:`Poland`,spread:3.5},CZ:{lat:49.8175,lng:15.473,name:`Czechia`,spread:1.8},SE:{lat:60.1282,lng:18.6435,name:`Sweden`,spread:5},NO:{lat:60.472,lng:8.4689,name:`Norway`,spread:5},FI:{lat:61.9241,lng:25.7482,name:`Finland`,spread:4},DK:{lat:56.2639,lng:9.5018,name:`Denmark`,spread:1.5},IS:{lat:64.9631,lng:-19.0208,name:`Iceland`,spread:3},GR:{lat:39.0742,lng:21.8243,name:`Greece`,spread:3},TR:{lat:38.9637,lng:35.2433,name:`Turkey`,spread:6},RO:{lat:45.9432,lng:24.9668,name:`Romania`,spread:3},HU:{lat:47.1625,lng:19.5033,name:`Hungary`,spread:2},UA:{lat:48.3794,lng:31.1656,name:`Ukraine`,spread:5},RU:{lat:61.524,lng:80,name:`Russia`,spread:28},BG:{lat:42.7339,lng:25.4858,name:`Bulgaria`,spread:2},HR:{lat:45.1,lng:15.2,name:`Croatia`,spread:2},RS:{lat:44.0165,lng:21.0059,name:`Serbia`,spread:2},SK:{lat:48.669,lng:19.699,name:`Slovakia`,spread:1.8},SI:{lat:46.1512,lng:14.9955,name:`Slovenia`,spread:1.2},LT:{lat:55.1694,lng:23.8813,name:`Lithuania`,spread:1.5},LV:{lat:56.8796,lng:24.6032,name:`Latvia`,spread:1.5},EE:{lat:58.5953,lng:25.0136,name:`Estonia`,spread:1.5},BY:{lat:53.7098,lng:27.9534,name:`Belarus`,spread:3},MD:{lat:47.4116,lng:28.3699,name:`Moldova`,spread:1.2},AL:{lat:41.1533,lng:20.1683,name:`Albania`,spread:1},MK:{lat:41.6086,lng:21.7453,name:`North Macedonia`,spread:1},BA:{lat:43.9159,lng:17.6791,name:`Bosnia and Herzegovina`,spread:1.2},ME:{lat:42.7087,lng:19.3744,name:`Montenegro`,spread:.8},XK:{lat:42.6026,lng:20.903,name:`Kosovo`,spread:.7},LU:{lat:49.8153,lng:6.1296,name:`Luxembourg`,spread:.4},MT:{lat:35.9375,lng:14.3754,name:`Malta`,spread:.3},CY:{lat:35.1264,lng:33.4299,name:`Cyprus`,spread:.6},CN:{lat:35.8617,lng:104.1954,name:`China`,spread:18},JP:{lat:36.2048,lng:138.2529,name:`Japan`,spread:5},KR:{lat:35.9078,lng:127.7669,name:`South Korea`,spread:2},IN:{lat:20.5937,lng:78.9629,name:`India`,spread:12},ID:{lat:-2.7893,lng:113.9213,name:`Indonesia`,spread:12},PH:{lat:12.8797,lng:121.774,name:`Philippines`,spread:5},VN:{lat:14.0583,lng:108.2772,name:`Vietnam`,spread:5},TH:{lat:15.87,lng:100.9925,name:`Thailand`,spread:4},MY:{lat:4.2105,lng:101.9758,name:`Malaysia`,spread:4},SG:{lat:1.3521,lng:103.8198,name:`Singapore`,spread:.3},PK:{lat:30.3753,lng:69.3451,name:`Pakistan`,spread:6},BD:{lat:23.685,lng:90.3563,name:`Bangladesh`,spread:3},LK:{lat:7.8731,lng:80.7718,name:`Sri Lanka`,spread:2},MM:{lat:21.9162,lng:95.956,name:`Myanmar`,spread:6},KH:{lat:12.5657,lng:104.991,name:`Cambodia`,spread:3},LA:{lat:19.8563,lng:102.4955,name:`Laos`,spread:3},NP:{lat:28.3949,lng:84.124,name:`Nepal`,spread:3},IR:{lat:32.4279,lng:53.688,name:`Iran`,spread:7},IQ:{lat:33.2232,lng:43.6793,name:`Iraq`,spread:4},IL:{lat:31.0461,lng:34.8516,name:`Israel`,spread:1},SA:{lat:23.8859,lng:45.0792,name:`Saudi Arabia`,spread:8},AE:{lat:23.4241,lng:53.8478,name:`UAE`,spread:2},QA:{lat:25.3548,lng:51.1839,name:`Qatar`,spread:.6},KW:{lat:29.3117,lng:47.4818,name:`Kuwait`,spread:.8},OM:{lat:21.4735,lng:55.9754,name:`Oman`,spread:4},JO:{lat:30.5852,lng:36.2384,name:`Jordan`,spread:2},LB:{lat:33.8547,lng:35.8623,name:`Lebanon`,spread:.7},SY:{lat:34.8021,lng:38.9968,name:`Syria`,spread:3},YE:{lat:15.5527,lng:48.5164,name:`Yemen`,spread:4},AF:{lat:33.9391,lng:67.71,name:`Afghanistan`,spread:5},KZ:{lat:48.0196,lng:66.9237,name:`Kazakhstan`,spread:13},UZ:{lat:41.3775,lng:64.5853,name:`Uzbekistan`,spread:5},TM:{lat:38.9697,lng:59.5563,name:`Turkmenistan`,spread:5},KG:{lat:41.2044,lng:74.7661,name:`Kyrgyzstan`,spread:3},TJ:{lat:38.861,lng:71.2761,name:`Tajikistan`,spread:3},AZ:{lat:40.1431,lng:47.5769,name:`Azerbaijan`,spread:2},GE:{lat:42.3154,lng:43.3569,name:`Georgia`,spread:2},AM:{lat:40.0691,lng:45.0382,name:`Armenia`,spread:1.2},HK:{lat:22.3193,lng:114.1694,name:`Hong Kong`,spread:.3},TW:{lat:23.6978,lng:120.9605,name:`Taiwan`,spread:1.5},AU:{lat:-25.2744,lng:133.7751,name:`Australia`,spread:18},NZ:{lat:-40.9006,lng:174.886,name:`New Zealand`,spread:5},PG:{lat:-6.314,lng:143.9555,name:`Papua New Guinea`,spread:5},FJ:{lat:-16.578,lng:179.4144,name:`Fiji`,spread:1}},re=Object.fromEntries(Object.entries(C).map(([e,t])=>[e,{lat:t.lat,lng:t.lng}]));function w(e){return!e||e.length!==2?null:C[e.toUpperCase()]??null}function T(e,t){let n=w(e);if(!n||t<=0)return[];let r=[],i=0;for(let t=0;t<e.length;t++)i=i*31+e.charCodeAt(t)>>>0;for(let e=0;e<t;e++){i=i+1831565813>>>0;let e=i;e=Math.imul(e^e>>>15,e|1)>>>0,e=(e^e+(Math.imul(e^e>>>7,e|61)>>>0))>>>0;let t=((e^e>>>14)>>>0)/4294967296;i=i+2246822507>>>0;let a=i;a=Math.imul(a^a>>>15,a|1)>>>0,a=(a^a+(Math.imul(a^a>>>7,a|61)>>>0))>>>0;let o=((a^a>>>14)>>>0)/4294967296,s=n.spread*Math.sqrt(t),c=o*2*Math.PI;r.push({lat:n.lat+s*Math.sin(c)*.7,lng:n.lng+s*Math.cos(c)/Math.max(.3,Math.cos(n.lat*Math.PI/180))})}return r}const E=360,D=180,O=new Uint8Array(E*D),k=new Uint8Array(E*D),A=[`__OCEAN__`];function j(e){let t=(e%360+360)%360;return Math.floor(t)}function M(e){return Math.max(0,Math.min(D-1,Math.floor(90-e)))}function N(e,t,n){let r=M(e),i=j(t);O[r*E+i]=1,k[r*E+i]=n}for(let e of Object.keys(C)){let t=C[e];A.push(e);let n=A.length-1,r=Math.max(.5,t.spread*.85),i=Math.max(.25,Math.cos(t.lat*Math.PI/180)),a=Math.max(.5,t.spread/i),o=Math.floor(t.lat-r),s=Math.ceil(t.lat+r),c=Math.floor(t.lng-a),l=Math.ceil(t.lng+a);for(let e=o;e<=s;e++)for(let i=c;i<=l;i++){let o=(e-t.lat)/r,s=(i-t.lng)/a;s*s+o*o>1||N(e,i,n)}}const P=new Uint8Array(O);for(let e=1;e<D-1;e++)for(let t=0;t<E;t++){if(O[e*E+t])continue;let n=0,r=0;for(let i=-1;i<=1;i++)for(let a=-1;a<=1;a++){if(i===0&&a===0)continue;let o=(t+a+E)%E;O[(e+i)*E+o]&&(n++,r||=k[(e+i)*E+o]??0)}n>=4&&(P[e*E+t]=1,k[e*E+t]=r)}O.set(P);const F=new Uint8Array(E*D);for(let e=0;e<D;e++)for(let t=0;t<E;t++){let n=k[e*E+t];if(!n)continue;let r=e>0?k[(e-1)*E+t]:0,i=e<D-1?k[(e+1)*E+t]:0,a=k[e*E+(t-1+E)%E],o=k[e*E+(t+1)%E];(r!==n||i!==n||a!==n||o!==n)&&(F[e*E+t]=1)}function I(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(D-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return O[n*E+i]===1?1:0}function L(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(D-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return F[n*E+i]===1?1:0}function R(e){return e*Math.PI/180}function z(e,t){let n=R(e),r=R(t);return{x:Math.cos(n)*Math.sin(r),y:Math.sin(n),z:Math.cos(n)*Math.cos(r)}}function B(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:n*e.x+r*e.z,y:e.y,z:-r*e.x+n*e.z}}function V(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:e.x,y:n*e.y-r*e.z,z:r*e.y+n*e.z}}function H(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function U(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function W(e,t,n,r){let i=r*r;for(let a=-r;a<=r;a++)for(let o=-r;o<=r;o++)o*o+a*a<=i&&U(e,Math.round(t+o),Math.round(n+a))}const G=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function K(e,t,n){let r=0;for(let i=0;i<G.length;i++){let[a,o]=G[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function q(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`·`:r<=5?`○`:`●`}function J(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function Y(e,t,n){if(e.z<0)return null;let r=t/2,i=n/2,a=Math.min(t,n/2)*.95;return{x:r+e.x*a,y:i-e.y*a}}function X(e){let t=e.dw/2,n=e.dh/2,r=Math.min(e.dw,e.dh/2)*.95,i=Math.round(2*Math.PI*r);for(let a=0;a<i;a++){let o=a/i*2*Math.PI,s=Math.round(t+r*Math.cos(o)),c=Math.round(n+r*Math.sin(o));U(e,s,c)}}function ie(e,t,n){for(let r of[-60,-30,0,30,60])for(let i=-180;i<=180;i+=4){let a=V(B(z(r,i),t),n),o=Y(a,e.dw,e.dh);o&&U(e,Math.round(o.x),Math.round(o.y))}for(let r=-180;r<180;r+=30)for(let i=-85;i<=85;i+=4){let a=V(B(z(i,r),t),n),o=Y(a,e.dw,e.dh);o&&U(e,Math.round(o.x),Math.round(o.y))}}function ae({visitors:e,highlight:t,width:n=50,height:r=25,rotationDeg:i=0,tiltDeg:a=20,gridlines:o=!0,asciiOnly:c}){let{theme:l}=s(),u=J(c),d=H(n,r),f=H(n,r),p=H(n,r),m=H(n,r),_=H(n,r),v=R(i),y=R(-a);X(d),o&&ie(d,v,y);{let e=f.dw/2,t=f.dh/2,n=Math.min(f.dw,f.dh/2)*.95,r=Math.cos(v),i=Math.sin(v),a=Math.cos(y),o=Math.sin(y);for(let s=0;s<f.dh;s++){let c=(t-s)/n;if(!(c<-1||c>1))for(let t=0;t<f.dw;t++){let l=(t-e)/n,u=l*l+c*c;if(u>1)continue;let d=Math.sqrt(1-u),m=l,h=c,g=a*h+o*d,_=-o*h+a*d,v=r*m-i*_,y=i*m+r*_,b=Math.asin(g)*(180/Math.PI),x=Math.atan2(v,y)*(180/Math.PI);I(b,x)&&(U(f,t,s),L(b,x)&&U(p,t,s))}}}for(let t of e){let e=V(B(z(t.lat,t.lng),v),y),n=Y(e,m.dw,m.dh);if(!n)continue;let r=typeof t.freshness==`number`?t.freshness:.5;W(m,n.x,n.y,r>.7?2:1)}if(t&&t.length>0)for(let e of t){let t=V(B(z(e.lat,e.lng),v),y),n=Y(t,_.dw,_.dh);if(!n)continue;W(_,n.x,n.y,2)}let x=[];for(let e=0;e<r;e++){let t=[],r=null,i=(e,n)=>{r&&r.color===e?r.text+=n:(r={color:e,text:n},t.push(r))};for(let r=0;r<n;r++){let n=u?q(_,r,e):K(_,r,e);if(n!==` `){i(l.warn,n);continue}let a=u?q(m,r,e):K(m,r,e);if(a!==` `){i(l.accent,a);continue}let o=u?q(p,r,e):K(p,r,e);if(o!==` `){i(l.fg,o);continue}let s=u?q(f,r,e):K(f,r,e);if(s!==` `){i(l.success,s);continue}let c=u?q(d,r,e):K(d,r,e);if(c!==` `){i(l.muted,c);continue}let h=t.length>0?t[t.length-1]:void 0;i(h?h.color:l.muted,` `)}x.push(b.createElement(h,{key:e},b.createElement(g,null,t.map((e,t)=>b.createElement(g,{key:t,color:e.color,bold:!0},e.text)))))}return b.createElement(h,{flexDirection:`column`},x)}async function Z(e,t,n){let r=await e.getGeo(t).catch(()=>({countries:[],cities:[]})),i=(r.countries??[]).map(e=>{let t=w(e.country),r=n.get(e.country)??0;return{code:e.country,visitors:e.visitors,lat:t?.lat,lng:t?.lng,freshness:e.visitors>r?1:.4}});return{countries:i,totalVisitors:i.reduce((e,t)=>e+t.visitors,0),unknownCount:i.filter(e=>typeof e.lat!=`number`).reduce((e,t)=>e+t.visitors,0),lastFetchedAt:Date.now()}}async function Q(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:o.cliVersion,token:c}),u,f;try{({siteId:u,site:f}=await d(l,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(o.browser){let e=m(`globe`,{siteId:u});o.json?process.stdout.write(JSON.stringify({openedUrl:e})+`
|
|
2
|
-
`):process.stdout.write(`\n Opening Mapbox globe in your default browser:\n ${e}\n\n`);try{await a(e)}catch{}return 0}if(i(o)){let e=await Z(l,u,new Map);return r({type:`globe.snapshot`,data:{countries:e.countries,total:e.totalVisitors,unknownCount:e.unknownCount}}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(ue,{api:l,siteId:u,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const oe=5e3,se=60,ce=1,le=80,ue=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:d}=v(),{theme:_}=s(),[C,re]=S(null),[E,D]=S(!0),[O,k]=S(null),[A,j]=S(0),[M,N]=S(!1),[P,F]=S(20),[I,L]=S(1),[R,z]=S(0),B=te(new Map),[V,H]=S(!1);y(n=>{if(!V){if(n===`/`){H(!0);return}if(n===`q`){d(),i(0);return}if(n===` `){N(e=>!e);return}if(n===`+`||n===`=`){L(e=>Math.min(1.6,e+.1));return}if(n===`-`||n===`_`){L(e=>Math.max(.7,e-.1));return}if(n===`t`){F(e=>(e+15)%60);return}if(n===`j`){z(e=>e+1);return}if(n===`k`){z(e=>Math.max(0,e-1));return}if(n===`o`||n===`O`||n===`w`){a(m(`globe`,{siteId:t}));return}if(n===`c`&&C){let e=C.countries[R];e?.lng!==void 0&&(j(-e.lng),N(!0));return}n===`r`&&(async()=>{try{let n=await Z(e,t,B.current);B.current=new Map(n.countries.map(e=>[e.code,e.visitors])),re(n)}catch(e){k(e.message)}})()}}),x(()=>{let n=!1,r=null,i=async()=>{try{let r=await Z(e,t,B.current);if(n)return;B.current=new Map(r.countries.map(e=>[e.code,e.visitors])),re(r),D(!1)}catch(e){n||(k(e.message),D(!1))}n||(r=setTimeout(i,oe))};return i(),()=>{n=!0,r&&clearTimeout(r)}},[e,t]),x(()=>{if(M)return;let e=setInterval(()=>{j(e=>(e+ce)%360)},se);return()=>clearInterval(e)},[M]);let U=ee(()=>{if(!C)return[];let e=[];for(let t of C.countries){if(typeof t.lat!=`number`||typeof t.lng!=`number`)continue;let n=Math.min(le,Math.max(3,t.visitors*5));for(let r of T(t.code,n))e.push({lat:r.lat,lng:r.lng,freshness:t.freshness})}return e},[C]),W=ee(()=>{if(!C)return[];let e=C.countries[Math.min(R,C.countries.length-1)];return!e||typeof e.lat!=`number`?[]:T(e.code,Math.min(80,Math.max(8,e.visitors*4)))},[C,R]),G=`globe · ${n} · live`,K=[{key:`q`,label:`quit`},{key:`j/k`,label:`select country`},{key:`c`,label:`center on selected`},{key:`space`,label:M?`resume`:`pause`},{key:`t`,label:`tilt ${P}°`},{key:`+/-`,label:`zoom`},{key:`o`,label:`open web globe`},{key:`r`,label:`refresh`},{key:`/`,label:`ask AI`}];if(V)return b.createElement(u,{cliVersion:r,api:e,dashboardContext:{commandName:`globe`,siteId:t,siteLabel:n,metricsSnapshot:C},onClose:()=>H(!1)});if(E)return b.createElement(h,{flexDirection:`column`},b.createElement(c,{version:r,subtitle:G}),b.createElement(o,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:_.accent},b.createElement(ne,{type:`dots`})),b.createElement(g,null,` Spinning up Earth…`))));if(O)return b.createElement(h,{flexDirection:`column`},b.createElement(c,{version:r,subtitle:G}),b.createElement(f,{reason:`error`,headline:`Failed to load`,hint:O}),b.createElement(l,{items:K}));if(!C||C.countries.length===0&&C.unknownCount===0)return b.createElement(h,{flexDirection:`column`},b.createElement(c,{version:r,subtitle:G}),b.createElement(f,{reason:`no-data`,headline:`No geolocated visitors yet`,hint:`Visit your site to populate the map.`}),b.createElement(l,{items:K}));let q=process.stdout.columns??100,J=36,Y=Math.max(40,Math.min(90,q-J-4)),X=Math.round(Y*I),ie=Math.round(X*.5),Q=C.countries.slice(0,12),ue=Math.max(1,...Q.map(e=>e.visitors)),de=Math.max(1,Math.floor((Date.now()-C.lastFetchedAt)/1e3)),$=C.countries[Math.min(R,C.countries.length-1)],fe=$?w($.code):null;return b.createElement(h,{flexDirection:`column`},b.createElement(c,{version:r,subtitle:G}),$?b.createElement(h,{flexDirection:`row`,marginBottom:1},b.createElement(h,{width:2}),b.createElement(h,{borderStyle:`round`,borderColor:_.warn,paddingX:1},b.createElement(g,{color:_.warn,bold:!0},fe?.name??$.code),b.createElement(g,{color:_.dim},` · `),b.createElement(g,{color:_.fg},$.visitors,` visitor`,$.visitors===1?``:`s`))):null,b.createElement(h,{flexDirection:`row`},b.createElement(h,{flexDirection:`column`,marginRight:2},b.createElement(ae,{visitors:U,highlight:W,width:X,height:ie,rotationDeg:A,tiltDeg:P}),b.createElement(h,{marginTop:1},b.createElement(g,{color:_.dim},C.totalVisitors,` visitors · `,C.countries.length,` countries`,C.unknownCount>0?` · ${C.unknownCount} unmapped`:``,` · `,M?`rotation paused`:`↻ ${ce}°/${se}ms`,` · refreshed `,de,`s ago`))),b.createElement(h,{flexDirection:`column`,width:J},b.createElement(o,{title:`Live by country`},Q.map((e,t)=>{let n=t===Math.min(R,C.countries.length-1),r=e.freshness>.7,i=n?_.warn:r?_.success:_.fg;return b.createElement(h,{key:e.code,flexDirection:`row`},b.createElement(h,{width:2},b.createElement(g,{color:_.warn},n?`›`:` `)),b.createElement(h,{width:3},b.createElement(g,{color:i,bold:n},e.code)),b.createElement(p,{value:e.visitors,max:ue,width:14,showPercent:!1}),b.createElement(h,{width:6},b.createElement(g,{color:_.muted},String(e.visitors).padStart(5))))})),C.countries.length>12?b.createElement(h,{marginTop:1},b.createElement(g,{color:_.muted},`+`,C.countries.length-12,` more (j/k to scroll)`)):null)),b.createElement(l,{items:K}))};export{Q as globeCommand};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import"./formatter-DDG2TSOz.js";import{emit$1 as i,isHeadless as a}from"./emit-C9vAopcy.js";import{openInBrowser as o}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{resolveSiteId as d}from"./resolve-site-DQVcWhjG.js";import{DataTable as f}from"./data-table-DJzT7bAr.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";async function w(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let u,f;try{({siteId:u,site:f}=await d(l,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(a(o)){let e=await l.getHeatmaps(u);return i({type:`heatmaps.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(T,{api:l,siteId:u,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const T=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=v(),{theme:d}=c(),[_,w]=S(null),[T,E]=S(!0),[D,O]=S(null);if(y(e=>{if(e===`o`||e===`O`){o(m(`heatmaps`,{siteId:t}));return}e===`q`&&(a(),i(0))}),x(()=>{let n=!1;return(async()=>{try{let r=await e.getHeatmaps(t);n||(w(r),E(!1))}catch(e){n||(O(e.message),E(!1))}})(),()=>{n=!0}},[e,t]),T)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`heatmaps · ${n}`}),b.createElement(s,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:d.accent},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Fetching heatmaps…`))));if(D)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`heatmaps · ${n}`}),b.createElement(p,{reason:`error`,headline:`Failed to load`,hint:D}));if(!_||_.length===0)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`heatmaps · ${n}`}),b.createElement(p,{reason:`no-data`,headline:`No heatmaps yet`,hint:`Enable heatmaps in your site settings`}));let k=[{key:`url`,label:`page`,width:36},{key:`type`,label:`type`,width:12},{key:`captureCount`,label:`captures`,align:`right`,width:10},{key:`createdAt`,label:`first seen`,width:24}];return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`heatmaps · ${n}`}),b.createElement(s,{title:`Heatmaps (${_.length})`},b.createElement(f,{columns:k,data:_,zebra:!0})),b.createElement(h,{marginTop:1},b.createElement(g,{color:d.muted},`Open any heatmap at https://app.zenovay.com/heatmaps`)),b.createElement(u,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{w as heatmapsCommand};
|