(query: string, options: StateSearchOptions)
| 452 | } |
| 453 | |
| 454 | function createTextMatcher(query: string, options: StateSearchOptions): RegExp { |
| 455 | if (query.length === 0) { |
| 456 | throw new Error("Search query must not be empty"); |
| 457 | } |
| 458 | |
| 459 | let source = options.regex ? query : escapeRegExp(query); |
| 460 | if (options.wholeWord) { |
| 461 | source = `\\b(?:${source})\\b`; |
| 462 | } |
| 463 | |
| 464 | try { |
| 465 | return new RegExp(source, options.caseSensitive === false ? "gi" : "g"); |
| 466 | } catch (error) { |
| 467 | const message = error instanceof Error ? error.message : String(error); |
| 468 | throw new Error(`Invalid search pattern: ${message}`); |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | function escapeRegExp(value: string): string { |
| 473 | return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); |
no test coverage detected