diff --git a/src/screens/Search/__tests__/utils.test.ts b/src/screens/Search/__tests__/utils.test.ts index 64ccdeedd0..81610cc59a 100644 --- a/src/screens/Search/__tests__/utils.test.ts +++ b/src/screens/Search/__tests__/utils.test.ts @@ -24,9 +24,20 @@ describe(`parseSearchQuery`, () => { input: `bluesky since:2021-01-01:00:00:00`, output: {query: `bluesky`, params: {since: `2021-01-01:00:00:00`}}, }, + { + input: `bluesky lang:"en"`, + output: {query: `bluesky`, params: {lang: `en`}}, + }, + { + input: `bluesky "literal" lang:en "from:invalid"`, + output: {query: `bluesky "literal" "from:invalid"`, params: {lang: `en`}}, + }, ] - it.each(tests)(`%p`, ({input, output}) => { - expect(parseSearchQuery(input)).toEqual(output) - }) + it.each(tests)( + `$input -> $output.query $output.params`, + ({input, output}) => { + expect(parseSearchQuery(input)).toEqual(output) + }, + ) }) diff --git a/src/screens/Search/utils.ts b/src/screens/Search/utils.ts index 6ade389717..dcf92c0926 100644 --- a/src/screens/Search/utils.ts +++ b/src/screens/Search/utils.ts @@ -2,15 +2,15 @@ export type Params = Record export function parseSearchQuery(rawQuery: string) { let base = rawQuery - const rawLiterals = rawQuery.match(/".+"/gi) || [] + const rawLiterals = rawQuery.match(/[^:\w\d]".+?"/gi) || [] // remove literals from base for (const literal of rawLiterals) { - base = base.replace(literal, '') + base = base.replace(literal.trim(), '') } // find remaining params in base - const rawParams = base.match(/[a-z]+:[a-z-\.@\d:]+/gi) || [] + const rawParams = base.match(/[a-z]+:[a-z-\.@\d:"]+/gi) || [] for (const param of rawParams) { base = base.replace(param, '') @@ -20,10 +20,10 @@ export function parseSearchQuery(rawQuery: string) { const params = rawParams.reduce((params, param) => { const [name, ...value] = param.split(/:/) - params[name] = value.join(':') // dates can contain additional colons + params[name] = value.join(':').replace(/"/g, '') // dates can contain additional colons return params }, {} as Params) - const literals = rawLiterals.map(l => String(l)) + const literals = rawLiterals.map(l => String(l).trim()) return { query: [base, literals.join(' ')].filter(Boolean).join(' '),