import { HttpBackend , HttpErrorResponse , HttpEvent , HttpHandler , HttpInterceptor , HttpRequest , HttpResponse , HttpResponseBase , HTTP_INTERCEPTORS } from '@angular/common/http' ; import { Injectable , Injector } from '@angular/core' ; import { Observable , of , throwError } from 'rxjs' ; import { delay } from 'rxjs/operators' ; import { deepCopy } from '@delon/util/other' ; import type { NzSafeAny } from 'ng-zorro-antd/core/types' ; import { MockRequest } from './interface' ; import { MockService } from './mock.service' ; import { MockStatusError } from './status.error' ; class HttpMockInterceptorHandler implements HttpHandler { constructor ( private next , private interceptor ) { } handle ( req ) { return this . interceptor . intercept ( req , this . next ) ; } } @ Injectable ( ) export class MockInterceptor implements HttpInterceptor { constructor ( private injector ) { } intercept ( req , next ) { const src = this . injector . get ( MockService ) ; const config = src . config ; const rule = src . getRule ( req . method , req . url . split ( '?' ) [ 0 ] ) ; if ( ! rule && ! config . force ) { return next . handle ( req ) ; } let res ; switch ( typeof rule ! . callback ) { case 'function' : const mockRequest = { original : req , body : req . body , queryString : { } , headers : { } , params : rule ! . params } ; const urlParams = req . url . split ( '?' ) ; if ( urlParams . length > 1 ) { urlParams [ 1 ] . split ( '&' ) . forEach ( item => { const itemArr = item . split ( '=' ) ; const key = itemArr [ 0 ] ; const value = itemArr [ 1 ] ; if ( Object . keys ( mockRequest . queryString ) . includes ( key ) ) { if ( ! Array . isArray ( mockRequest . queryString [ key ] ) ) { mockRequest . queryString [ key ] = [ mockRequest . queryString [ key ] ] ; } mockRequest . queryString [ key ] . push ( value ) ; } else { mockRequest . queryString [ key ] = value ; } } ) ; } req . params . keys ( ) . forEach ( key => ( mockRequest . queryString [ key ] = req . params . get ( key ) ) ) ; req . headers . keys ( ) . forEach ( key => ( mockRequest . headers [ key ] = req . headers . get ( key ) ) ) ; try { res = rule ! . callback . call ( this , mockRequest ) ; } catch ( e ) { res = new HttpErrorResponse ( { url : req . url , headers : req . headers , status : e instanceof MockStatusError ? e . status : 400 , statusText : e . statusText || 'Unknown Error' , error : e . error } ) ; } break ; default : res = rule ! . callback ; break ; } if ( ! ( res instanceof HttpResponseBase ) ) { res = new HttpResponse ( { status : 200 , url : req . url , body : res } ) ; } if ( res . body ) { res . body = deepCopy ( res . body ) ; } if ( config . log ) { console . log ( `%c👽${ req . method }->${ req . urlWithParams }->request` , 'background:#000;color:#bada55' , req ) ; console . log ( `%c👽${ req . method }->${ req . urlWithParams }->response` , 'background:#000;color:#bada55' , res ) ; } const res$ = res instanceof HttpErrorResponse ? throwError ( ( ) => res ) : of ( res ) ; if ( config . executeOtherInterceptors ) { const interceptors = this . injector . get ( HTTP_INTERCEPTORS , [ ] ) ; const lastInterceptors = interceptors . slice ( interceptors . indexOf ( this ) + 1 ) ; if ( lastInterceptors . length > 0 ) { const chain = lastInterceptors . reduceRight ( ( _next , _interceptor ) => new HttpMockInterceptorHandler ( _next , _interceptor ) , { handle : ( ) => res$ } as HttpBackend ) ; return chain . handle ( req ) . pipe ( delay ( config . delay ! ) ) ; } } return res$ . pipe ( delay ( config . delay ! ) ) ; } }