viza 1.7.27 → 1.7.31
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/src/cli/program.js +2 -0
- package/dist/src/commands/billing/login/aws/aws.js +6 -11
- package/dist/src/commands/github/register.js +7 -0
- package/dist/src/commands/github/secrets/backup/backup.js +57 -0
- package/dist/src/commands/github/secrets/backup/register.js +17 -0
- package/dist/src/commands/github/secrets/register.js +9 -0
- package/dist/src/commands/github/secrets/restore/register.js +17 -0
- package/dist/src/commands/github/secrets/restore/restore.js +57 -0
- package/dist/src/commands/login/aws/aws.js +6 -11
- package/dist/src/core/dispatch.js +10 -4
- package/dist/src/ui/index.js +1 -1
- package/dist/src/ui/runtimeLogRenderer.js +48 -0
- package/package.json +3 -3
- /package/dist/src/ui/{logRenderer.js → infraLogRenderer.js} +0 -0
package/dist/src/cli/program.js
CHANGED
|
@@ -8,6 +8,7 @@ import { registerAwsCommand } from "../commands/aws/register.js";
|
|
|
8
8
|
import { registerInfraCommand } from "../commands/infra/register.js";
|
|
9
9
|
import { registerAgeCommand } from "../commands/age/register.js";
|
|
10
10
|
import { registerBillingCommand } from "../commands/billing/register.js";
|
|
11
|
+
import { registerGithubCommand } from "../commands/github/register.js";
|
|
11
12
|
export function createProgram() {
|
|
12
13
|
const program = new Command();
|
|
13
14
|
program
|
|
@@ -19,6 +20,7 @@ export function createProgram() {
|
|
|
19
20
|
registerAwsCommand(program);
|
|
20
21
|
registerBillingCommand(program);
|
|
21
22
|
registerBootstrapCommand(program);
|
|
23
|
+
registerGithubCommand(program);
|
|
22
24
|
registerInfraCommand(program);
|
|
23
25
|
registerLoginCommand(program);
|
|
24
26
|
program
|
|
@@ -41,20 +41,15 @@ export async function loginBillingAwsCommand(options) {
|
|
|
41
41
|
admin: options.admin === true
|
|
42
42
|
}
|
|
43
43
|
}, {
|
|
44
|
-
log: "
|
|
44
|
+
log: "show",
|
|
45
45
|
});
|
|
46
|
-
if (!result
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
if (result.kind !== "runtime") {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (!result.data) {
|
|
46
|
+
if (!result ||
|
|
47
|
+
result.status !== "success" ||
|
|
48
|
+
result.kind !== "runtime" ||
|
|
49
|
+
!result.data?.result) {
|
|
55
50
|
return;
|
|
56
51
|
}
|
|
57
|
-
const awsResult = result.data;
|
|
52
|
+
const awsResult = result.data.result;
|
|
58
53
|
if (typeof awsResult.loginUrl !== "string" ||
|
|
59
54
|
typeof awsResult.shortUrl !== "string" ||
|
|
60
55
|
typeof awsResult.ttlHours !== "number") {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { resolveEnv } from "../../../../context/env.js";
|
|
2
|
+
import { resolveResourceHubIntent } from "../../../../context/hubIntent.js";
|
|
3
|
+
import { dispatchIntentAndWait } from "../../../../core/dispatch.js";
|
|
4
|
+
/**
|
|
5
|
+
* Target teams for `viza login aws`.
|
|
6
|
+
* This is a CLI-only UX constraint for fail-fast validation.
|
|
7
|
+
* NOT a policy and MUST NOT be sent to gateway.
|
|
8
|
+
*/
|
|
9
|
+
const TARGET_TEAMS = {
|
|
10
|
+
"dev": [
|
|
11
|
+
"viza-super"
|
|
12
|
+
],
|
|
13
|
+
"prod": [
|
|
14
|
+
"viza-super"
|
|
15
|
+
]
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* viza github secrets backup
|
|
19
|
+
*
|
|
20
|
+
* Flow:
|
|
21
|
+
* 1) Resolve env (deterministic)
|
|
22
|
+
* 2) Resolve user identity (trusted via gh auth)
|
|
23
|
+
* 3) CLI pre-check against target teams (fail-fast UX)
|
|
24
|
+
* 4) Derive ONE valid team (deterministic)
|
|
25
|
+
* 5) Dispatch frozen intent to gateway
|
|
26
|
+
*/
|
|
27
|
+
export async function backupGithubSecretsCommand(options) {
|
|
28
|
+
// 1) Resolve environment
|
|
29
|
+
const env = resolveEnv(options);
|
|
30
|
+
const intent = resolveResourceHubIntent(env);
|
|
31
|
+
// Resolve allowed teams
|
|
32
|
+
// - Dispatch mode: restrict by targetEnv
|
|
33
|
+
// - Status mode: allow union of all env teams (read-only query)
|
|
34
|
+
const allowedTeams = options.status === true && env === "dev"
|
|
35
|
+
? Array.from(new Set([
|
|
36
|
+
...TARGET_TEAMS.dev,
|
|
37
|
+
...TARGET_TEAMS.prod,
|
|
38
|
+
]))
|
|
39
|
+
: TARGET_TEAMS[env];
|
|
40
|
+
// 5) Dispatch intent (freeze)
|
|
41
|
+
await dispatchIntentAndWait({
|
|
42
|
+
intent,
|
|
43
|
+
commandType: "github.secrets.backup",
|
|
44
|
+
infraKey: "core",
|
|
45
|
+
targetEnv: env,
|
|
46
|
+
allowedTeams,
|
|
47
|
+
selfHosted: options.selfHosted === true,
|
|
48
|
+
keepLog: options.removeLog !== true,
|
|
49
|
+
flowGates: {
|
|
50
|
+
secrets: true,
|
|
51
|
+
},
|
|
52
|
+
payload: {}
|
|
53
|
+
}, {
|
|
54
|
+
status: options.status === true,
|
|
55
|
+
log: "show",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { backupGithubSecretsCommand } from "./backup.js";
|
|
2
|
+
import { getResolvedOptions } from "../../../../cli/resolveOptions.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register:
|
|
5
|
+
* viza github secrets backup
|
|
6
|
+
*/
|
|
7
|
+
export function registerGithubSecretsBackupCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command("backup")
|
|
10
|
+
.description("Backup GitHub secrets and environment variables to AWS SSM")
|
|
11
|
+
.option("--prod", "Use production environment")
|
|
12
|
+
.option("--dev", "Use development environment")
|
|
13
|
+
.action(async (_opts, command) => {
|
|
14
|
+
const fullOpts = getResolvedOptions(command);
|
|
15
|
+
await backupGithubSecretsCommand(fullOpts);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { registerGithubSecretsBackupCommand } from "./backup/register.js";
|
|
2
|
+
import { registerGithubSecretsRestoreCommand } from "./restore/register.js";
|
|
3
|
+
export function registerGithubSecretsCommand(github) {
|
|
4
|
+
const secrets = github
|
|
5
|
+
.command("secrets")
|
|
6
|
+
.description("GitHub secrets management");
|
|
7
|
+
registerGithubSecretsBackupCommand(secrets);
|
|
8
|
+
registerGithubSecretsRestoreCommand(secrets);
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { restoreGithubSecretsCommand } from "./restore.js";
|
|
2
|
+
import { getResolvedOptions } from "../../../../cli/resolveOptions.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register:
|
|
5
|
+
* viza github secrets restore
|
|
6
|
+
*/
|
|
7
|
+
export function registerGithubSecretsRestoreCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command("restore")
|
|
10
|
+
.description("Restore GitHub secrets and environment variables to AWS SSM")
|
|
11
|
+
.option("--prod", "Use production environment")
|
|
12
|
+
.option("--dev", "Use development environment")
|
|
13
|
+
.action(async (_opts, command) => {
|
|
14
|
+
const fullOpts = getResolvedOptions(command);
|
|
15
|
+
await restoreGithubSecretsCommand(fullOpts);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { resolveEnv } from "../../../../context/env.js";
|
|
2
|
+
import { resolveRuntimeHubIntent } from "../../../../context/hubIntent.js";
|
|
3
|
+
import { dispatchIntentAndWait } from "../../../../core/dispatch.js";
|
|
4
|
+
/**
|
|
5
|
+
* Target teams for `viza login aws`.
|
|
6
|
+
* This is a CLI-only UX constraint for fail-fast validation.
|
|
7
|
+
* NOT a policy and MUST NOT be sent to gateway.
|
|
8
|
+
*/
|
|
9
|
+
const TARGET_TEAMS = {
|
|
10
|
+
"dev": [
|
|
11
|
+
"viza-super"
|
|
12
|
+
],
|
|
13
|
+
"prod": [
|
|
14
|
+
"viza-super"
|
|
15
|
+
]
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* viza github secrets restore
|
|
19
|
+
*
|
|
20
|
+
* Flow:
|
|
21
|
+
* 1) Resolve env (deterministic)
|
|
22
|
+
* 2) Resolve user identity (trusted via gh auth)
|
|
23
|
+
* 3) CLI pre-check against target teams (fail-fast UX)
|
|
24
|
+
* 4) Derive ONE valid team (deterministic)
|
|
25
|
+
* 5) Dispatch frozen intent to gateway
|
|
26
|
+
*/
|
|
27
|
+
export async function restoreGithubSecretsCommand(options) {
|
|
28
|
+
// 1) Resolve environment
|
|
29
|
+
const env = resolveEnv(options);
|
|
30
|
+
const intent = resolveRuntimeHubIntent();
|
|
31
|
+
// Resolve allowed teams
|
|
32
|
+
// - Dispatch mode: restrict by targetEnv
|
|
33
|
+
// - Status mode: allow union of all env teams (read-only query)
|
|
34
|
+
const allowedTeams = options.status === true && env === "dev"
|
|
35
|
+
? Array.from(new Set([
|
|
36
|
+
...TARGET_TEAMS.dev,
|
|
37
|
+
...TARGET_TEAMS.prod,
|
|
38
|
+
]))
|
|
39
|
+
: TARGET_TEAMS[env];
|
|
40
|
+
// 5) Dispatch intent (freeze)
|
|
41
|
+
await dispatchIntentAndWait({
|
|
42
|
+
intent,
|
|
43
|
+
commandType: "github.secrets.restore",
|
|
44
|
+
infraKey: "core",
|
|
45
|
+
targetEnv: env,
|
|
46
|
+
allowedTeams,
|
|
47
|
+
selfHosted: options.selfHosted === true,
|
|
48
|
+
keepLog: options.removeLog !== true,
|
|
49
|
+
flowGates: {
|
|
50
|
+
secrets: true,
|
|
51
|
+
},
|
|
52
|
+
payload: {}
|
|
53
|
+
}, {
|
|
54
|
+
status: options.status === true,
|
|
55
|
+
log: "show",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -60,20 +60,15 @@ export async function loginAwsCommand(options) {
|
|
|
60
60
|
}
|
|
61
61
|
}, {
|
|
62
62
|
status: options.status === true,
|
|
63
|
-
log: "
|
|
63
|
+
log: "show",
|
|
64
64
|
});
|
|
65
|
-
if (!result
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
if (result.kind !== "runtime") {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (!result.data) {
|
|
65
|
+
if (!result ||
|
|
66
|
+
result.status !== "success" ||
|
|
67
|
+
result.kind !== "runtime" ||
|
|
68
|
+
!result.data?.result) {
|
|
74
69
|
return;
|
|
75
70
|
}
|
|
76
|
-
const awsResult = result.data;
|
|
71
|
+
const awsResult = result.data.result;
|
|
77
72
|
if (typeof awsResult.loginUrl !== "string" ||
|
|
78
73
|
typeof awsResult.shortUrl !== "string" ||
|
|
79
74
|
typeof awsResult.ttlHours !== "number") {
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { dispatcherDispatch, } from "@vizamodo/viza-dispatcher";
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import { startSpinner, stopSpinner } from "../ui/spinner.js";
|
|
4
|
-
import { renderLog } from "../ui/
|
|
4
|
+
import { renderLog } from "../ui/infraLogRenderer.js";
|
|
5
5
|
import { showDispatchBanner } from "../ui/banner.js";
|
|
6
6
|
import { getCliVersion, checkForCliUpdateSoft } from "./version.js";
|
|
7
7
|
import { resolveExecutionMode } from "./resolveExecutionMode.js";
|
|
8
|
+
import { renderRuntimeLog } from "../ui/runtimeLogRenderer.js";
|
|
8
9
|
/**
|
|
9
10
|
* KISS log rendering.
|
|
10
11
|
* - success + hide => no log
|
|
11
12
|
* - otherwise => render log (if present)
|
|
12
13
|
*/
|
|
13
|
-
function maybeRenderLog(result, policy
|
|
14
|
-
//
|
|
14
|
+
function maybeRenderLog(result, policy) {
|
|
15
|
+
// Runtime execution (hub-worker)
|
|
15
16
|
if (result.kind !== "github") {
|
|
17
|
+
// Respect log policy: hide means do not render runtime logs
|
|
18
|
+
if (policy === "hide") {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
renderRuntimeLog(result.data);
|
|
16
22
|
return;
|
|
17
23
|
}
|
|
18
24
|
// KISS: only skip logs when success + hide.
|
|
@@ -133,7 +139,7 @@ export async function dispatchIntentAndWait(input, opts = {}) {
|
|
|
133
139
|
try {
|
|
134
140
|
const result = await handle.wait();
|
|
135
141
|
stopSpinner(spinner, result.status === "success" ? "✅ Done" : "❌ Failed");
|
|
136
|
-
maybeRenderLog(result, policy
|
|
142
|
+
maybeRenderLog(result, policy);
|
|
137
143
|
if (result.status !== "success") {
|
|
138
144
|
throw new Error(`Dispatch failed: ${result.status}`);
|
|
139
145
|
}
|
package/dist/src/ui/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// public exports (optional)
|
|
2
2
|
import { showBanner } from "./banner.js";
|
|
3
3
|
import { startSpinner, stopSpinner } from "./spinner.js";
|
|
4
|
-
import { renderLog } from "./
|
|
4
|
+
import { renderLog } from "./infraLogRenderer.js";
|
|
5
5
|
export function beginUi(opts) {
|
|
6
6
|
if (opts.banner) {
|
|
7
7
|
showBanner(opts.banner);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
/**
|
|
3
|
+
* Render logs for runtime commands executed via the hub worker.
|
|
4
|
+
* The runtime contract is:
|
|
5
|
+
*
|
|
6
|
+
* {
|
|
7
|
+
* ok: boolean
|
|
8
|
+
* correlationId: string
|
|
9
|
+
* log: RuntimeLogEntry[]
|
|
10
|
+
* result?: any
|
|
11
|
+
* error?: any
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
export function renderRuntimeLog(runtime) {
|
|
15
|
+
if (!runtime) {
|
|
16
|
+
console.log(chalk.red("\n────── Runtime Command ───────────────────────────────────────────────────────────────────────────────────────────────────"));
|
|
17
|
+
console.log(chalk.red("No runtime data returned from dispatcher."));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const { ok, correlationId, log = [], error } = runtime ?? {};
|
|
21
|
+
console.log(chalk.yellow(`\n────── Runtime Command (${correlationId ?? "unknown"}) ───────────────────────────────────────────────────────────────────────────────────────`));
|
|
22
|
+
if (!Array.isArray(log) || log.length === 0) {
|
|
23
|
+
console.log(chalk.gray("No runtime logs available."));
|
|
24
|
+
}
|
|
25
|
+
for (const entry of log) {
|
|
26
|
+
const step = entry?.step != null ? String(entry.step).padStart(2, "0") : "--";
|
|
27
|
+
const title = entry?.title ?? "step";
|
|
28
|
+
const message = entry?.message ?? "";
|
|
29
|
+
const duration = entry?.durationMs;
|
|
30
|
+
console.log(`\n${chalk.gray(step)} ${chalk.cyan(title)}`);
|
|
31
|
+
if (message) {
|
|
32
|
+
console.log(` ${chalk.white(message)}`);
|
|
33
|
+
}
|
|
34
|
+
if (duration != null) {
|
|
35
|
+
console.log(` ${chalk.gray(`(${duration}ms)`)}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!ok && error) {
|
|
39
|
+
console.log(chalk.red("\n────── ERROR ───────────────────────────────────────────────────────────────────────────────────────────────────────────"));
|
|
40
|
+
console.log(error?.message ?? error);
|
|
41
|
+
if (error?.stack) {
|
|
42
|
+
console.log(chalk.gray(error.stack));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
console.log(ok
|
|
46
|
+
? chalk.green("\n────── ✔ SUCCESS ──────────────────────────────────────────────────────────────────────────────────────────────────────────")
|
|
47
|
+
: chalk.red("\n────── ✖ FAILED ───────────────────────────────────────────────────────────────────────────────────────────────────────────"));
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "viza",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Viza unified command line interface",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"release:full": "rm -rf dist && npx npm-check-updates -u && npm install && git add package.json package-lock.json && git commit -m 'chore(deps): auto update dependencies before release' || echo 'No changes' && node versioning.js && npm login && npm publish --tag latest --access public && git push"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@vizamodo/viza-dispatcher": "^1.5.
|
|
20
|
+
"@vizamodo/viza-dispatcher": "^1.5.20",
|
|
21
21
|
"adm-zip": "^0.5.16",
|
|
22
22
|
"chalk": "^5.6.2",
|
|
23
23
|
"clipboardy": "^5.3.1",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/adm-zip": "^0.5.7",
|
|
31
31
|
"@types/figlet": "^1.7.0",
|
|
32
|
-
"@types/node": "^25.
|
|
32
|
+
"@types/node": "^25.4.0",
|
|
33
33
|
"@types/prompts": "^2.4.9",
|
|
34
34
|
"ts-node": "^10.9.2",
|
|
35
35
|
"typescript": "^5.9.3"
|
|
File without changes
|