diff options
Diffstat (limited to 'server/models/utils.ts')
-rw-r--r-- | server/models/utils.ts | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/server/models/utils.ts b/server/models/utils.ts index bdf2291f0..3e3825b32 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts | |||
@@ -219,6 +219,54 @@ function searchAttribute (sourceField, targetField) { | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | interface QueryStringFilterPrefixes { | ||
223 | [key: string]: string | { prefix: string, handler: Function, multiple?: boolean } | ||
224 | } | ||
225 | |||
226 | function parseQueryStringFilter (q: string, prefixes: QueryStringFilterPrefixes) { | ||
227 | const tokens = q // tokenize only if we have a querystring | ||
228 | ? [].concat.apply([], q.split('"').map((v, i) => i % 2 ? v : v.split(' '))).filter(Boolean) | ||
229 | : [] | ||
230 | |||
231 | // TODO: when Typescript supports Object.fromEntries, replace with the Object method | ||
232 | function fromEntries<T> (entries: [keyof T, T[keyof T]][]): T { | ||
233 | return entries.reduce( | ||
234 | (acc, [ key, value ]) => ({ ...acc, [key]: value }), | ||
235 | {} as T | ||
236 | ) | ||
237 | } | ||
238 | |||
239 | const objectMap = (obj, fn) => fromEntries( | ||
240 | Object.entries(obj).map( | ||
241 | ([ k, v ], i) => [ k, fn(v, k, i) ] | ||
242 | ) | ||
243 | ) | ||
244 | |||
245 | return { | ||
246 | // search is the querystring minus defined filters | ||
247 | search: tokens.filter(e => !Object.values(prefixes).some(p => { | ||
248 | if (typeof p === "string") { | ||
249 | return e.startsWith(p) | ||
250 | } else { | ||
251 | return e.startsWith(p.prefix) | ||
252 | } | ||
253 | })).join(' '), | ||
254 | // filters defined in prefixes are added under their own name | ||
255 | ...objectMap(prefixes, v => { | ||
256 | if (typeof v === "string") { | ||
257 | return tokens.filter(e => e.startsWith(v)).map(e => e.slice(v.length)) | ||
258 | } else { | ||
259 | const _tokens = tokens.filter(e => e.startsWith(v.prefix)).map(e => e.slice(v.prefix.length)).map(v.handler) | ||
260 | return !v.multiple | ||
261 | ? _tokens.length > 0 | ||
262 | ? _tokens[0] | ||
263 | : '' | ||
264 | : _tokens | ||
265 | } | ||
266 | }) | ||
267 | } | ||
268 | } | ||
269 | |||
222 | // --------------------------------------------------------------------------- | 270 | // --------------------------------------------------------------------------- |
223 | 271 | ||
224 | export { | 272 | export { |
@@ -241,7 +289,8 @@ export { | |||
241 | getFollowsSort, | 289 | getFollowsSort, |
242 | buildDirectionAndField, | 290 | buildDirectionAndField, |
243 | createSafeIn, | 291 | createSafeIn, |
244 | searchAttribute | 292 | searchAttribute, |
293 | parseQueryStringFilter | ||
245 | } | 294 | } |
246 | 295 | ||
247 | // --------------------------------------------------------------------------- | 296 | // --------------------------------------------------------------------------- |