22/* eslint-disable no-param-reassign, no-use-before-define */
33
44import type {
5- ExtendedResolveParams ,
5+ ResolveParams ,
6+ ConnectionResolveParams ,
67 composeWithConnectionOpts ,
78 connectionSortOpts ,
9+ CursorDataType ,
10+ GraphQLConnectionType ,
811} from '../definition' ;
912import { Resolver , TypeComposer } from 'graphql-compose' ;
1013import { GraphQLInt } from 'graphql' ;
@@ -25,15 +28,21 @@ export function prepareConnectionResolver(
2528 + 'This function returns ID from provided object.' ) ;
2629 }
2730
28- const countResolver = typeComposer . getResolver ( 'count' ) ;
31+ const countResolver = typeComposer . getResolver ( opts . countResolverName ) ;
2932 if ( ! countResolver ) {
30- throw new Error ( `TypeComposer(${ typeComposer . getTypeName ( ) } ) should have 'count' resolver` ) ;
33+ throw new Error ( `TypeComposer(${ typeComposer . getTypeName ( ) } ) provided to composeWithConnection `
34+ + `should have resolver with name '${ opts . countResolverName } ' `
35+ + 'due opts.countResolverName.' ) ;
3136 }
37+ const countResolve = countResolver . composeResolve ( ) ;
3238
33- const findManyResolver = typeComposer . getResolver ( 'findMany' ) ;
39+ const findManyResolver = typeComposer . getResolver ( opts . findResolverName ) ;
3440 if ( ! findManyResolver ) {
35- throw new Error ( `TypeComposer(${ typeComposer . getTypeName ( ) } ) should have 'findMany' resolver` ) ;
41+ throw new Error ( `TypeComposer(${ typeComposer . getTypeName ( ) } ) provided to composeWithConnection `
42+ + `should have resolver with name '${ opts . findResolverName } ' `
43+ + 'due opts.countResolverName.' ) ;
3644 }
45+ const findManyResolve = findManyResolver . composeResolve ( ) ;
3746
3847 const additionalArgs = { } ;
3948 if ( findManyResolver . hasArg ( 'filter' ) ) {
@@ -70,16 +79,17 @@ export function prepareConnectionResolver(
7079 description : 'Sort argument for data ordering' ,
7180 } ,
7281 } ,
73- resolve : ( resolveParams : ExtendedResolveParams ) => {
82+ resolve : ( resolveParams : ConnectionResolveParams ) => {
7483 const { projection = { } , args = { } } = resolveParams ;
75- const findManyParams = Object . assign ( { } , resolveParams , {
76- args : { } ,
77- projection : { } ,
78- } ) ;
79- const connSortOpts : connectionSortOpts = resolveParams . args . sort ;
84+ const findManyParams : ResolveParams = Object . assign (
85+ { } ,
86+ resolveParams ,
87+ { args : { } } // clear this params in copy
88+ ) ;
89+ const sortOptions : connectionSortOpts = args . sort ;
8090
81- const first = args . first ;
82- const last = args . last ;
91+ const first = parseInt ( args . first , 10 ) ;
92+ const last = parseInt ( args . last , 10 ) ;
8393
8494 const limit = last || first ;
8595 const skip = ( first - last ) || 0 ;
@@ -89,30 +99,40 @@ export function prepareConnectionResolver(
8999 findManyParams . args . skip = skip ;
90100 }
91101
92- let filter = findManyParams . args . filter ;
102+ let filter = findManyParams . args . filter || { } ;
93103 const beginCursorData = cursorToData ( args . after ) ;
94104 if ( beginCursorData ) {
95- filter = connSortOpts . cursorToFilter ( beginCursorData , filter ) ;
105+ filter = sortOptions . cursorToFilter ( beginCursorData , filter ) ;
96106 }
97107 const endCursorData = cursorToData ( args . before ) ;
98108 if ( endCursorData ) {
99- filter = connSortOpts . cursorToFilter ( endCursorData , filter ) ;
109+ filter = sortOptions . cursorToFilter ( endCursorData , filter ) ;
100110 }
101111 findManyParams . args . filter = filter ;
102-
103112 findManyParams . args . skip = skip ;
104- // findManyParams.args.sort // TODO
105- // findManyParams.projection // TODO
113+
114+ findManyParams . args . sort = sortOptions . sortValue ;
115+ findManyParams . projection = projection ;
116+ sortOptions . uniqueFields . forEach ( fieldName => {
117+ findManyParams . projection [ fieldName ] = true ;
118+ } ) ;
106119
107120 let countPromise ;
108121 if ( projection . count ) {
109- countPromise = countResolver ( resolveParams ) ;
122+ countPromise = countResolve ( resolveParams ) ;
110123 }
111- const findManyPromise = findManyResolver ( findManyParams ) ;
112124 const hasPreviousPage = skip > 0 ;
113125 let hasNextPage = false ; // will be requested +1 document, to check next page presence
114126
115- return findManyPromise
127+ const filterDataForCursor = ( record ) => {
128+ const result = { } ;
129+ sortOptions . uniqueFields . forEach ( fieldName => {
130+ result [ fieldName ] = record [ fieldName ] ;
131+ } ) ;
132+ return result ;
133+ } ;
134+
135+ return findManyResolve ( findManyParams )
116136 . then ( recordList => {
117137 const edges = [ ] ;
118138 // if returned more than `limit` records, strip array and mark that exists next page
@@ -122,9 +142,8 @@ export function prepareConnectionResolver(
122142 }
123143 // transform record to object { cursor, node }
124144 recordList . forEach ( record => {
125- const id = typeComposer . getRecordId ( record ) ;
126145 edges . push ( {
127- cursor : idToCursor ( id ) ,
146+ cursor : dataToCursor ( filterDataForCursor ( record ) ) ,
128147 node : record ,
129148 } ) ;
130149 } ) ;
@@ -155,41 +174,30 @@ export function prepareConnectionResolver(
155174 } ) ;
156175}
157176
158- export function emptyConnection ( ) {
177+ export function emptyConnection ( ) : GraphQLConnectionType {
159178 return {
160179 count : 0 ,
161180 edges : [ ] ,
162181 pageInfo : {
163- startCursor : null ,
164- endCursor : null ,
182+ startCursor : '' ,
183+ endCursor : '' ,
165184 hasPreviousPage : false ,
166185 hasNextPage : false ,
167186 } ,
168187 } ;
169188}
170189
171- export function idToCursor ( id : string ) {
172- return id ;
173- }
174-
175- export function cursorToId ( cursor : string ) {
176- return cursor ;
177- }
178-
179-
180-
181- var PREFIX = 'arrayconnection:' ;
182-
183- /**
184- * Creates the cursor string from an offset.
185- */
186- export function offsetToCursor ( offset : number ) : ConnectionCursor {
187- return base64 ( PREFIX + offset ) ;
190+ export function cursorToData ( id ?: ?string ) : ?CursorDataType {
191+ if ( id ) {
192+ try {
193+ return JSON . parse ( id ) || null ;
194+ } catch ( err ) {
195+ return null ;
196+ }
197+ }
198+ return null ;
188199}
189200
190- /**
191- * Rederives the offset from the cursor string.
192- */
193- export function cursorToOffset ( cursor : ConnectionCursor ) : number {
194- return parseInt ( unbase64 ( cursor ) . substring ( PREFIX . length ) , 10 ) ;
201+ export function dataToCursor ( cursorData : CursorDataType ) : string {
202+ return JSON . stringify ( cursorData ) ;
195203}
0 commit comments