(input: string)
| 38 | * Returns: { name: ['react'], keywords: ['typescript', 'hooks'], text: 'some text' } |
| 39 | */ |
| 40 | export function parseSearchOperators(input: string): ParsedSearchOperators { |
| 41 | const result: ParsedSearchOperators = {} |
| 42 | |
| 43 | // Regex to match operators: name:value, desc:value, description:value, kw:value, keyword:value |
| 44 | // Value continues until whitespace or next operator |
| 45 | const operatorRegex = /\b(name|desc|description|kw|keyword):(\S+)/gi |
| 46 | |
| 47 | let remaining = input |
| 48 | let match |
| 49 | |
| 50 | while ((match = operatorRegex.exec(input)) !== null) { |
| 51 | const [fullMatch, operator, value] = match |
| 52 | if (!operator || !value) continue |
| 53 | |
| 54 | const values = value |
| 55 | .split(',') |
| 56 | .map(v => v.trim()) |
| 57 | .filter(Boolean) |
| 58 | |
| 59 | const normalizedOp = operator.toLowerCase() |
| 60 | if (normalizedOp === 'name') { |
| 61 | result.name = [...(result.name ?? []), ...values] |
| 62 | } else if (normalizedOp === 'desc' || normalizedOp === 'description') { |
| 63 | result.description = [...(result.description ?? []), ...values] |
| 64 | } else if (normalizedOp === 'kw' || normalizedOp === 'keyword') { |
| 65 | result.keywords = [...(result.keywords ?? []), ...values] |
| 66 | } |
| 67 | |
| 68 | // Remove matched operator from remaining text |
| 69 | remaining = remaining.replace(fullMatch, '') |
| 70 | } |
| 71 | |
| 72 | // Clean up remaining text |
| 73 | const cleanedText = remaining.trim().replace(/\s+/g, ' ') |
| 74 | if (cleanedText) { |
| 75 | result.text = cleanedText |
| 76 | } |
| 77 | |
| 78 | // Deduplicate keywords (case-insensitive) |
| 79 | if (result.keywords) { |
| 80 | const seen = new Set<string>() |
| 81 | result.keywords = result.keywords.filter(kw => { |
| 82 | const lower = kw.toLowerCase() |
| 83 | if (seen.has(lower)) return false |
| 84 | seen.add(lower) |
| 85 | return true |
| 86 | }) |
| 87 | } |
| 88 | |
| 89 | return result |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | * Check if parsed operators has any content |
no outgoing calls
no test coverage detected