@@ -791,27 +791,85 @@ module.exports.getData = async (req, res) => {
791791 }
792792
793793 const connection = await getConnection ( projectId ) ;
794- const model = getCompiledModel ( connection , collectionConfig , projectId , project . resources . db . isExternal ) ;
794+ const model = getCompiledModel (
795+ connection ,
796+ collectionConfig ,
797+ projectId ,
798+ project . resources . db . isExternal ,
799+ ) ;
795800
796- // const collectionsList = await mongoose.connection.db.listCollections({ name: finalCollectionName }).toArray ();
801+ const baseQuery = model . find ( ) ;
797802
798- const query = model . find ( ) ;
803+ // Strip password from users collection
799804 if ( collectionName === 'users' ) {
800- query . select ( '-password' ) ;
805+ baseQuery . select ( '-password' ) ;
806+ }
807+
808+ // Handle ?count=true — return document count only
809+ if ( req . query . count === 'true' ) {
810+ const countEngine = new QueryEngine ( model . find ( ) , req . query ) ;
811+ const count = await countEngine . filter ( ) . query . countDocuments ( ) ;
812+ return res . status ( 200 ) . json ( {
813+ success : true ,
814+ data : { count } ,
815+ message : "Count fetched successfully." ,
816+ } ) ;
801817 }
802818
803- const features = new QueryEngine ( query , req . query )
819+ const features = new QueryEngine ( baseQuery , req . query )
804820 . filter ( )
805821 . sort ( )
806- . paginate ( ) ;
822+ . limitFields ( ) // fixes: ?fields= and ?meta=false now work
823+ . populate ( ) ; // fixes: ?populate= and ?expand= now work
824+
825+ // Get total before paginating
826+ const total = await features . count ( ) ;
827+
828+ // Cursor-based pagination if ?cursor= is provided, otherwise offset-based
829+ const useCursor = ! ! req . query . cursor ;
830+ if ( useCursor ) {
831+ features . cursorPaginate ( ) ;
832+ } else {
833+ features . paginate ( ) ;
834+ }
807835
808836 const data = await features . query . lean ( ) ;
809837
810- res . json ( data ) ;
838+ // Cursor: slice to limit and generate next cursor token
839+ let items = data ;
840+ let nextCursor = null ;
841+ if ( useCursor ) {
842+ const limit = Math . min ( parseInt ( req . query . limit , 10 ) || 100 , 100 ) ;
843+ features . generateNextCursor ( data , limit ) ;
844+ items = data . slice ( 0 , limit ) ;
845+ nextCursor = features . nextCursor ;
846+ }
847+
848+ const responseMeta = useCursor
849+ ? {
850+ total,
851+ cursor : req . query . cursor || null ,
852+ nextCursor,
853+ limit : Math . max ( 1 , Math . min ( parseInt ( req . query . limit , 10 ) || 100 , 100 ) ) ,
854+ }
855+ : {
856+ total,
857+ page : parseInt ( req . query . page , 10 ) || 1 ,
858+ limit : Math . max ( 1 , Math . min ( parseInt ( req . query . limit , 10 ) || 100 , 100 ) ) ,
859+ } ;
860+
861+ res . json ( {
862+ success : true ,
863+ data : {
864+ items,
865+ ...responseMeta ,
866+ } ,
867+ message : "Data fetched successfully." ,
868+ } ) ;
811869 } catch ( err ) {
812870 res . status ( 500 ) . json ( { error : err . message } ) ;
813871 }
814- }
872+ } ;
815873
816874module . exports . deleteCollection = async ( req , res ) => {
817875 try {
0 commit comments