]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/utils.ts
parseQueryStringFilter cleanup
[github/Chocobozzz/PeerTube.git] / server / models / utils.ts
index bdf2291f0ceb5b34ed3c089de5e71044ec7304b8..fe4596d31b5ff5818033a5ce8a2448ce0eed3748 100644 (file)
@@ -219,6 +219,51 @@ function searchAttribute (sourceField, targetField) {
   }
 }
 
+interface QueryStringFilterPrefixes {
+  [key: string]: string | { prefix: string, handler: Function, multiple?: boolean }
+}
+
+function parseQueryStringFilter (q: string, prefixes: QueryStringFilterPrefixes): {
+  search: string
+  [key: string]: string | number | string[] | number[]
+} {
+  const tokens = q // tokenize only if we have a querystring
+    ? [].concat.apply([], q.split('"').map((v, i) => i % 2 ? v : v.split(' '))).filter(Boolean) // split by space unless using double quotes
+    : []
+
+  const objectMap = (obj, fn) => Object.fromEntries(
+    Object.entries(obj).map(
+      ([ k, v ], i) => [ k, fn(v, k, i) ]
+    )
+  )
+
+  return {
+    // search is the querystring minus defined filters
+    search: tokens.filter(e => !Object.values(prefixes).some(p => {
+      if (typeof p === 'string') {
+        return e.startsWith(p)
+      } else {
+        return e.startsWith(p.prefix)
+      }
+    })).join(' '),
+    // filters defined in prefixes are added under their own name
+    ...objectMap(prefixes, p => {
+      if (typeof p === 'string') {
+        return tokens.filter(e => e.startsWith(p)).map(e => e.slice(p.length)) // we keep the matched item, and remove its prefix
+      } else {
+        const _tokens = tokens.filter(e => e.startsWith(p.prefix)).map(e => e.slice(p.prefix.length)).map(p.handler)
+        // multiple is false by default, meaning we usually just keep the first occurence of a given prefix
+        if (!p.multiple && _tokens.length > 0) {
+          return _tokens[0]
+        } else if (!p.multiple) {
+          return ''
+        }
+        return _tokens
+      }
+    })
+  }
+}
+
 // ---------------------------------------------------------------------------
 
 export {
@@ -241,7 +286,8 @@ export {
   getFollowsSort,
   buildDirectionAndField,
   createSafeIn,
-  searchAttribute
+  searchAttribute,
+  parseQueryStringFilter
 }
 
 // ---------------------------------------------------------------------------