UNPKG

gensx

Version:
164 lines 7.79 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 { useCallback, useEffect, useState } from "react"; // Core service helpers – replace with real ones import { createEnvironment, listEnvironments } from "../models/environment.js"; import { checkProjectExists, createProject } from "../models/projects.js"; import { getSelectedEnvironment, validateAndSelectEnvironment, } from "../utils/env-config.js"; import { ErrorMessage } from "./ErrorMessage.js"; import { LoadingSpinner } from "./LoadingSpinner.js"; export const EnvironmentResolver = ({ projectName, specifiedEnvironment, allowCreate = true, yes = false, onResolved, }) => { const { exit } = useApp(); const [phase, setPhase] = useState("loading"); const [error, setError] = useState(null); const [environments, setEnvironments] = useState([]); const [selected, setSelected] = useState(null); const [newEnvName, setNewEnvName] = useState(""); const [projectExists, setProjectExists] = useState(false); //----------------------------------------------------------- // Helpers //----------------------------------------------------------- const finish = useCallback((envName) => { setPhase("done"); onResolved(envName); }, [onResolved]); const bootstrap = useCallback(async () => { try { // 1. Flag overrides everything if (specifiedEnvironment) { finish(specifiedEnvironment); return; } // 2. Fetch project state const [exists, envs, preselected] = await Promise.all([ checkProjectExists(projectName), listEnvironments(projectName), getSelectedEnvironment(projectName), ]); setProjectExists(exists); if (!allowCreate && !exists) { throw new Error(`Project '${projectName}' does not exist.`); } // 3. Non‑interactive shortcut if (yes) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition const envName = preselected ?? envs[0]?.name ?? "default"; // Auto‑create if necessary (but no persistence beyond that) if (!envs.some((env) => env.name === envName)) { if (!exists) { await createProject(projectName, envName); await validateAndSelectEnvironment(projectName, envName); } else { await createEnvironment(projectName, envName); } } finish(envName); return; } // 4. If there was a pre‑selected env, ask confirmation first if (preselected) { setSelected(preselected); setEnvironments(envs.map((env) => env.name)); setNewEnvName(envs.length === 0 ? "default" : ""); setPhase("auto‑resolved"); return; } // 5. Otherwise show list prompt setEnvironments(envs.map((env) => env.name)); setNewEnvName(envs.length === 0 ? "default" : ""); setPhase("select"); } catch (err) { setError(err.message); setPhase("error"); setTimeout(() => { exit(); }, 50); } }, [specifiedEnvironment, projectName, yes, finish, exit]); useEffect(() => { void bootstrap(); }, [bootstrap]); if (phase === "loading") { return (_jsx(Box, { children: _jsx(LoadingSpinner, { message: "Resolving environment..." }) })); } if (phase === "error" && error) { return _jsx(ErrorMessage, { message: error }); } // 1️⃣ Confirm use of pre‑selected environment if (phase === "auto‑resolved" && selected) { return (_jsx(ConfirmSelected, { env: selected, onYes: () => { finish(selected); }, onNo: () => { setPhase("select"); } })); } // 2️⃣ Select from existing list or create new if (phase === "select") { const items = [ ...environments.map((name) => ({ label: name, value: name })), ...(allowCreate ? [{ label: "+ create new", value: "__create__" }] : []), ]; return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "\u279C" }), " Select an environment for project", " ", _jsx(Text, { color: "cyan", children: projectName }), ":"] }), _jsx(SelectInput, { items: items, onSelect: (item) => { if (item.value === "__create__") { setPhase("createPrompt"); } else { finish(item.value); } } })] })); } // 3️⃣ Ask for new env name if (phase === "createPrompt") { return (_jsx(Box, { flexDirection: "column", children: _jsxs(Text, { color: "blue", children: ["\u279C ", _jsx(Text, { color: "white", children: "Enter a name for the new environment:" }), " ", _jsx(TextInput, { value: newEnvName, onChange: setNewEnvName, onSubmit: (value) => { const trimmed = value.trim(); if (!trimmed) return; setPhase("creating"); void (async () => { try { if (!projectExists) { await createProject(projectName, trimmed); await validateAndSelectEnvironment(projectName, trimmed); } else { await createEnvironment(projectName, trimmed); } finish(trimmed); } catch (err) { setError(err.message); setPhase("error"); setTimeout(() => { exit(); }, 50); } })(); } })] }) })); } if (phase === "creating") { return (_jsx(Box, { children: _jsx(LoadingSpinner, { message: !projectExists ? `Creating project ${projectName} and environment ${newEnvName}...` : `Creating environment ${newEnvName}...` }) })); } // done – we unmount via onResolved in parent return null; }; const ConfirmSelected = ({ env, onYes, onNo }) => { const items = [ { label: "Yes", value: "yes" }, { label: "No", value: "no" }, ]; return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "\u279C" }), " Use selected environment", " ", _jsx(Text, { color: "green", children: env }), "?"] }), _jsx(SelectInput, { items: items, onSelect: (item) => { if (item.value === "yes") { onYes(); } else { onNo(); } } })] })); }; //# sourceMappingURL=EnvironmentResolver.js.map