import { Breadcrumb , Event , Response , User } from '@sentry/types' ; import { getGlobalObject , logger , SentryError } from '@sentry/utils' ; import { CordovaOptions } from './backend' ; import { CordovaPlatformType } from './types' ; import { getPlatform , processLevel , serializeObject } from './utils' ; /**
 * Our internal interface for calling native functions
 */ export const NATIVE = { PLUGIN_NAME : 'Sentry' , SUPPORTS_NATIVE_TRANSPORT : [ CordovaPlatformType . Ios , CordovaPlatformType . Android ] , SUPPORTS_NATIVE_SCOPE_SYNC : [ CordovaPlatformType . Ios , CordovaPlatformType . Android ] , SUPPORTS_NATIVE_SDK : [ CordovaPlatformType . Android , CordovaPlatformType . Ios ] , param options async startWithOptions ( _options ) { if ( this . SUPPORTS_NATIVE_SDK . includes ( getPlatform ( ) ) ) { const options = { enableNative : true , ... _options , } ; this . enableNative = options . enableNative ; if ( ! options . enableNative ) { return false ; } if ( ! options . dsn ) { logger . warn ( 'Warning: No DSN was provided. The Sentry SDK will be disabled. Native SDK will also not be initialized.' ) ; return false ; } const { beforeSend , beforeBreadcrumb , integrations , defaultIntegrations , transport , ... filteredOptions } = options ; return this . _nativeCall ( 'startWithOptions' , filteredOptions ) . then ( ( ) => { this . _nativeInitialized = true ; return true ; } ) . catch ( ( ) => { this . _nativeInitialized = false ; logger . warn ( 'Warning: Native SDK was not initialized.' ) ; return false ; } ) ; } this . _nativeInitialized = false ; return false ; } , param event async sendEvent ( event ) { if ( ! this . isNativeClientAvailable ( ) ) { throw this . _NativeClientError ; } if ( ! this . isNativeTransportAvailable ( ) ) { throw this . _NativeTransportError ; } event . level = event . level ? processLevel ( event . level ) : undefined ; const header = { event_id : event . event_id , sdk : event . sdk , } ; const payload = { ... event , message : { message : event . message , } , } ; if ( getPlatform ( ) === CordovaPlatformType . Android ) { const headerString = JSON . stringify ( header ) ; const payloadString = JSON . stringify ( payload ) ; const payloadType = payload . type ?? 'event' ; return this . _nativeCall ( 'captureEnvelope' , headerString , payloadString , payloadType ) ; } const serializedPayload = JSON . parse ( JSON . stringify ( payload ) ) ; return this . _nativeCall ( 'captureEnvelope' , header , serializedPayload ) ; } , param action param args async _nativeCall ( action , ... args ) { return new Promise < any > ( ( resolve , reject ) => { if ( ! this . enableNative ) { reject ( 'enableNative = false, using browser transport' ) ; return ; } const _window = getGlobalObject < any > ( ) ; const exec = _window && _window . Cordova && _window . Cordova . exec ; if ( ! exec ) { reject ( 'Cordova.exec not available' ) ; } else { try { _window . Cordova . exec ( resolve , reject , this . PLUGIN_NAME , action , args ) ; } catch ( e ) { reject ( 'Cordova.exec not available' ) ; } } } ) ; } , param key param value setUser ( user ) { if ( ! this . isNativeScopeSyncAvailable ( ) ) { return ; } let defaultUserKeys = null ; let otherUserKeys = null ; if ( user ) { const { id , ip_address , email , username , ... otherKeys } = user ; defaultUserKeys = serializeObject ( { email , id , ip_address , username , } ) ; otherUserKeys = serializeObject ( otherKeys ) ; } void this . _nativeCall ( 'setUser' , defaultUserKeys , otherUserKeys ) ; } , param key param value setTag ( key , value ) { if ( ! this . isNativeScopeSyncAvailable ( ) ) { return ; } const stringifiedValue = typeof value === 'string' ? value : JSON . stringify ( value ) ; void this . _nativeCall ( 'setTag' , key , stringifiedValue ) ; } , param key param extra setExtra ( key , extra ) { if ( ! this . isNativeScopeSyncAvailable ( ) ) { return ; } const stringifiedExtra = typeof extra === 'string' ? extra : JSON . stringify ( extra ) ; void this . _nativeCall ( 'setExtra' , key , stringifiedExtra ) ; } , param breadcrumb addBreadcrumb ( breadcrumb ) { if ( ! this . isNativeScopeSyncAvailable ( ) ) { return ; } void this . _nativeCall ( 'addBreadcrumb' , { ... breadcrumb , level : breadcrumb . level ? processLevel ( breadcrumb . level ) : undefined , data : breadcrumb . data ? serializeObject ( breadcrumb . data ) : undefined , } ) ; } , /**
     * Clears breadcrumbs on the native scope.
     */ clearBreadcrumbs ( ) { if ( ! this . isNativeScopeSyncAvailable ( ) ) { return ; } void this . _nativeCall ( 'clearBreadcrumbs' ) ; } , param key param context setContext ( key , context ) { if ( ! this . isNativeScopeSyncAvailable ( ) ) { return ; } void this . _nativeCall ( 'setContext' , key , context !== null ? serializeObject ( context ) : null ) ; } , /**
     * Triggers a native crash.
     * Use this only for testing purposes.
     */ crash ( ) { if ( ! this . enableNative ) { return ; } if ( ! this . isNativeClientAvailable ( ) ) { throw this . _NativeClientError ; } void this . _nativeCall ( 'crash' ) ; } , /**
     * Returns whether the native client is available.
     */ isNativeClientAvailable ( ) { return this . enableNative && this . _nativeInitialized ; } , /**
     * Returns whether the native transport is available.
     */ isNativeTransportAvailable ( ) { return this . isNativeClientAvailable ( ) && this . SUPPORTS_NATIVE_TRANSPORT . includes ( getPlatform ( ) ) ; } , /**
     * Returns whether native bridge supports scope sync.
     */ isNativeScopeSyncAvailable ( ) { return this . isNativeClientAvailable ( ) && this . SUPPORTS_NATIVE_SCOPE_SYNC . includes ( getPlatform ( ) ) ; } , _NativeClientError : new SentryError ( 'Native Client is not available.' ) , _NativeTransportError : new SentryError ( 'Native Transport is not available.' ) , enableNative : true , _nativeInitialized : false , /** true if `getPlatform` has been called */ _didGetPlatform : false , } ;