onveloz 0.0.0-beta.32 → 0.0.0-beta.33
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/index.mjs +121 -32
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1260,7 +1260,7 @@ async function requireAuth(options) {
|
|
|
1260
1260
|
|
|
1261
1261
|
//#endregion
|
|
1262
1262
|
//#region src/lib/client.ts
|
|
1263
|
-
const CLI_VERSION = "0.0.0-beta.
|
|
1263
|
+
const CLI_VERSION = "0.0.0-beta.33";
|
|
1264
1264
|
const USER_AGENT = `veloz-cli/${CLI_VERSION}`;
|
|
1265
1265
|
/**
|
|
1266
1266
|
* Client source — "cli" by default; the init wizard sets this to "cli-wizard"
|
|
@@ -24221,7 +24221,7 @@ const LOGO_LINES$1 = [
|
|
|
24221
24221
|
];
|
|
24222
24222
|
const BRAND_COLOR$1 = "#FF4D00";
|
|
24223
24223
|
function getVersion() {
|
|
24224
|
-
return "0.0.0-beta.
|
|
24224
|
+
return "0.0.0-beta.33";
|
|
24225
24225
|
}
|
|
24226
24226
|
function printBanner(subtitle) {
|
|
24227
24227
|
const version$2 = getVersion();
|
|
@@ -25327,7 +25327,7 @@ async function fetchLatestVersion() {
|
|
|
25327
25327
|
}
|
|
25328
25328
|
}
|
|
25329
25329
|
function getCurrentVersion() {
|
|
25330
|
-
return "0.0.0-beta.
|
|
25330
|
+
return "0.0.0-beta.33";
|
|
25331
25331
|
}
|
|
25332
25332
|
/**
|
|
25333
25333
|
* Install a specific CLI version. Returns true on success.
|
|
@@ -30407,7 +30407,7 @@ function PickerMenu({ items, onSelect, onCancel }) {
|
|
|
30407
30407
|
|
|
30408
30408
|
//#endregion
|
|
30409
30409
|
//#region src/wizard/ui/primitives/ScreenLayout.tsx
|
|
30410
|
-
const version = "0.0.0-beta.
|
|
30410
|
+
const version = "0.0.0-beta.33";
|
|
30411
30411
|
const LOGO_LINES = [
|
|
30412
30412
|
"██╗ ██╗███████╗██╗ ██████╗ ███████╗",
|
|
30413
30413
|
"██║ ██║██╔════╝██║ ██╔═══██╗╚══███╔╝",
|
|
@@ -30596,6 +30596,7 @@ function createInitialSession() {
|
|
|
30596
30596
|
selectedOrgId: null,
|
|
30597
30597
|
newOrgName: null,
|
|
30598
30598
|
orgCreateError: null,
|
|
30599
|
+
reauthNotice: null,
|
|
30599
30600
|
detectedFramework: null,
|
|
30600
30601
|
detectedFrameworkLabel: null,
|
|
30601
30602
|
selectedFramework: null,
|
|
@@ -30729,29 +30730,45 @@ function AuthScreen({ store }) {
|
|
|
30729
30730
|
})]
|
|
30730
30731
|
})] });
|
|
30731
30732
|
}
|
|
30732
|
-
if (session.authPhase === "browser" || session.authPhase === "polling") return /* @__PURE__ */ jsxs(ScreenLayout, { children: [
|
|
30733
|
-
|
|
30734
|
-
|
|
30735
|
-
|
|
30736
|
-
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
|
|
30741
|
-
|
|
30742
|
-
|
|
30743
|
-
}), session.authVerificationUrl ? /* @__PURE__ */ jsxs(Box, {
|
|
30733
|
+
if (session.authPhase === "browser" || session.authPhase === "polling") return /* @__PURE__ */ jsxs(ScreenLayout, { children: [
|
|
30734
|
+
session.reauthNotice ? /* @__PURE__ */ jsx(Box, {
|
|
30735
|
+
marginBottom: 1,
|
|
30736
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
30737
|
+
color: "yellow",
|
|
30738
|
+
children: ["⚠ ", session.reauthNotice]
|
|
30739
|
+
})
|
|
30740
|
+
}) : null,
|
|
30741
|
+
/* @__PURE__ */ jsx(Spinner, { label: COPY.authPolling }),
|
|
30742
|
+
session.authDeviceCode ? /* @__PURE__ */ jsxs(Box, {
|
|
30743
|
+
marginTop: 1,
|
|
30744
30744
|
flexDirection: "column",
|
|
30745
|
-
|
|
30746
|
-
|
|
30747
|
-
|
|
30748
|
-
|
|
30749
|
-
|
|
30750
|
-
|
|
30751
|
-
|
|
30752
|
-
|
|
30753
|
-
|
|
30754
|
-
|
|
30745
|
+
gap: 1,
|
|
30746
|
+
children: [/* @__PURE__ */ jsxs(Box, {
|
|
30747
|
+
gap: 1,
|
|
30748
|
+
children: [/* @__PURE__ */ jsx(Text, { children: COPY.authDeviceCode }), /* @__PURE__ */ jsx(Text, {
|
|
30749
|
+
bold: true,
|
|
30750
|
+
color: BRAND_COLOR,
|
|
30751
|
+
children: session.authDeviceCode
|
|
30752
|
+
})]
|
|
30753
|
+
}), session.authVerificationUrl ? /* @__PURE__ */ jsxs(Box, {
|
|
30754
|
+
flexDirection: "column",
|
|
30755
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
30756
|
+
dimColor: true,
|
|
30757
|
+
children: COPY.authBrowserFallback
|
|
30758
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
30759
|
+
dimColor: true,
|
|
30760
|
+
children: session.authVerificationUrl
|
|
30761
|
+
})]
|
|
30762
|
+
}) : null]
|
|
30763
|
+
}) : null
|
|
30764
|
+
] });
|
|
30765
|
+
return /* @__PURE__ */ jsxs(ScreenLayout, { children: [session.reauthNotice ? /* @__PURE__ */ jsx(Box, {
|
|
30766
|
+
marginBottom: 1,
|
|
30767
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
30768
|
+
color: "yellow",
|
|
30769
|
+
children: ["⚠ ", session.reauthNotice]
|
|
30770
|
+
})
|
|
30771
|
+
}) : null, /* @__PURE__ */ jsx(Spinner, { label: COPY.authChecking })] });
|
|
30755
30772
|
}
|
|
30756
30773
|
function OrgCreateForm({ store }) {
|
|
30757
30774
|
const [value, setValue] = useState("");
|
|
@@ -33884,6 +33901,15 @@ var WizardStore = class {
|
|
|
33884
33901
|
this.$session.setKey("authPhase", "browser");
|
|
33885
33902
|
this.emitChange();
|
|
33886
33903
|
}
|
|
33904
|
+
/** Show a banner on AuthScreen explaining why we're re-running device auth. */
|
|
33905
|
+
setReauthNotice(message) {
|
|
33906
|
+
this.$session.setKey("reauthNotice", message);
|
|
33907
|
+
this.emitChange();
|
|
33908
|
+
}
|
|
33909
|
+
clearReauthNotice() {
|
|
33910
|
+
this.$session.setKey("reauthNotice", null);
|
|
33911
|
+
this.emitChange();
|
|
33912
|
+
}
|
|
33887
33913
|
setAvailableOrgs(orgs) {
|
|
33888
33914
|
this.$session.setKey("availableOrgs", orgs);
|
|
33889
33915
|
this.$session.setKey("authPhase", "org-select");
|
|
@@ -34157,7 +34183,6 @@ async function uploadInitTelemetry(sessionDir) {
|
|
|
34157
34183
|
return;
|
|
34158
34184
|
}
|
|
34159
34185
|
const authConfig = loadConfig();
|
|
34160
|
-
if (!authConfig.apiKey) return;
|
|
34161
34186
|
const files = readdirSync(sessionDir).filter((name) => {
|
|
34162
34187
|
const full = join(sessionDir, name);
|
|
34163
34188
|
try {
|
|
@@ -34170,9 +34195,10 @@ async function uploadInitTelemetry(sessionDir) {
|
|
|
34170
34195
|
if (files.length === 0) return;
|
|
34171
34196
|
const client = createClient(authConfig.apiUrl, () => {
|
|
34172
34197
|
const headers = {
|
|
34173
|
-
|
|
34174
|
-
"
|
|
34198
|
+
"User-Agent": "veloz-cli/telemetry",
|
|
34199
|
+
"X-Veloz-Client-Source": "cli-wizard"
|
|
34175
34200
|
};
|
|
34201
|
+
if (authConfig.apiKey) headers.Authorization = `Bearer ${authConfig.apiKey}`;
|
|
34176
34202
|
if (authConfig.organizationId) headers["X-Organization-Id"] = authConfig.organizationId;
|
|
34177
34203
|
return headers;
|
|
34178
34204
|
});
|
|
@@ -34263,7 +34289,7 @@ function startTUI(cwd) {
|
|
|
34263
34289
|
}));
|
|
34264
34290
|
teardown = unmount;
|
|
34265
34291
|
const cleanup = () => {
|
|
34266
|
-
if (process.stdout.isTTY) process.stdout.write("\x1B[0m
|
|
34292
|
+
if (process.stdout.isTTY) process.stdout.write("\x1B[0m");
|
|
34267
34293
|
};
|
|
34268
34294
|
process.on("exit", cleanup);
|
|
34269
34295
|
let sigintCount = 0;
|
|
@@ -34304,6 +34330,20 @@ function describeError(err) {
|
|
|
34304
34330
|
};
|
|
34305
34331
|
return { message: typeof err === "string" ? err : JSON.stringify(err) };
|
|
34306
34332
|
}
|
|
34333
|
+
/**
|
|
34334
|
+
* Detect an ORPC / HTTP 401 from a thrown value. Covers the three shapes we see
|
|
34335
|
+
* in practice: ORPCError instances (`.code === "UNAUTHORIZED"`), ORPC fetch
|
|
34336
|
+
* failures that preserve `.status === 401`, and raw Error messages containing
|
|
34337
|
+
* "Unauthorized".
|
|
34338
|
+
*/
|
|
34339
|
+
function isUnauthorizedError(err) {
|
|
34340
|
+
if (!err || typeof err !== "object") return false;
|
|
34341
|
+
const e = err;
|
|
34342
|
+
if (e.code === "UNAUTHORIZED") return true;
|
|
34343
|
+
if (e.status === 401) return true;
|
|
34344
|
+
if (typeof e.message === "string" && /unauthorized/i.test(e.message)) return true;
|
|
34345
|
+
return false;
|
|
34346
|
+
}
|
|
34307
34347
|
/** Compose the error string we persist on `meta.error`. */
|
|
34308
34348
|
function formatErrorForMeta(prefix, err) {
|
|
34309
34349
|
const { message, stack } = describeError(err);
|
|
@@ -34421,6 +34461,29 @@ async function runInitFlow(c, logger, cwd) {
|
|
|
34421
34461
|
const tui = startTUI();
|
|
34422
34462
|
const { store } = tui;
|
|
34423
34463
|
logger.log("tui", "TUI started");
|
|
34464
|
+
try {
|
|
34465
|
+
return await runInteractiveFlow({
|
|
34466
|
+
tui,
|
|
34467
|
+
store,
|
|
34468
|
+
logger,
|
|
34469
|
+
cwd,
|
|
34470
|
+
analysis,
|
|
34471
|
+
detectedFrameworkId,
|
|
34472
|
+
detectedLabel,
|
|
34473
|
+
forcedFramework
|
|
34474
|
+
});
|
|
34475
|
+
} catch (err) {
|
|
34476
|
+
try {
|
|
34477
|
+
tui.unmount();
|
|
34478
|
+
} catch {}
|
|
34479
|
+
const { message } = describeError(err);
|
|
34480
|
+
process.stderr.write(`\n✗ Erro: ${message}\n`);
|
|
34481
|
+
process.stderr.write(` Logs de depuração: ${logger.dir}\n\n`);
|
|
34482
|
+
throw err;
|
|
34483
|
+
}
|
|
34484
|
+
}
|
|
34485
|
+
async function runInteractiveFlow(opts) {
|
|
34486
|
+
const { tui, store, logger, cwd, analysis, detectedFrameworkId, detectedLabel, forcedFramework } = opts;
|
|
34424
34487
|
store.setDetection({
|
|
34425
34488
|
framework: detectedFrameworkId,
|
|
34426
34489
|
frameworkLabel: detectedLabel,
|
|
@@ -34842,6 +34905,31 @@ async function listOrganizations() {
|
|
|
34842
34905
|
}));
|
|
34843
34906
|
}
|
|
34844
34907
|
/**
|
|
34908
|
+
* Fetch orgs, handling an expired local API key by transparently re-running
|
|
34909
|
+
* the device auth flow inside the TUI. The user sees: "Verificando autenticação…"
|
|
34910
|
+
* → "Sessão expirou, autenticando novamente…" → device-code screen →
|
|
34911
|
+
* org picker, without ever bailing back to the shell.
|
|
34912
|
+
*/
|
|
34913
|
+
async function listOrgsOrReauth(store) {
|
|
34914
|
+
const logger = getSessionLogger();
|
|
34915
|
+
try {
|
|
34916
|
+
return await listOrganizations();
|
|
34917
|
+
} catch (err) {
|
|
34918
|
+
if (!isUnauthorizedError(err)) throw err;
|
|
34919
|
+
logger.log("auth", "stale api key detected (401) — forcing re-login", { message: describeError(err).message });
|
|
34920
|
+
store.setReauthNotice("Sua sessão expirou. Vamos autenticar novamente para continuar.");
|
|
34921
|
+
saveConfig({ apiKey: "" });
|
|
34922
|
+
const config = loadConfig();
|
|
34923
|
+
store.setAuthPhase("browser");
|
|
34924
|
+
const token = await performDeviceAuth(store, config.apiUrl);
|
|
34925
|
+
if (!token) throw new Error("Autenticação cancelada ou expirada.");
|
|
34926
|
+
logger.log("auth", "re-login succeeded — retrying org fetch");
|
|
34927
|
+
saveConfig({ apiKey: token });
|
|
34928
|
+
store.clearReauthNotice();
|
|
34929
|
+
return await listOrganizations();
|
|
34930
|
+
}
|
|
34931
|
+
}
|
|
34932
|
+
/**
|
|
34845
34933
|
* Create a new organization via Better Auth. The slug is derived from the name
|
|
34846
34934
|
* and suffixed with a random token when a collision occurs.
|
|
34847
34935
|
*/
|
|
@@ -34910,8 +34998,9 @@ async function resolveAuthAndOrg(store) {
|
|
|
34910
34998
|
}
|
|
34911
34999
|
} else logger.log("auth", "already authenticated from config");
|
|
34912
35000
|
logger.log("auth", "fetching organizations");
|
|
34913
|
-
const orgs = await
|
|
35001
|
+
const orgs = await listOrgsOrReauth(store);
|
|
34914
35002
|
logger.log("auth", "organizations loaded", { count: orgs.length });
|
|
35003
|
+
config = loadConfig();
|
|
34915
35004
|
let chosen;
|
|
34916
35005
|
if (orgs.length === 0) {
|
|
34917
35006
|
store.setAuthPhase("org-create");
|
|
@@ -34962,7 +35051,7 @@ async function runOrgCreationFlow(store, apiUrl) {
|
|
|
34962
35051
|
//#region src/index.ts
|
|
34963
35052
|
if (process.argv.includes("--mcp")) process.env.VELOZ_MCP = "true";
|
|
34964
35053
|
const cli = Cli.create("veloz", {
|
|
34965
|
-
version: "0.0.0-beta.
|
|
35054
|
+
version: "0.0.0-beta.33",
|
|
34966
35055
|
description: "CLI da plataforma Veloz — deploy rápido para o Brasil",
|
|
34967
35056
|
env: z.object({ VELOZ_ENV: z.string().optional().describe("Ambiente alvo (ex: preview, staging)") }),
|
|
34968
35057
|
mcp: { command: "npx -y onveloz --mcp" }
|