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 { 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 { 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; } } }