import { Observable } from 'rxjs/Observable' ; import { SDKFetch , SDKFetchOptions } from '../SDKFetch' ; import { Page } from '../Net' ; export type MapFunc < T , K = T > = ( value : T , index : number , array : T [ ] , headers : Headers ) => K ; export type RequestOptions < T , K > = SDKFetchOptions & { pageSize ? : number ; urlQuery ? : { } ; mapFn ? : MapFunc < T , K > ; includeHeaders ? : true ; wrapped ? : false ; /**
     * 设置请求使用的 HTTP 方法，默认使用 'get'，如果查询内容
     * 不适合使用 GET 方法，可以提供 'post' 设置使用 POST 方法。
     */ method ? : 'get' | 'post' ; } ; function toUrlQuery < T > ( state , perRequestPageSize ? , perRequestUrlQuery ? ) { const urlQuery = { ... state . urlQuery , ... perRequestUrlQuery } ; const pageSize = perRequestPageSize || ( urlQuery && ( urlQuery [ 'pageSize' ] || urlQuery [ 'count' ] ) ) || state . pageSize ; switch ( state . kind ) { case Page . Kind . PageCount : urlQuery [ 'page' ] = state . nextPage ; urlQuery [ 'count' ] = pageSize ; break ; case Page . Kind . PageToken : urlQuery [ 'pageToken' ] = state . nextPageToken ; urlQuery [ 'pageSize' ] = pageSize ; break ; } return urlQuery ; } export function page < T , K = T > ( this , state , options ? ) ; export function page < T , K = T > ( this , state , options ? ) ; export function page < T , K = T > ( this , state , options ? ) ; export function page < T , K = T > ( this , state , options = { } ) { const { pageSize , urlQuery , mapFn , method , ... requestOptions } = options ; const paginationUrlQuery = toUrlQuery ( state , pageSize , urlQuery ) ; const httpMethod = method || 'get' ; const request$ = this [ httpMethod ] < T [ ] | Page . OriginalResponse < T > > ( state . urlPath , paginationUrlQuery , { ... requestOptions , wrapped : false , includeHeaders : true } ) ; return request$ . map ( ( { headers , body } ) => { switch ( state . kind ) { case Page . Kind . PageCount : { const result = body as T [ ] ; return ! options . mapFn ? result as any as K [ ] : result . map ( ( x , i , arr ) => options . mapFn ! ( x , i , arr , headers ) ) ; } case Page . Kind . PageToken : { const resp = body as Page . OriginalResponse < T > ; const result = resp . result ; return { nextPageToken : resp . nextPageToken , totalSize : resp . totalSize , result : ! options . mapFn ? result as any as K [ ] : result . map ( ( x , i , arr ) => options . mapFn ! ( x , i , arr , headers ) ) } ; } default : return body ; } } ) ; } export type ExpandPageOptions < T , K > = RequestOptions < T , K > & { mutate ? : boolean ; loadMore$ ? : Observable < { } > ; skipConcat ? : boolean ; } ; export function expandPage < T , K = T > ( this , state , options ? ) ; export function expandPage < T , K = T > ( this , state , options ? ) ; export function expandPage < T , K = T > ( this , state , options ? ) ; param state param options export function expandPage < T , K = T > ( this , state , options = { } ) { const { mutate , loadMore$ , skipConcat , ... requestOptions } = options ; const page$ = ( loadMore$ || Observable . empty ( ) ) . startWith ( { } ) . pipe ( Page . expand < K > ( ( s ) => this . page ( s , requestOptions ) , skipConcat ? Page . accUpdate : Page . accConcat , state ) ) . mergeAll ( ) ; return ! mutate ? page$ : page$ . do ( ( nextState ) => Object . assign ( state , nextState ) ) ; } SDKFetch . prototype . expandPage = expandPage ; SDKFetch . prototype . page = page ; declare module '../SDKFetch' { interface SDKFetch { expandPage : typeof expandPage ; page : typeof page ; } }