* 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)
| 1426 | * @returns true if the query matches the pattern |
| 1427 | */ |
| 1428 | function matchesPattern(matchQuery: string, matcher: string): boolean { |
| 1429 | if (!matcher || matcher === '*') { |
| 1430 | return true |
| 1431 | } |
| 1432 | // Check if it's a simple string or pipe-separated list (no regex special chars except |) |
| 1433 | if (/^[a-zA-Z0-9_|]+$/.test(matcher)) { |
| 1434 | // Handle pipe-separated exact matches |
| 1435 | if (matcher.includes('|')) { |
| 1436 | const patterns = matcher |
| 1437 | .split('|') |
| 1438 | .map(p => normalizeLegacyToolName(p.trim())) |
| 1439 | return patterns.includes(matchQuery) |
| 1440 | } |
| 1441 | // Simple exact match |
| 1442 | return matchQuery === normalizeLegacyToolName(matcher) |
| 1443 | } |
| 1444 | |
| 1445 | // Otherwise treat as regex |
| 1446 | try { |
| 1447 | const regex = new RegExp(matcher) |
| 1448 | if (regex.test(matchQuery)) { |
| 1449 | return true |
| 1450 | } |
| 1451 | // Also test against legacy names so patterns like "^Task$" still match |
| 1452 | for (const legacyName of getLegacyToolNames(matchQuery)) { |
| 1453 | if (regex.test(legacyName)) { |
| 1454 | return true |
| 1455 | } |
| 1456 | } |
| 1457 | return false |
| 1458 | } catch { |
| 1459 | // If the regex is invalid, log error and return false |
| 1460 | logForDebugging(`Invalid regex pattern in hook matcher: ${matcher}`) |
| 1461 | return false |
| 1462 | } |
| 1463 | } |
| 1464 | |
| 1465 | type IfConditionMatcher = (ifCondition: string) => boolean |
| 1466 |
no test coverage detected