1
1
import { Integration } from '@sentry/types' ;
2
2
3
- export type UserFunctionIntegrations = ( integrations : Integration [ ] ) => Integration [ ] ;
4
- export type UserIntegrations = Integration [ ] | UserFunctionIntegrations ;
3
+ export type UserIntegrationsFunction = ( integrations : Integration [ ] ) => Integration [ ] ;
4
+ export type UserIntegrations = Integration [ ] | UserIntegrationsFunction ;
5
5
6
- type Options = {
6
+ type ForcedIntegrationOptions = {
7
7
[ integrationName : string ] :
8
8
| {
9
9
keyPath : string ;
@@ -25,69 +25,72 @@ type Options = {
25
25
function setNestedKey ( obj : Record < string , any > , keyPath : string , value : unknown ) : void {
26
26
// Ex. foo.bar.zoop will extract foo and bar.zoop
27
27
const match = keyPath . match ( / ( [ a - z ] + ) \. ( .* ) / i) ;
28
+ // The match will be null when there's no more recursing to do, i.e., when we've reached the right level of the object
28
29
if ( match === null ) {
29
30
obj [ keyPath ] = value ;
30
31
} else {
32
+ // `match[1]` is the initial segment of the path, and `match[2]` is the remainder of the path
31
33
setNestedKey ( obj [ match [ 1 ] ] , match [ 2 ] , value ) ;
32
34
}
33
35
}
34
36
35
37
/**
36
- * Retrieves the patched integrations with the provided integration.
38
+ * Enforces inclusion of a given integration with specified options in an integration array originally determined by the
39
+ * user, by either including the given default instance or by patching an existing user instance with the given options.
37
40
*
38
- * The integration must be present in the final user integrations, and they are compared
39
- * by integration name. If the user has defined one, there's nothing to patch; if not,
40
- * the provided integration is added.
41
+ * Ideally this would happen when integrations are set up, but there isn't currently a mechanism there for merging
42
+ * options from a default integration instance with those from a user-provided instance of the same integration, only
43
+ * for allowing the user to override a default instance entirely. (TODO: Fix that.)
41
44
*
42
- * @param integration The integration to patch, if necessary.
45
+ * @param defaultIntegrationInstance An instance of the integration with the correct options already set
43
46
* @param userIntegrations Integrations defined by the user.
44
- * @param options options to update for a particular integration
45
- * @returns Final integrations, patched if necessary .
47
+ * @param forcedOptions Options with which to patch an existing user-derived instance on the integration.
48
+ * @returns A final integrations array .
46
49
*/
47
- export function addIntegration (
48
- integration : Integration ,
50
+ export function addOrUpdateIntegration (
51
+ defaultIntegrationInstance : Integration ,
49
52
userIntegrations : UserIntegrations ,
50
- options : Options = { } ,
53
+ forcedOptions : ForcedIntegrationOptions = { } ,
51
54
) : UserIntegrations {
52
55
if ( Array . isArray ( userIntegrations ) ) {
53
- return addIntegrationToArray ( integration , userIntegrations , options ) ;
56
+ return addOrUpdateIntegrationInArray ( defaultIntegrationInstance , userIntegrations , forcedOptions ) ;
54
57
} else {
55
- return addIntegrationToFunction ( integration , userIntegrations , options ) ;
58
+ return addOrUpdateIntegrationInFunction ( defaultIntegrationInstance , userIntegrations , forcedOptions ) ;
56
59
}
57
60
}
58
61
59
- function addIntegrationToArray (
60
- integration : Integration ,
62
+ function addOrUpdateIntegrationInArray (
63
+ defaultIntegrationInstance : Integration ,
61
64
userIntegrations : Integration [ ] ,
62
- options : Options ,
65
+ forcedOptions : ForcedIntegrationOptions ,
63
66
) : Integration [ ] {
64
67
let includesName = false ;
65
68
// eslint-disable-next-line @typescript-eslint/prefer-for-of
66
69
for ( let x = 0 ; x < userIntegrations . length ; x ++ ) {
67
- if ( userIntegrations [ x ] . name === integration . name ) {
70
+ if ( userIntegrations [ x ] . name === defaultIntegrationInstance . name ) {
68
71
includesName = true ;
69
72
}
70
73
71
- const op = options [ userIntegrations [ x ] . name ] ;
72
- if ( op ) {
73
- setNestedKey ( userIntegrations [ x ] , op . keyPath , op . value ) ;
74
+ const optionToSet = forcedOptions [ userIntegrations [ x ] . name ] ;
75
+ if ( optionToSet ) {
76
+ setNestedKey ( userIntegrations [ x ] , optionToSet . keyPath , optionToSet . value ) ;
74
77
}
75
78
}
76
79
77
80
if ( includesName ) {
78
81
return userIntegrations ;
79
82
}
80
- return [ ...userIntegrations , integration ] ;
83
+ return [ ...userIntegrations , defaultIntegrationInstance ] ;
81
84
}
82
85
83
- function addIntegrationToFunction (
84
- integration : Integration ,
85
- userIntegrationsFunc : UserFunctionIntegrations ,
86
- options : Options ,
87
- ) : UserFunctionIntegrations {
88
- const wrapper : UserFunctionIntegrations = defaultIntegrations => {
86
+ function addOrUpdateIntegrationInFunction (
87
+ defaultIntegrationInstance : Integration ,
88
+ userIntegrationsFunc : UserIntegrationsFunction ,
89
+ forcedOptions : ForcedIntegrationOptions ,
90
+ ) : UserIntegrationsFunction {
91
+ const wrapper : UserIntegrationsFunction = defaultIntegrations => {
89
92
const userFinalIntegrations = userIntegrationsFunc ( defaultIntegrations ) ;
90
- return addIntegrationToArray ( integration , userFinalIntegrations , options ) ;
93
+ return addOrUpdateIntegrationInArray ( defaultIntegrationInstance , userFinalIntegrations , forcedOptions ) ;
91
94
} ;
92
95
return wrapper ;
93
96
}
0 commit comments