import { BrtCookies , BrtData , BrtFeedback , BrtField , BrtLog , BrtNavigatorInfo , BrtScreenInfo , BrtServiceWorker } from '@bruit/types' ; import { BrtFieldType } from '@bruit/types/dist/enums/brt-field-type' ; import { NavigatorTool } from '../bruit-tools/navigator' ; import { ScreenTool } from '../bruit-tools/screen' ; import * as Config from '../config/config.json' ; import { BruitIoConfig } from '../models/bruit-io-config.class' ; import { Api } from './api' ; export class Feedback implements BrtFeedback { bruitIoConfig : BruitIoConfig ; apiKey : string ; apiUrl : string = Config [ 'BRUIT_IO_API_URL' ] ; date : string ; canvas : Blob ; url : string ; cookies : BrtCookies ; navigator : BrtNavigatorInfo ; display : BrtScreenInfo ; logs : Array < BrtLog > ; data : Array < BrtData > ; serviceWorkers : Array < BrtServiceWorker > ; version : string ; constructor ( bruitIoConfig ? , apiKey ? ) { this . bruitIoConfig = bruitIoConfig ; this . apiUrl = bruitIoConfig . apiUrl ; this . version = Config [ 'version' ] ; if ( this . bruitIoConfig ) this . apiKey = this . bruitIoConfig . apiKey ; if ( apiKey ) this . apiKey = apiKey ; } param formFields param data param dataFn public async send ( formFields , data = [ ] , dataFn ? ) { try { const agreementField = formFields . find ( field => field . id === 'agreement' ) ; const agreement = agreementField ? agreementField . value : false ; if ( agreement ) { const [ screenShot , navigator , serviceWorkers ] = await Promise . all ( [ ScreenTool . getScreenshot ( this . bruitIoConfig ) . catch ( err => { console . error ( '!!! An error occured with html2canvas screenshot, we send feedback without it. err=' , err ) ; return Promise . resolve ( null ) ; } ) , NavigatorTool . getInfo ( ) , NavigatorTool . getServiceWorkersList ( ) ] ) ; this . navigator = navigator ; this . serviceWorkers = serviceWorkers ; this . canvas = screenShot ; this . url = NavigatorTool . getUrl ( ) ; this . cookies = NavigatorTool . getCookies ( ) ; this . display = ScreenTool . getInfo ( ) ; if ( ( < any > console ) . overloadable && ( < any > console ) . overloaded && ( < any > console ) . overloaded . logArray ) { this . logs = ( < any > console ) . logArray ( ) ; } else { this . logs = [ ] ; } } const dataFromFn = await this . getDataFromFn ( dataFn ) ; const formData = formFields . map ( field => this . fieldToData ( field ) ) ; this . data = [ ... formData , ... data , ... dataFromFn ] ; return Api . postFeedback ( { date : new Date ( ) . toString ( ) , apiKey : this . apiKey , version : this . version , canvas : agreement ? this . canvas : undefined , url : this . url , cookies : agreement ? this . cookies : undefined , navigator : agreement ? this . navigator : undefined , display : agreement ? this . display : undefined , logs : agreement ? this . logs : undefined , serviceWorkers : agreement ? this . serviceWorkers : undefined , data : this . data } , this . apiUrl ) ; } catch ( e ) { throw e ; } } param dataFn return private getDataFromFn < T = ( ) => Array < BrtData > | Promise < Array < BrtData > > > ( dataFn ? ) { if ( dataFn ) { if ( typeof dataFn === 'function' ) { const dataFromFn = ( dataFn as any ) ( ) ; if ( typeof dataFromFn === 'function' || ( typeof dataFromFn === 'object' && ( < Promise < Array < BrtData > > > dataFromFn ) . then ) ) { return this . getDataFromFn ( dataFromFn ) ; } return Promise . resolve ( dataFromFn ) ; } else if ( typeof dataFn === 'object' && ( dataFn as any ) . then ) { return < any > dataFn ; } } else { return Promise . resolve ( [ ] ) ; } } param field return private fieldToData ( field ) { const data = < BrtData > { type : field . type , value : field . value , label : field . label , id : field . id } ; if ( data . type === BrtFieldType . RATING ) { data . max = field . max || 5 ; } return data ; } }