import { HasId , QueryKey , DocumentSnapshot , QuerySnapshot , WhereFilterOp , FieldPath , OrderByDirection , Query as FirestoreQuery } from './types' ; import { Converter } from './converter' ; import { Context } from './context' ; export class Query < T extends HasId , S > { constructor ( public converter , public context , public query ) { } where ( fieldPath , opStr , value ) { this . query = this . query . where ( fieldPath as string | FieldPath , opStr , value ) ; return this ; } orderBy ( fieldPath , directionStr ? ) { this . query = this . query . orderBy ( fieldPath as string | FieldPath , directionStr ) ; return this ; } limit ( limit ) { this . query = this . query . limit ( limit ) ; return this ; } startAt ( snapshot ) ; startAt ( ... fieldValues ) ; startAt ( snapshotOrValue , ... fieldValues ) { if ( ! this . query ) throw new Error ( 'no query statement before startAt()' ) ; this . query = this . query . startAt ( snapshotOrValue , ... fieldValues ) ; return this ; } startAfter ( snapshot ) ; startAfter ( ... fieldValues ) ; startAfter ( snapshotOrValue , ... fieldValues ) { if ( ! this . query ) throw new Error ( 'no query statement before startAfter()' ) ; this . query = this . query . startAfter ( snapshotOrValue , ... fieldValues ) ; return this ; } endAt ( snapshot ) ; endAt ( ... fieldValues ) ; endAt ( snapshotOrValue , ... fieldValues ) { if ( ! this . query ) throw new Error ( 'no query statement before endAt()' ) ; this . query = this . query . endAt ( snapshotOrValue , ... fieldValues ) ; return this ; } endBefore ( snapshot ) ; endBefore ( ... fieldValues ) ; endBefore ( snapshotOrValue , ... fieldValues ) { if ( ! this . query ) throw new Error ( 'no query statement before endBefore()' ) ; this . query = this . query . endBefore ( snapshotOrValue , ... fieldValues ) ; return this ; } async fetch ( ) { if ( ! this . query ) throw new Error ( 'no query statement before fetch()' ) ; if ( this . context . tx ) throw new Error ( 'Web SDK transaction.get() does not support QuerySnapshot' ) ; const snapshot = await this . query . get ( ) ; return snapshot . docs . map ( ( documentSnapshot ) => { return this . converter . decode ( documentSnapshot ) ; } ) ; } onSnapshot ( callback ) { if ( ! this . query ) throw new Error ( 'no query statement before onSnapshot()' ) ; return this . query . onSnapshot ( ( _querySnapshot ) => { callback ( _querySnapshot , this . converter . decode . bind ( this . converter ) ) ; } ) ; } }