@amplitude/plugin-session-replay-react-native 0.4.10 → 0.5.0-sr-4646-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +21 -1
  2. package/android/src/main/java/com/amplitude/pluginsessionreplayreactnative/PluginSessionReplayReactNativeModule.kt +14 -3
  3. package/ios/PluginSessionReplayReactNative.mm +1 -1
  4. package/ios/PluginSessionReplayReactNative.swift +19 -1
  5. package/lib/commonjs/index.js +0 -7
  6. package/lib/commonjs/index.js.map +1 -1
  7. package/lib/commonjs/session-replay-config.js +40 -2
  8. package/lib/commonjs/session-replay-config.js.map +1 -1
  9. package/lib/commonjs/session-replay.js +11 -2
  10. package/lib/commonjs/session-replay.js.map +1 -1
  11. package/lib/commonjs/version.js +1 -1
  12. package/lib/commonjs/version.js.map +1 -1
  13. package/lib/module/index.js +0 -1
  14. package/lib/module/index.js.map +1 -1
  15. package/lib/module/session-replay-config.js +36 -2
  16. package/lib/module/session-replay-config.js.map +1 -1
  17. package/lib/module/session-replay.js +11 -2
  18. package/lib/module/session-replay.js.map +1 -1
  19. package/lib/module/version.js +1 -1
  20. package/lib/module/version.js.map +1 -1
  21. package/lib/typescript/index.d.ts +1 -1
  22. package/lib/typescript/index.d.ts.map +1 -1
  23. package/lib/typescript/session-replay-config.d.ts +56 -3
  24. package/lib/typescript/session-replay-config.d.ts.map +1 -1
  25. package/lib/typescript/session-replay.d.ts +3 -1
  26. package/lib/typescript/session-replay.d.ts.map +1 -1
  27. package/lib/typescript/version.d.ts +1 -1
  28. package/lib/typescript/version.d.ts.map +1 -1
  29. package/package.json +1 -1
  30. package/src/index.tsx +1 -2
  31. package/src/session-replay-config.ts +69 -5
  32. package/src/session-replay.ts +17 -6
  33. package/src/version.ts +1 -1
package/README.md CHANGED
@@ -20,15 +20,35 @@ const config: SessionReplayConfig = {
20
20
  enableRemoteConfig: true, // default true
21
21
  sampleRate: 1, // default 0
22
22
  logLevel: LogLevel.Warn, // default LogLevel.Warn
23
+ privacyConfig: { maskLevel: 'medium' }, // 'medium' is the default
23
24
  };
24
25
  await init('YOUR_API_KEY').promise;
25
26
  await add(new SessionReplayPlugin(config)).promise;
26
27
 
27
28
  ```
28
29
 
30
+ ## Mask levels
31
+
32
+ Control how aggressively Session Replay masks sensitive content via the `privacyConfig.maskLevel` config option:
33
+
34
+ | Value | What gets masked |
35
+ |---|---|
36
+ | `'light'` | Password and phone-number `<TextInput>` fields only |
37
+ | `'medium'` (default) | All `<TextInput>` fields |
38
+ | `'conservative'` | All `<TextInput>` fields **and** all `<Text>` elements |
39
+
40
+ ```js
41
+ import { SessionReplayPlugin } from '@amplitude/plugin-session-replay-react-native';
42
+
43
+ const config: SessionReplayConfig = {
44
+ privacyConfig: { maskLevel: 'conservative' }, // mask all text and inputs
45
+ };
46
+ ```
47
+
48
+ > **Note:** Third-party text renderers that bypass UIKit/Android's standard text views (for example `react-native-svg`, `@shopify/react-native-skia`) are not detected by automatic masking. Wrap such content in `<AmpMaskView mask="amp-mask">` to mask it manually.
29
49
 
30
50
  ## Masking views
31
- To maks certain views, add the `AmpMaskView` tag with the mask property `amp-mask` around the section to be masked
51
+ To mask certain views, add the `AmpMaskView` tag with the mask property `amp-mask` around the section to be masked
32
52
 
33
53
  ```js
34
54
  import { AmpMaskView } from '@amplitude/plugin-session-replay-react-native';
@@ -1,6 +1,8 @@
1
1
  package com.amplitude.pluginsessionreplayreactnative
2
2
 
3
3
  import com.amplitude.android.sessionreplay.SessionReplay
4
+ import com.amplitude.android.sessionreplay.config.MaskLevel
5
+ import com.amplitude.android.sessionreplay.config.PrivacyConfig
4
6
  import com.amplitude.common.Logger
5
7
  import com.amplitude.common.android.LogcatLogger
6
8
  import com.amplitude.core.ServerZone
@@ -20,7 +22,7 @@ class PluginSessionReplayReactNativeModule(private val reactContext: ReactApplic
20
22
  }
21
23
 
22
24
  @ReactMethod
23
- fun setup(apiKey: String, deviceId: String?, sessionId: Double, serverZone: String?, sampleRate: Double, enableRemoteConfig: Boolean, logLevel: Int, autoStart: Boolean) {
25
+ fun setup(apiKey: String, deviceId: String?, sessionId: Double, serverZone: String?, sampleRate: Double, enableRemoteConfig: Boolean, logLevel: Int, autoStart: Boolean, maskLevel: String) {
24
26
  LogcatLogger.logger.logMode = when (logLevel) {
25
27
  0 -> Logger.LogMode.OFF
26
28
  1 -> Logger.LogMode.ERROR
@@ -30,6 +32,13 @@ class PluginSessionReplayReactNativeModule(private val reactContext: ReactApplic
30
32
  else -> Logger.LogMode.WARN
31
33
  }
32
34
 
35
+ val mappedMaskLevel = when (maskLevel.lowercase()) {
36
+ "light" -> MaskLevel.LIGHT
37
+ "medium" -> MaskLevel.MEDIUM
38
+ "conservative" -> MaskLevel.CONSERVATIVE
39
+ else -> MaskLevel.MEDIUM
40
+ }
41
+
33
42
  LogcatLogger.logger.debug("""
34
43
  setup:
35
44
  API Key: $apiKey
@@ -40,6 +49,7 @@ class PluginSessionReplayReactNativeModule(private val reactContext: ReactApplic
40
49
  Enable Remote Config: $enableRemoteConfig
41
50
  Log Level: $logLevel
42
51
  Auto Start: $autoStart
52
+ Mask Level: $maskLevel
43
53
  """.trimIndent())
44
54
 
45
55
  sessionReplay = SessionReplay(
@@ -54,7 +64,8 @@ class PluginSessionReplayReactNativeModule(private val reactContext: ReactApplic
54
64
  "EU" -> ServerZone.EU
55
65
  else -> ServerZone.US
56
66
  },
57
- autoStart = autoStart
67
+ autoStart = autoStart,
68
+ privacyConfig = PrivacyConfig(maskLevel = mappedMaskLevel)
58
69
  )
59
70
  }
60
71
 
@@ -87,7 +98,7 @@ class PluginSessionReplayReactNativeModule(private val reactContext: ReactApplic
87
98
  }
88
99
  promise.resolve(map)
89
100
  }
90
-
101
+
91
102
  @ReactMethod
92
103
  fun start() {
93
104
  sessionReplay.start()
@@ -2,7 +2,7 @@
2
2
 
3
3
  @interface RCT_EXTERN_MODULE(PluginSessionReplayReactNative, NSObject)
4
4
 
5
- RCT_EXTERN_METHOD(setup:(NSString)apiKey deviceId:(NSString)deviceId sessionId:(nonnull NSNumber)sessionId serverZone:(NSString)serverZone sampleRate:(float)sampleRate enableRemoteConfig:(BOOL)enableRemoteConfig logLevel:(int)logLevel autoStart:(BOOL)autoStart resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
5
+ RCT_EXTERN_METHOD(setup:(NSString)apiKey deviceId:(NSString)deviceId sessionId:(nonnull NSNumber)sessionId serverZone:(NSString)serverZone sampleRate:(float)sampleRate enableRemoteConfig:(BOOL)enableRemoteConfig logLevel:(int)logLevel autoStart:(BOOL)autoStart maskLevel:(NSString)maskLevel resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
6
6
 
7
7
  RCT_EXTERN_METHOD(setSessionId:(nonnull NSNumber)sessionId resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
8
8
 
@@ -6,7 +6,7 @@ class PluginSessionReplayReactNative: NSObject {
6
6
 
7
7
  var sessionReplay: SessionReplay!
8
8
 
9
- @objc(setup:deviceId:sessionId:serverZone:sampleRate:enableRemoteConfig:logLevel:autoStart:resolve:reject:)
9
+ @objc(setup:deviceId:sessionId:serverZone:sampleRate:enableRemoteConfig:logLevel:autoStart:maskLevel:resolve:reject:)
10
10
  func setup(_ apiKey: String,
11
11
  deviceId: String,
12
12
  sessionId: NSNumber,
@@ -15,6 +15,7 @@ class PluginSessionReplayReactNative: NSObject {
15
15
  enableRemoteConfig: Bool,
16
16
  logLevel: Int,
17
17
  autoStart: Bool,
18
+ maskLevel: String,
18
19
  resolve: RCTPromiseResolveBlock,
19
20
  reject: RCTPromiseRejectBlock) -> Void {
20
21
  print(
@@ -28,6 +29,7 @@ class PluginSessionReplayReactNative: NSObject {
28
29
  Enable Remote Config: \(enableRemoteConfig)
29
30
  Log Level: \(logLevel)
30
31
  Auto Start: \(autoStart)
32
+ Mask Level: \(maskLevel)
31
33
  """
32
34
  )
33
35
  sessionReplay = SessionReplay(apiKey:apiKey,
@@ -36,6 +38,7 @@ class PluginSessionReplayReactNative: NSObject {
36
38
  sampleRate: sampleRate,
37
39
  logger:ConsoleLogger(logLevel: logLevel),
38
40
  serverZone: serverZone == "EU" ? .EU : .US,
41
+ maskLevel: .fromString(maskLevel),
39
42
  enableRemoteConfig: enableRemoteConfig)
40
43
  if (autoStart) {
41
44
  sessionReplay.start()
@@ -90,3 +93,18 @@ class PluginSessionReplayReactNative: NSObject {
90
93
  resolve(nil)
91
94
  }
92
95
  }
96
+
97
+ extension MaskLevel {
98
+ static func fromString(_ input: String) -> MaskLevel {
99
+ switch input.lowercased() {
100
+ case "light":
101
+ return .light
102
+ case "medium":
103
+ return .medium
104
+ case "conservative":
105
+ return .conservative
106
+ default:
107
+ return .medium
108
+ }
109
+ }
110
+ }
@@ -9,12 +9,6 @@ Object.defineProperty(exports, "AmpMaskView", {
9
9
  return _appMaskView.AmpMaskView;
10
10
  }
11
11
  });
12
- Object.defineProperty(exports, "SessionReplayConfig", {
13
- enumerable: true,
14
- get: function () {
15
- return _sessionReplayConfig.SessionReplayConfig;
16
- }
17
- });
18
12
  Object.defineProperty(exports, "SessionReplayPlugin", {
19
13
  enumerable: true,
20
14
  get: function () {
@@ -23,5 +17,4 @@ Object.defineProperty(exports, "SessionReplayPlugin", {
23
17
  });
24
18
  var _sessionReplay = require("./session-replay");
25
19
  var _appMaskView = require("./app-mask-view");
26
- var _sessionReplayConfig = require("./session-replay-config");
27
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_sessionReplay","require","_appMaskView","_sessionReplayConfig"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AAEA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,oBAAA,GAAAF,OAAA","ignoreList":[]}
1
+ {"version":3,"names":["_sessionReplay","require","_appMaskView"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AAGA,IAAAC,YAAA,GAAAD,OAAA","ignoreList":[]}
@@ -3,14 +3,52 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "LogLevel", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _analyticsTypes.LogLevel;
10
+ }
11
+ });
6
12
  exports.getDefaultConfig = void 0;
7
13
  var _analyticsTypes = require("@amplitude/analytics-types");
14
+ /**
15
+ * Masking levels for sensitive content in session replay.
16
+ *
17
+ * Declared as a string-literal union (rather than an `enum`) to match the
18
+ * Session Replay browser SDK and avoid the const-enum inlining pitfalls of
19
+ * string enums under aggressive compilers. Kept structurally identical to the
20
+ * standalone `@amplitude/session-replay-react-native` SDK's `MaskLevel` so the
21
+ * two packages stay in lockstep without coupling the plugin's runtime to the
22
+ * standalone native module.
23
+ *
24
+ * - `light`: mask only inputs that are always sensitive (password, etc.).
25
+ * - `medium`: mask all `<TextInput>` fields.
26
+ * - `conservative`: mask all `<TextInput>` fields and all `<Text>` content.
27
+ */
28
+
29
+ /**
30
+ * Configuration for the Session Replay React Native plugin.
31
+ *
32
+ * Unlike the standalone `@amplitude/session-replay-react-native` SDK, the
33
+ * plugin auto-sources `apiKey`, `deviceId`, `sessionId`, and `serverZone`
34
+ * from the analytics client's `ReactNativeConfig` at `setup()` time, so
35
+ * those fields are intentionally absent from the public plugin config.
36
+ * The plugin also never shipped a deprecated top-level `maskLevel`, so no
37
+ * input-boundary normalization (and no `SessionReplayConfigInternal` alias)
38
+ * is needed here.
39
+ */
40
+
8
41
  const getDefaultConfig = () => {
9
42
  return {
10
- sampleRate: 0,
43
+ autoStart: true,
11
44
  enableRemoteConfig: true,
12
45
  logLevel: _analyticsTypes.LogLevel.Warn,
13
- autoStart: true
46
+ // Intentionally left without a `maskLevel`: the effective default
47
+ // (`'medium'`) is resolved once at the native boundary in `setup()`.
48
+ // Baking it in here would make a partial user `privacyConfig` (e.g. `{}`)
49
+ // unable to fall through to the `?? 'medium'` resolution.
50
+ privacyConfig: {},
51
+ sampleRate: 0
14
52
  };
15
53
  };
16
54
  exports.getDefaultConfig = getDefaultConfig;
@@ -1 +1 @@
1
- {"version":3,"names":["_analyticsTypes","require","getDefaultConfig","sampleRate","enableRemoteConfig","logLevel","LogLevel","Warn","autoStart","exports"],"sourceRoot":"../../src","sources":["session-replay-config.ts"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AASO,MAAMC,gBAA2C,GAAGA,CAAA,KAAM;EAC/D,OAAO;IACLC,UAAU,EAAE,CAAC;IACbC,kBAAkB,EAAE,IAAI;IACxBC,QAAQ,EAAEC,wBAAQ,CAACC,IAAI;IACvBC,SAAS,EAAE;EACb,CAAC;AACH,CAAC;AAACC,OAAA,CAAAP,gBAAA,GAAAA,gBAAA","ignoreList":[]}
1
+ {"version":3,"names":["_analyticsTypes","require","getDefaultConfig","autoStart","enableRemoteConfig","logLevel","LogLevel","Warn","privacyConfig","sampleRate","exports"],"sourceRoot":"../../src","sources":["session-replay-config.ts"],"mappings":";;;;;;;;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAmCO,MAAMC,gBAAqD,GAAGA,CAAA,KAAM;EACzE,OAAO;IACLC,SAAS,EAAE,IAAI;IACfC,kBAAkB,EAAE,IAAI;IACxBC,QAAQ,EAAEC,wBAAQ,CAACC,IAAI;IACvB;IACA;IACA;IACA;IACAC,aAAa,EAAE,CAAC,CAAC;IACjBC,UAAU,EAAE;EACd,CAAC;AACH,CAAC;AAACC,OAAA,CAAAR,gBAAA,GAAAA,gBAAA","ignoreList":[]}
@@ -7,7 +7,6 @@ exports.SessionReplayPlugin = void 0;
7
7
  var _nativeModule = require("./native-module");
8
8
  var _version = require("./version");
9
9
  var _sessionReplayConfig = require("./session-replay-config");
10
- var _analyticsTypes = require("@amplitude/analytics-types");
11
10
  /* eslint-disable @typescript-eslint/no-unsafe-call */
12
11
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
13
12
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
@@ -32,7 +31,17 @@ class SessionReplayPlugin {
32
31
  async setup(config, _) {
33
32
  this.config = config;
34
33
  console.log(`Installing @amplitude/plugin-session-replay-react-native, version ${_version.VERSION}.`);
35
- await _nativeModule.PluginSessionReplayReactNative.setup(config.apiKey, config.deviceId, config.sessionId, config.serverZone, this.sessionReplayConfig.sampleRate ?? 1, this.sessionReplayConfig.enableRemoteConfig ?? true, this.sessionReplayConfig.logLevel ?? _analyticsTypes.LogLevel.Warn, this.sessionReplayConfig.autoStart ?? true);
34
+ // `apiKey`, `deviceId`, `sessionId`, and `serverZone` are sourced from the
35
+ // analytics client's `ReactNativeConfig` because the plugin runs inside an
36
+ // initialized Amplitude SDK and inherits identity from it.
37
+ // Resolve the effective mask level here — the single source of truth for
38
+ // the default. `privacyConfig.maskLevel` can be `undefined` when a partial
39
+ // `privacyConfig` (e.g. `{}`) is supplied, so fall back to `'medium'` rather
40
+ // than forwarding `undefined` across the native bridge.
41
+ const resolvedMaskLevel = this.sessionReplayConfig.privacyConfig.maskLevel ?? 'medium';
42
+ await _nativeModule.PluginSessionReplayReactNative.setup(config.apiKey, config.deviceId, config.sessionId, config.serverZone, this.sessionReplayConfig.sampleRate, this.sessionReplayConfig.enableRemoteConfig, this.sessionReplayConfig.logLevel, this.sessionReplayConfig.autoStart,
43
+ // TODO(SDKRN-15): Migrate native bridge to accept the full privacyConfig object instead of a flat maskLevel string.
44
+ resolvedMaskLevel);
36
45
  this.isInitialized = true;
37
46
  }
38
47
  async execute(event) {
@@ -1 +1 @@
1
- {"version":3,"names":["_nativeModule","require","_version","_sessionReplayConfig","_analyticsTypes","SessionReplayPlugin","name","type","isInitialized","constructor","config","sessionReplayConfig","getDefaultConfig","console","log","setup","_","VERSION","PluginSessionReplayReactNative","apiKey","deviceId","sessionId","serverZone","sampleRate","enableRemoteConfig","logLevel","LogLevel","Warn","autoStart","execute","event","Promise","resolve","getSessionId","setSessionId","session_id","sessionRecordingProperties","getSessionReplayProperties","event_properties","start","stop","teardown","exports"],"sourceRoot":"../../src","sources":["session-replay.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_nativeModule","require","_version","_sessionReplayConfig","SessionReplayPlugin","name","type","isInitialized","constructor","config","sessionReplayConfig","getDefaultConfig","console","log","setup","_","VERSION","resolvedMaskLevel","privacyConfig","maskLevel","PluginSessionReplayReactNative","apiKey","deviceId","sessionId","serverZone","sampleRate","enableRemoteConfig","logLevel","autoStart","execute","event","Promise","resolve","getSessionId","setSessionId","session_id","sessionRecordingProperties","getSessionReplayProperties","event_properties","start","stop","teardown","exports"],"sourceRoot":"../../src","sources":["session-replay.ts"],"mappings":"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","ignoreList":[]}
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.VERSION = void 0;
7
- const VERSION = exports.VERSION = '0.4.10';
7
+ const VERSION = exports.VERSION = '0.5.0-sr-4646-rc.0';
8
8
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["VERSION","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAO,MAAMA,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,QAAQ","ignoreList":[]}
1
+ {"version":3,"names":["VERSION","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAO,MAAMA,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,oBAAoB","ignoreList":[]}
@@ -1,4 +1,3 @@
1
1
  export { SessionReplayPlugin } from './session-replay';
2
2
  export { AmpMaskView } from './app-mask-view';
3
- export { SessionReplayConfig } from './session-replay-config';
4
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["SessionReplayPlugin","AmpMaskView","SessionReplayConfig"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,kBAAkB;AAEtD,SAASC,WAAW,QAAQ,iBAAiB;AAE7C,SAASC,mBAAmB,QAAQ,yBAAyB","ignoreList":[]}
1
+ {"version":3,"names":["SessionReplayPlugin","AmpMaskView"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,kBAAkB;AAGtD,SAASC,WAAW,QAAQ,iBAAiB","ignoreList":[]}
@@ -1,10 +1,44 @@
1
1
  import { LogLevel } from '@amplitude/analytics-types';
2
+
3
+ /**
4
+ * Masking levels for sensitive content in session replay.
5
+ *
6
+ * Declared as a string-literal union (rather than an `enum`) to match the
7
+ * Session Replay browser SDK and avoid the const-enum inlining pitfalls of
8
+ * string enums under aggressive compilers. Kept structurally identical to the
9
+ * standalone `@amplitude/session-replay-react-native` SDK's `MaskLevel` so the
10
+ * two packages stay in lockstep without coupling the plugin's runtime to the
11
+ * standalone native module.
12
+ *
13
+ * - `light`: mask only inputs that are always sensitive (password, etc.).
14
+ * - `medium`: mask all `<TextInput>` fields.
15
+ * - `conservative`: mask all `<TextInput>` fields and all `<Text>` content.
16
+ */
17
+
18
+ /**
19
+ * Configuration for the Session Replay React Native plugin.
20
+ *
21
+ * Unlike the standalone `@amplitude/session-replay-react-native` SDK, the
22
+ * plugin auto-sources `apiKey`, `deviceId`, `sessionId`, and `serverZone`
23
+ * from the analytics client's `ReactNativeConfig` at `setup()` time, so
24
+ * those fields are intentionally absent from the public plugin config.
25
+ * The plugin also never shipped a deprecated top-level `maskLevel`, so no
26
+ * input-boundary normalization (and no `SessionReplayConfigInternal` alias)
27
+ * is needed here.
28
+ */
29
+
2
30
  export const getDefaultConfig = () => {
3
31
  return {
4
- sampleRate: 0,
32
+ autoStart: true,
5
33
  enableRemoteConfig: true,
6
34
  logLevel: LogLevel.Warn,
7
- autoStart: true
35
+ // Intentionally left without a `maskLevel`: the effective default
36
+ // (`'medium'`) is resolved once at the native boundary in `setup()`.
37
+ // Baking it in here would make a partial user `privacyConfig` (e.g. `{}`)
38
+ // unable to fall through to the `?? 'medium'` resolution.
39
+ privacyConfig: {},
40
+ sampleRate: 0
8
41
  };
9
42
  };
43
+ export { LogLevel };
10
44
  //# sourceMappingURL=session-replay-config.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["LogLevel","getDefaultConfig","sampleRate","enableRemoteConfig","logLevel","Warn","autoStart"],"sourceRoot":"../../src","sources":["session-replay-config.ts"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,4BAA4B;AASrD,OAAO,MAAMC,gBAA2C,GAAGA,CAAA,KAAM;EAC/D,OAAO;IACLC,UAAU,EAAE,CAAC;IACbC,kBAAkB,EAAE,IAAI;IACxBC,QAAQ,EAAEJ,QAAQ,CAACK,IAAI;IACvBC,SAAS,EAAE;EACb,CAAC;AACH,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["LogLevel","getDefaultConfig","autoStart","enableRemoteConfig","logLevel","Warn","privacyConfig","sampleRate"],"sourceRoot":"../../src","sources":["session-replay-config.ts"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,4BAA4B;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAmCA,OAAO,MAAMC,gBAAqD,GAAGA,CAAA,KAAM;EACzE,OAAO;IACLC,SAAS,EAAE,IAAI;IACfC,kBAAkB,EAAE,IAAI;IACxBC,QAAQ,EAAEJ,QAAQ,CAACK,IAAI;IACvB;IACA;IACA;IACA;IACAC,aAAa,EAAE,CAAC,CAAC;IACjBC,UAAU,EAAE;EACd,CAAC;AACH,CAAC;AACD,SAASP,QAAQ","ignoreList":[]}
@@ -7,7 +7,6 @@
7
7
  import { PluginSessionReplayReactNative } from './native-module';
8
8
  import { VERSION } from './version';
9
9
  import { getDefaultConfig } from './session-replay-config';
10
- import { LogLevel } from '@amplitude/analytics-types';
11
10
  export class SessionReplayPlugin {
12
11
  name = '@amplitude/plugin-session-replay-react-native';
13
12
  type = 'enrichment';
@@ -26,7 +25,17 @@ export class SessionReplayPlugin {
26
25
  async setup(config, _) {
27
26
  this.config = config;
28
27
  console.log(`Installing @amplitude/plugin-session-replay-react-native, version ${VERSION}.`);
29
- await PluginSessionReplayReactNative.setup(config.apiKey, config.deviceId, config.sessionId, config.serverZone, this.sessionReplayConfig.sampleRate ?? 1, this.sessionReplayConfig.enableRemoteConfig ?? true, this.sessionReplayConfig.logLevel ?? LogLevel.Warn, this.sessionReplayConfig.autoStart ?? true);
28
+ // `apiKey`, `deviceId`, `sessionId`, and `serverZone` are sourced from the
29
+ // analytics client's `ReactNativeConfig` because the plugin runs inside an
30
+ // initialized Amplitude SDK and inherits identity from it.
31
+ // Resolve the effective mask level here — the single source of truth for
32
+ // the default. `privacyConfig.maskLevel` can be `undefined` when a partial
33
+ // `privacyConfig` (e.g. `{}`) is supplied, so fall back to `'medium'` rather
34
+ // than forwarding `undefined` across the native bridge.
35
+ const resolvedMaskLevel = this.sessionReplayConfig.privacyConfig.maskLevel ?? 'medium';
36
+ await PluginSessionReplayReactNative.setup(config.apiKey, config.deviceId, config.sessionId, config.serverZone, this.sessionReplayConfig.sampleRate, this.sessionReplayConfig.enableRemoteConfig, this.sessionReplayConfig.logLevel, this.sessionReplayConfig.autoStart,
37
+ // TODO(SDKRN-15): Migrate native bridge to accept the full privacyConfig object instead of a flat maskLevel string.
38
+ resolvedMaskLevel);
30
39
  this.isInitialized = true;
31
40
  }
32
41
  async execute(event) {
@@ -1 +1 @@
1
- {"version":3,"names":["PluginSessionReplayReactNative","VERSION","getDefaultConfig","LogLevel","SessionReplayPlugin","name","type","isInitialized","constructor","config","sessionReplayConfig","console","log","setup","_","apiKey","deviceId","sessionId","serverZone","sampleRate","enableRemoteConfig","logLevel","Warn","autoStart","execute","event","Promise","resolve","getSessionId","setSessionId","session_id","sessionRecordingProperties","getSessionReplayProperties","event_properties","start","stop","teardown"],"sourceRoot":"../../src","sources":["session-replay.ts"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAGA,SAASA,8BAA8B,QAAQ,iBAAiB;AAChE,SAASC,OAAO,QAAQ,WAAW;AACnC,SAA8BC,gBAAgB,QAAQ,yBAAyB;AAC/E,SAASC,QAAQ,QAAQ,4BAA4B;AAErD,OAAO,MAAMC,mBAAmB,CAAmE;EACjGC,IAAI,GAAG,+CAA+C;EACtDC,IAAI,GAAG,YAAY;EACnB;;EAEA;;EAEAC,aAAa,GAAG,KAAK;EAIrBC,WAAWA,CAACC,MAA2B,GAAG,CAAC,CAAC,EAAE;IAC5C,IAAI,CAACC,mBAAmB,GAAG;MACzB,GAAGR,gBAAgB,CAAC,CAAC;MACrB,GAAGO;IACL,CAAC;IACDE,OAAO,CAACC,GAAG,CAAC,gDAAgD,EAAE,IAAI,CAACF,mBAAmB,CAAC;EACzF;EAEA,MAAMG,KAAKA,CAACJ,MAAyB,EAAEK,CAAoB,EAAiB;IAC1E,IAAI,CAACL,MAAM,GAAGA,MAAM;IACpBE,OAAO,CAACC,GAAG,CAAC,qEAAqEX,OAAO,GAAG,CAAC;IAC5F,MAAMD,8BAA8B,CAACa,KAAK,CACxCJ,MAAM,CAACM,MAAM,EACbN,MAAM,CAACO,QAAQ,EACfP,MAAM,CAACQ,SAAS,EAChBR,MAAM,CAACS,UAAU,EACjB,IAAI,CAACR,mBAAmB,CAACS,UAAU,IAAI,CAAC,EACxC,IAAI,CAACT,mBAAmB,CAACU,kBAAkB,IAAI,IAAI,EACnD,IAAI,CAACV,mBAAmB,CAACW,QAAQ,IAAIlB,QAAQ,CAACmB,IAAI,EAClD,IAAI,CAACZ,mBAAmB,CAACa,SAAS,IAAI,IACxC,CAAC;IACD,IAAI,CAAChB,aAAa,GAAG,IAAI;EAC3B;EAEA,MAAMiB,OAAOA,CAACC,KAAY,EAAyB;IACjD,IAAI,CAAC,IAAI,CAAClB,aAAa,EAAE;MACvB,OAAOmB,OAAO,CAACC,OAAO,CAACF,KAAK,CAAC;IAC/B;;IAEA;IACA;IACA;IACA,IAAI,IAAI,CAAChB,MAAM,CAACQ,SAAS,IAAI,IAAI,CAACR,MAAM,CAACQ,SAAS,MAAM,MAAMjB,8BAA8B,CAAC4B,YAAY,CAAC,CAAC,CAAC,EAAE;MAC5G,MAAM5B,8BAA8B,CAAC6B,YAAY,CAAC,IAAI,CAACpB,MAAM,CAACQ,SAAS,CAAC;IAC1E;IACA;IACA;IACA,IAAI,IAAI,CAACR,MAAM,CAACQ,SAAS,IAAI,IAAI,CAACR,MAAM,CAACQ,SAAS,KAAKQ,KAAK,CAACK,UAAU,EAAE;MACvE,MAAMC,0BAA0B,GAAG,MAAM/B,8BAA8B,CAACgC,0BAA0B,CAAC,CAAC;MACpGP,KAAK,CAACQ,gBAAgB,GAAG;QACvB,GAAGR,KAAK,CAACQ,gBAAgB;QACzB,GAAGF;MACL,CAAC;IACH;IACA,OAAOL,OAAO,CAACC,OAAO,CAACF,KAAK,CAAC;EAC/B;EAEA,MAAMS,KAAKA,CAAA,EAAkB;IAC3B,IAAI,IAAI,CAAC3B,aAAa,EAAE;MACtB,MAAMP,8BAA8B,CAACkC,KAAK,CAAC,CAAC;IAC9C;EACF;EAEA,MAAMC,IAAIA,CAAA,EAAkB;IAC1B,IAAI,IAAI,CAAC5B,aAAa,EAAE;MACtB,MAAMP,8BAA8B,CAACmC,IAAI,CAAC,CAAC;IAC7C;EACF;EAEA,MAAMC,QAAQA,CAAA,EAAkB;IAC9B,IAAI,IAAI,CAAC7B,aAAa,EAAE;MACtB,MAAMP,8BAA8B,CAACoC,QAAQ,CAAC,CAAC;IACjD;IACA;IACA;;IAEA;IACA,IAAI,CAAC3B,MAAM,GAAG,IAAI;IAClB,IAAI,CAACF,aAAa,GAAG,KAAK;EAC5B;EAEA,MAAMyB,0BAA0BA,CAAA,EAAG;IACjC,IAAI,CAAC,IAAI,CAACzB,aAAa,EAAE;MACvB,OAAO,CAAC,CAAC;IACX;IACA,OAAOP,8BAA8B,CAACgC,0BAA0B,CAAC,CAAC;EACpE;AACF","ignoreList":[]}
1
+ {"version":3,"names":["PluginSessionReplayReactNative","VERSION","getDefaultConfig","SessionReplayPlugin","name","type","isInitialized","constructor","config","sessionReplayConfig","console","log","setup","_","resolvedMaskLevel","privacyConfig","maskLevel","apiKey","deviceId","sessionId","serverZone","sampleRate","enableRemoteConfig","logLevel","autoStart","execute","event","Promise","resolve","getSessionId","setSessionId","session_id","sessionRecordingProperties","getSessionReplayProperties","event_properties","start","stop","teardown"],"sourceRoot":"../../src","sources":["session-replay.ts"],"mappings":"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","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.4.10';
1
+ export const VERSION = '0.5.0-sr-4646-rc.0';
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["VERSION"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":"AAAA,OAAO,MAAMA,OAAO,GAAG,QAAQ","ignoreList":[]}
1
+ {"version":3,"names":["VERSION"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":"AAAA,OAAO,MAAMA,OAAO,GAAG,oBAAoB","ignoreList":[]}
@@ -1,4 +1,4 @@
1
1
  export { SessionReplayPlugin } from './session-replay';
2
+ export { type SessionReplayConfig, type MaskLevel, type PrivacyConfig } from './session-replay-config';
2
3
  export { AmpMaskView } from './app-mask-view';
3
- export { SessionReplayConfig } from './session-replay-config';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAEvG,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,9 +1,62 @@
1
1
  import { LogLevel } from '@amplitude/analytics-types';
2
+ /**
3
+ * Masking levels for sensitive content in session replay.
4
+ *
5
+ * Declared as a string-literal union (rather than an `enum`) to match the
6
+ * Session Replay browser SDK and avoid the const-enum inlining pitfalls of
7
+ * string enums under aggressive compilers. Kept structurally identical to the
8
+ * standalone `@amplitude/session-replay-react-native` SDK's `MaskLevel` so the
9
+ * two packages stay in lockstep without coupling the plugin's runtime to the
10
+ * standalone native module.
11
+ *
12
+ * - `light`: mask only inputs that are always sensitive (password, etc.).
13
+ * - `medium`: mask all `<TextInput>` fields.
14
+ * - `conservative`: mask all `<TextInput>` fields and all `<Text>` content.
15
+ */
16
+ export type MaskLevel = 'light' | 'medium' | 'conservative';
17
+ export interface PrivacyConfig {
18
+ maskLevel?: MaskLevel;
19
+ }
20
+ /**
21
+ * Configuration for the Session Replay React Native plugin.
22
+ *
23
+ * Unlike the standalone `@amplitude/session-replay-react-native` SDK, the
24
+ * plugin auto-sources `apiKey`, `deviceId`, `sessionId`, and `serverZone`
25
+ * from the analytics client's `ReactNativeConfig` at `setup()` time, so
26
+ * those fields are intentionally absent from the public plugin config.
27
+ * The plugin also never shipped a deprecated top-level `maskLevel`, so no
28
+ * input-boundary normalization (and no `SessionReplayConfigInternal` alias)
29
+ * is needed here.
30
+ */
2
31
  export interface SessionReplayConfig {
3
- sampleRate?: number;
32
+ /**
33
+ * Whether to automatically start recording when the plugin is added
34
+ * @default true
35
+ */
36
+ autoStart?: boolean;
37
+ /**
38
+ * Whether to enable remote configuration
39
+ * @default true
40
+ */
4
41
  enableRemoteConfig?: boolean;
42
+ /**
43
+ * Log level for the SDK
44
+ * @default LogLevel.Warn
45
+ */
5
46
  logLevel?: LogLevel;
6
- autoStart?: boolean;
47
+ /**
48
+ * Privacy configuration for session replay.
49
+ * When `maskLevel` is omitted it resolves to `'medium'` at the native boundary.
50
+ * @default {}
51
+ */
52
+ privacyConfig?: PrivacyConfig;
53
+ /**
54
+ * Sample rate for session replay (0.0 to 1.0)
55
+ * Determines what percentage of sessions will be recorded
56
+ * @default 0
57
+ */
58
+ sampleRate?: number;
7
59
  }
8
- export declare const getDefaultConfig: () => SessionReplayConfig;
60
+ export declare const getDefaultConfig: () => Required<SessionReplayConfig>;
61
+ export { LogLevel };
9
62
  //# sourceMappingURL=session-replay-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-replay-config.d.ts","sourceRoot":"","sources":["../../src/session-replay-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,mBAOpC,CAAC"}
1
+ {"version":3,"file":"session-replay-config.d.ts","sourceRoot":"","sources":["../../src/session-replay-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,cAAc,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,QAAQ,CAAC,mBAAmB,CAYhE,CAAC;AACF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,11 +1,12 @@
1
1
  import type { EnrichmentPlugin, Event, ReactNativeClient, ReactNativeConfig } from '@amplitude/analytics-types';
2
2
  import { SessionReplayConfig } from './session-replay-config';
3
+ type ResolvedSessionReplayConfig = Required<SessionReplayConfig>;
3
4
  export declare class SessionReplayPlugin implements EnrichmentPlugin<ReactNativeClient, ReactNativeConfig> {
4
5
  name: string;
5
6
  type: "enrichment";
6
7
  config: ReactNativeConfig;
7
8
  isInitialized: boolean;
8
- sessionReplayConfig: SessionReplayConfig;
9
+ sessionReplayConfig: ResolvedSessionReplayConfig;
9
10
  constructor(config?: SessionReplayConfig);
10
11
  setup(config: ReactNativeConfig, _: ReactNativeClient): Promise<void>;
11
12
  execute(event: Event): Promise<Event | null>;
@@ -14,4 +15,5 @@ export declare class SessionReplayPlugin implements EnrichmentPlugin<ReactNative
14
15
  teardown(): Promise<void>;
15
16
  getSessionReplayProperties(): Promise<any>;
16
17
  }
18
+ export {};
17
19
  //# sourceMappingURL=session-replay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIhH,OAAO,EAAE,mBAAmB,EAAoB,MAAM,yBAAyB,CAAC;AAGhF,qBAAa,mBAAoB,YAAW,gBAAgB,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAChG,IAAI,SAAmD;IACvD,IAAI,eAAyB;IAI7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,aAAa,UAAS;IAEtB,mBAAmB,EAAE,mBAAmB,CAAC;gBAE7B,MAAM,GAAE,mBAAwB;IAQtC,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrE,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAuB5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAYzB,0BAA0B;CAMjC"}
1
+ {"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIhH,OAAO,EAAE,mBAAmB,EAAoB,MAAM,yBAAyB,CAAC;AAEhF,KAAK,2BAA2B,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AAEjE,qBAAa,mBAAoB,YAAW,gBAAgB,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAChG,IAAI,SAAmD;IACvD,IAAI,eAAyB;IAI7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,aAAa,UAAS;IAEtB,mBAAmB,EAAE,2BAA2B,CAAC;gBAErC,MAAM,GAAE,mBAAwB;IAQtC,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BrE,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAuB5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAYzB,0BAA0B;CAMjC"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.4.10";
1
+ export declare const VERSION = "0.5.0-sr-4646-rc.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,uBAAuB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amplitude/plugin-session-replay-react-native",
3
- "version": "0.4.10",
3
+ "version": "0.5.0-sr-4646-rc.0",
4
4
  "description": "Amplitude Session Replay plugin for React Native",
5
5
  "keywords": [
6
6
  "analytics",
package/src/index.tsx CHANGED
@@ -1,5 +1,4 @@
1
1
  export { SessionReplayPlugin } from './session-replay';
2
+ export { type SessionReplayConfig, type MaskLevel, type PrivacyConfig } from './session-replay-config';
2
3
 
3
4
  export { AmpMaskView } from './app-mask-view';
4
-
5
- export { SessionReplayConfig } from './session-replay-config';
@@ -1,17 +1,81 @@
1
1
  import { LogLevel } from '@amplitude/analytics-types';
2
2
 
3
+ /**
4
+ * Masking levels for sensitive content in session replay.
5
+ *
6
+ * Declared as a string-literal union (rather than an `enum`) to match the
7
+ * Session Replay browser SDK and avoid the const-enum inlining pitfalls of
8
+ * string enums under aggressive compilers. Kept structurally identical to the
9
+ * standalone `@amplitude/session-replay-react-native` SDK's `MaskLevel` so the
10
+ * two packages stay in lockstep without coupling the plugin's runtime to the
11
+ * standalone native module.
12
+ *
13
+ * - `light`: mask only inputs that are always sensitive (password, etc.).
14
+ * - `medium`: mask all `<TextInput>` fields.
15
+ * - `conservative`: mask all `<TextInput>` fields and all `<Text>` content.
16
+ */
17
+ export type MaskLevel = 'light' | 'medium' | 'conservative';
18
+
19
+ export interface PrivacyConfig {
20
+ maskLevel?: MaskLevel;
21
+ }
22
+
23
+ /**
24
+ * Configuration for the Session Replay React Native plugin.
25
+ *
26
+ * Unlike the standalone `@amplitude/session-replay-react-native` SDK, the
27
+ * plugin auto-sources `apiKey`, `deviceId`, `sessionId`, and `serverZone`
28
+ * from the analytics client's `ReactNativeConfig` at `setup()` time, so
29
+ * those fields are intentionally absent from the public plugin config.
30
+ * The plugin also never shipped a deprecated top-level `maskLevel`, so no
31
+ * input-boundary normalization (and no `SessionReplayConfigInternal` alias)
32
+ * is needed here.
33
+ */
3
34
  export interface SessionReplayConfig {
4
- sampleRate?: number;
35
+ /**
36
+ * Whether to automatically start recording when the plugin is added
37
+ * @default true
38
+ */
39
+ autoStart?: boolean;
40
+
41
+ /**
42
+ * Whether to enable remote configuration
43
+ * @default true
44
+ */
5
45
  enableRemoteConfig?: boolean;
46
+
47
+ /**
48
+ * Log level for the SDK
49
+ * @default LogLevel.Warn
50
+ */
6
51
  logLevel?: LogLevel;
7
- autoStart?: boolean;
52
+
53
+ /**
54
+ * Privacy configuration for session replay.
55
+ * When `maskLevel` is omitted it resolves to `'medium'` at the native boundary.
56
+ * @default {}
57
+ */
58
+ privacyConfig?: PrivacyConfig;
59
+
60
+ /**
61
+ * Sample rate for session replay (0.0 to 1.0)
62
+ * Determines what percentage of sessions will be recorded
63
+ * @default 0
64
+ */
65
+ sampleRate?: number;
8
66
  }
9
67
 
10
- export const getDefaultConfig: () => SessionReplayConfig = () => {
68
+ export const getDefaultConfig: () => Required<SessionReplayConfig> = () => {
11
69
  return {
12
- sampleRate: 0,
70
+ autoStart: true,
13
71
  enableRemoteConfig: true,
14
72
  logLevel: LogLevel.Warn,
15
- autoStart: true,
73
+ // Intentionally left without a `maskLevel`: the effective default
74
+ // (`'medium'`) is resolved once at the native boundary in `setup()`.
75
+ // Baking it in here would make a partial user `privacyConfig` (e.g. `{}`)
76
+ // unable to fall through to the `?? 'medium'` resolution.
77
+ privacyConfig: {},
78
+ sampleRate: 0,
16
79
  };
17
80
  };
81
+ export { LogLevel };
@@ -8,7 +8,8 @@ import type { EnrichmentPlugin, Event, ReactNativeClient, ReactNativeConfig } fr
8
8
  import { PluginSessionReplayReactNative } from './native-module';
9
9
  import { VERSION } from './version';
10
10
  import { SessionReplayConfig, getDefaultConfig } from './session-replay-config';
11
- import { LogLevel } from '@amplitude/analytics-types';
11
+
12
+ type ResolvedSessionReplayConfig = Required<SessionReplayConfig>;
12
13
 
13
14
  export class SessionReplayPlugin implements EnrichmentPlugin<ReactNativeClient, ReactNativeConfig> {
14
15
  name = '@amplitude/plugin-session-replay-react-native';
@@ -19,7 +20,7 @@ export class SessionReplayPlugin implements EnrichmentPlugin<ReactNativeClient,
19
20
  config: ReactNativeConfig;
20
21
  isInitialized = false;
21
22
 
22
- sessionReplayConfig: SessionReplayConfig;
23
+ sessionReplayConfig: ResolvedSessionReplayConfig;
23
24
 
24
25
  constructor(config: SessionReplayConfig = {}) {
25
26
  this.sessionReplayConfig = {
@@ -32,15 +33,25 @@ export class SessionReplayPlugin implements EnrichmentPlugin<ReactNativeClient,
32
33
  async setup(config: ReactNativeConfig, _: ReactNativeClient): Promise<void> {
33
34
  this.config = config;
34
35
  console.log(`Installing @amplitude/plugin-session-replay-react-native, version ${VERSION}.`);
36
+ // `apiKey`, `deviceId`, `sessionId`, and `serverZone` are sourced from the
37
+ // analytics client's `ReactNativeConfig` because the plugin runs inside an
38
+ // initialized Amplitude SDK and inherits identity from it.
39
+ // Resolve the effective mask level here — the single source of truth for
40
+ // the default. `privacyConfig.maskLevel` can be `undefined` when a partial
41
+ // `privacyConfig` (e.g. `{}`) is supplied, so fall back to `'medium'` rather
42
+ // than forwarding `undefined` across the native bridge.
43
+ const resolvedMaskLevel = this.sessionReplayConfig.privacyConfig.maskLevel ?? 'medium';
35
44
  await PluginSessionReplayReactNative.setup(
36
45
  config.apiKey,
37
46
  config.deviceId,
38
47
  config.sessionId,
39
48
  config.serverZone,
40
- this.sessionReplayConfig.sampleRate ?? 1,
41
- this.sessionReplayConfig.enableRemoteConfig ?? true,
42
- this.sessionReplayConfig.logLevel ?? LogLevel.Warn,
43
- this.sessionReplayConfig.autoStart ?? true,
49
+ this.sessionReplayConfig.sampleRate,
50
+ this.sessionReplayConfig.enableRemoteConfig,
51
+ this.sessionReplayConfig.logLevel,
52
+ this.sessionReplayConfig.autoStart,
53
+ // TODO(SDKRN-15): Migrate native bridge to accept the full privacyConfig object instead of a flat maskLevel string.
54
+ resolvedMaskLevel,
44
55
  );
45
56
  this.isInitialized = true;
46
57
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.4.10';
1
+ export const VERSION = '0.5.0-sr-4646-rc.0';