gensx
Version:
`GenSX command line tools.
103 lines • 7.77 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import fs, { existsSync } from "node:fs";
import { resolve } from "node:path";
import axios from "axios";
import FormData from "form-data";
import { Box, Text, useApp } from "ink";
import Spinner from "ink-spinner";
import { useCallback, useState } from "react";
import { EnvironmentResolver } from "../components/EnvironmentResolver.js";
import { ErrorMessage } from "../components/ErrorMessage.js";
import { FirstTimeSetup } from "../components/FirstTimeSetup.js";
import { LoadingSpinner } from "../components/LoadingSpinner.js";
import { useProjectName } from "../hooks/useProjectName.js";
import { getAuth } from "../utils/config.js";
import { validateAndSelectEnvironment } from "../utils/env-config.js";
import { generateSchema } from "../utils/schema.js";
import { USER_AGENT } from "../utils/user-agent.js";
import { build } from "./build.js";
export const DeployUI = ({ file, options }) => {
const { exit } = useApp();
const [phase, setPhase] = useState("resolveEnv");
const [error, setError] = useState(null);
const [deployment, setDeployment] = useState(null);
const [auth, setAuth] = useState(null);
const [resolvedEnv, setResolvedEnv] = useState(null);
const [buildProgress, setBuildProgress] = useState([]);
const { loading, error: projectError, projectName, isFromConfig, } = useProjectName(options.project, true);
const deployWorkflow = useCallback(async (environment) => {
try {
setPhase("building");
let schemas;
let bundleFile;
if (options.archive) {
bundleFile = options.archive;
const absolutePath = resolve(process.cwd(), file);
if (!existsSync(absolutePath)) {
throw new Error(`File ${file} does not exist`);
}
schemas = generateSchema(absolutePath);
}
else {
const buildResult = await build(file, {}, (data) => {
setBuildProgress((prev) => [...prev, data]);
});
bundleFile = buildResult.bundleFile;
schemas = buildResult.schemas;
}
// 2. Get auth config
const authConfig = await getAuth();
if (!authConfig) {
throw new Error("Not authenticated. Please run 'gensx login' first.");
}
setAuth(authConfig);
setPhase("deploying");
// 3. Create form data with bundle
const form = new FormData();
form.append("file", fs.createReadStream(bundleFile), "bundle.js");
if (options.envVar) {
form.append("environmentVariables", JSON.stringify(options.envVar));
}
form.append("schemas", JSON.stringify(schemas));
// Use the project-specific deploy endpoint
const url = new URL(`/org/${authConfig.org}/projects/${encodeURIComponent(projectName)}/environments/${encodeURIComponent(environment)}/deploy`, authConfig.apiBaseUrl);
const response = await axios.post(url.toString(), form, {
headers: {
Authorization: `Bearer ${authConfig.token}`,
"User-Agent": USER_AGENT,
},
});
if (response.status >= 400) {
throw new Error(`Failed to deploy: ${response.status} ${response.statusText}`);
}
const deploymentData = response.data;
await validateAndSelectEnvironment(projectName, environment);
setDeployment(deploymentData);
setPhase("done");
setTimeout(() => {
exit();
}, 100);
}
catch (err) {
setError(err.message);
setPhase("error");
setTimeout(() => {
exit();
}, 100);
}
}, [file, options, projectName, exit]);
if (error || projectError) {
return (_jsx(ErrorMessage, { message: error ?? projectError?.message ?? "Unknown error" }));
}
if (loading || !projectName) {
return _jsx(LoadingSpinner, { message: "Resolving project..." });
}
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(FirstTimeSetup, {}), isFromConfig && phase === "resolveEnv" && (_jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "\u2139" }), " Using project name from gensx.yaml:", " ", _jsx(Text, { color: "cyan", children: projectName })] })), phase === "resolveEnv" && (_jsx(EnvironmentResolver, { projectName: projectName, specifiedEnvironment: options.env, allowCreate: true, yes: options.yes, onResolved: (env) => {
setResolvedEnv(env);
void deployWorkflow(env);
} })), phase === "building" && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { flexDirection: "column", children: options.verbose &&
buildProgress.map((line, index) => (_jsx(Text, { children: line }, index))) }), _jsx(LoadingSpinner, { message: "Building workflows using docker..." })] })), phase === "deploying" && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u2714" }), _jsx(Text, { children: " Built workflows" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u2714" }), _jsx(Text, { children: " Generated schemas" })] }), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Spinner, { type: "dots" }), " ", _jsxs(Text, { dimColor: true, children: ["Deploying project ", _jsx(Text, { color: "cyan", children: projectName }), " to GenSX Cloud ", _jsx(Text, { dimColor: true, children: "(environment:" }), " ", _jsx(Text, { color: "cyan", dimColor: true, children: resolvedEnv }), _jsx(Text, { dimColor: true, children: ")" })] })] }) })] })), phase === "done" && deployment && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u2714" }), _jsx(Text, { children: " Built workflows" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u2714" }), _jsx(Text, { children: " Generated schemas" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u2714" }), _jsx(Text, { children: " Deployed to GenSX Cloud" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u2714" }), _jsxs(Text, { children: [" ", "Environment ", _jsx(Text, { color: "cyan", children: resolvedEnv }), " is now selected"] })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "white", children: "Available Workflows:" }), _jsx(Box, { flexDirection: "column", children: deployment.workflows.map((workflow) => (_jsxs(Text, { color: "cyan", children: ["- ", workflow.name] }, workflow.id))) })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsxs(Text, { color: "white", children: ["Dashboard:", " ", _jsxs(Text, { color: "cyan", children: [auth?.consoleBaseUrl, "/", auth?.org, "/", deployment.projectName, "/", deployment.environmentName, "/workflows", deployment.buildId
? `?deploymentId=${deployment.buildId}`
: ""] })] }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: ["Project: ", _jsx(Text, { color: "cyan", children: deployment.projectName })] }), _jsxs(Text, { children: ["Environment:", " ", _jsx(Text, { color: "cyan", children: deployment.environmentName })] })] })] }))] }));
};
//# sourceMappingURL=deploy.js.map