11// @flow
22import { configureScope } from '@sentry/minimal' ;
33import { Scope } from '@sentry/types' ;
4- import { Action , AnyAction , PreloadedState , Reducer , StoreEnhancer , StoreEnhancerStoreCreator } from 'redux' ;
4+
5+ interface Action < T = any > {
6+ type : T ;
7+ }
8+
9+ interface AnyAction extends Action {
10+ [ extraProps : string ] : any ;
11+ }
12+
13+ type Reducer < S = any , A extends Action = AnyAction > = ( state : S | undefined , action : A ) => S ;
14+
15+ type Dispatch < A extends Action = AnyAction > = < T extends A > ( action : T , ...extraArgs : any [ ] ) => T ;
16+
17+ type ExtendState < State , Extension > = [ Extension ] extends [ never ] ? State : State & Extension ;
18+
19+ type Unsubscribe = ( ) => void ;
20+
21+ interface Store < S = any , A extends Action = AnyAction , StateExt = never , Ext = { } > {
22+ dispatch : Dispatch < A > ;
23+ getState ( ) : S ;
24+ subscribe ( listener : ( ) => void ) : Unsubscribe ;
25+ replaceReducer < NewState , NewActions extends Action > (
26+ nextReducer : Reducer < NewState , NewActions > ,
27+ ) : Store < ExtendState < NewState , StateExt > , NewActions , StateExt , Ext > & Ext ;
28+ }
29+
30+ declare const $CombinedState : unique symbol ;
31+
32+ type CombinedState < S > = { readonly [ $CombinedState ] ?: undefined } & S ;
33+
34+ type PreloadedState < S > = Required < S > extends {
35+ [ $CombinedState ] : undefined ;
36+ }
37+ ? S extends CombinedState < infer S1 >
38+ ? { [ K in keyof S1 ] ?: S1 [ K ] extends object ? PreloadedState < S1 [ K ] > : S1 [ K ] }
39+ : never
40+ : { [ K in keyof S ] : S [ K ] extends string | number | boolean | symbol ? S [ K ] : PreloadedState < S [ K ] > } ;
41+
42+ type StoreEnhancer < Ext = { } , StateExt = never > = (
43+ next : StoreEnhancerStoreCreator < Ext , StateExt > ,
44+ ) => StoreEnhancerStoreCreator < Ext , StateExt > ;
45+
46+ type StoreEnhancerStoreCreator < Ext = { } , StateExt = never > = < S = any , A extends Action = AnyAction > (
47+ reducer : Reducer < S , A > ,
48+ preloadedState ?: PreloadedState < S > ,
49+ ) => Store < ExtendState < S , StateExt > , A , StateExt , Ext > & Ext ;
550
651export interface SentryEnhancerOptions {
752 /**
853 * Transforms the state before attaching it to an event.
954 * Use this to remove any private data before sending it to Sentry.
1055 * Return null to not attach the state.
1156 */
12- stateTransformer ( state : any | undefined ) : any | null ;
57+ stateTransformer < S > ( state : S | undefined ) : ( S & any ) | null ;
1358 /**
1459 * Transforms the action before sending it as a breadcrumb.
1560 * Use this to remove any private data before sending it to Sentry.
@@ -19,7 +64,7 @@ export interface SentryEnhancerOptions {
1964 /**
2065 * Called on every state update, configure the Sentry Scope with the redux state.
2166 */
22- configureScopeWithState ?( scope : Scope , state : any ) : void ;
67+ configureScopeWithState ?< S > ( scope : Scope , state : S ) : void ;
2368}
2469
2570const ACTION_BREADCRUMB_CATEGORY = 'redux.action' ;
@@ -29,9 +74,14 @@ const STATE_CONTEXT_KEY = 'redux.state';
2974const defaultOptions : SentryEnhancerOptions = {
3075 actionTransformer : action => action ,
3176 // tslint:disable-next-line: no-unsafe-any
32- stateTransformer : state => state ,
77+ stateTransformer : state => state || null ,
3378} ;
3479
80+ /**
81+ * Creates an enhancer that would be passed to Redux's createStore to log actions and the latest state to Sentry.
82+ *
83+ * @param enhancerOptions Options to pass to the enhancer
84+ */
3585function createReduxEnhancer ( enhancerOptions ?: Partial < SentryEnhancerOptions > ) : StoreEnhancer {
3686 const options = {
3787 ...defaultOptions ,
@@ -59,6 +109,7 @@ function createReduxEnhancer(enhancerOptions?: Partial<SentryEnhancerOptions>):
59109
60110 /* Set latest state to scope */
61111 const transformedState = options . stateTransformer ( newState ) ;
112+ // tslint:disable-next-line: strict-type-predicates
62113 if ( typeof transformedState !== 'undefined' && transformedState !== null ) {
63114 // tslint:disable-next-line: no-unsafe-any
64115 scope . setContext ( STATE_CONTEXT_KEY , transformedState ) ;
0 commit comments