11import * as atob from 'atob' ;
2- import { get , mapValues } from 'lodash' ;
2+ import { get } from 'lodash' ;
33import { start } from '../../types/Cursor' ;
44import Entity from '../../types/Entity' ;
55// tslint:disable-next-line:no-unused
@@ -13,30 +13,53 @@ const xor = (conditionA: boolean, conditionB: boolean) => {
1313 return ( conditionA && ! conditionB ) || ( ! conditionA && conditionB ) ;
1414} ;
1515
16+ const getCursorKeyFilter = < E extends Entity > (
17+ sortKey : string ,
18+ sort : Sort < E > ,
19+ pagination : Pagination ,
20+ cursorObj : any ,
21+ ) => {
22+ const sortOrder = get ( sort , sortKey ) ;
23+ const ascendingPagination = ! xor (
24+ sortOrder === asc ,
25+ pagination . direction === forward ,
26+ ) ;
27+ const cursorValue = get ( cursorObj , sortKey ) ;
28+ if ( ascendingPagination ) {
29+ if ( sortKey === 'id' ) {
30+ return { $gt : cursorValue } ;
31+ } else {
32+ return { $gte : cursorValue } ;
33+ }
34+ } else {
35+ if ( sortKey === 'id' ) {
36+ return { $lt : cursorValue } ;
37+ } else {
38+ return { $lte : cursorValue } ;
39+ }
40+ }
41+ } ;
42+
1643export default < E extends Entity > ( pagination : Pagination , sort : Sort < E > ) : Filter < E > => {
17- if ( pagination . cursor === start ) {
44+ const cursor = pagination . cursor ;
45+ if ( cursor === start ) {
1846 return { } ;
1947 }
20- const cursor = pagination . cursor ;
48+
2149 const cursorObj = JSON . parse ( atob ( cursor ) ) ;
22- const filter = mapValues ( cursorObj , ( cursorValue , sortKey ) => {
23- const ascendingPagination = ! xor (
24- get ( sort , sortKey ) === asc ,
25- pagination . direction === forward ,
26- ) ;
27- if ( ascendingPagination ) {
28- if ( sortKey === 'id' ) {
29- return { $gt : cursorValue } ;
30- } else {
31- return { $gte : cursorValue } ;
32- }
33- } else {
34- if ( sortKey === 'id' ) {
35- return { $lt : cursorValue } ;
36- } else {
37- return { $lte : cursorValue } ;
38- }
39- }
50+ const sortKeys = Object . keys ( sort ) ;
51+ const sortKeyFilters = sortKeys . map ( ( sortKey , keyIndex ) => {
52+ const sortKeysToMatch = sortKeys . slice ( 0 , keyIndex ) ;
53+ const matchFilter = sortKeysToMatch . reduce ( ( result : any , sortKeyToMatch ) => {
54+ result [ sortKeyToMatch ] = cursorObj [ sortKeyToMatch ] ;
55+ return result ;
56+ } , { } ) ;
57+
58+ const cursorKeyFilter = getCursorKeyFilter ( sortKey , sort , pagination , cursorObj ) ;
59+ matchFilter [ sortKey ] = cursorKeyFilter ;
60+ return matchFilter ;
4061 } ) ;
62+
63+ const filter = { $or : sortKeyFilters } ;
4164 return filter as any as Filter < E > ;
4265} ;
0 commit comments