X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2Fcore%2Frest%2Frest.service.ts;h=d8b5ffb1851755aee06a8373a2c035c4cc5bc1d9;hb=0c302acb3c358b4d4d8dee45aed1de1108ea37ea;hp=9e32c6d582eefc3405f2b8b52844d8ceea71738b;hpb=8491293b02ed2ec53eb0fa128161ea0b08d3def9;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/app/core/rest/rest.service.ts b/client/src/app/core/rest/rest.service.ts index 9e32c6d58..d8b5ffb18 100644 --- a/client/src/app/core/rest/rest.service.ts +++ b/client/src/app/core/rest/rest.service.ts @@ -1,21 +1,23 @@ +import * as debug from 'debug' import { SortMeta } from 'primeng/api' import { HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { ComponentPaginationLight } from './component-pagination.model' import { RestPagination } from './rest-pagination' +const debugLogger = debug('peertube:rest') + interface QueryStringFilterPrefixes { [key: string]: { prefix: string - handler?: (v: string) => string | number + handler?: (v: string) => string | number | boolean multiple?: boolean isBoolean?: boolean } } -type ParseQueryStringFilterResult = { - [key: string]: string | number | boolean | (string | number | boolean)[] -} +type ParseQueryStringFilters = Partial> +type ParseQueryStringFiltersResult = ParseQueryStringFilters & { search?: string } @Injectable() export class RestService { @@ -29,19 +31,27 @@ export class RestService { } if (sort !== undefined) { - let sortString = '' + newParams = newParams.set('sort', this.buildSortString(sort)) + } - if (typeof sort === 'string') { - sortString = sort - } else { - const sortPrefix = sort.order === 1 ? '' : '-' - sortString = sortPrefix + sort.field - } + return newParams + } - newParams = newParams.set('sort', sortString) + buildSortString (sort: SortMeta | string) { + if (typeof sort === 'string') { + return sort } - return newParams + const sortPrefix = sort.order === 1 ? '' : '-' + return sortPrefix + sort.field + } + + addArrayParams (params: HttpParams, name: string, values: (string | number)[]) { + for (const v of values) { + params = params.append(name, v) + } + + return params } addObjectParams (params: HttpParams, object: { [ name: string ]: any }) { @@ -49,8 +59,8 @@ export class RestService { const value = object[name] if (value === undefined || value === null) continue - if (Array.isArray(value) && value.length !== 0) { - for (const v of value) params = params.append(name, v) + if (Array.isArray(value)) { + params = this.addArrayParams(params, name, value) } else { params = params.append(name, value) } @@ -59,45 +69,54 @@ export class RestService { return params } - componentPaginationToRestPagination (componentPagination: ComponentPaginationLight): RestPagination { + componentToRestPagination (componentPagination: ComponentPaginationLight): RestPagination { const start: number = (componentPagination.currentPage - 1) * componentPagination.itemsPerPage const count: number = componentPagination.itemsPerPage return { start, count } } - parseQueryStringFilter (q: string, prefixes: QueryStringFilterPrefixes): ParseQueryStringFilterResult { + /* + * Returns an object containing the filters and the remaining search + */ + parseQueryStringFilter (q: string, prefixes: T): ParseQueryStringFiltersResult { if (!q) return {} - // Tokenize the strings using spaces that are not in quotes - const tokens = q.match(/(?:[^\s"]+|"[^"]*")+/g) - .filter(token => !!token) + const tokens = this.tokenizeString(q) // Build prefix array const prefixeStrings = Object.values(prefixes) - .map(p => p.prefix) + .map(p => p.prefix) + + debugLogger(`Built tokens "${tokens.join(', ')}" for prefixes "${prefixeStrings.join(', ')}"`) // Search is the querystring minus defined filters const searchTokens = tokens.filter(t => { return prefixeStrings.every(prefixString => t.startsWith(prefixString) === false) }) - const additionalFilters: ParseQueryStringFilterResult = {} + const additionalFilters: ParseQueryStringFilters = {} - for (const prefixKey of Object.keys(prefixes)) { + for (const prefixKey of Object.keys(prefixes) as (keyof T)[]) { const prefixObj = prefixes[prefixKey] const prefix = prefixObj.prefix const matchedTokens = tokens.filter(t => t.startsWith(prefix)) .map(t => t.slice(prefix.length)) // Keep the value filter - .map(t => t.replace(/^"|"$/g, '')) + .map(t => t.replace(/^"|"$/g, '')) // Remove "" .map(t => { if (prefixObj.handler) return prefixObj.handler(t) + if (prefixObj.isBoolean) { + if (t === 'true') return true + if (t === 'false') return false + + return undefined + } + return t }) - .filter(t => !!t || t === 0) - .map(t => prefixObj.isBoolean ? t === 'true' : t) + .filter(t => t !== null && t !== undefined) if (matchedTokens.length === 0) continue @@ -106,10 +125,22 @@ export class RestService { : matchedTokens[0] } + const search = searchTokens.join(' ') || undefined + + debugLogger('Built search: ' + search, additionalFilters) + return { - search: searchTokens.join(' ') || undefined, + search, ...additionalFilters } } + + tokenizeString (q: string) { + if (!q) return [] + + // Tokenize the strings using spaces that are not in quotes + return q.match(/(?:[^\s"]+|"[^"]*")+/g) + .filter(token => !!token) + } }