(tools: readonly ToolRow[])
| 261 | }; |
| 262 | |
| 263 | const buildConnectionGroups = (tools: readonly ToolRow[]): readonly ToolkitConnectionGroup[] => { |
| 264 | const groups = new Map<string, ToolkitConnectionGroup & { tools: ToolRow[] }>(); |
| 265 | for (const tool of tools) { |
| 266 | const owner = toolOwner(tool); |
| 267 | const key = `${owner}:${tool.integration}:${toolConnectionName(tool)}`; |
| 268 | const existing = groups.get(key); |
| 269 | if (existing) { |
| 270 | existing.tools.push(tool); |
| 271 | continue; |
| 272 | } |
| 273 | groups.set(key, { |
| 274 | id: key, |
| 275 | owner, |
| 276 | integration: String(tool.integration), |
| 277 | connection: toolConnectionName(tool), |
| 278 | patterns: [], |
| 279 | tools: [tool], |
| 280 | }); |
| 281 | } |
| 282 | return [...groups.values()] |
| 283 | .map((group) => { |
| 284 | const sortedTools = [...group.tools].sort(compareTools); |
| 285 | return { |
| 286 | ...group, |
| 287 | patterns: reducePolicyPatterns(sortedTools.map(connectionPatternForTool)), |
| 288 | tools: sortedTools, |
| 289 | }; |
| 290 | }) |
| 291 | .sort(compareConnectionGroups); |
| 292 | }; |
| 293 | |
| 294 | const compareTools = (a: ToolRow, b: ToolRow): number => |
| 295 | String(a.name).localeCompare(String(b.name)) || toolMatchId(a).localeCompare(toolMatchId(b)); |
no test coverage detected