/** * Convert a node to a XYFlow node * * @param node * @param onNodeChange * @param updateInternals * @returns */ export const toXYFlow = (node, onNodeChange, updateInternals) => { // return node return { id : node.id, type : node.type, // position width : node.position?.width || 280, height : node.position?.minimised ? null : node.position?.height, position : { x : node.position?.x || 0, y : node.position?.y || 0, }, minimised : node.position?.minimised, // data data : { ...node, onChange : (key, value) => onNodeChange(node.id, key, value), onUpdate : () => updateInternals(node.id), }, } }; /** * convert a XYFlow node to a node * * @param node */ export const fromXYFlow = (node) => { // return node return { id : node.id, type : node.type, spec : node.data?.spec || {}, name : node.data?.name, // position position : { x : node.position.x, y : node.position.y, width : node.width, height : node.height, minimised : node.minimised, }, inputs : node.data?.inputs, outputs : node.data?.outputs, // input input : node.data?.input || {}, }; }; /** * Validates whether a connection between two nodes is valid based on their types * * @param {Object} connection - The proposed connection * @param {Array} value - Current YAML nodes in the workflow * @param {Object} sNodes - Signal nodes data containing node type definitions * @returns {boolean} Whether the connection is valid */ export const isValidConnection = (connection, value, sNodes) => { // Extract handle identifiers const sourceHandle = `${connection.sourceHandle}`.split('-').slice(2).join('-'); const targetHandle = `${connection.targetHandle}`.split('-').slice(2).join('-'); // Find source and target nodes const sourceNode = value.find((n) => (n.id === connection.source) || (n.temp === connection.source)); const targetNode = value.find((n) => (n.id === connection.target) || (n.temp === connection.target)); // Get node type definitions const sourceActualNode = sNodes[sourceNode?.node || sourceNode?.type]; const targetActualNode = sNodes[targetNode?.node || targetNode?.type]; // Find input/output definitions const sourceInput = sourceActualNode?.outputs?.find((input) => input.id === sourceHandle) || sourceNode?.outputs?.find((input) => input.id === sourceHandle); const targetInput = targetActualNode?.inputs?.find((input) => input.id === targetHandle) || targetNode?.inputs?.find((input) => input.id === targetHandle); // Get types const sourceType = sourceInput?.type?.[0]?.id || sourceInput?.type?.[0]?.name; const targetType = targetInput?.type?.[0]?.id || targetInput?.type?.[0]?.name; // Validate connection types return sourceType === 'any' || targetType === 'any' || targetType === sourceType || (targetType === 'string' && sourceType === 'enum'); };