import { ChartColumn, Clapperboard, Code, Columns2, FileText, Globe, Image as ImageIcon, Music2, PanelTop, Palette, Pencil, Settings2, Shapes, Sparkles, Table2, Type, Video, WandSparkles } from "lucide-react"; import { NODE_SPECS } from "@/constant/canvas"; import { MEDIA_NODE_MIN_SIZE } from "@/lib/canvas/canvas-node-size"; import { CanvasNodeType, type CanvasNodeData } from "@/types/canvas"; import type { CanvasNodeDefinition } from "../node-definition"; import { registerNodeDefinitions } from "../node-registry"; /** 非媒体节点的拉伸下限 */ const DEFAULT_MIN_SIZE = { width: 220, height: 160 } as const; /** * 每种内置节点的自有特征。 * * 尺寸、默认标题与初始 metadata 不在这里重复——它们的数据源是 constant/canvas.ts 的 * NODE_SPECS,下方装配时统一读取。 * * 内置节点保持集中定义;第三方节点通过同一 registry 以命名空间 ID 动态注册。 */ const BUILTIN_NODE_TRAITS = { [CanvasNodeType.Image]: { label: "图片", icon: , minSize: MEDIA_NODE_MIN_SIZE, keepAspectRatio: (node: CanvasNodeData) => !node.metadata?.freeResize, showInCreateMenu: true, resourceKind: (node: CanvasNodeData) => (node.metadata?.content || node.metadata?.storageKey ? "image" : null), generationMode: () => "image", inputKind: "image", }, [CanvasNodeType.Text]: { label: "文本", icon: , minSize: DEFAULT_MIN_SIZE, showInCreateMenu: true, resourceKind: (node: CanvasNodeData) => (node.metadata?.content || node.metadata?.prompt ? "text" : null), generationMode: () => "text", inputKind: "text", }, [CanvasNodeType.Drawing]: { label: "绘图", icon: , minSize: DEFAULT_MIN_SIZE, showInCreateMenu: true, // 绘图产出的是图像,所以作为素材与输入都按图片计。 resourceKind: (node: CanvasNodeData) => (node.metadata?.drawingId ? "image" : null), inputKind: "image", }, [CanvasNodeType.Script]: { label: "分镜脚本", icon: , // 分镜脚本的表格布局需要更宽的下限;高度仍由内容动态撑开(见 canvas-node.tsx)。 minSize: { width: 800, height: DEFAULT_MIN_SIZE.height }, showInCreateMenu: true, generationMode: () => "text", inputKind: "text", }, [CanvasNodeType.Skill]: { label: "技能", icon: , minSize: DEFAULT_MIN_SIZE, // 技能节点由技能库插入,不占创建菜单格位。 showInCreateMenu: false, // 技能注入的是提示词文本,故按文本素材计。 resourceKind: (node: CanvasNodeData) => (node.metadata?.skillSnapshot || node.metadata?.content ? "text" : null), inputKind: "text", }, [CanvasNodeType.Config]: { label: "生成配置", icon: , minSize: DEFAULT_MIN_SIZE, // 生成配置由连线时自动创建。 showInCreateMenu: false, // 生成模式由用户在配置节点上选择,缺省按图片。 generationMode: (node: CanvasNodeData) => node.metadata?.generationMode || "image", // 不设 inputKind:配置节点本身不是参考素材,不参与容量计数。 }, [CanvasNodeType.Video]: { label: "视频", icon: