"use client"; /** * 스크립트 실행 액션 노드 * Python, Shell, PowerShell 등 외부 스크립트를 실행하는 노드 */ import { memo } from "react"; import { Handle, Position, NodeProps } from "reactflow"; import { Terminal, FileCode, Play } from "lucide-react"; import type { ScriptActionNodeData } from "@/types/node-editor"; // 스크립트 타입별 아이콘 색상 const SCRIPT_TYPE_COLORS: Record = { python: { bg: "bg-yellow-100", text: "text-yellow-700", label: "Python" }, shell: { bg: "bg-green-100", text: "text-green-700", label: "Shell" }, powershell: { bg: "bg-blue-100", text: "text-blue-700", label: "PowerShell" }, node: { bg: "bg-emerald-100", text: "text-emerald-700", label: "Node.js" }, executable: { bg: "bg-gray-100", text: "text-gray-700", label: "실행파일" }, }; export const ScriptActionNode = memo(({ data, selected }: NodeProps) => { const scriptTypeInfo = SCRIPT_TYPE_COLORS[data.scriptType] || SCRIPT_TYPE_COLORS.executable; const hasScript = data.executionMode === "inline" ? !!data.inlineScript : !!data.scriptPath; return (
{/* 입력 핸들 */} {/* 헤더 */}
{data.displayName || "스크립트 실행"}
{/* 본문 */}
{/* 스크립트 타입 */}
{scriptTypeInfo.label} {data.executionMode === "inline" ? "인라인" : "파일"}
{/* 스크립트 정보 */}
{data.executionMode === "inline" ? ( <> {hasScript ? ( {data.inlineScript!.split("\n").length}줄 스크립트 ) : ( 스크립트 입력 필요 )} ) : ( <> {hasScript ? ( {data.scriptPath} ) : ( 파일 경로 필요 )} )}
{/* 입력 방식 */}
입력: {data.inputMethod === "stdin" && "표준입력 (stdin)"} {data.inputMethod === "args" && "명령줄 인자"} {data.inputMethod === "env" && "환경변수"} {data.inputMethod === "file" && "파일"}
{/* 타임아웃 */} {data.options?.timeout && (
타임아웃: {Math.round(data.options.timeout / 1000)}초
)}
{/* 출력 핸들 */}
); }); ScriptActionNode.displayName = "ScriptActionNode";