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