* 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)
| 1348 | * @returns true if the query matches the pattern |
| 1349 | */ |
| 1350 | function matchesPattern(matchQuery: string, matcher: string): boolean { |
| 1351 | if (!matcher || matcher === '*') { |
| 1352 | return true |
| 1353 | } |
| 1354 | // Check if it's a simple string or pipe-separated list (no regex special chars except |) |
| 1355 | if (/^[a-zA-Z0-9_|]+$/.test(matcher)) { |
| 1356 | // Handle pipe-separated exact matches |
| 1357 | if (matcher.includes('|')) { |
| 1358 | const patterns = matcher |
| 1359 | .split('|') |
| 1360 | .map(p => normalizeLegacyToolName(p.trim())) |
| 1361 | return patterns.includes(matchQuery) |
| 1362 | } |
| 1363 | // Simple exact match |
| 1364 | return matchQuery === normalizeLegacyToolName(matcher) |
| 1365 | } |
| 1366 | |
| 1367 | // Otherwise treat as regex |
| 1368 | try { |
| 1369 | const regex = new RegExp(matcher) |
| 1370 | if (regex.test(matchQuery)) { |
| 1371 | return true |
| 1372 | } |
| 1373 | // Also test against legacy names so patterns like "^Task$" still match |
| 1374 | for (const legacyName of getLegacyToolNames(matchQuery)) { |
| 1375 | if (regex.test(legacyName)) { |
| 1376 | return true |
| 1377 | } |
| 1378 | } |
| 1379 | return false |
| 1380 | } catch { |
| 1381 | // If the regex is invalid, log error and return false |
| 1382 | logForDebugging(`Invalid regex pattern in hook matcher: ${matcher}`) |
| 1383 | return false |
| 1384 | } |
| 1385 | } |
| 1386 | |
| 1387 | type IfConditionMatcher = (ifCondition: string) => boolean |
| 1388 |
no test coverage detected