* Check if a match query matches a hook matcher pattern * @param matchQuery The query to match (e.g., 'Write', 'Edit', 'Bash') * @param matcher The matcher pattern - can be: * - Simple string for exact match (e.g., 'Write') * - Pipe-separated list for multiple exact matches (e.g., 'Write|Edi
(matchQuery: string, matcher: string)
| 1481 | * @returns true if the query matches the pattern |
| 1482 | */ |
| 1483 | function matchesPattern(matchQuery: string, matcher: string): boolean { |
| 1484 | if (!matcher || matcher === '*') { |
| 1485 | return true |
| 1486 | } |
| 1487 | // Check if it's a simple string or pipe-separated list (no regex special chars except |) |
| 1488 | if (/^[a-zA-Z0-9_|]+$/.test(matcher)) { |
| 1489 | // Handle pipe-separated exact matches |
| 1490 | if (matcher.includes('|')) { |
| 1491 | const patterns = matcher |
| 1492 | .split('|') |
| 1493 | .map(p => normalizeLegacyToolName(p.trim())) |
| 1494 | return patterns.includes(matchQuery) |
| 1495 | } |
| 1496 | // Simple exact match |
| 1497 | return matchQuery === normalizeLegacyToolName(matcher) |
| 1498 | } |
| 1499 | |
| 1500 | // Otherwise treat as regex |
| 1501 | try { |
| 1502 | const regex = new RegExp(matcher) |
| 1503 | if (regex.test(matchQuery)) { |
| 1504 | return true |
| 1505 | } |
| 1506 | // Also test against legacy names so patterns like "^Task$" still match |
| 1507 | for (const legacyName of getLegacyToolNames(matchQuery)) { |
| 1508 | if (regex.test(legacyName)) { |
| 1509 | return true |
| 1510 | } |
| 1511 | } |
| 1512 | return false |
| 1513 | } catch { |
| 1514 | // If the regex is invalid, log error and return false |
| 1515 | logForDebugging(`Invalid regex pattern in hook matcher: ${matcher}`) |
| 1516 | return false |
| 1517 | } |
| 1518 | } |
| 1519 | |
| 1520 | type IfConditionMatcher = (ifCondition: string) => boolean |
| 1521 |
no test coverage detected