diff options
Diffstat (limited to 'server/models/utils.ts')
-rw-r--r-- | server/models/utils.ts | 60 |
1 files changed, 6 insertions, 54 deletions
diff --git a/server/models/utils.ts b/server/models/utils.ts index fe4596d31..b2573cd35 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts | |||
@@ -207,60 +207,13 @@ function buildDirectionAndField (value: string) { | |||
207 | return { direction, field } | 207 | return { direction, field } |
208 | } | 208 | } |
209 | 209 | ||
210 | function searchAttribute (sourceField, targetField) { | 210 | function searchAttribute (sourceField?: string, targetField?: string) { |
211 | if (sourceField) { | 211 | if (!sourceField) return {} |
212 | return { | ||
213 | [targetField]: { | ||
214 | [Op.iLike]: `%${sourceField}%` | ||
215 | } | ||
216 | } | ||
217 | } else { | ||
218 | return {} | ||
219 | } | ||
220 | } | ||
221 | |||
222 | interface QueryStringFilterPrefixes { | ||
223 | [key: string]: string | { prefix: string, handler: Function, multiple?: boolean } | ||
224 | } | ||
225 | |||
226 | function parseQueryStringFilter (q: string, prefixes: QueryStringFilterPrefixes): { | ||
227 | search: string | ||
228 | [key: string]: string | number | string[] | number[] | ||
229 | } { | ||
230 | const tokens = q // tokenize only if we have a querystring | ||
231 | ? [].concat.apply([], q.split('"').map((v, i) => i % 2 ? v : v.split(' '))).filter(Boolean) // split by space unless using double quotes | ||
232 | : [] | ||
233 | |||
234 | const objectMap = (obj, fn) => Object.fromEntries( | ||
235 | Object.entries(obj).map( | ||
236 | ([ k, v ], i) => [ k, fn(v, k, i) ] | ||
237 | ) | ||
238 | ) | ||
239 | 212 | ||
240 | return { | 213 | return { |
241 | // search is the querystring minus defined filters | 214 | [targetField]: { |
242 | search: tokens.filter(e => !Object.values(prefixes).some(p => { | 215 | [Op.iLike]: `%${sourceField}%` |
243 | if (typeof p === 'string') { | 216 | } |
244 | return e.startsWith(p) | ||
245 | } else { | ||
246 | return e.startsWith(p.prefix) | ||
247 | } | ||
248 | })).join(' '), | ||
249 | // filters defined in prefixes are added under their own name | ||
250 | ...objectMap(prefixes, p => { | ||
251 | if (typeof p === 'string') { | ||
252 | return tokens.filter(e => e.startsWith(p)).map(e => e.slice(p.length)) // we keep the matched item, and remove its prefix | ||
253 | } else { | ||
254 | const _tokens = tokens.filter(e => e.startsWith(p.prefix)).map(e => e.slice(p.prefix.length)).map(p.handler) | ||
255 | // multiple is false by default, meaning we usually just keep the first occurence of a given prefix | ||
256 | if (!p.multiple && _tokens.length > 0) { | ||
257 | return _tokens[0] | ||
258 | } else if (!p.multiple) { | ||
259 | return '' | ||
260 | } | ||
261 | return _tokens | ||
262 | } | ||
263 | }) | ||
264 | } | 217 | } |
265 | } | 218 | } |
266 | 219 | ||
@@ -286,8 +239,7 @@ export { | |||
286 | getFollowsSort, | 239 | getFollowsSort, |
287 | buildDirectionAndField, | 240 | buildDirectionAndField, |
288 | createSafeIn, | 241 | createSafeIn, |
289 | searchAttribute, | 242 | searchAttribute |
290 | parseQueryStringFilter | ||
291 | } | 243 | } |
292 | 244 | ||
293 | // --------------------------------------------------------------------------- | 245 | // --------------------------------------------------------------------------- |