Improve query parsing

This commit is contained in:
Eric Bailey
2024-09-24 20:53:42 -05:00
parent f7f5c94b0c
commit 8e4c6e0964
2 changed files with 19 additions and 8 deletions
+14 -3
View File
@@ -24,9 +24,20 @@ describe(`parseSearchQuery`, () => {
input: `bluesky since:2021-01-01:00:00:00`, input: `bluesky since:2021-01-01:00:00:00`,
output: {query: `bluesky`, params: {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}) => { it.each(tests)(
expect(parseSearchQuery(input)).toEqual(output) `$input -> $output.query $output.params`,
}) ({input, output}) => {
expect(parseSearchQuery(input)).toEqual(output)
},
)
}) })
+5 -5
View File
@@ -2,15 +2,15 @@ export type Params = Record<string, string>
export function parseSearchQuery(rawQuery: string) { export function parseSearchQuery(rawQuery: string) {
let base = rawQuery let base = rawQuery
const rawLiterals = rawQuery.match(/".+"/gi) || [] const rawLiterals = rawQuery.match(/[^:\w\d]".+?"/gi) || []
// remove literals from base // remove literals from base
for (const literal of rawLiterals) { for (const literal of rawLiterals) {
base = base.replace(literal, '') base = base.replace(literal.trim(), '')
} }
// find remaining params in base // 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) { for (const param of rawParams) {
base = base.replace(param, '') base = base.replace(param, '')
@@ -20,10 +20,10 @@ export function parseSearchQuery(rawQuery: string) {
const params = rawParams.reduce((params, param) => { const params = rawParams.reduce((params, param) => {
const [name, ...value] = param.split(/:/) 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 return params
}, {} as Params) }, {} as Params)
const literals = rawLiterals.map(l => String(l)) const literals = rawLiterals.map(l => String(l).trim())
return { return {
query: [base, literals.join(' ')].filter(Boolean).join(' '), query: [base, literals.join(' ')].filter(Boolean).join(' '),