Decomposes the monolith `infra/setup/cli.ts` into clean `infra/setup/prompts/` and `infra/setup/commands/` directories while adhering to Cliffy idiomatic modularity. Validated via `deno check`, tests, and format. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
146 lines
4.6 KiB
TypeScript
146 lines
4.6 KiB
TypeScript
import { Select } from "jsr:@cliffy/prompt@1.0.0-rc.7";
|
|
import * as colors from "jsr:@std/fmt@0.225.2/colors";
|
|
import {
|
|
AuthSetupConfig,
|
|
COMPOSE_PATH,
|
|
DEFAULT_AUTH_CONFIG,
|
|
ENV_PATH,
|
|
readEnv,
|
|
SPIRE_COMPOSE_PATH,
|
|
} from "../env.ts";
|
|
import { handleAuthSetup } from "./auth.ts";
|
|
import { handleTestConnection } from "../commands/test.ts";
|
|
import {
|
|
downloadWorkloadProto,
|
|
executeBuildImage,
|
|
executeProtobufCompilation,
|
|
generateBuildCommands,
|
|
} from "../build.ts";
|
|
|
|
export async function handleReviewConfigs(): Promise<void> {
|
|
const envContent = await Deno.readTextFile(ENV_PATH).catch(() => null);
|
|
const composeContent = await Deno.readTextFile(COMPOSE_PATH).catch(() =>
|
|
null
|
|
);
|
|
const spireComposeContent = await Deno.readTextFile(SPIRE_COMPOSE_PATH).catch(
|
|
() => null,
|
|
);
|
|
|
|
if (!envContent && !composeContent && !spireComposeContent) {
|
|
console.log(
|
|
colors.red("\n✗ No generated configs found. Run the setup first.\n"),
|
|
);
|
|
return;
|
|
}
|
|
|
|
while (true) {
|
|
const action = await Select.prompt({
|
|
message: "Review Generated Configs",
|
|
options: [
|
|
{ name: "[Show .env]", value: "env" },
|
|
{ name: "[Show compose.yml]", value: "compose" },
|
|
{ name: "[Show compose.spire.yml]", value: "spire_compose" },
|
|
{ name: "[Back to Main Menu]", value: "back" },
|
|
],
|
|
});
|
|
|
|
if (action === "env") {
|
|
console.log(colors.bold(colors.blue(`\n=== ${ENV_PATH} ===\n`)));
|
|
console.log(envContent || colors.yellow("File not found."));
|
|
console.log();
|
|
} else if (action === "compose") {
|
|
console.log(colors.bold(colors.blue(`\n=== ${COMPOSE_PATH} ===\n`)));
|
|
console.log(composeContent || colors.yellow("File not found."));
|
|
console.log();
|
|
} else if (action === "spire_compose") {
|
|
console.log(
|
|
colors.bold(colors.blue(`\n=== ${SPIRE_COMPOSE_PATH} ===\n`)),
|
|
);
|
|
console.log(spireComposeContent || colors.yellow("File not found."));
|
|
console.log();
|
|
} else if (action === "back") {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// SIDE EFFECT: Runs the interactive CLI wizard.
|
|
export async function runSetupWizard(): Promise<void> {
|
|
console.log(colors.bold(colors.blue("=== Auth Setup Wizard ===\n")));
|
|
|
|
const loadedEnv = await readEnv();
|
|
let currentConfig: AuthSetupConfig = {
|
|
...DEFAULT_AUTH_CONFIG,
|
|
...loadedEnv,
|
|
};
|
|
|
|
if (Object.keys(loadedEnv).length > 0 && currentConfig.domainName) {
|
|
await handleTestConnection(currentConfig.domainName);
|
|
console.log();
|
|
}
|
|
|
|
while (true) {
|
|
const action = await Select.prompt({
|
|
message: "Main Menu",
|
|
options: [
|
|
{ name: "[Test Auth Connection]", value: "test" },
|
|
{ name: "[Configure Auth Yes API]", value: "auth" },
|
|
{ name: "[Compile Protobuf Definitions]", value: "compile_proto" },
|
|
{ name: "[Review Generated Configs]", value: "review" },
|
|
{ name: "[Build and Push Auth Image]", value: "build" },
|
|
{ name: "[Exit]", value: "exit" },
|
|
],
|
|
});
|
|
|
|
if (action === "test") {
|
|
await handleTestConnection(currentConfig.domainName);
|
|
console.log();
|
|
} else if (action === "auth") {
|
|
currentConfig = await handleAuthSetup(currentConfig);
|
|
} else if (action === "compile_proto") {
|
|
try {
|
|
await downloadWorkloadProto();
|
|
await executeProtobufCompilation();
|
|
console.log(colors.green("\n✓ Successfully compiled protobufs!\n"));
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
console.log(
|
|
colors.red(`\n✗ Protobuf compilation failed: ${error.message}\n`),
|
|
);
|
|
} else {
|
|
console.log(
|
|
colors.red(`\n✗ Protobuf compilation failed: ${error}\n`),
|
|
);
|
|
}
|
|
}
|
|
} else if (action === "review") {
|
|
await handleReviewConfigs();
|
|
} else if (action === "build") {
|
|
try {
|
|
const commands = generateBuildCommands(currentConfig.reg);
|
|
await executeBuildImage(commands);
|
|
console.log(colors.green("\n✓ Successfully built and pushed image!"));
|
|
console.log(
|
|
colors.green("You may now deploy your stack by running:\n"),
|
|
);
|
|
console.log(
|
|
colors.cyan(
|
|
"podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml up -d\n",
|
|
),
|
|
);
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
console.log(
|
|
colors.red(`\n✗ Build process failed: ${error.message}\n`),
|
|
);
|
|
} else {
|
|
console.log(colors.red(`\n✗ Build process failed: ${error}\n`));
|
|
}
|
|
}
|
|
} else if (action === "exit") {
|
|
console.log(colors.gray("Exiting...\n"));
|
|
break;
|
|
}
|
|
}
|
|
}
|