UNPKG

gensx

Version:
234 lines 11.9 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { Box, Text, useApp } from "ink"; import SelectInput from "ink-select-input"; import TextInput from "ink-text-input"; import { useEffect, useState } from "react"; import { ErrorMessage } from "../../components/ErrorMessage.js"; import { LoadingSpinner } from "../../components/LoadingSpinner.js"; import { checkProjectExists, createProject } from "../../models/projects.js"; import { getAuth } from "../../utils/config.js"; import { validateAndSelectEnvironment } from "../../utils/env-config.js"; import { readProjectConfig } from "../../utils/project-config.js"; function useCreateProject(initialProjectName, initialDescription, initialEnvironmentName, yes) { const { exit } = useApp(); const [step, setStep] = useState("initial"); const [error, setError] = useState(null); const [loading, setLoading] = useState(true); const [shouldCreate, setShouldCreate] = useState(null); const [projectConfig, setProjectConfig] = useState({ projectName: initialProjectName, description: initialDescription, environmentName: initialEnvironmentName, }); const setProjectName = (name) => { setProjectConfig((prev) => ({ ...prev, projectName: name })); }; const handleProjectNameSubmit = (value) => { const trimmed = value.trim(); if (trimmed) { setProjectName(trimmed); // After setting project name, prompt for environment name setStep("prompting_environment_name"); } else { setError(new Error("No project name found. Either specify --project or create a gensx.yaml file with a 'projectName' field.")); setStep("error"); setTimeout(() => { exit(); }, 100); } }; const setEnvironmentName = (name) => { setProjectConfig((prev) => ({ ...prev, environmentName: name })); }; useEffect(() => { let mounted = true; async function initializeProject() { try { // Check authentication first const authConfig = await getAuth(); if (!authConfig) { throw new Error("Not authenticated. Please run 'gensx login' first."); } // Try to read project config from gensx.yaml if not provided via CLI let configFromFile = null; if (!initialProjectName || !initialDescription) { try { configFromFile = await readProjectConfig(process.cwd()); } catch { // No config file or error reading it, that's okay } } if (!mounted) return; // Use CLI args first, then config file, then prompt const resolvedConfig = { projectName: initialProjectName ?? configFromFile?.projectName, description: initialDescription ?? configFromFile?.description, environmentName: initialEnvironmentName, }; setProjectConfig(resolvedConfig); // Check what we need to prompt for if (!resolvedConfig.projectName) { setStep("prompting_project_name"); setLoading(false); } else { // Check if project already exists const projectExists = await checkProjectExists(resolvedConfig.projectName); if (projectExists) { throw new Error(`Project ${resolvedConfig.projectName} already exists`); } // If yes flag is set, skip environment name prompt and go straight to creation if (yes) { // Set default environment name only if none provided via CLI if (!resolvedConfig.environmentName) { setProjectConfig((prev) => ({ ...prev, environmentName: "default", })); } setStep("confirming_creation"); setShouldCreate(true); } else if (resolvedConfig.environmentName) { // If environment name provided via CLI, skip the prompt but still show confirmation setStep("confirming_creation"); } else { // Only prompt for environment name if not provided via CLI setStep("prompting_environment_name"); } setLoading(false); } } catch (err) { if (!mounted) return; const thrownError = err instanceof Error ? err : new Error(String(err)); setError(thrownError); setStep("error"); setLoading(false); setTimeout(() => { exit(); }, 100); } } // Only run initialization once if (step === "initial") { void initializeProject(); } return () => { mounted = false; }; }, [ step, initialProjectName, initialDescription, initialEnvironmentName, yes, exit, ]); // Separate useEffect for handling project creation useEffect(() => { let mounted = true; async function handleProjectCreation() { if (step !== "confirming_creation" || shouldCreate === null) return; try { if (shouldCreate) { if (!projectConfig.projectName) { throw new Error("Project name is required"); } setStep("creating_project"); // Create the project with environment await createProject(projectConfig.projectName, projectConfig.environmentName, projectConfig.description); // Set the environment as active if (projectConfig.environmentName) { setStep("creating_environment"); const success = await validateAndSelectEnvironment(projectConfig.projectName, projectConfig.environmentName); if (!success) { throw new Error("Failed to set environment as active"); } } setStep("done"); } else { setError(new Error("Project creation cancelled")); setStep("error"); setTimeout(() => { exit(); }, 100); } } catch (err) { if (!mounted) return; const thrownError = err instanceof Error ? err : new Error(String(err)); setError(thrownError); setStep("error"); setTimeout(() => { exit(); }, 100); } } // Handle project creation confirmation if (step === "confirming_creation" && shouldCreate !== null) { void handleProjectCreation(); } return () => { mounted = false; }; }, [step, shouldCreate, projectConfig, exit]); return { loading, error, step, projectConfig, setProjectName, setEnvironmentName, setShouldCreate, setStep, handleProjectNameSubmit, }; } export function CreateProjectUI({ projectName: initialProjectName, description: initialDescription, environmentName: initialEnvironmentName, yes, }) { const { loading, error, step, projectConfig, setProjectName, setEnvironmentName, setShouldCreate, setStep, handleProjectNameSubmit, } = useCreateProject(initialProjectName, initialDescription, initialEnvironmentName, yes); if (error) { return _jsx(ErrorMessage, { message: error.message }); } if (loading || step === "creating_project" || step === "creating_environment") { const message = step === "creating_project" ? "Creating project..." : step === "creating_environment" ? "Setting up environment..." : "Loading..."; return _jsx(LoadingSpinner, { message: message }); } if (step === "prompting_project_name") { return (_jsx(Box, { flexDirection: "column", children: _jsxs(Text, { color: "blue", children: ["\u279C ", _jsx(Text, { color: "white", children: "Enter project name:" }), " ", _jsx(TextInput, { value: projectConfig.projectName ?? "", onChange: setProjectName, onSubmit: handleProjectNameSubmit })] }) })); } if (step === "prompting_environment_name") { return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [!initialProjectName && (_jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "\u2139" }), " Using project name from gensx.yaml:", " ", _jsx(Text, { color: "cyan", children: projectConfig.projectName })] })), _jsxs(Text, { color: "blue", children: ["\u279C ", _jsx(Text, { color: "white", children: "Enter initial environment name:" }), " ", _jsx(TextInput, { value: projectConfig.environmentName ?? "default", onChange: setEnvironmentName, onSubmit: (value) => { const trimmed = value.trim() || "default"; setEnvironmentName(trimmed); setStep("confirming_creation"); } })] })] })); } if (step === "confirming_creation") { return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "─".repeat(40) }), _jsx(Box, { paddingLeft: 1, children: _jsx(Text, { children: _jsx(Text, { color: "white", children: "Project Details" }) }) }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "─".repeat(40) }), _jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { children: ["Project: ", _jsx(Text, { color: "cyan", children: projectConfig.projectName })] }) }), _jsx(Box, { paddingLeft: 1, children: _jsxs(Text, { children: ["Environment:", " ", _jsx(Text, { color: "cyan", children: projectConfig.environmentName })] }) }), _jsx(Text, { color: "gray", children: "─".repeat(40) })] }), _jsxs(Box, { paddingTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "\u279C" }), " Create this project?"] }), _jsx(SelectInput, { items: [ { label: "Yes", value: "yes" }, { label: "No", value: "no" }, ], onSelect: (item) => { setShouldCreate(item.value === "yes"); } })] })] })); } if (step === "done") { return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "green", children: "\u2714" }), " ", "Project ", _jsx(Text, { color: "green", children: projectConfig.projectName }), " created successfully"] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, color: "green", children: "\u2714" }), " ", "Environment ", _jsx(Text, { color: "cyan", children: projectConfig.environmentName }), " ", "created and selected"] })] })); } return null; } //# sourceMappingURL=create.js.map