gensx
Version:
`GenSX command line tools.
105 lines • 5.76 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { existsSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
import { Box, Text, useApp } from "ink";
import { useEffect, useState } from "react";
import { ErrorMessage } from "../components/ErrorMessage.js";
import { LoadingSpinner } from "../components/LoadingSpinner.js";
import { bundleWorkflow } from "../utils/bundler.js";
import { generateSchema } from "../utils/schema.js";
function useBuild(file, options) {
const [phase, setPhase] = useState("validating");
const [error, setError] = useState(null);
const [result, setResult] = useState(null);
const { exit } = useApp();
const [buildProgress, setBuildProgress] = useState([]);
useEffect(() => {
let mounted = true;
async function buildWorkflow() {
try {
// 1. Validate file exists and is a TypeScript file
const absolutePath = resolve(process.cwd(), file);
if (!existsSync(absolutePath)) {
throw new Error(`File ${file} does not exist`);
}
if (!file.endsWith(".ts") && !file.endsWith(".tsx")) {
throw new Error("Only TypeScript files (.ts or .tsx) are supported");
}
if (!mounted)
return;
const outDir = options.outDir ?? resolve(process.cwd(), ".gensx");
const schemaFilePath = resolve(outDir, "schema.json");
let bundlePath;
if (!options.schemaOnly) {
setPhase("bundling");
bundlePath = await bundleWorkflow(absolutePath, outDir, (data) => {
setBuildProgress((prev) => [...prev, data]);
}, options.watch ?? false);
}
setPhase("generatingSchema");
// Generate schema locally
const workflowSchemas = generateSchema(absolutePath, options.tsconfig);
writeFileSync(schemaFilePath, JSON.stringify(workflowSchemas, null, 2));
setResult({
bundleFile: bundlePath ?? "",
schemaFile: schemaFilePath,
schemas: workflowSchemas,
});
setPhase("done");
if (options.verbose) {
setTimeout(() => {
exit();
}, 100);
}
}
catch (err) {
if (!mounted)
return;
setError(err.message);
setPhase("error");
setTimeout(() => {
exit();
}, 100);
}
}
void buildWorkflow();
return () => {
mounted = false;
};
}, [file, options, exit]);
return { phase, error, result, buildProgress };
}
export function BuildWorkflowUI({ file, options }) {
const { phase, error, result, buildProgress } = useBuild(file, options);
if (error) {
return _jsx(ErrorMessage, { message: error });
}
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [phase === "validating" && (_jsx(LoadingSpinner, { message: "Validating workflow file..." })), phase === "bundling" && (_jsxs(Box, { flexDirection: "column", children: [_jsx(LoadingSpinner, { message: "Building workflows using docker..." }), _jsx(Box, { flexDirection: "column", children: options.verbose &&
buildProgress.map((line, index) => (_jsx(Text, { children: line }, index))) })] })), phase === "generatingSchema" && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "\u2714" }), _jsx(Text, { children: " Built workflows" })] }), _jsx(LoadingSpinner, { message: "Generating schemas..." })] })), phase === "done" && result && (_jsx(Box, { flexDirection: "column", children: _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" })] }), options.verbose && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: ["Bundle: ", _jsx(Text, { color: "cyan", children: result.bundleFile })] }), _jsxs(Text, { children: ["Schema: ", _jsx(Text, { color: "cyan", children: result.schemaFile })] })] }))] }) }))] }));
}
// Keep the original build function for programmatic usage
export async function build(file, options = {}, onProgress) {
const outDir = options.outDir ?? resolve(process.cwd(), ".gensx");
const schemaFile = resolve(outDir, "schema.json");
// 1. Validate file exists and is a TypeScript file
const absolutePath = resolve(process.cwd(), file);
if (!existsSync(absolutePath)) {
throw new Error(`File ${file} does not exist`);
}
if (!file.endsWith(".ts") && !file.endsWith(".tsx")) {
throw new Error("Only TypeScript files (.ts or .tsx) are supported");
}
const bundleFilePath = await bundleWorkflow(absolutePath, outDir, onProgress ??
(() => {
// Do nothing
}), options.watch ?? false);
// Generate schema locally
const workflowSchemas = generateSchema(absolutePath, options.tsconfig);
writeFileSync(schemaFile, JSON.stringify(workflowSchemas, null, 2));
return {
bundleFile: bundleFilePath,
schemaFile: schemaFile,
schemas: workflowSchemas,
};
}
//# sourceMappingURL=build.js.map