onveloz 0.0.0-beta.33 → 0.0.0-beta.36
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as statusLabels, i as TERMINAL_STATUSES, m as success, n as isHiddenMessage, o as getClient, p as info, r as parseBuildLine, t as cleanDisplayLine } from "./index.mjs";
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { Box, Static, Text, render, useApp } from "ink";
|
|
@@ -9,12 +9,12 @@ const TIMESTAMP_RE = /^\[(\d{4}-\d{2}-\d{2}T[\d:.]+Z)\]\s*/;
|
|
|
9
9
|
const STEP_PREFIX_RE = /^#(\d+)\s+(.*)/;
|
|
10
10
|
const TIMING_PREFIX_RE = /^(\d+\.\d+)\s*(.*)/;
|
|
11
11
|
const DONE_RE = /^DONE\s+([\d.]+s?)$/;
|
|
12
|
-
const STAGE_RE = /^\[([\w-]+)\s+(\d+)\/\d+\]/;
|
|
12
|
+
const STAGE_RE = /^\[\s*(?:([\w-]+)\s+)?(\d+)\/\d+\]/;
|
|
13
13
|
function parseStageInfo(title) {
|
|
14
14
|
const match = title.match(STAGE_RE);
|
|
15
15
|
if (!match) return null;
|
|
16
16
|
return {
|
|
17
|
-
stage: match[1].toLowerCase(),
|
|
17
|
+
stage: (match[1] ?? "").toLowerCase(),
|
|
18
18
|
substep: parseInt(match[2], 10)
|
|
19
19
|
};
|
|
20
20
|
}
|
|
@@ -32,9 +32,9 @@ const PRE_START_HEADER_RE = /^──\s*Logs do comando pre-start/;
|
|
|
32
32
|
/** Matches the pre-start unavailable message. */
|
|
33
33
|
const PRE_START_UNAVAILABLE_RE = /^──\s*Logs do comando pre-start indisponíveis/;
|
|
34
34
|
/** Matches the crash log section header written by the reconciler. */
|
|
35
|
-
const CRASH_LOG_HEADER_RE = /^──\s*Logs do container \(crash\)/;
|
|
35
|
+
const CRASH_LOG_HEADER_RE = /^──\s*Logs do (?:serviço \(falha\)|container \(crash\))/;
|
|
36
36
|
/** Matches the crash logs unavailable message. */
|
|
37
|
-
const CRASH_LOG_UNAVAILABLE_RE = /^──\s*Logs do container indisponíveis/;
|
|
37
|
+
const CRASH_LOG_UNAVAILABLE_RE = /^──\s*Logs do (?:serviço|container) indisponíveis/;
|
|
38
38
|
/** Lines that mark the beginning of the deploy/rollout phase. */
|
|
39
39
|
const DEPLOY_PHASE_MARKERS = [
|
|
40
40
|
/^Realizando deploy/,
|
|
@@ -175,16 +175,16 @@ function parseBuildSteps(rawText) {
|
|
|
175
175
|
const stageOrder = buildStageOrder(numberedWithIndex.map((n) => n.step));
|
|
176
176
|
numberedWithIndex.sort((a, b) => {
|
|
177
177
|
if (a.step.phase !== b.step.phase) return a.step.phase - b.step.phase;
|
|
178
|
-
if (a.step.startedAt && b.step.startedAt) {
|
|
179
|
-
const tsDiff = new Date(a.step.startedAt).getTime() - new Date(b.step.startedAt).getTime();
|
|
180
|
-
if (tsDiff !== 0) return tsDiff;
|
|
181
|
-
}
|
|
182
178
|
const aInfo = parseStageInfo(a.step.title);
|
|
183
179
|
const bInfo = parseStageInfo(b.step.title);
|
|
184
180
|
const aOrder = aInfo ? stageOrder.get(aInfo.stage) ?? 99 : 99;
|
|
185
181
|
const bOrder = bInfo ? stageOrder.get(bInfo.stage) ?? 99 : 99;
|
|
186
182
|
if (aOrder !== bOrder) return aOrder - bOrder;
|
|
187
|
-
|
|
183
|
+
const aSubstep = aInfo?.substep ?? a.step.stepNumber ?? 0;
|
|
184
|
+
const bSubstep = bInfo?.substep ?? b.step.stepNumber ?? 0;
|
|
185
|
+
if (aSubstep !== bSubstep) return aSubstep - bSubstep;
|
|
186
|
+
if (a.step.startedAt && b.step.startedAt) return new Date(a.step.startedAt).getTime() - new Date(b.step.startedAt).getTime();
|
|
187
|
+
return 0;
|
|
188
188
|
});
|
|
189
189
|
const result = [];
|
|
190
190
|
let nIdx = 0;
|
package/dist/index.mjs
CHANGED
|
@@ -222,32 +222,32 @@ const SERVICE_SIZES = {
|
|
|
222
222
|
};
|
|
223
223
|
const SERVICE_SIZE_KEYS = Object.keys(SERVICE_SIZES);
|
|
224
224
|
const HOURS_PER_MONTH = 720;
|
|
225
|
-
/** Service monthly prices in cents. */
|
|
225
|
+
/** Service monthly prices in cents. Magalu Cloud base + 10% margin. */
|
|
226
226
|
const SERVICE_MONTHLY_PRICES = {
|
|
227
|
-
basico:
|
|
228
|
-
essencial:
|
|
229
|
-
turbo:
|
|
230
|
-
"turbo-plus":
|
|
231
|
-
nitro:
|
|
232
|
-
"nitro-plus":
|
|
227
|
+
basico: 500,
|
|
228
|
+
essencial: 2e3,
|
|
229
|
+
turbo: 4e3,
|
|
230
|
+
"turbo-plus": 7e3,
|
|
231
|
+
nitro: 9500,
|
|
232
|
+
"nitro-plus": 17e3
|
|
233
233
|
};
|
|
234
|
-
/** Disk-based DB monthly prices in cents
|
|
234
|
+
/** Disk-based DB monthly prices in cents. Service price + 15% managed premium. */
|
|
235
235
|
const DATABASE_MONTHLY_PRICES = {
|
|
236
|
-
basico:
|
|
237
|
-
essencial:
|
|
238
|
-
turbo:
|
|
239
|
-
"turbo-plus":
|
|
240
|
-
nitro:
|
|
241
|
-
"nitro-plus":
|
|
236
|
+
basico: 600,
|
|
237
|
+
essencial: 2300,
|
|
238
|
+
turbo: 4600,
|
|
239
|
+
"turbo-plus": 8e3,
|
|
240
|
+
nitro: 11e3,
|
|
241
|
+
"nitro-plus": 19500
|
|
242
242
|
};
|
|
243
|
-
/** Redis monthly prices in cents. */
|
|
243
|
+
/** Redis monthly prices in cents. Matches disk-DB pricing. */
|
|
244
244
|
const REDIS_MONTHLY_PRICES = {
|
|
245
|
-
basico:
|
|
246
|
-
essencial:
|
|
247
|
-
turbo:
|
|
248
|
-
"turbo-plus":
|
|
249
|
-
nitro:
|
|
250
|
-
"nitro-plus":
|
|
245
|
+
basico: 600,
|
|
246
|
+
essencial: 2300,
|
|
247
|
+
turbo: 4600,
|
|
248
|
+
"turbo-plus": 8e3,
|
|
249
|
+
nitro: 11e3,
|
|
250
|
+
"nitro-plus": 19500
|
|
251
251
|
};
|
|
252
252
|
/** Hourly rates derived from monthly prices (cents per instance per hour). */
|
|
253
253
|
const SERVICE_HOURLY_RATES = Object.fromEntries(Object.entries(SERVICE_MONTHLY_PRICES).map(([k, v]) => [k, v / HOURS_PER_MONTH]));
|
|
@@ -292,6 +292,18 @@ const PROJECT_FLAG_DEFINITIONS = {
|
|
|
292
292
|
shield: {
|
|
293
293
|
label: "Shield",
|
|
294
294
|
description: "Auditoria de segurança automática (Veloz Shield) a cada deploy. Detecta Supabase e executa verificações de RLS, secrets e HTTP."
|
|
295
|
+
},
|
|
296
|
+
multiProvider: {
|
|
297
|
+
label: "Multi-Provider",
|
|
298
|
+
description: "Roteia este projeto pela nova arquitetura multi-provider (agent + DesiredState + build como Job). Desligado = pipeline atual (reconciler + workers)."
|
|
299
|
+
},
|
|
300
|
+
blobStorage: {
|
|
301
|
+
label: "Blob Storage + CDN",
|
|
302
|
+
description: "Armazenamento de arquivos estáticos com CDN via Cloudflare R2 + Worker"
|
|
303
|
+
},
|
|
304
|
+
imageOptimization: {
|
|
305
|
+
label: "Otimização de imagens",
|
|
306
|
+
description: "Otimização de imagens em /_next/image (AVIF/WebP, redimensionamento). Aplica-se aos domínios verificados deste projeto."
|
|
295
307
|
}
|
|
296
308
|
};
|
|
297
309
|
const PROJECT_FLAG_KEYS = Object.keys(PROJECT_FLAG_DEFINITIONS);
|
|
@@ -598,7 +610,7 @@ const LOWERCASE_SIZE_KEYS = DATABASE_SIZE_KEYS.map((k) => k);
|
|
|
598
610
|
const DatabaseSizeSchema = z$1.enum(LOWERCASE_SIZE_KEYS);
|
|
599
611
|
const DatabaseConfigSchema = z$1.object({
|
|
600
612
|
id: z$1.string().optional(),
|
|
601
|
-
name: z$1.string().optional(),
|
|
613
|
+
name: z$1.string().max(63).regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/).optional(),
|
|
602
614
|
engine: z$1.enum([
|
|
603
615
|
"postgresql",
|
|
604
616
|
"mysql",
|
|
@@ -607,6 +619,7 @@ const DatabaseConfigSchema = z$1.object({
|
|
|
607
619
|
version: z$1.string().optional(),
|
|
608
620
|
storage: z$1.string().regex(/^[0-9]+(Gi)$/).refine((val) => Number.parseInt(val, 10) >= 10, "Tamanho mínimo de storage é 10Gi").optional(),
|
|
609
621
|
size: DatabaseSizeSchema.optional(),
|
|
622
|
+
insightsEnabled: z$1.boolean().optional(),
|
|
610
623
|
pooler: PoolerConfigSchema.optional(),
|
|
611
624
|
fromTemplate: z$1.string().optional()
|
|
612
625
|
});
|
|
@@ -1260,7 +1273,7 @@ async function requireAuth(options) {
|
|
|
1260
1273
|
|
|
1261
1274
|
//#endregion
|
|
1262
1275
|
//#region src/lib/client.ts
|
|
1263
|
-
const CLI_VERSION = "0.0.0-beta.
|
|
1276
|
+
const CLI_VERSION = "0.0.0-beta.36";
|
|
1264
1277
|
const USER_AGENT = `veloz-cli/${CLI_VERSION}`;
|
|
1265
1278
|
/**
|
|
1266
1279
|
* Client source — "cli" by default; the init wizard sets this to "cli-wizard"
|
|
@@ -1299,7 +1312,14 @@ async function getAuthHeaders() {
|
|
|
1299
1312
|
}
|
|
1300
1313
|
async function getClient() {
|
|
1301
1314
|
const authConfig = await requireAuth();
|
|
1302
|
-
return createClient(authConfig.apiUrl, () =>
|
|
1315
|
+
return createClient(authConfig.apiUrl, () => {
|
|
1316
|
+
const fresh = loadConfig();
|
|
1317
|
+
return buildVelozHeaders({
|
|
1318
|
+
apiKey: authConfig.apiKey,
|
|
1319
|
+
apiUrl: authConfig.apiUrl,
|
|
1320
|
+
organizationId: fresh.organizationId ?? authConfig.organizationId
|
|
1321
|
+
});
|
|
1322
|
+
});
|
|
1303
1323
|
}
|
|
1304
1324
|
|
|
1305
1325
|
//#endregion
|
|
@@ -1322,7 +1342,7 @@ const requireAuth$1 = middleware(async (c, next) => {
|
|
|
1322
1342
|
description: "Autenticar na plataforma"
|
|
1323
1343
|
}] }
|
|
1324
1344
|
});
|
|
1325
|
-
const { performLogin: performLogin$1 } = await import("./login-
|
|
1345
|
+
const { performLogin: performLogin$1 } = await import("./login-BXY4HXAt.mjs");
|
|
1326
1346
|
await performLogin$1();
|
|
1327
1347
|
}
|
|
1328
1348
|
await next();
|
|
@@ -1440,6 +1460,32 @@ orgsGroup.command("use", {
|
|
|
1440
1460
|
//#endregion
|
|
1441
1461
|
//#region src/lib/org-resolver.ts
|
|
1442
1462
|
/**
|
|
1463
|
+
* Server emits `ORG_MISMATCH` (FORBIDDEN with `data.code === "ORG_MISMATCH"`)
|
|
1464
|
+
* when the X-Organization-Id header points at a different org than the
|
|
1465
|
+
* resource's owning org AND the user is a verified member of that target org
|
|
1466
|
+
* (see `packages/api/src/lib/ownership.ts:throwOrgMismatch`). The error data
|
|
1467
|
+
* carries the correct `organizationId` so the CLI can switch transparently.
|
|
1468
|
+
*/
|
|
1469
|
+
function isOrgMismatchError(error) {
|
|
1470
|
+
if (!(error instanceof Error)) return false;
|
|
1471
|
+
const e = error;
|
|
1472
|
+
return e.data?.code === "ORG_MISMATCH" && typeof e.data?.organizationId === "string";
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Persist the org id surfaced by an `ORG_MISMATCH` error and notify the user.
|
|
1476
|
+
* Returns the new org id so callers can decide whether to retry. Trusts the
|
|
1477
|
+
* server's membership check — no extra round-trip required.
|
|
1478
|
+
*/
|
|
1479
|
+
function applyOrgMismatchSwitch(error) {
|
|
1480
|
+
if (!isOrgMismatchError(error)) return null;
|
|
1481
|
+
const targetOrgId = error.data?.organizationId;
|
|
1482
|
+
if (!targetOrgId) return null;
|
|
1483
|
+
if (loadConfig().organizationId === targetOrgId) return null;
|
|
1484
|
+
saveConfig({ organizationId: targetOrgId });
|
|
1485
|
+
info(`Workspace alterado automaticamente para o dono deste recurso (${chalk.dim(targetOrgId)}).`);
|
|
1486
|
+
return targetOrgId;
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
1443
1489
|
* Ensure an active organization is selected for the current CLI session.
|
|
1444
1490
|
*
|
|
1445
1491
|
* Short-circuits when:
|
|
@@ -2167,6 +2213,25 @@ const tlsStatusLabels = {
|
|
|
2167
2213
|
ACTIVE: "Ativo",
|
|
2168
2214
|
FAILED: "Falhou"
|
|
2169
2215
|
};
|
|
2216
|
+
const purposeLabels = {
|
|
2217
|
+
traffic: "tráfego",
|
|
2218
|
+
ownership: "validação de propriedade",
|
|
2219
|
+
ssl: "validação de SSL"
|
|
2220
|
+
};
|
|
2221
|
+
function printDnsRecords(records) {
|
|
2222
|
+
if (records.length === 0) return;
|
|
2223
|
+
console.log();
|
|
2224
|
+
console.log(chalk.yellow.bold(" Registros DNS a publicar:"));
|
|
2225
|
+
for (const r of records) {
|
|
2226
|
+
const label = purposeLabels[r.purpose] ?? r.purpose;
|
|
2227
|
+
console.log(` ${chalk.cyan(r.type.padEnd(5))} ${chalk.white(r.name)} → ${chalk.white(r.value)} ${chalk.dim(`(${label})`)}`);
|
|
2228
|
+
}
|
|
2229
|
+
if (records.some((r) => r.type === "TXT")) {
|
|
2230
|
+
console.log();
|
|
2231
|
+
console.log(chalk.dim(" TXT são obrigatórios para curingas (propriedade da zona + SSL DV)."));
|
|
2232
|
+
}
|
|
2233
|
+
console.log();
|
|
2234
|
+
}
|
|
2170
2235
|
const domainsGroup = Cli.create("domains", { description: "Gerenciar domínios personalizados" });
|
|
2171
2236
|
domainsGroup.command("list", {
|
|
2172
2237
|
description: "Listar domínios dos serviços",
|
|
@@ -2181,7 +2246,17 @@ domainsGroup.command("list", {
|
|
|
2181
2246
|
id: z.string(),
|
|
2182
2247
|
domain: z.string(),
|
|
2183
2248
|
tlsStatus: z.string(),
|
|
2184
|
-
isAutoGenerated: z.boolean()
|
|
2249
|
+
isAutoGenerated: z.boolean(),
|
|
2250
|
+
dnsRecords: z.array(z.object({
|
|
2251
|
+
type: z.enum(["CNAME", "TXT"]),
|
|
2252
|
+
name: z.string(),
|
|
2253
|
+
value: z.string(),
|
|
2254
|
+
purpose: z.enum([
|
|
2255
|
+
"traffic",
|
|
2256
|
+
"ownership",
|
|
2257
|
+
"ssl"
|
|
2258
|
+
])
|
|
2259
|
+
})).default([])
|
|
2185
2260
|
}))
|
|
2186
2261
|
})) }),
|
|
2187
2262
|
async run(c) {
|
|
@@ -2203,14 +2278,19 @@ domainsGroup.command("list", {
|
|
|
2203
2278
|
});
|
|
2204
2279
|
continue;
|
|
2205
2280
|
}
|
|
2206
|
-
for (const d of domains)
|
|
2281
|
+
for (const d of domains) {
|
|
2282
|
+
console.log(` ${d.id} ${chalk.bold(d.domain)} ${tlsStatusLabels[d.tlsStatus] ?? d.tlsStatus} ${d.isAutoGenerated ? "Auto" : "Personalizado"}`);
|
|
2283
|
+
const records = d.dnsRecords ?? [];
|
|
2284
|
+
if (!d.isAutoGenerated && d.tlsStatus !== "ACTIVE" && records.length > 0) printDnsRecords(records);
|
|
2285
|
+
}
|
|
2207
2286
|
result$2.push({
|
|
2208
2287
|
serviceName: service$2.name,
|
|
2209
2288
|
domains: domains.map((d) => ({
|
|
2210
2289
|
id: d.id,
|
|
2211
2290
|
domain: d.domain,
|
|
2212
2291
|
tlsStatus: d.tlsStatus,
|
|
2213
|
-
isAutoGenerated: d.isAutoGenerated
|
|
2292
|
+
isAutoGenerated: d.isAutoGenerated,
|
|
2293
|
+
dnsRecords: d.dnsRecords ?? []
|
|
2214
2294
|
}))
|
|
2215
2295
|
});
|
|
2216
2296
|
}
|
|
@@ -2238,14 +2318,12 @@ domainsGroup.command("add", {
|
|
|
2238
2318
|
})
|
|
2239
2319
|
});
|
|
2240
2320
|
success(`Domínio ${chalk.bold(c.args.dominio)} adicionado com sucesso!`);
|
|
2241
|
-
|
|
2242
|
-
console.log(chalk.yellow.bold(" Instruções de DNS:"));
|
|
2243
|
-
console.log(chalk.white(` ${result$2.dnsInstruction}`));
|
|
2244
|
-
console.log();
|
|
2321
|
+
printDnsRecords(result$2.dnsRecords ?? []);
|
|
2245
2322
|
return c.ok({
|
|
2246
2323
|
id: result$2.id,
|
|
2247
2324
|
domain: c.args.dominio,
|
|
2248
|
-
dnsInstruction: result$2.dnsInstruction
|
|
2325
|
+
dnsInstruction: result$2.dnsInstruction,
|
|
2326
|
+
dnsRecords: result$2.dnsRecords ?? []
|
|
2249
2327
|
}, { cta: { commands: [{
|
|
2250
2328
|
command: `domains verify ${result$2.id}`,
|
|
2251
2329
|
description: "Verificar configuração DNS"
|
|
@@ -2268,15 +2346,114 @@ domainsGroup.command("verify", {
|
|
|
2268
2346
|
if (result$2.ready) success(`Domínio ${chalk.bold(result$2.domain.domain)} com TLS ativo!`);
|
|
2269
2347
|
else {
|
|
2270
2348
|
console.log(chalk.yellow(`\n⚠ Certificado TLS de ${chalk.bold(result$2.domain.domain)} ainda sendo provisionado.`));
|
|
2271
|
-
|
|
2349
|
+
const records = result$2.domain.dnsRecords ?? [];
|
|
2350
|
+
if (records.length > 0) {
|
|
2351
|
+
info("Confirme que os registros DNS abaixo estão publicados:");
|
|
2352
|
+
printDnsRecords(records);
|
|
2353
|
+
} else info("Rode `veloz domains list` para ver os registros DNS esperados.");
|
|
2272
2354
|
}
|
|
2273
2355
|
return {
|
|
2274
2356
|
ready: result$2.ready,
|
|
2275
2357
|
domain: result$2.domain.domain,
|
|
2276
|
-
tlsStatus: result$2.domain.tlsStatus
|
|
2358
|
+
tlsStatus: result$2.domain.tlsStatus,
|
|
2359
|
+
dnsRecords: result$2.domain.dnsRecords ?? []
|
|
2360
|
+
};
|
|
2361
|
+
}
|
|
2362
|
+
});
|
|
2363
|
+
domainsGroup.command("search", {
|
|
2364
|
+
description: "Buscar domínios disponíveis para registro",
|
|
2365
|
+
middleware: [requireAuth$1],
|
|
2366
|
+
args: z.object({ query: z.string().describe("Nome do domínio a buscar (ex: meusite)") }),
|
|
2367
|
+
output: z.array(z.object({
|
|
2368
|
+
domain: z.string(),
|
|
2369
|
+
available: z.boolean()
|
|
2370
|
+
})),
|
|
2371
|
+
async run(c) {
|
|
2372
|
+
const client = await getClient();
|
|
2373
|
+
const results = await withSpinner({
|
|
2374
|
+
text: "Buscando domínios...",
|
|
2375
|
+
fn: () => client.domains.search({ query: c.args.query })
|
|
2376
|
+
});
|
|
2377
|
+
if (results.length === 0) {
|
|
2378
|
+
info("Nenhum resultado encontrado.");
|
|
2379
|
+
return [];
|
|
2380
|
+
}
|
|
2381
|
+
for (const r of results) {
|
|
2382
|
+
const status = r.available ? chalk.green("Disponível") : chalk.red("Indisponível");
|
|
2383
|
+
console.log(` ${chalk.bold(r.domain.padEnd(30))} ${status}`);
|
|
2384
|
+
}
|
|
2385
|
+
return results;
|
|
2386
|
+
}
|
|
2387
|
+
});
|
|
2388
|
+
domainsGroup.command("buy", {
|
|
2389
|
+
description: "Registrar um domínio",
|
|
2390
|
+
middleware: [requireAuth$1],
|
|
2391
|
+
args: z.object({ dominio: z.string().describe("Domínio a registrar (ex: meusite.com)") }),
|
|
2392
|
+
options: z.object({ service: z.string().optional().describe("Conectar ao serviço automaticamente") }),
|
|
2393
|
+
output: z.object({
|
|
2394
|
+
id: z.string(),
|
|
2395
|
+
domain: z.string(),
|
|
2396
|
+
status: z.string()
|
|
2397
|
+
}),
|
|
2398
|
+
async run(c) {
|
|
2399
|
+
const client = await getClient();
|
|
2400
|
+
const serviceId = c.options.service ? await resolveServiceId(c.options.service) : void 0;
|
|
2401
|
+
const result$2 = await withSpinner({
|
|
2402
|
+
text: `Registrando ${chalk.bold(c.args.dominio)}...`,
|
|
2403
|
+
fn: () => client.domains.register({
|
|
2404
|
+
domain: c.args.dominio,
|
|
2405
|
+
serviceId
|
|
2406
|
+
})
|
|
2407
|
+
});
|
|
2408
|
+
success(`Domínio ${chalk.bold(c.args.dominio)} registrado com sucesso!`);
|
|
2409
|
+
if (serviceId) success("DNS configurado e domínio conectado ao serviço automaticamente.");
|
|
2410
|
+
else info(`Para conectar a um serviço: ${chalk.bold(`veloz domains add ${c.args.dominio} --service <nome>`)}`);
|
|
2411
|
+
return {
|
|
2412
|
+
id: result$2.id,
|
|
2413
|
+
domain: result$2.domain,
|
|
2414
|
+
status: result$2.status
|
|
2277
2415
|
};
|
|
2278
2416
|
}
|
|
2279
2417
|
});
|
|
2418
|
+
domainsGroup.command("purchased", {
|
|
2419
|
+
description: "Listar domínios registrados",
|
|
2420
|
+
middleware: [requireAuth$1],
|
|
2421
|
+
output: z.array(z.object({
|
|
2422
|
+
id: z.string(),
|
|
2423
|
+
domain: z.string(),
|
|
2424
|
+
status: z.string(),
|
|
2425
|
+
expiresAt: z.string().nullable()
|
|
2426
|
+
})),
|
|
2427
|
+
async run() {
|
|
2428
|
+
const client = await getClient();
|
|
2429
|
+
const purchased = await withSpinner({
|
|
2430
|
+
text: "Carregando domínios registrados...",
|
|
2431
|
+
fn: () => client.domains.listPurchased({})
|
|
2432
|
+
});
|
|
2433
|
+
if (purchased.length === 0) {
|
|
2434
|
+
info("Nenhum domínio registrado.");
|
|
2435
|
+
return [];
|
|
2436
|
+
}
|
|
2437
|
+
const statusLabels$1 = {
|
|
2438
|
+
REGISTERING: chalk.yellow("Registrando"),
|
|
2439
|
+
PROPAGATING: chalk.yellow("Propagando DNS"),
|
|
2440
|
+
ACTIVE: chalk.green("Ativo"),
|
|
2441
|
+
FAILED: chalk.red("Falhou"),
|
|
2442
|
+
EXPIRED: chalk.red("Expirado")
|
|
2443
|
+
};
|
|
2444
|
+
for (const d of purchased) {
|
|
2445
|
+
const status = statusLabels$1[d.status] ?? d.status;
|
|
2446
|
+
const expires = d.expiresAt ? new Date(d.expiresAt).toLocaleDateString("pt-BR") : "—";
|
|
2447
|
+
console.log(` ${d.id} ${chalk.bold(d.domain.padEnd(30))} ${status} Expira: ${expires}`);
|
|
2448
|
+
}
|
|
2449
|
+
return purchased.map((d) => ({
|
|
2450
|
+
id: d.id,
|
|
2451
|
+
domain: d.domain,
|
|
2452
|
+
status: d.status,
|
|
2453
|
+
expiresAt: d.expiresAt ? new Date(d.expiresAt).toISOString() : null
|
|
2454
|
+
}));
|
|
2455
|
+
}
|
|
2456
|
+
});
|
|
2280
2457
|
domainsGroup.command("delete", {
|
|
2281
2458
|
description: "Remover domínio",
|
|
2282
2459
|
middleware: [requireAuth$1],
|
|
@@ -5056,22 +5233,6 @@ githubGroup.command("setup", {
|
|
|
5056
5233
|
const s = spinner("Verificando instalação do GitHub App...");
|
|
5057
5234
|
const installation = await client.github.getInstallation({ owner: remote.owner });
|
|
5058
5235
|
s.stop();
|
|
5059
|
-
if (installation.error === "TOKEN_EXPIRED") {
|
|
5060
|
-
warn("Token do GitHub expirado. Faça login novamente no dashboard para reconectar sua conta GitHub.");
|
|
5061
|
-
return {
|
|
5062
|
-
connected: false,
|
|
5063
|
-
installationId: null,
|
|
5064
|
-
projectId
|
|
5065
|
-
};
|
|
5066
|
-
}
|
|
5067
|
-
if (installation.error === "RATE_LIMITED") {
|
|
5068
|
-
warn("Limite de requisições do GitHub atingido. Aguarde alguns minutos e tente novamente.");
|
|
5069
|
-
return {
|
|
5070
|
-
connected: false,
|
|
5071
|
-
installationId: null,
|
|
5072
|
-
projectId
|
|
5073
|
-
};
|
|
5074
|
-
}
|
|
5075
5236
|
if (installation.installed && installation.installationId) {
|
|
5076
5237
|
info(`GitHub App já instalado para ${chalk.bold(remote.owner)}.`);
|
|
5077
5238
|
await client.projects.connectRepo({
|
|
@@ -5134,14 +5295,6 @@ githubGroup.command("setup", {
|
|
|
5134
5295
|
installationId = check.installationId;
|
|
5135
5296
|
break;
|
|
5136
5297
|
}
|
|
5137
|
-
if (check.error === "TOKEN_EXPIRED") {
|
|
5138
|
-
pollSpinner.fail("Token do GitHub expirou durante a espera.");
|
|
5139
|
-
return {
|
|
5140
|
-
connected: false,
|
|
5141
|
-
installationId: null,
|
|
5142
|
-
projectId
|
|
5143
|
-
};
|
|
5144
|
-
}
|
|
5145
5298
|
}
|
|
5146
5299
|
pollSpinner.stop();
|
|
5147
5300
|
if (!installationId) {
|
|
@@ -5233,28 +5386,37 @@ const statusLabels = {
|
|
|
5233
5386
|
BUILDING: "Compilando",
|
|
5234
5387
|
BUILD_FAILED: "Falha na compilação",
|
|
5235
5388
|
DEPLOYING: "Realizando deploy",
|
|
5389
|
+
WAITING_ON_PROVIDER: "Provisionando",
|
|
5236
5390
|
LIVE: "Ativo",
|
|
5237
5391
|
FAILED: "Falhou",
|
|
5238
|
-
CANCELLED: "Cancelado"
|
|
5392
|
+
CANCELLED: "Cancelado",
|
|
5393
|
+
SKIPPED: "Ignorado",
|
|
5394
|
+
SUPERSEDED: "Substituído"
|
|
5239
5395
|
};
|
|
5240
5396
|
function makeStatusIcons() {
|
|
5241
5397
|
if (!process.stdout.isTTY) return {
|
|
5242
5398
|
QUEUED: "○",
|
|
5243
5399
|
BUILDING: "●",
|
|
5244
5400
|
DEPLOYING: "●",
|
|
5401
|
+
WAITING_ON_PROVIDER: "●",
|
|
5245
5402
|
LIVE: "●",
|
|
5246
5403
|
BUILD_FAILED: "●",
|
|
5247
5404
|
FAILED: "●",
|
|
5248
|
-
CANCELLED: "●"
|
|
5405
|
+
CANCELLED: "●",
|
|
5406
|
+
SKIPPED: "○",
|
|
5407
|
+
SUPERSEDED: "●"
|
|
5249
5408
|
};
|
|
5250
5409
|
return {
|
|
5251
5410
|
QUEUED: chalk.gray("○"),
|
|
5252
5411
|
BUILDING: chalk.yellow("●"),
|
|
5253
5412
|
DEPLOYING: chalk.blue("●"),
|
|
5413
|
+
WAITING_ON_PROVIDER: chalk.blue("●"),
|
|
5254
5414
|
LIVE: chalk.green("●"),
|
|
5255
5415
|
BUILD_FAILED: chalk.red("●"),
|
|
5256
5416
|
FAILED: chalk.red("●"),
|
|
5257
|
-
CANCELLED: chalk.gray("●")
|
|
5417
|
+
CANCELLED: chalk.gray("●"),
|
|
5418
|
+
SKIPPED: chalk.gray("○"),
|
|
5419
|
+
SUPERSEDED: chalk.gray("●")
|
|
5258
5420
|
};
|
|
5259
5421
|
}
|
|
5260
5422
|
function getStatusIcon(status) {
|
|
@@ -5268,6 +5430,7 @@ const TERMINAL_STATUSES = new Set([
|
|
|
5268
5430
|
"BUILD_FAILED",
|
|
5269
5431
|
"FAILED",
|
|
5270
5432
|
"CANCELLED",
|
|
5433
|
+
"SKIPPED",
|
|
5271
5434
|
"SUPERSEDED"
|
|
5272
5435
|
]);
|
|
5273
5436
|
|
|
@@ -5435,7 +5598,7 @@ async function streamDeploymentLogs(deploymentId, serviceId, serviceName) {
|
|
|
5435
5598
|
const isTTY = !mcp && process.stdout.isTTY;
|
|
5436
5599
|
const isGHA = !mcp && process.env.GITHUB_ACTIONS === "true";
|
|
5437
5600
|
if (isTTY && !isVerbose) {
|
|
5438
|
-
const { renderDeployTUI } = await import("./deploy-tui-
|
|
5601
|
+
const { renderDeployTUI } = await import("./deploy-tui-6DaoY351.mjs");
|
|
5439
5602
|
return renderDeployTUI(deploymentId, serviceId, serviceName);
|
|
5440
5603
|
}
|
|
5441
5604
|
const allLogLines = [];
|
|
@@ -5476,6 +5639,9 @@ async function streamDeploymentLogs(deploymentId, serviceId, serviceName) {
|
|
|
5476
5639
|
} catch {}
|
|
5477
5640
|
} catch {}
|
|
5478
5641
|
}
|
|
5642
|
+
if (!TERMINAL_STATUSES.has(finalStatus)) try {
|
|
5643
|
+
finalStatus = (await client.deployments.get({ deploymentId })).status;
|
|
5644
|
+
} catch {}
|
|
5479
5645
|
if (isGHA) endGroup();
|
|
5480
5646
|
const urls = finalStatus === "LIVE" ? await fetchDeployUrls$1(client, serviceId) : [];
|
|
5481
5647
|
if (finalStatus === "LIVE") {
|
|
@@ -24221,7 +24387,7 @@ const LOGO_LINES$1 = [
|
|
|
24221
24387
|
];
|
|
24222
24388
|
const BRAND_COLOR$1 = "#FF4D00";
|
|
24223
24389
|
function getVersion() {
|
|
24224
|
-
return "0.0.0-beta.
|
|
24390
|
+
return "0.0.0-beta.36";
|
|
24225
24391
|
}
|
|
24226
24392
|
function printBanner(subtitle) {
|
|
24227
24393
|
const version$2 = getVersion();
|
|
@@ -24254,9 +24420,16 @@ function stripAnsi(str) {
|
|
|
24254
24420
|
//#endregion
|
|
24255
24421
|
//#region src/lib/retry.ts
|
|
24256
24422
|
async function withRetry(fn$2, maxRetries = 3) {
|
|
24423
|
+
let orgSwitched = false;
|
|
24257
24424
|
for (let attempt = 0; attempt <= maxRetries; attempt++) try {
|
|
24258
24425
|
return await fn$2();
|
|
24259
24426
|
} catch (error) {
|
|
24427
|
+
if (!orgSwitched && isOrgMismatchError(error)) {
|
|
24428
|
+
if (applyOrgMismatchSwitch(error)) {
|
|
24429
|
+
orgSwitched = true;
|
|
24430
|
+
continue;
|
|
24431
|
+
}
|
|
24432
|
+
}
|
|
24260
24433
|
if (attempt >= maxRetries) throw error;
|
|
24261
24434
|
const rateLimit = isRateLimitError(error);
|
|
24262
24435
|
if (rateLimit) {
|
|
@@ -24310,7 +24483,8 @@ async function deploySingleService(service$2, options) {
|
|
|
24310
24483
|
const baseTarball = await createBaseTarball(projectRoot);
|
|
24311
24484
|
const deployment = await withRetry(() => client.deployments.create({
|
|
24312
24485
|
serviceId: service$2.serviceId,
|
|
24313
|
-
serviceConfig: service$2.serviceConfig
|
|
24486
|
+
serviceConfig: service$2.serviceConfig,
|
|
24487
|
+
config: service$2.config
|
|
24314
24488
|
}));
|
|
24315
24489
|
try {
|
|
24316
24490
|
await withRetry(() => uploadTarball(deployment.id, baseTarball.tarPath));
|
|
@@ -24354,7 +24528,8 @@ async function deployMultipleServices(services, options) {
|
|
|
24354
24528
|
try {
|
|
24355
24529
|
const deployment = await withRetry(() => client.deployments.create({
|
|
24356
24530
|
serviceId: service$2.serviceId,
|
|
24357
|
-
serviceConfig: service$2.serviceConfig
|
|
24531
|
+
serviceConfig: service$2.serviceConfig,
|
|
24532
|
+
config: service$2.config
|
|
24358
24533
|
}));
|
|
24359
24534
|
await withRetry(() => client.deployments.startBuild({
|
|
24360
24535
|
deploymentId: deployment.id,
|
|
@@ -24415,6 +24590,15 @@ async function deployMultipleServices(services, options) {
|
|
|
24415
24590
|
}
|
|
24416
24591
|
if (isTTY) output.renderProgress(progressMap);
|
|
24417
24592
|
}
|
|
24593
|
+
const finalProgress = progressMap.get(service$2.serviceId);
|
|
24594
|
+
if (finalProgress && !finalProgress.completed) try {
|
|
24595
|
+
const d = await client.deployments.get({ deploymentId });
|
|
24596
|
+
finalProgress.status = d.status;
|
|
24597
|
+
finalProgress.completed = TERMINAL_STATUSES.has(d.status);
|
|
24598
|
+
finalProgress.success = d.status === "LIVE";
|
|
24599
|
+
if (!isTTY) output.statusUpdate(service$2.serviceName, d.status);
|
|
24600
|
+
else output.renderProgress(progressMap);
|
|
24601
|
+
} catch {}
|
|
24418
24602
|
} catch (error) {
|
|
24419
24603
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
24420
24604
|
const progress = progressMap.get(service$2.serviceId);
|
|
@@ -25327,7 +25511,7 @@ async function fetchLatestVersion() {
|
|
|
25327
25511
|
}
|
|
25328
25512
|
}
|
|
25329
25513
|
function getCurrentVersion() {
|
|
25330
|
-
return "0.0.0-beta.
|
|
25514
|
+
return "0.0.0-beta.36";
|
|
25331
25515
|
}
|
|
25332
25516
|
/**
|
|
25333
25517
|
* Install a specific CLI version. Returns true on success.
|
|
@@ -25389,7 +25573,7 @@ async function provisionDatabases(config, opts) {
|
|
|
25389
25573
|
const client = await getClient();
|
|
25390
25574
|
const serverDatabases = await withSpinner({
|
|
25391
25575
|
text: "Verificando bancos de dados...",
|
|
25392
|
-
fn: () => client.databases.list({ projectId })
|
|
25576
|
+
fn: () => withRetry(() => client.databases.list({ projectId }))
|
|
25393
25577
|
});
|
|
25394
25578
|
const idUpdates = {};
|
|
25395
25579
|
for (const [key, dbConfig] of entries) {
|
|
@@ -25665,6 +25849,7 @@ async function triggerDeploy(serviceId, serviceName) {
|
|
|
25665
25849
|
async function findServicesFromConfig() {
|
|
25666
25850
|
const config = loadConfig$1();
|
|
25667
25851
|
if (!config) return [];
|
|
25852
|
+
if (!config.project.id) return [];
|
|
25668
25853
|
const missingIds = Object.entries(config.services).filter(([_, svc]) => !svc.id);
|
|
25669
25854
|
if (missingIds.length > 0 && config.project.id) {
|
|
25670
25855
|
const client = await getClient();
|
|
@@ -26470,7 +26655,7 @@ function registerDeploy(cli$1) {
|
|
|
26470
26655
|
run(c) {
|
|
26471
26656
|
const opts = c.options;
|
|
26472
26657
|
if (opts.dryRun) return dryRunFlow();
|
|
26473
|
-
if (isMcpMode()) return
|
|
26658
|
+
if (isMcpMode()) return headlessDeployFlow(opts);
|
|
26474
26659
|
return cliDeployFlow(opts);
|
|
26475
26660
|
}
|
|
26476
26661
|
});
|
|
@@ -26597,7 +26782,14 @@ function buildDraftVelozConfig(input) {
|
|
|
26597
26782
|
services: configServices
|
|
26598
26783
|
};
|
|
26599
26784
|
}
|
|
26600
|
-
|
|
26785
|
+
/**
|
|
26786
|
+
* Non-interactive deploy flow used by both MCP mode and `veloz init --ci`.
|
|
26787
|
+
*
|
|
26788
|
+
* Bootstraps a project + service automatically when no veloz.json exists,
|
|
26789
|
+
* then deploys. Output is routed through `createDeployOutput()` which picks
|
|
26790
|
+
* the right formatter for the current environment (MCP, GHA, plain, TTY).
|
|
26791
|
+
*/
|
|
26792
|
+
async function* headlessDeployFlow(opts) {
|
|
26601
26793
|
migrateResourcesConfig();
|
|
26602
26794
|
if (isInheritedConfig()) {
|
|
26603
26795
|
const parentRoot = findProjectRoot();
|
|
@@ -30407,7 +30599,7 @@ function PickerMenu({ items, onSelect, onCancel }) {
|
|
|
30407
30599
|
|
|
30408
30600
|
//#endregion
|
|
30409
30601
|
//#region src/wizard/ui/primitives/ScreenLayout.tsx
|
|
30410
|
-
const version = "0.0.0-beta.
|
|
30602
|
+
const version = "0.0.0-beta.36";
|
|
30411
30603
|
const LOGO_LINES = [
|
|
30412
30604
|
"██╗ ██╗███████╗██╗ ██████╗ ███████╗",
|
|
30413
30605
|
"██║ ██║██╔════╝██║ ██╔═══██╗╚══███╔╝",
|
|
@@ -34349,11 +34541,16 @@ function formatErrorForMeta(prefix, err) {
|
|
|
34349
34541
|
const { message, stack } = describeError(err);
|
|
34350
34542
|
return stack ? `${prefix}: ${message}\n${stack}` : `${prefix}: ${message}`;
|
|
34351
34543
|
}
|
|
34352
|
-
|
|
34353
|
-
|
|
34354
|
-
|
|
34355
|
-
|
|
34356
|
-
|
|
34544
|
+
const TERMINAL_SIGNALS = [
|
|
34545
|
+
"SIGHUP",
|
|
34546
|
+
"SIGTERM",
|
|
34547
|
+
"SIGQUIT"
|
|
34548
|
+
];
|
|
34549
|
+
const SIGNAL_EXIT_CODES = {
|
|
34550
|
+
SIGHUP: 129,
|
|
34551
|
+
SIGTERM: 143,
|
|
34552
|
+
SIGQUIT: 131
|
|
34553
|
+
};
|
|
34357
34554
|
function installCrashHandlers(logger) {
|
|
34358
34555
|
const handleCrash = (kind, err) => {
|
|
34359
34556
|
const { message, stack } = describeError(err);
|
|
@@ -34364,13 +34561,23 @@ function installCrashHandlers(logger) {
|
|
|
34364
34561
|
process.stderr.write(`[veloz init] ${kind}: ${message}\n`);
|
|
34365
34562
|
finalizeAndUploadOnce(logger, "error", { error: formatErrorForMeta(kind, err) }).catch(() => {}).finally(() => process.exit(1));
|
|
34366
34563
|
};
|
|
34564
|
+
const handleSignal = (signal) => {
|
|
34565
|
+
logger.log("signal", `${signal} received`);
|
|
34566
|
+
finalizeAndUploadOnce(logger, "abort", { error: `signal ${signal}` }).catch(() => {}).finally(() => process.exit(SIGNAL_EXIT_CODES[signal]));
|
|
34567
|
+
};
|
|
34367
34568
|
const onUncaught = (err) => handleCrash("uncaughtException", err);
|
|
34368
34569
|
const onUnhandled = (reason) => handleCrash("unhandledRejection", reason);
|
|
34570
|
+
const signalHandlers = TERMINAL_SIGNALS.map((signal) => {
|
|
34571
|
+
const handler = () => handleSignal(signal);
|
|
34572
|
+
process.on(signal, handler);
|
|
34573
|
+
return [signal, handler];
|
|
34574
|
+
});
|
|
34369
34575
|
process.on("uncaughtException", onUncaught);
|
|
34370
34576
|
process.on("unhandledRejection", onUnhandled);
|
|
34371
34577
|
return () => {
|
|
34372
34578
|
process.off("uncaughtException", onUncaught);
|
|
34373
34579
|
process.off("unhandledRejection", onUnhandled);
|
|
34580
|
+
for (const [signal, handler] of signalHandlers) process.off(signal, handler);
|
|
34374
34581
|
};
|
|
34375
34582
|
}
|
|
34376
34583
|
/** Detect repo using the lazy local filesystem layer. */
|
|
@@ -34397,7 +34604,7 @@ function registerInit(cli$1) {
|
|
|
34397
34604
|
description: "Wizard de deploy — configura e faz deploy do projeto automaticamente",
|
|
34398
34605
|
options: z.object({
|
|
34399
34606
|
framework: z.string().optional().describe("Forçar framework específico (ex: nextjs-app-router, express)"),
|
|
34400
|
-
ci: z.boolean().default(false).describe("Modo CI
|
|
34607
|
+
ci: z.boolean().default(false).describe("Modo CI — pula o wizard de IA e faz deploy direto via veloz deploy")
|
|
34401
34608
|
}),
|
|
34402
34609
|
alias: {
|
|
34403
34610
|
framework: "f",
|
|
@@ -34451,12 +34658,8 @@ async function runInitFlow(c, logger, cwd) {
|
|
|
34451
34658
|
const detectedLabel = analysis.framework?.label ?? null;
|
|
34452
34659
|
if (!process.stdout.isTTY || c.options.ci) {
|
|
34453
34660
|
logger.log("mode", "running headless (no TUI)");
|
|
34454
|
-
|
|
34455
|
-
|
|
34456
|
-
frameworkId: forcedFramework ?? detectedFrameworkId ?? "nodejs",
|
|
34457
|
-
frameworkLabel: forcedFramework ? FRAMEWORK_LABELS[forcedFramework] ?? forcedFramework : detectedLabel ?? "Node.js",
|
|
34458
|
-
packageManager: analysis.packageManager ?? "npm"
|
|
34459
|
-
});
|
|
34661
|
+
if (forcedFramework) process.stderr.write(`[veloz init] aviso: --framework é ignorado em modo CI. Configure o framework em veloz.json.\n`);
|
|
34662
|
+
return await runHeadless({ cwd });
|
|
34460
34663
|
}
|
|
34461
34664
|
const tui = startTUI();
|
|
34462
34665
|
const { store } = tui;
|
|
@@ -34640,14 +34843,6 @@ async function runGithubSetupFlow(store, cwd) {
|
|
|
34640
34843
|
return;
|
|
34641
34844
|
}
|
|
34642
34845
|
const installation = await client.github.getInstallation({ owner: remote.owner });
|
|
34643
|
-
if (installation.error === "TOKEN_EXPIRED") {
|
|
34644
|
-
store.failGithubSetup("Token do GitHub expirado. Reconecte sua conta no dashboard e tente novamente.");
|
|
34645
|
-
return;
|
|
34646
|
-
}
|
|
34647
|
-
if (installation.error === "RATE_LIMITED") {
|
|
34648
|
-
store.failGithubSetup("Limite de requisições do GitHub atingido. Tente de novo em alguns minutos.");
|
|
34649
|
-
return;
|
|
34650
|
-
}
|
|
34651
34846
|
if (installation.installed && installation.installationId) {
|
|
34652
34847
|
store.setGithubSetupPhase("connecting");
|
|
34653
34848
|
await client.projects.connectRepo({
|
|
@@ -34795,7 +34990,7 @@ function runVelozSubcommand(args$1) {
|
|
|
34795
34990
|
* Poll the server for a completed GitHub App installation on `owner`.
|
|
34796
34991
|
* Returns the installation id when detected, or null on timeout / auth loss.
|
|
34797
34992
|
*/
|
|
34798
|
-
async function pollGithubInstallation(
|
|
34993
|
+
async function pollGithubInstallation(_store, owner) {
|
|
34799
34994
|
const client = await getClient();
|
|
34800
34995
|
const maxAttempts = 60;
|
|
34801
34996
|
const pollInterval = 5e3;
|
|
@@ -34805,35 +35000,20 @@ async function pollGithubInstallation(store, owner) {
|
|
|
34805
35000
|
});
|
|
34806
35001
|
const check = await client.github.getInstallation({ owner });
|
|
34807
35002
|
if (check.installed && check.installationId) return check.installationId;
|
|
34808
|
-
if (check.error === "TOKEN_EXPIRED") {
|
|
34809
|
-
store.failGithubSetup("Token do GitHub expirou durante a espera.");
|
|
34810
|
-
return null;
|
|
34811
|
-
}
|
|
34812
35003
|
}
|
|
34813
35004
|
return null;
|
|
34814
35005
|
}
|
|
35006
|
+
/**
|
|
35007
|
+
* In CI / non-TTY contexts (real CI runners, MCP tool calls, Claude Code's
|
|
35008
|
+
* bash tool), `veloz init` delegates to the deterministic deploy flow rather
|
|
35009
|
+
* than spawning a Claude Code agent. The deploy flow auto-bootstraps the
|
|
35010
|
+
* project + service when no veloz.json exists, then deploys.
|
|
35011
|
+
*/
|
|
34815
35012
|
async function runHeadless(opts) {
|
|
34816
|
-
const { WizardStore: WizardStore$1 } = await import("./store-CFF2J0lW.mjs");
|
|
34817
|
-
const { runAgent: run } = await import("./agent-interface-DL5S8SEn.mjs");
|
|
34818
35013
|
const logger = getSessionLogger();
|
|
34819
35014
|
logger.log("headless", "resolving auth (non-interactive)");
|
|
34820
35015
|
const config = await requireAuth({ nonInteractive: true });
|
|
34821
|
-
const store = new WizardStore$1();
|
|
34822
|
-
store.setAuth({
|
|
34823
|
-
userName: "CI",
|
|
34824
|
-
orgId: config.organizationId ?? "",
|
|
34825
|
-
orgName: "",
|
|
34826
|
-
apiKey: config.apiKey
|
|
34827
|
-
});
|
|
34828
|
-
store.subscribe(() => {
|
|
34829
|
-
const s = store.session;
|
|
34830
|
-
const lastLog = s.agentLogLines[s.agentLogLines.length - 1];
|
|
34831
|
-
if (lastLog) process.stderr.write(`[veloz init] ${lastLog}\n`);
|
|
34832
|
-
});
|
|
34833
35016
|
logger.updateMeta({
|
|
34834
|
-
framework: opts.frameworkId,
|
|
34835
|
-
frameworkLabel: opts.frameworkLabel,
|
|
34836
|
-
packageManager: opts.packageManager,
|
|
34837
35017
|
userName: "CI",
|
|
34838
35018
|
orgId: config.organizationId ?? ""
|
|
34839
35019
|
});
|
|
@@ -34846,37 +35026,35 @@ async function runHeadless(opts) {
|
|
|
34846
35026
|
};
|
|
34847
35027
|
process.on("SIGINT", onSigint);
|
|
34848
35028
|
try {
|
|
34849
|
-
logger.log("headless", "invoking
|
|
34850
|
-
|
|
34851
|
-
|
|
34852
|
-
|
|
34853
|
-
|
|
34854
|
-
|
|
34855
|
-
|
|
34856
|
-
|
|
34857
|
-
|
|
34858
|
-
|
|
34859
|
-
|
|
34860
|
-
|
|
34861
|
-
|
|
34862
|
-
|
|
34863
|
-
|
|
34864
|
-
|
|
35029
|
+
logger.log("headless", "invoking headlessDeployFlow", { cwd: opts.cwd });
|
|
35030
|
+
process.stderr.write("[veloz init] modo CI, executando deploy não-interativo...\n");
|
|
35031
|
+
let success$1 = false;
|
|
35032
|
+
let url;
|
|
35033
|
+
for await (const event of headlessDeployFlow({
|
|
35034
|
+
all: true,
|
|
35035
|
+
yes: true
|
|
35036
|
+
})) if (event.type === "result") {
|
|
35037
|
+
const data = event.data;
|
|
35038
|
+
if (data?.status === "LIVE") {
|
|
35039
|
+
success$1 = true;
|
|
35040
|
+
url ??= data.urls?.[0];
|
|
35041
|
+
} else if (data?.failReason) logger.log("headless", "deploy failed", {
|
|
35042
|
+
status: data.status,
|
|
35043
|
+
failReason: data.failReason
|
|
35044
|
+
});
|
|
35045
|
+
}
|
|
35046
|
+
await finalizeAndUploadOnce(logger, success$1 ? "success" : "error", { deployUrl: url });
|
|
34865
35047
|
return {
|
|
34866
35048
|
success: success$1,
|
|
34867
|
-
url
|
|
35049
|
+
url
|
|
34868
35050
|
};
|
|
34869
35051
|
} catch (err) {
|
|
34870
35052
|
const { message, stack } = describeError(err);
|
|
34871
|
-
logger.log("headless", "
|
|
35053
|
+
logger.log("headless", "deploy threw", {
|
|
34872
35054
|
message,
|
|
34873
35055
|
stack
|
|
34874
35056
|
});
|
|
34875
|
-
await finalizeAndUploadOnce(logger, "error", {
|
|
34876
|
-
error: formatErrorForMeta("headless", err),
|
|
34877
|
-
deployUrl: store.session.deployUrl ?? void 0,
|
|
34878
|
-
retries: store.session.retryCount
|
|
34879
|
-
});
|
|
35057
|
+
await finalizeAndUploadOnce(logger, "error", { error: formatErrorForMeta("headless", err) });
|
|
34880
35058
|
throw err;
|
|
34881
35059
|
} finally {
|
|
34882
35060
|
process.off("SIGINT", onSigint);
|
|
@@ -35051,7 +35229,7 @@ async function runOrgCreationFlow(store, apiUrl) {
|
|
|
35051
35229
|
//#region src/index.ts
|
|
35052
35230
|
if (process.argv.includes("--mcp")) process.env.VELOZ_MCP = "true";
|
|
35053
35231
|
const cli = Cli.create("veloz", {
|
|
35054
|
-
version: "0.0.0-beta.
|
|
35232
|
+
version: "0.0.0-beta.36",
|
|
35055
35233
|
description: "CLI da plataforma Veloz — deploy rápido para o Brasil",
|
|
35056
35234
|
env: z.object({ VELOZ_ENV: z.string().optional().describe("Ambiente alvo (ex: preview, staging)") }),
|
|
35057
35235
|
mcp: { command: "npx -y onveloz --mcp" }
|
|
@@ -35172,4 +35350,4 @@ registerInit(cli);
|
|
|
35172
35350
|
cli.serve();
|
|
35173
35351
|
|
|
35174
35352
|
//#endregion
|
|
35175
|
-
export {
|
|
35353
|
+
export { statusLabels as a, buildDeviceAuthClient as c, pollForToken as d, registerLogin as f, TERMINAL_STATUSES as i, buildVerificationUrl as l, success as m, isHiddenMessage as n, getClient as o, info as p, parseBuildLine as r, DEVICE_AUTH_CLIENT_ID as s, cleanDisplayLine as t, performLogin as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "onveloz",
|
|
3
|
-
"version": "0.0.0-beta.
|
|
3
|
+
"version": "0.0.0-beta.36",
|
|
4
4
|
"description": "CLI da plataforma Veloz — deploy rápido para o Brasil",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"brasil",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"ink": "^6.8.0",
|
|
38
38
|
"nanostores": "^0.11.3",
|
|
39
39
|
"ora": "^8.2.0",
|
|
40
|
-
"react": "
|
|
40
|
+
"react": "catalog:",
|
|
41
41
|
"tar": "^6.2.0",
|
|
42
42
|
"ws": "^8.20.0",
|
|
43
43
|
"zod": "^4.1.13"
|
package/dist/login-B0sENXl7.mjs
DELETED
package/dist/store-CFF2J0lW.mjs
DELETED