@nectarcrm/ccx 0.5.1 → 0.5.3
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/bin/ccx.js +32 -6
- package/package.json +1 -1
package/bin/ccx.js
CHANGED
|
@@ -511,13 +511,21 @@ async function autoUpdate() {
|
|
|
511
511
|
const prefix = globalPrefix()
|
|
512
512
|
if (!prefix) return save({ error: 'ccx não foi instalado com npm install -g' })
|
|
513
513
|
try {
|
|
514
|
-
const
|
|
515
|
-
|
|
514
|
+
const args = ['install', '-g', '--prefix', prefix, `${PKG}@${latest}`]
|
|
515
|
+
const opts = { stdio: ['ignore', 'ignore', 'pipe'], timeout: 180_000 }
|
|
516
|
+
// O npm que vem com o Node, rodado pelo próprio Node: sem cmd.exe, então espaço no caminho
|
|
517
|
+
// (C:\Program Files\nodejs, C:\Users\Nome Sobrenome) não quebra o comando
|
|
518
|
+
const cli = [join(dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npm-cli.js'), join(dirname(dirname(process.execPath)), 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js')].find(existsSync)
|
|
519
|
+
if (cli) execFileSync(process.execPath, [cli, ...args], opts)
|
|
520
|
+
else if (WIN) execFileSync('npm.cmd', args.map(a => `"${a}"`), { ...opts, shell: true })
|
|
521
|
+
else execFileSync('npm', args, opts)
|
|
516
522
|
log(`ccx atualizado: ${mine} → ${latest}`)
|
|
517
523
|
save({})
|
|
518
524
|
}
|
|
519
525
|
catch (e) {
|
|
520
|
-
|
|
526
|
+
// O motivo de verdade vem no fim do stderr do npm (ex.: EACCES, EPERM, ENOTFOUND)
|
|
527
|
+
const why = String(e.stderr ?? '').split(/\r?\n/).map(l => l.replace(/^npm (error|ERR!) ?/, '').trim()).filter(Boolean)
|
|
528
|
+
const msg = why.find(l => /^(code )?E[A-Z]+/.test(l)) ?? why.at(-1) ?? e.message.split('\n')[0]
|
|
521
529
|
log(`não consegui atualizar o ccx pra ${latest}: ${msg}`)
|
|
522
530
|
save({ error: msg })
|
|
523
531
|
}
|
|
@@ -669,9 +677,22 @@ function when(d) {
|
|
|
669
677
|
const dd = Math.floor(mins / 1440), hh = Math.floor((mins % 1440) / 60), mm = mins % 60
|
|
670
678
|
return dd ? `${dd}d ${hh}h` : hh ? `${hh}h${String(mm).padStart(2, '0')}` : `${mm}min`
|
|
671
679
|
}
|
|
680
|
+
// O servidor diz quem dá pra usar (available); app antigo não manda: vale como disponível
|
|
681
|
+
const usableNow = a => a.available !== false
|
|
682
|
+
// Conta no limite (97% ou mais, a regra do painel): vale o limite que estiver mais alto
|
|
683
|
+
function limitText(a) {
|
|
684
|
+
const week = (a.weekly_pct ?? 0) >= (a.five_hour_pct ?? 0)
|
|
685
|
+
const at = week ? a.weekly_resets_at : a.five_hour_resets_at
|
|
686
|
+
const d = at && new Date(at)
|
|
687
|
+
const back = !d ? '' : d.toDateString() === new Date().toDateString()
|
|
688
|
+
? ` · volta ${d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })}`
|
|
689
|
+
: ` · volta ${d.toLocaleDateString('pt-BR', { weekday: 'short' }).replace('.', '')} ${d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })}`
|
|
690
|
+
return `no limite ${week ? 'da semana' : 'da sessão de 5h'} (${week ? a.weekly_pct : a.five_hour_pct}%)${back}`
|
|
691
|
+
}
|
|
672
692
|
function line(a) {
|
|
673
693
|
const name = a.slug.padEnd(14)
|
|
674
694
|
if (a.five_hour_pct === null && a.weekly_pct === null) return `${name} ${c(90, a.status === 'ok' ? 'sem leitura ainda' : 'desconectada — avise um admin')}`
|
|
695
|
+
if (!usableNow(a) && (a.status === 'ok' || a.status === 'erro_leitura')) return `${name} ${c(31, limitText(a))}`
|
|
675
696
|
const at = s => s && new Date(s)
|
|
676
697
|
return `${name} 5h ${colorPct(a.five_hour_pct ?? 0).padEnd(isTTY ? 13 : 4)} (reinicia em ${when(at(a.five_hour_resets_at))}) semana ${colorPct(a.weekly_pct ?? 0).padEnd(isTTY ? 13 : 4)} (reinicia em ${when(at(a.weekly_resets_at))})`
|
|
677
698
|
}
|
|
@@ -734,15 +755,20 @@ async function chooseAccount(app, key) {
|
|
|
734
755
|
if (!list.length) die('Nenhuma conta liberada pra você. Peça a um admin.')
|
|
735
756
|
if (list.length === 1) return list[0].slug
|
|
736
757
|
if (!process.stdin.isTTY) return recommended ?? die('Nenhuma conta disponível agora.')
|
|
737
|
-
|
|
738
|
-
|
|
758
|
+
// Só as que dá pra usar ganham número; as no limite aparecem embaixo, sem número
|
|
759
|
+
const options = list.filter(usableNow)
|
|
760
|
+
const current = a => (a.id === app.account?.id ? c(90, ' (atual)') : '')
|
|
761
|
+
console.error(options.length ? 'Qual conta este computador deve usar?\n' : 'Nenhuma conta com folga agora.\n')
|
|
762
|
+
options.forEach((a, i) => console.error(` ${c(1, String(i + 1))} ${line(a)}${a.slug === recommended ? c(36, ' ← recomendada') : ''}${current(a)}`))
|
|
763
|
+
for (const a of list.filter(a => !usableNow(a))) console.error(` ${c(90, '–')} ${line(a)}${current(a)}`)
|
|
764
|
+
if (!options.length) die('\nPra usar uma delas mesmo assim: ccx <conta>')
|
|
739
765
|
const { createInterface } = await import('node:readline/promises')
|
|
740
766
|
const rl = createInterface({ input: process.stdin, output: process.stderr })
|
|
741
767
|
for (;;) {
|
|
742
768
|
const ans = (await rl.question(`\nNúmero${recommended ? ' (Enter = recomendada)' : ''}: `).catch(() => die('\nCancelado.'))).trim()
|
|
743
769
|
if (!ans && recommended) { rl.close(); return recommended }
|
|
744
770
|
const n = Number(ans)
|
|
745
|
-
if (Number.isInteger(n) && n >= 1 && n <=
|
|
771
|
+
if (Number.isInteger(n) && n >= 1 && n <= options.length) { rl.close(); return options[n - 1].slug }
|
|
746
772
|
console.error('Digite um dos números da lista.')
|
|
747
773
|
}
|
|
748
774
|
}
|