JSON Canvas MCP Server

by Cam10001110101
Verified
  • jsoncanvas
"""Edge implementations for JSON Canvas.""" from typing import Dict, Literal, Optional from .errors import InvalidEdgeError class Edge: """Edge implementation for connecting nodes.""" def __init__( self, id: str, from_node: str, to_node: str, from_side: Optional[Literal["top", "right", "bottom", "left"]] = None, from_end: Optional[Literal["none", "arrow"]] = None, to_side: Optional[Literal["top", "right", "bottom", "left"]] = None, to_end: Optional[Literal["none", "arrow"]] = None, color: Optional[str] = None, label: Optional[str] = None ) -> None: """Initialize an edge. Args: id: Unique identifier for the edge from_node: Node ID where the connection starts to_node: Node ID where the connection ends from_side: Optional side where this edge starts from_end: Optional shape of the endpoint at the edge start to_side: Optional side where this edge ends to_end: Optional shape of the endpoint at the edge end color: Optional color of the line label: Optional text label for the edge """ self.id = id self.from_node = from_node self.to_node = to_node # Validate sides valid_sides = ["top", "right", "bottom", "left", None] if from_side not in valid_sides: raise InvalidEdgeError( "from_side must be one of: top, right, bottom, left" ) if to_side not in valid_sides: raise InvalidEdgeError( "to_side must be one of: top, right, bottom, left" ) self.from_side = from_side self.to_side = to_side # Validate endpoints valid_ends = ["none", "arrow", None] if from_end not in valid_ends: raise InvalidEdgeError( "from_end must be one of: none, arrow" ) if to_end not in valid_ends: raise InvalidEdgeError( "to_end must be one of: none, arrow" ) self.from_end = from_end or "none" # Default to "none" self.to_end = to_end or "arrow" # Default to "arrow" # Validate color self.validate_color(color) self.color = color self.label = label @classmethod def validate_color(cls, color: Optional[str]) -> None: """Validate a color value. Args: color: Color value to validate (hex format or preset number) Raises: InvalidEdgeError: If the color is invalid """ if color is not None: if not ( (color.startswith("#") and len(color) == 7) or color in ["1", "2", "3", "4", "5", "6"] ): raise InvalidEdgeError( "Color must be a hex code (#RRGGBB) or preset number (1-6)" ) def to_dict(self) -> Dict: """Convert edge to dictionary representation. Returns: Dictionary representation of the edge """ edge_dict = { "id": self.id, "fromNode": self.from_node, "toNode": self.to_node, "fromEnd": self.from_end, "toEnd": self.to_end } if self.from_side is not None: edge_dict["fromSide"] = self.from_side if self.to_side is not None: edge_dict["toSide"] = self.to_side if self.color is not None: edge_dict["color"] = self.color if self.label is not None: edge_dict["label"] = self.label return edge_dict @classmethod def from_dict(cls, data: Dict) -> "Edge": """Create an edge from a dictionary. Args: data: Dictionary representation of an edge Returns: A new Edge instance """ return cls( id=data["id"], from_node=data["fromNode"], to_node=data["toNode"], from_side=data.get("fromSide"), from_end=data.get("fromEnd"), to_side=data.get("toSide"), to_end=data.get("toEnd"), color=data.get("color"), label=data.get("label") )