@zenifra/cli 0.2.5 → 0.2.6
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/README.md +36 -0
- package/bin/zenifra.mjs +175 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ zenifra valkey credentials status --project <project-id> --operation <operation-
|
|
|
72
72
|
zenifra project url --project <project-id>
|
|
73
73
|
zenifra project logs --project <project-id> --instance <instance-id>
|
|
74
74
|
zenifra project metrics --project <project-id> --instance <instance-id>
|
|
75
|
+
zenifra project metrics capabilities --project <project-id>
|
|
75
76
|
zenifra project network --project <project-id> --view summary
|
|
76
77
|
zenifra project image set --project <project-id> --image ghcr.io/zenifra/app:tag
|
|
77
78
|
zenifra project envs --project <project-id>
|
|
@@ -93,6 +94,41 @@ zenifra deploy --project <project-id> --branch main
|
|
|
93
94
|
zenifra deploy watch --project <project-id> --build <build-id>
|
|
94
95
|
```
|
|
95
96
|
|
|
97
|
+
## Metricas de projetos Valkey
|
|
98
|
+
|
|
99
|
+
O comando `zenifra project metrics` mostra as metricas do projeto e, para projetos Valkey, o snapshot da instancia selecionada:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
zenifra project metrics --project <project-id> --instance instance-1
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A saida legivel inclui:
|
|
106
|
+
|
|
107
|
+
- recursos: CPU e memoria da instancia;
|
|
108
|
+
- capacidade: memoria usada, pico, limite e fragmentacao;
|
|
109
|
+
- clientes conectados e bloqueados;
|
|
110
|
+
- atividade: operacoes por segundo e trafego de entrada/saida;
|
|
111
|
+
- ciclo de vida: chaves expiradas e removidas;
|
|
112
|
+
- uptime e perfil (`cache`, `key-value` ou `queue`);
|
|
113
|
+
- confiabilidade: replicacao e persistencia, quando disponiveis.
|
|
114
|
+
|
|
115
|
+
Perfis especificos podem incluir:
|
|
116
|
+
|
|
117
|
+
- `cache`: hits, misses e hit ratio;
|
|
118
|
+
- `key-value`: total de chaves e chaves com expiracao;
|
|
119
|
+
- `queue`: metricas comuns, sem estimar profundidade quando ela nao esta disponivel.
|
|
120
|
+
|
|
121
|
+
Para consultar o nivel de acesso e os grupos disponiveis antes de buscar um snapshot:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
zenifra project metrics capabilities --project <project-id>
|
|
125
|
+
zenifra project metrics capabilities --project <project-id> --json
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`--json` preserva a resposta publica da API. Valores ausentes sao exibidos como `indisponivel` no modo legivel; `0` continua sendo um valor valido. O historico nao esta disponivel neste momento.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
96
132
|
## Builds GitHub
|
|
97
133
|
|
|
98
134
|
Use `zenifra builds` para listar o historico de builds e `zenifra builds logs` para ler os logs do pipeline GitHub de um build especifico.
|
package/bin/zenifra.mjs
CHANGED
|
@@ -181,6 +181,7 @@ Usage:
|
|
|
181
181
|
zenifra project url --project <id> [--json]
|
|
182
182
|
zenifra project logs --project <id> [--instance <id>] [--json]
|
|
183
183
|
zenifra project metrics --project <id> [--instance <id>] [--json]
|
|
184
|
+
zenifra project metrics capabilities --project <id> [--json]
|
|
184
185
|
zenifra project network --project <id> [--view <summary|status-codes|routes|user-agents|request-events|source-ips>] [--json]
|
|
185
186
|
zenifra project image set --project <id> --image <image> [--json]
|
|
186
187
|
zenifra project exposure set --project <id> --exposure <public|private> [--json]
|
|
@@ -416,11 +417,11 @@ const HELP_SPECS = [
|
|
|
416
417
|
},
|
|
417
418
|
{
|
|
418
419
|
command: 'project',
|
|
419
|
-
usage: 'zenifra project\n zenifra project info --project <id> [--json]\n zenifra project url --project <id> [--json]\n zenifra project logs --project <id> [--instance <id>] [--json]\n zenifra project metrics --project <id> [--instance <id>] [--json]\n zenifra project network --project <id> [--view <summary|status-codes|routes|user-agents|request-events|source-ips>] [--json]\n zenifra project image set --project <id> --image <image> [--json]\n zenifra project exposure set --project <id> --exposure <public|private> [--json]\n zenifra project envs --project <id> [--json] [--show-values]\n zenifra project env add --project <id> --name <name> --value <value> [--json]\n zenifra project env update --project <id> --name <name> --value <value> [--json]\n zenifra project env remove --project <id> --name <name> [--json]\n zenifra project autoscaling --project <id> [--json]\n zenifra project autoscaling set --project <id> --min <n> --max <n> [--cpu <percent>] [--memory <percent>] [--json]\n zenifra project autoscaling disable --project <id> [--json]\n zenifra project autoscaling events --project <id> [--direction <scale_up|scale_down>] [--from <iso>] [--to <iso>] [--page <n>] [--limit <n>] [--json]\n zenifra project billing usage --project <id> [--from <iso>] [--to <iso>] [--page <n>] [--limit <n>] [--json]\n zenifra project instances --project <id> [--json]\n zenifra project instances set --project <id> --count <n> [--json]',
|
|
420
|
+
usage: 'zenifra project\n zenifra project info --project <id> [--json]\n zenifra project url --project <id> [--json]\n zenifra project logs --project <id> [--instance <id>] [--json]\n zenifra project metrics --project <id> [--instance <id>] [--json]\n zenifra project metrics capabilities --project <id> [--json]\n zenifra project network --project <id> [--view <summary|status-codes|routes|user-agents|request-events|source-ips>] [--json]\n zenifra project image set --project <id> --image <image> [--json]\n zenifra project exposure set --project <id> --exposure <public|private> [--json]\n zenifra project envs --project <id> [--json] [--show-values]\n zenifra project env add --project <id> --name <name> --value <value> [--json]\n zenifra project env update --project <id> --name <name> --value <value> [--json]\n zenifra project env remove --project <id> --name <name> [--json]\n zenifra project autoscaling --project <id> [--json]\n zenifra project autoscaling set --project <id> --min <n> --max <n> [--cpu <percent>] [--memory <percent>] [--json]\n zenifra project autoscaling disable --project <id> [--json]\n zenifra project autoscaling events --project <id> [--direction <scale_up|scale_down>] [--from <iso>] [--to <iso>] [--page <n>] [--limit <n>] [--json]\n zenifra project billing usage --project <id> [--from <iso>] [--to <iso>] [--page <n>] [--limit <n>] [--json]\n zenifra project instances --project <id> [--json]\n zenifra project instances set --project <id> --count <n> [--json]',
|
|
420
421
|
description: 'Agrupa comandos operacionais e de introspecao sobre um projeto especifico.',
|
|
421
422
|
examples: ['zenifra project', 'zenifra project info --project proj_1', 'zenifra project env add --project proj_1 --name NODE_ENV --value production'],
|
|
422
423
|
output: 'Zenifra CLI - project',
|
|
423
|
-
notes: ['Use "zenifra help project <subcomando>" para detalhes de info, url, logs, metrics, network, image, exposure, autoscaling, billing, envs e instances.'],
|
|
424
|
+
notes: ['Use "zenifra help project <subcomando>" para detalhes de info, url, logs, metrics, capabilities, network, image, exposure, autoscaling, billing, envs e instances.'],
|
|
424
425
|
},
|
|
425
426
|
{
|
|
426
427
|
command: 'project info',
|
|
@@ -453,11 +454,26 @@ const HELP_SPECS = [
|
|
|
453
454
|
{
|
|
454
455
|
command: 'project metrics',
|
|
455
456
|
usage: 'zenifra project metrics --project <id> [--instance <id>] [--json]',
|
|
456
|
-
description: 'Mostra
|
|
457
|
-
flags: ['--project <id> ID do projeto.', '--instance <id> Filtra uma instancia.', '--json Imprime a resposta em JSON.'],
|
|
458
|
-
examples: ['zenifra project metrics --project 507f1f77bcf86cd799439012 --instance web-1'],
|
|
459
|
-
output: '
|
|
460
|
-
jsonOutput: '{"type":"
|
|
457
|
+
description: 'Mostra metricas de recursos do projeto e, para Valkey, o snapshot nativo da instancia.',
|
|
458
|
+
flags: ['--project <id> ID do projeto.', '--instance <id> Filtra uma instancia.', '--json Imprime a resposta em JSON sem formatacao adicional.'],
|
|
459
|
+
examples: ['zenifra project metrics --project 507f1f77bcf86cd799439012 --instance web-1', 'zenifra project metrics --project 507f1f77bcf86cd799439012 --instance instance-1'],
|
|
460
|
+
output: 'Campo Valor\n---------- ----------------\nPerfil cache\nDisponibilidade available\nMemoria usada 100 MB',
|
|
461
|
+
jsonOutput: '{"instance":"instance-1","type":"valkey","availability":"available","valkey":{"schema_version":1,"profile":"cache","memory":{"used_bytes":104857600}}}',
|
|
462
|
+
notes: [
|
|
463
|
+
'Para projetos Valkey, a saida legivel inclui recursos, capacidade, clientes, atividade, ciclo de vida de chaves, perfil e confiabilidade.',
|
|
464
|
+
'Valores ausentes sao exibidos como indisponivel; zero continua sendo um valor valido.',
|
|
465
|
+
'Use "zenifra project metrics capabilities --project <id>" para consultar o acesso e os grupos de metricas disponiveis.',
|
|
466
|
+
],
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
command: 'project metrics capabilities',
|
|
470
|
+
usage: 'zenifra project metrics capabilities --project <id> [--json]',
|
|
471
|
+
description: 'Mostra os grupos de metricas e o nivel de acesso disponivel para o projeto.',
|
|
472
|
+
flags: ['--project <id> ID do projeto.', '--json Imprime a resposta em JSON.'],
|
|
473
|
+
examples: ['zenifra project metrics capabilities --project 507f1f77bcf86cd799439012'],
|
|
474
|
+
output: 'Campo Valor\n---------- ------------------------------------------------------------\nAcesso snapshot\nAtualizacao 60 s\nHistorico indisponivel',
|
|
475
|
+
jsonOutput: '{"access":"snapshot","groups":["resources","capacity","clients","activity","key_lifecycle","profile","reliability"],"refresh_seconds":60,"history":null}',
|
|
476
|
+
notes: ['A API permanece como fonte de autorizacao. A CLI nao mantem uma lista local de planos.'],
|
|
461
477
|
},
|
|
462
478
|
{
|
|
463
479
|
command: 'project network',
|
|
@@ -1486,6 +1502,9 @@ async function request(session, flags, method, path, {
|
|
|
1486
1502
|
if (response.status === 429 && Number.isFinite(Number(payload?.retry_after_seconds))) {
|
|
1487
1503
|
throw new CliError(`${message} Tente novamente em ${Number(payload.retry_after_seconds)} segundo(s).`);
|
|
1488
1504
|
}
|
|
1505
|
+
if (response.status === 402 && path.includes('/metrics') && /support metrics/i.test(String(message))) {
|
|
1506
|
+
throw new CliError('Este projeto nao possui acesso a metricas.');
|
|
1507
|
+
}
|
|
1489
1508
|
if (String(message).includes('missing x-organization-id')) {
|
|
1490
1509
|
throw new CliError('Organizacao nao selecionada. Rode "zenifra org set" ou use --org <id>.');
|
|
1491
1510
|
}
|
|
@@ -1526,6 +1545,128 @@ function printTable(rows, columns) {
|
|
|
1526
1545
|
}
|
|
1527
1546
|
}
|
|
1528
1547
|
|
|
1548
|
+
function formatValkeyNumber(value) {
|
|
1549
|
+
if (value === null || value === undefined || !Number.isFinite(Number(value))) return 'indisponivel';
|
|
1550
|
+
return String(value);
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
function formatValkeyBytes(value, suffix = '') {
|
|
1554
|
+
if (value === null || value === undefined || !Number.isFinite(Number(value))) return 'indisponivel';
|
|
1555
|
+
|
|
1556
|
+
const numericValue = Number(value);
|
|
1557
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
1558
|
+
let unitIndex = 0;
|
|
1559
|
+
let normalizedValue = numericValue;
|
|
1560
|
+
while (normalizedValue >= 1024 && unitIndex < units.length - 1) {
|
|
1561
|
+
normalizedValue /= 1024;
|
|
1562
|
+
unitIndex += 1;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
const digits = normalizedValue >= 100 ? 0 : normalizedValue >= 10 ? 1 : 2;
|
|
1566
|
+
const formattedValue = Number(normalizedValue.toFixed(digits)).toString();
|
|
1567
|
+
return `${formattedValue} ${units[unitIndex]}${suffix}`;
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
function formatValkeyPercent(value) {
|
|
1571
|
+
if (value === null || value === undefined || !Number.isFinite(Number(value))) return 'indisponivel';
|
|
1572
|
+
return `${Number((Number(value) * 100).toFixed(2))}%`;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
function valkeyMetricRows(metrics) {
|
|
1576
|
+
const native = metrics?.valkey;
|
|
1577
|
+
const rows = [
|
|
1578
|
+
{ field: 'Instancia', value: metrics?.instance || '-' },
|
|
1579
|
+
{ field: 'Disponibilidade', value: metrics?.availability || 'indisponivel' },
|
|
1580
|
+
{ field: 'Observado em', value: metrics?.observed_at || 'indisponivel' },
|
|
1581
|
+
{ field: 'CPU', value: formatValkeyNumber(metrics?.cpu) },
|
|
1582
|
+
{ field: 'Memoria', value: formatValkeyBytes(metrics?.memory) },
|
|
1583
|
+
];
|
|
1584
|
+
|
|
1585
|
+
if (!native) {
|
|
1586
|
+
rows.push({ field: 'Metricas Valkey', value: 'indisponivel' });
|
|
1587
|
+
return rows;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
rows.push(
|
|
1591
|
+
{ field: 'Perfil', value: native.profile || '-' },
|
|
1592
|
+
{ field: 'Memoria usada', value: formatValkeyBytes(native.memory?.used_bytes) },
|
|
1593
|
+
{ field: 'Pico de memoria', value: formatValkeyBytes(native.memory?.peak_bytes) },
|
|
1594
|
+
{ field: 'Limite de memoria', value: formatValkeyBytes(native.memory?.limit_bytes) },
|
|
1595
|
+
{ field: 'Fragmentacao', value: formatValkeyNumber(native.memory?.fragmentation_ratio) },
|
|
1596
|
+
{ field: 'Clientes conectados', value: formatValkeyNumber(native.clients?.connected) },
|
|
1597
|
+
{ field: 'Clientes bloqueados', value: formatValkeyNumber(native.clients?.blocked) },
|
|
1598
|
+
{ field: 'Operacoes por segundo', value: formatValkeyNumber(native.activity?.operations_per_second) },
|
|
1599
|
+
{ field: 'Entrada', value: formatValkeyBytes(native.activity?.input_bytes_per_second, '/s') },
|
|
1600
|
+
{ field: 'Saida', value: formatValkeyBytes(native.activity?.output_bytes_per_second, '/s') },
|
|
1601
|
+
{ field: 'Chaves expiradas', value: formatValkeyNumber(native.keys?.expired_total) },
|
|
1602
|
+
{ field: 'Chaves removidas', value: formatValkeyNumber(native.keys?.evicted_total) },
|
|
1603
|
+
{ field: 'Uptime', value: `${formatValkeyNumber(native.uptime_seconds)} s` },
|
|
1604
|
+
);
|
|
1605
|
+
|
|
1606
|
+
if (native.cache) {
|
|
1607
|
+
rows.push(
|
|
1608
|
+
{ field: 'Cache hits', value: formatValkeyNumber(native.cache.hits_total) },
|
|
1609
|
+
{ field: 'Cache misses', value: formatValkeyNumber(native.cache.misses_total) },
|
|
1610
|
+
{ field: 'Hit ratio', value: formatValkeyPercent(native.cache.hit_ratio) },
|
|
1611
|
+
);
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
if (native.key_value) {
|
|
1615
|
+
rows.push(
|
|
1616
|
+
{ field: 'Total de chaves', value: formatValkeyNumber(native.key_value.keys_total) },
|
|
1617
|
+
{ field: 'Chaves com expiracao', value: formatValkeyNumber(native.key_value.keys_with_expiration) },
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
if (native.reliability) {
|
|
1622
|
+
const replication = native.reliability.replication;
|
|
1623
|
+
const persistence = native.reliability.persistence;
|
|
1624
|
+
if (replication) {
|
|
1625
|
+
rows.push(
|
|
1626
|
+
{ field: 'Replicacao', value: replication.status || 'indisponivel' },
|
|
1627
|
+
{ field: 'Repl. disponiveis', value: formatValkeyNumber(replication.replicas_available) },
|
|
1628
|
+
{ field: 'Repl. esperadas', value: formatValkeyNumber(replication.replicas_expected) },
|
|
1629
|
+
{ field: 'Lag', value: replication.lag_seconds === null || replication.lag_seconds === undefined ? 'indisponivel' : `${replication.lag_seconds} s` },
|
|
1630
|
+
);
|
|
1631
|
+
}
|
|
1632
|
+
if (persistence) {
|
|
1633
|
+
rows.push(
|
|
1634
|
+
{ field: 'Persistencia', value: persistence.status || 'indisponivel' },
|
|
1635
|
+
{ field: 'Persistencia ativa', value: persistence.enabled === null || persistence.enabled === undefined ? 'indisponivel' : persistence.enabled ? 'sim' : 'nao' },
|
|
1636
|
+
{ field: 'Ultimo sucesso', value: persistence.last_success_at || 'indisponivel' },
|
|
1637
|
+
);
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
return rows;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
function printValkeyMetrics(metrics) {
|
|
1645
|
+
printTable(valkeyMetricRows(metrics), [
|
|
1646
|
+
{ label: 'Campo', value: (row) => row.field },
|
|
1647
|
+
{ label: 'Valor', value: (row) => row.value },
|
|
1648
|
+
]);
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
function printMetricsCapabilities(capabilities) {
|
|
1652
|
+
const groups = Array.isArray(capabilities?.groups) && capabilities.groups.length > 0
|
|
1653
|
+
? capabilities.groups.join(', ')
|
|
1654
|
+
: 'nenhum';
|
|
1655
|
+
const history = capabilities?.history
|
|
1656
|
+
? `${capabilities.history.retention_seconds} s de retencao`
|
|
1657
|
+
: 'indisponivel';
|
|
1658
|
+
|
|
1659
|
+
printTable([
|
|
1660
|
+
{ field: 'Acesso', value: capabilities?.access || 'indisponivel' },
|
|
1661
|
+
{ field: 'Grupos', value: groups },
|
|
1662
|
+
{ field: 'Atualizacao', value: capabilities?.refresh_seconds === null || capabilities?.refresh_seconds === undefined ? 'indisponivel' : `${capabilities.refresh_seconds} s` },
|
|
1663
|
+
{ field: 'Historico', value: history },
|
|
1664
|
+
], [
|
|
1665
|
+
{ label: 'Campo', value: (row) => row.field },
|
|
1666
|
+
{ label: 'Valor', value: (row) => row.value },
|
|
1667
|
+
]);
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1529
1670
|
function asArray(value) {
|
|
1530
1671
|
if (Array.isArray(value)) return value;
|
|
1531
1672
|
if (Array.isArray(value?.projects)) return value.projects;
|
|
@@ -2230,6 +2371,11 @@ function formatBrl(value) {
|
|
|
2230
2371
|
}).format(Number.isFinite(number) ? number : 0);
|
|
2231
2372
|
}
|
|
2232
2373
|
|
|
2374
|
+
function formatBrlFromCents(value) {
|
|
2375
|
+
const number = Number(value ?? 0);
|
|
2376
|
+
return formatBrl(Number.isFinite(number) ? number / 100 : 0);
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2233
2379
|
function humanizeStorageName(value) {
|
|
2234
2380
|
const raw = String(value || '').trim();
|
|
2235
2381
|
if (!raw) return { storage: '-', type: '-' };
|
|
@@ -2377,9 +2523,9 @@ function printPlansCatalogs(payload, type) {
|
|
|
2377
2523
|
process.stdout.write('HTTP\n');
|
|
2378
2524
|
printTable(asArray(payload.http), [
|
|
2379
2525
|
{ label: 'Plano', value: (plan) => plan.plan || '-' },
|
|
2380
|
-
{ label: 'Hora', value: (plan) =>
|
|
2381
|
-
{ label: 'Mes', value: (plan) =>
|
|
2382
|
-
{ label: 'Ano', value: (plan) =>
|
|
2526
|
+
{ label: 'Hora', value: (plan) => formatBrlFromCents(plan.prices?.hourly) },
|
|
2527
|
+
{ label: 'Mes', value: (plan) => formatBrlFromCents(plan.prices?.monthly) },
|
|
2528
|
+
{ label: 'Ano', value: (plan) => formatBrlFromCents(plan.prices?.yearly) },
|
|
2383
2529
|
{ label: 'Recursos', value: (plan) => asArray(plan.features).join(', ') || '-' },
|
|
2384
2530
|
]);
|
|
2385
2531
|
}
|
|
@@ -2389,9 +2535,9 @@ function printPlansCatalogs(payload, type) {
|
|
|
2389
2535
|
process.stdout.write('PostgreSQL / MariaDB\n');
|
|
2390
2536
|
printTable(asArray(payload.database), [
|
|
2391
2537
|
{ label: 'Plano', value: (plan) => plan.plan || '-' },
|
|
2392
|
-
{ label: 'Hora', value: (plan) =>
|
|
2393
|
-
{ label: 'Mes', value: (plan) =>
|
|
2394
|
-
{ label: 'Ano', value: (plan) =>
|
|
2538
|
+
{ label: 'Hora', value: (plan) => formatBrlFromCents(plan.prices?.hourly) },
|
|
2539
|
+
{ label: 'Mes', value: (plan) => formatBrlFromCents(plan.prices?.monthly) },
|
|
2540
|
+
{ label: 'Ano', value: (plan) => formatBrlFromCents(plan.prices?.yearly) },
|
|
2395
2541
|
{ label: 'Recursos', value: (plan) => asArray(plan.features).join(', ') || '-' },
|
|
2396
2542
|
]);
|
|
2397
2543
|
}
|
|
@@ -3281,6 +3427,16 @@ async function handleProjectLogs(session, flags) {
|
|
|
3281
3427
|
printLogs(logs, flags);
|
|
3282
3428
|
}
|
|
3283
3429
|
|
|
3430
|
+
async function handleProjectMetricsCapabilities(session, flags) {
|
|
3431
|
+
const projectId = requireProjectId(flags, 'project metrics capabilities');
|
|
3432
|
+
if (!projectId) return;
|
|
3433
|
+
const orgId = await resolveOrgId(session, flags);
|
|
3434
|
+
const capabilities = unwrapData(await request(session, flags, 'GET', `/project/${projectId}/metrics/capabilities`, { orgId }));
|
|
3435
|
+
|
|
3436
|
+
if (flags.json) return printJson(capabilities);
|
|
3437
|
+
printMetricsCapabilities(capabilities);
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3284
3440
|
async function handleProjectMetrics(session, flags) {
|
|
3285
3441
|
const projectId = requireProjectId(flags, 'project metrics');
|
|
3286
3442
|
if (!projectId) return
|
|
@@ -3289,6 +3445,9 @@ async function handleProjectMetrics(session, flags) {
|
|
|
3289
3445
|
const metrics = unwrapData(await request(session, flags, 'GET', `/project/${projectId}/metrics${query}`, { orgId }));
|
|
3290
3446
|
|
|
3291
3447
|
if (flags.json) return printJson(metrics);
|
|
3448
|
+
if (metrics?.type === 'valkey') {
|
|
3449
|
+
return printValkeyMetrics(metrics);
|
|
3450
|
+
}
|
|
3292
3451
|
if (Array.isArray(metrics)) {
|
|
3293
3452
|
return printTable(metrics, [
|
|
3294
3453
|
{ label: 'Instancia', value: (metric) => metric.instance || '-' },
|
|
@@ -4038,7 +4197,7 @@ async function main() {
|
|
|
4038
4197
|
return;
|
|
4039
4198
|
}
|
|
4040
4199
|
|
|
4041
|
-
if (command === 'auth' && subcommand === 'login') return handleLogin(session, flags);
|
|
4200
|
+
if (command === 'auth' && subcommand === 'login') return await handleLogin(session, flags);
|
|
4042
4201
|
if (command === 'auth' && subcommand === 'api-key') return handleApiKeyLogin(session, flags);
|
|
4043
4202
|
if (command === 'auth' && subcommand === 'logout') return handleLogout(session, flags);
|
|
4044
4203
|
if (command === 'profile' && subcommand === 'list') return handleProfileList(session, flags);
|
|
@@ -4047,7 +4206,7 @@ async function main() {
|
|
|
4047
4206
|
if (command === 'profile' && subcommand === 'edit') return handleProfileEdit(session, flags, positional);
|
|
4048
4207
|
if (command === 'profile' && subcommand === 'use') return handleProfileUse(session, flags, positional);
|
|
4049
4208
|
if (command === 'profile' && subcommand === 'remove') return handleProfileRemove(session, flags, positional);
|
|
4050
|
-
if (command === 'login') return handleLogin(session, flags);
|
|
4209
|
+
if (command === 'login') return await handleLogin(session, flags);
|
|
4051
4210
|
if (command === 'logout') return handleLogout(session, flags);
|
|
4052
4211
|
if (command === 'plans') return handlePlans(session, flags);
|
|
4053
4212
|
if (command === 'create' && subcommand === 'project') return handleProjectCreate(session, flags);
|
|
@@ -4065,6 +4224,7 @@ async function main() {
|
|
|
4065
4224
|
if (command === 'project' && subcommand === 'info') return handleProjectInfo(session, flags);
|
|
4066
4225
|
if (command === 'project' && subcommand === 'url') return handleProjectUrl(session, flags);
|
|
4067
4226
|
if (command === 'project' && subcommand === 'logs') return handleProjectLogs(session, flags);
|
|
4227
|
+
if (command === 'project' && subcommand === 'metrics' && positional[2] === 'capabilities') return handleProjectMetricsCapabilities(session, flags);
|
|
4068
4228
|
if (command === 'project' && subcommand === 'metrics') return handleProjectMetrics(session, flags);
|
|
4069
4229
|
if (command === 'project' && subcommand === 'network') return handleProjectNetwork(session, flags);
|
|
4070
4230
|
if (command === 'project' && subcommand === 'image' && positional[2] === 'set') return handleProjectImageSet(session, flags);
|