import { IFindParams } from "./interfaces"; const encodeFilterValues = (value: string) => { return value // don't want to encode commas as they are used to send multiple args .split(",") .map(segment => { // decode first to allow client to send raw or encoded const decoded = decodeURIComponent(segment); return encodeURIComponent(decoded); }) .join(","); }; const excludeKeys = [ "include", "resource", "sort", "limit", "offset", "extras", "nocache" ]; export function createFilters(options: Partial) { const resource = options.resource; const filters = Object.keys(options).reduce((memo, key) => { if (excludeKeys.indexOf(key) === -1) { const optionsType = typeof options[key]; if (optionsType === "object") { // determine third filter value based on object keys const base = `filter${resource ? `[${resource}]` : ""}[${key}]`; const filterObject = options[key]; const filters = Object.keys(filterObject).map(k => { let filterValue = filterObject[k]; if (typeof filterValue === "string") { filterValue = encodeFilterValues(filterObject[k]); } return `${base}[${k}]=${filterValue}`; }); memo.push(filters.join("&")); } else { // fallback to equals if a simple string value let filterType = "equals"; let filterValue = optionsType === "string" ? encodeFilterValues(options[key] as string) : options[key]; memo.push( `filter${ resource ? `[${resource}]` : "" }[${key}][${filterType}]=${filterValue}` ); } } return memo; }, []); if (options.extras) { filters.push( Object.keys(options.extras) .reduce((memo, key) => { memo.push(`${key}=${options.extras[key]}`); return memo; }, []) .join("&") ); } if (options.sort) { filters.push(`sort=${options.sort}`); } if (options.limit) { filters.push(`page[limit]=${options.limit}`); } if (options.offset) { filters.push(`page[offset]=${options.offset}`); } return filters.join("&"); } export function createIncludes(include: string | string[]) { const includeString = Array.isArray(include) ? include.join(",") : include; return include ? `include=${includeString}` : ""; } export function createFindByIdUrl( url: string, id: string | string[], options: IFindParams = {} ) { const include = createIncludes(options.include); let noCache = ""; if (options.nocache) { noCache = "nocache=true"; } let idFilters = ""; if (Array.isArray(id)) { idFilters = `filter[${options.resource}][id][equals]=${id.join(",")}`; idFilters += `&page[limit]=${id.length}`; } const filters = createFilters({ resource: options.resource || this.resource, ...options }); const query = [include, noCache, idFilters, filters].filter(f => f).join("&"); if (query.length) { url += `?${query}`; } return url; }