noibu-react-native 0.2.12 → 0.2.14

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 (38) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +69 -0
  3. package/dist/api/ClientConfig.d.ts +3 -0
  4. package/dist/api/ClientConfig.js +3 -0
  5. package/dist/api/MetroplexSocket.d.ts +1 -1
  6. package/dist/api/MetroplexSocket.js +11 -5
  7. package/dist/constants.js +1 -1
  8. package/dist/mobileTransformer/mobile-replay/index.d.ts +10 -0
  9. package/dist/mobileTransformer/mobile-replay/index.js +57 -0
  10. package/dist/mobileTransformer/mobile-replay/mobile.types.d.ts +312 -0
  11. package/dist/mobileTransformer/mobile-replay/mobile.types.js +11 -0
  12. package/dist/mobileTransformer/mobile-replay/rrweb.d.ts +573 -0
  13. package/dist/mobileTransformer/mobile-replay/rrweb.js +39 -0
  14. package/dist/mobileTransformer/mobile-replay/schema/mobile/rr-mobile-schema.json.js +1559 -0
  15. package/dist/mobileTransformer/mobile-replay/schema/web/rr-web-schema.json.js +1183 -0
  16. package/dist/mobileTransformer/mobile-replay/transformer/colors.d.ts +1 -0
  17. package/dist/mobileTransformer/mobile-replay/transformer/colors.js +43 -0
  18. package/dist/mobileTransformer/mobile-replay/transformer/screen-chrome.d.ts +13 -0
  19. package/dist/mobileTransformer/mobile-replay/transformer/screen-chrome.js +142 -0
  20. package/dist/mobileTransformer/mobile-replay/transformer/transformers.d.ts +59 -0
  21. package/dist/mobileTransformer/mobile-replay/transformer/transformers.js +1160 -0
  22. package/dist/mobileTransformer/mobile-replay/transformer/types.d.ts +40 -0
  23. package/dist/mobileTransformer/mobile-replay/transformer/wireframeStyle.d.ts +16 -0
  24. package/dist/mobileTransformer/mobile-replay/transformer/wireframeStyle.js +197 -0
  25. package/dist/mobileTransformer/utils.d.ts +1 -0
  26. package/dist/mobileTransformer/utils.js +5 -0
  27. package/dist/monitors/http-tools/GqlErrorValidator.js +4 -3
  28. package/dist/pageVisit/HttpEventManager.js +2 -2
  29. package/dist/sessionRecorder/SessionRecorder.js +7 -4
  30. package/dist/sessionRecorder/nativeSessionRecorderSubscription.js +23 -3
  31. package/dist/sessionRecorder/types.d.ts +1 -1
  32. package/dist/utils/piiRedactor.js +15 -2
  33. package/dist/utils/piiRedactor.test.d.ts +1 -0
  34. package/ios/IOSPocEmitter.h +7 -0
  35. package/ios/IOSPocEmitter.m +33 -0
  36. package/noibu-react-native.podspec +50 -0
  37. package/package.json +17 -4
  38. package/android/.gitignore +0 -13
@@ -0,0 +1,40 @@
1
+ export interface StyleOverride {
2
+ borderWidth?: string | number;
3
+ borderRadius?: string | number;
4
+ borderColor?: string;
5
+ bottom?: boolean;
6
+ 'z-index'?: number;
7
+ paddingLeft?: string | number;
8
+ paddingRight?: string | number;
9
+ paddingTop?: string | number;
10
+ paddingBottom?: string | number;
11
+ verticalAlign?: 'top' | 'center' | 'bottom';
12
+ horizontalAlign?: 'left' | 'center' | 'right';
13
+ fontSize?: string | number;
14
+ fontFamily?: string;
15
+ color?: string;
16
+ backgroundColor?: string;
17
+ backgroundImage?: string;
18
+ backgroundSize?: string;
19
+ backgroundRepeat?: string;
20
+ [key: string]: unknown;
21
+ }
22
+ /**
23
+ * Represents the context in which a data conversion is happening.
24
+ * Includes information for id sequencing and timestamps to ensure
25
+ * consistent data handling during transformations.
26
+ */
27
+ export interface ConversionContext {
28
+ idSequence: Generator<number>;
29
+ timestamp?: number;
30
+ debugMode?: boolean;
31
+ styleOverride?: StyleOverride;
32
+ }
33
+ /**
34
+ * Represents the result of a conversion process.
35
+ * Contains the transformed data and relevant information for success or failure handling.
36
+ */
37
+ export interface ConversionResult<T = unknown> {
38
+ result: T;
39
+ context: ConversionContext;
40
+ }
@@ -0,0 +1,16 @@
1
+ import { wireframe, wireframeProgress } from '../mobile.types';
2
+ import { StyleOverride } from './types';
3
+ export declare function asStyleString(styleParts: string[]): string;
4
+ export declare function makeDimensionStyles(wireframe: wireframe): string;
5
+ export declare function makePositionStyles(wireframe: wireframe, styleOverride?: StyleOverride): string;
6
+ export declare function makeIndeterminateProgressStyles(wireframe: wireframeProgress, styleOverride?: StyleOverride): string;
7
+ export declare function makeDeterminateProgressStyles(wireframe: wireframeProgress, styleOverride?: StyleOverride): string;
8
+ /**
9
+ * normally use makeStylesString instead, but sometimes you need styles without any colors applied
10
+ * */
11
+ export declare function makeMinimalStyles(wireframe: wireframe, styleOverride?: StyleOverride): string;
12
+ export declare function makeBackgroundStyles(wireframe: wireframe, styleOverride?: StyleOverride): string;
13
+ export declare function makeColorStyles(wireframe: wireframe, styleOverride?: StyleOverride): string;
14
+ export declare function makeStylesString(wireframe: wireframe, styleOverride?: StyleOverride): string;
15
+ export declare function makeHTMLStyles(): string;
16
+ export declare function makeBodyStyles(): string;
@@ -0,0 +1,197 @@
1
+ import { dataURIOrPNG } from './transformers.js';
2
+
3
+ function ensureTrailingSemicolon(styles) {
4
+ return styles.endsWith(';') ? styles : styles + ';';
5
+ }
6
+ function stripTrailingSemicolon(styles) {
7
+ return styles.endsWith(';') ? styles.slice(0, -1) : styles;
8
+ }
9
+ function asStyleString(styleParts) {
10
+ if (styleParts.length === 0) {
11
+ return '';
12
+ }
13
+ return ensureTrailingSemicolon(styleParts
14
+ .map(stripTrailingSemicolon)
15
+ .filter(x => !!x)
16
+ .join(';'));
17
+ }
18
+ function isNumber(candidate) {
19
+ return typeof candidate === 'number' && Number.isFinite(candidate);
20
+ }
21
+ function isString(candidate) {
22
+ return typeof candidate === 'string' || candidate instanceof String;
23
+ }
24
+ function isUnitLike(candidate) {
25
+ return isNumber(candidate) || (isString(candidate) && candidate.length > 0);
26
+ }
27
+ function ensureUnit(value) {
28
+ return isNumber(value) ? `${value}px` : value.replace(/px$/g, '') + 'px';
29
+ }
30
+ function makeBorderStyles(wireframe, styleOverride) {
31
+ const styleParts = [];
32
+ const combinedStyles = Object.assign(Object.assign({}, wireframe.style), styleOverride);
33
+ if (isUnitLike(combinedStyles.borderWidth)) {
34
+ const borderWidth = ensureUnit(combinedStyles.borderWidth);
35
+ styleParts.push(`border-width: ${borderWidth}`);
36
+ }
37
+ if (isUnitLike(combinedStyles.borderRadius)) {
38
+ const borderRadius = ensureUnit(combinedStyles.borderRadius);
39
+ styleParts.push(`border-radius: ${borderRadius}`);
40
+ }
41
+ if (combinedStyles === null || combinedStyles === void 0 ? void 0 : combinedStyles.borderColor) {
42
+ styleParts.push(`border-color: ${combinedStyles.borderColor}`);
43
+ }
44
+ if (styleParts.length > 0) {
45
+ styleParts.push(`border-style: solid`);
46
+ }
47
+ return asStyleString(styleParts);
48
+ }
49
+ function makeDimensionStyles(wireframe) {
50
+ const styleParts = [];
51
+ if (wireframe.width === '100vw') {
52
+ styleParts.push(`width: 100vw`);
53
+ }
54
+ else if (isNumber(wireframe.width)) {
55
+ styleParts.push(`width: ${ensureUnit(wireframe.width)}`);
56
+ }
57
+ if (isNumber(wireframe.height)) {
58
+ styleParts.push(`height: ${ensureUnit(wireframe.height)}`);
59
+ }
60
+ return asStyleString(styleParts);
61
+ }
62
+ function makePositionStyles(wireframe, styleOverride) {
63
+ const styleParts = [];
64
+ styleParts.push(makeDimensionStyles(wireframe));
65
+ if (styleOverride === null || styleOverride === void 0 ? void 0 : styleOverride.bottom) {
66
+ styleParts.push(`bottom: 0`);
67
+ styleParts.push(`position: fixed`);
68
+ }
69
+ else {
70
+ const posX = wireframe.x || 0;
71
+ const posY = wireframe.y || 0;
72
+ if (isNumber(posX) || isNumber(posY)) {
73
+ styleParts.push(`position: fixed`);
74
+ if (isNumber(posX)) {
75
+ styleParts.push(`left: ${ensureUnit(posX)}`);
76
+ }
77
+ if (isNumber(posY)) {
78
+ styleParts.push(`top: ${ensureUnit(posY)}`);
79
+ }
80
+ }
81
+ }
82
+ if (styleOverride === null || styleOverride === void 0 ? void 0 : styleOverride['z-index']) {
83
+ styleParts.push(`z-index: ${styleOverride['z-index']}`);
84
+ }
85
+ return asStyleString(styleParts);
86
+ }
87
+ function makeLayoutStyles(wireframe, styleOverride) {
88
+ const styleParts = [];
89
+ const combinedStyles = Object.assign(Object.assign({}, wireframe.style), styleOverride);
90
+ if (combinedStyles.verticalAlign) {
91
+ styleParts.push(`align-items: ${{ top: 'flex-start', center: 'center', bottom: 'flex-end' }[combinedStyles.verticalAlign]}`);
92
+ }
93
+ if (combinedStyles.horizontalAlign) {
94
+ styleParts.push(`justify-content: ${{ left: 'flex-start', center: 'center', right: 'flex-end' }[combinedStyles.horizontalAlign]}`);
95
+ }
96
+ if (styleParts.length) {
97
+ styleParts.push(`display: flex`);
98
+ }
99
+ if (isUnitLike(combinedStyles.paddingLeft)) {
100
+ styleParts.push(`padding-left: ${ensureUnit(combinedStyles.paddingLeft)}`);
101
+ }
102
+ if (isUnitLike(combinedStyles.paddingRight)) {
103
+ styleParts.push(`padding-right: ${ensureUnit(combinedStyles.paddingRight)}`);
104
+ }
105
+ if (isUnitLike(combinedStyles.paddingTop)) {
106
+ styleParts.push(`padding-top: ${ensureUnit(combinedStyles.paddingTop)}`);
107
+ }
108
+ if (isUnitLike(combinedStyles.paddingBottom)) {
109
+ styleParts.push(`padding-bottom: ${ensureUnit(combinedStyles.paddingBottom)}`);
110
+ }
111
+ return asStyleString(styleParts);
112
+ }
113
+ function makeFontStyles(wireframe, styleOverride) {
114
+ const styleParts = [];
115
+ const combinedStyles = Object.assign(Object.assign({}, wireframe.style), styleOverride);
116
+ if (isUnitLike(combinedStyles.fontSize)) {
117
+ styleParts.push(`font-size: ${ensureUnit(combinedStyles === null || combinedStyles === void 0 ? void 0 : combinedStyles.fontSize)}`);
118
+ }
119
+ if (combinedStyles.fontFamily) {
120
+ styleParts.push(`font-family: ${combinedStyles.fontFamily}`);
121
+ }
122
+ return asStyleString(styleParts);
123
+ }
124
+ function makeIndeterminateProgressStyles(wireframe, styleOverride) {
125
+ const combinedStyles = Object.assign(Object.assign({}, wireframe.style), styleOverride);
126
+ return asStyleString([
127
+ makeBackgroundStyles(wireframe, styleOverride),
128
+ makePositionStyles(wireframe),
129
+ `border: 4px solid ${combinedStyles.borderColor || combinedStyles.color || 'transparent'};`,
130
+ `border-radius: 50%;border-top: 4px solid #fff;`,
131
+ `animation: spin 2s linear infinite;`,
132
+ ]);
133
+ }
134
+ function makeDeterminateProgressStyles(wireframe, styleOverride) {
135
+ const combinedStyles = Object.assign(Object.assign({}, wireframe.style), styleOverride);
136
+ const radialGradient = `radial-gradient(closest-side, white 80%, transparent 0 99.9%, white 0)`;
137
+ const conicGradient = `conic-gradient(${combinedStyles.color || 'black'} calc(${wireframe.value} * 1%), ${combinedStyles.backgroundColor} 0)`;
138
+ return asStyleString([
139
+ makeBackgroundStyles(wireframe, styleOverride),
140
+ makePositionStyles(wireframe),
141
+ 'border-radius: 50%',
142
+ `background: ${radialGradient}, ${conicGradient}`,
143
+ ]);
144
+ }
145
+ /**
146
+ * normally use makeStylesString instead, but sometimes you need styles without any colors applied
147
+ * */
148
+ function makeMinimalStyles(wireframe, styleOverride) {
149
+ return asStyleString([
150
+ makePositionStyles(wireframe, styleOverride),
151
+ makeLayoutStyles(wireframe, styleOverride),
152
+ makeFontStyles(wireframe, styleOverride),
153
+ ]);
154
+ }
155
+ function makeBackgroundStyles(wireframe, styleOverride) {
156
+ let styleParts = [];
157
+ const combinedStyles = Object.assign(Object.assign({}, wireframe.style), styleOverride);
158
+ if (combinedStyles.backgroundColor) {
159
+ styleParts.push(`background-color: ${combinedStyles.backgroundColor}`);
160
+ }
161
+ if (combinedStyles.backgroundImage) {
162
+ const backgroundImageURL = combinedStyles.backgroundImage.startsWith('url(')
163
+ ? combinedStyles.backgroundImage
164
+ : `url('${dataURIOrPNG(combinedStyles.backgroundImage)}')`;
165
+ styleParts = styleParts.concat([
166
+ `background-image: ${backgroundImageURL}`,
167
+ `background-size: ${combinedStyles.backgroundSize || 'contain'}`,
168
+ `background-repeat: ${combinedStyles.backgroundRepeat || 'no-repeat'}`,
169
+ ]);
170
+ }
171
+ return asStyleString(styleParts);
172
+ }
173
+ function makeColorStyles(wireframe, styleOverride) {
174
+ const combinedStyles = Object.assign(Object.assign({}, wireframe.style), styleOverride);
175
+ const styleParts = [
176
+ makeBackgroundStyles(wireframe, styleOverride),
177
+ makeBorderStyles(wireframe, styleOverride),
178
+ ];
179
+ if (combinedStyles.color) {
180
+ styleParts.push(`color: ${combinedStyles.color}`);
181
+ }
182
+ return asStyleString(styleParts);
183
+ }
184
+ function makeStylesString(wireframe, styleOverride) {
185
+ return asStyleString([
186
+ makeColorStyles(wireframe, styleOverride),
187
+ makeMinimalStyles(wireframe, styleOverride),
188
+ ]);
189
+ }
190
+ function makeHTMLStyles() {
191
+ return 'height: 100vh; width: 100vw;';
192
+ }
193
+ function makeBodyStyles() {
194
+ return 'height: 100vh; width: 100vw;';
195
+ }
196
+
197
+ export { asStyleString, makeBackgroundStyles, makeBodyStyles, makeColorStyles, makeDeterminateProgressStyles, makeDimensionStyles, makeHTMLStyles, makeIndeterminateProgressStyles, makeMinimalStyles, makePositionStyles, makeStylesString };
@@ -0,0 +1 @@
1
+ export declare function isObject(candidate: unknown): candidate is Record<string, unknown>;
@@ -0,0 +1,5 @@
1
+ function isObject(candidate) {
2
+ return typeof candidate === 'object' && candidate !== null;
3
+ }
4
+
5
+ export { isObject };
@@ -43,13 +43,14 @@ class GqlErrorValidator {
43
43
  static fromXhr(url, xhr) {
44
44
  return __awaiter(this, void 0, void 0, function* () {
45
45
  try {
46
- const isResponseValid = isInstanceOf(xhr, XMLHttpRequest) && xhr.status >= 200 && xhr.status <= 299;
46
+ const isResponseValid = xhr instanceof XMLHttpRequest && xhr.status >= 200 && xhr.status <= 299;
47
47
  if (!isResponseValid) {
48
48
  return null;
49
49
  }
50
50
  let contentType;
51
- if (xhr.noibuRequestHeaders) {
52
- contentType = xhr.noibuRequestHeaders.get(CONTENT_TYPE);
51
+ const xhrWithHeaders = xhr;
52
+ if (xhrWithHeaders.noibuRequestHeaders) {
53
+ contentType = xhrWithHeaders.noibuRequestHeaders.get(CONTENT_TYPE);
53
54
  }
54
55
  if (this._shouldHandleRequest(url, contentType)) {
55
56
  let data = null;
@@ -8,9 +8,9 @@ import { MetroplexMessageType, EventType } from 'noibu-metroplex-ts-bindings';
8
8
  /** @module PageVisitEventHTTP */
9
9
  /** http event manager */
10
10
  // maximum number of HTTP data events including errors to collect per page visit
11
- const MAX_HTTP_DATA_IF_ERROR_EVENT_COUNT = 120;
11
+ const MAX_HTTP_DATA_IF_ERROR_EVENT_COUNT = 2800;
12
12
  // maximum number of HTTP data events to collect per page visit
13
- const MAX_HTTP_DATA_EVENT_COUNT = 100;
13
+ const MAX_HTTP_DATA_EVENT_COUNT = 2500;
14
14
  /** if no value or it's less than 0, fallback to 0 */
15
15
  const validate = (value) => (!value || value < 0 ? 0 : value);
16
16
  /** Saves the HTTP event to the pageVisit Queue */
@@ -39,9 +39,7 @@ class SessionRecorder extends Singleton {
39
39
  const nativeSessionRecorderConfig = {
40
40
  logLevel: LogLevel.Verbose,
41
41
  };
42
- if (Platform.OS === 'android') {
43
- initialize('abc1234', nativeSessionRecorderConfig);
44
- }
42
+ initialize('abc1234', nativeSessionRecorderConfig);
45
43
  addSafeEventListener(window, 'click', () => this.handleFragPost());
46
44
  }
47
45
  /** Sets up the page hide handler to try to push remaining video events */
@@ -167,7 +165,12 @@ class SessionRecorder extends Singleton {
167
165
  pack(recorderEvent) {
168
166
  return __awaiter(this, void 0, void 0, function* () {
169
167
  // return JSON.stringify(recorderEvent);
170
- return SessionRecorder.compress(recorderEvent);
168
+ if (Platform.OS === 'ios') {
169
+ return recorderEvent;
170
+ }
171
+ else {
172
+ return SessionRecorder.compress(recorderEvent);
173
+ }
171
174
  });
172
175
  }
173
176
  /** Compresses the snapshot */
@@ -1,13 +1,14 @@
1
- import { NativeEventEmitter, Platform, NativeModules } from 'react-native';
1
+ import { Platform, NativeEventEmitter, NativeModules } from 'react-native';
2
2
  import { noibuLog } from '../utils/log.js';
3
+ import { transformEventToWeb } from '../mobileTransformer/mobile-replay/index.js';
3
4
 
4
5
  const LINKING_ERROR = `The package 'noibu-session-replay' doesn't seem to be linked. Make sure: \n\n` +
5
6
  // Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + TODO: add back when iOS is supported.
6
7
  '- You rebuilt the app after installing the package\n' +
7
8
  '- You are not using Expo Go\n';
8
- const { NativeSessionRecorder } = NativeModules;
9
+ const { NativeSessionRecorder, IOSPocEmitter } = NativeModules;
9
10
  let nativeModuleEmitter;
10
- const SupportedPlatforms = ['android'];
11
+ const SupportedPlatforms = ['android', 'ios'];
11
12
  /** The level of logging to show in the device logcat stream. */
12
13
  // eslint-disable-next-line no-shadow
13
14
  var LogLevel;
@@ -25,6 +26,11 @@ var LogLevel;
25
26
  * param config [OPTIONAL] The sessionreplay config, if not provided default values are used.
26
27
  */
27
28
  function initialize(projectId, config) {
29
+ if (Platform.OS === 'ios') {
30
+ nativeModuleEmitter = new NativeEventEmitter(IOSPocEmitter);
31
+ IOSPocEmitter.initialize();
32
+ return;
33
+ }
28
34
  if (!(typeof config === 'object' || typeof config === 'undefined')) {
29
35
  throw Error('Invalid session recording initialization arguments. Please check the docs for assitance.');
30
36
  }
@@ -68,6 +74,20 @@ function subscribeToNativeEvent(callback) {
68
74
  nativeModuleEmitter.addListener('noibuRecordingEvent', callback);
69
75
  // return () => subscription.remove();
70
76
  }
77
+ if (Platform.OS === 'ios') {
78
+ nativeModuleEmitter.addListener('iosPOCRecordingEvent', event => {
79
+ try {
80
+ let parsedMessage = JSON.parse(event.message);
81
+ if (Array.isArray(parsedMessage)) {
82
+ parsedMessage = parsedMessage[0];
83
+ }
84
+ const transformedEvent = transformEventToWeb(parsedMessage);
85
+ callback({ message: transformedEvent });
86
+ }
87
+ catch (e) {
88
+ }
89
+ });
90
+ }
71
91
  return () => { };
72
92
  }
73
93
 
@@ -86,6 +86,6 @@ export type NativeFrames = {
86
86
  p: (number | boolean | SubPicture)[][];
87
87
  a: (number[] | (number | string | string[])[])[];
88
88
  e: (string | number)[];
89
- };
89
+ } | string;
90
90
  export type UnsubscribeFn = () => void;
91
91
  export {};
@@ -1,6 +1,7 @@
1
1
  import { iterateObjectRecursively } from './object.js';
2
2
  import { PII_REDACTION_REPLACEMENT_STRING, PII_EMAIL_PATTERN } from '../constants.js';
3
3
  import { stringifyJSON } from './function.js';
4
+ import ClientConfig from '../api/ClientConfig.js';
4
5
 
5
6
  // Regex patterns for a best-effort attempt at blocking PII in HTTP requests
6
7
  const HTTP_PII_BLOCKING_PATTERNS = [
@@ -64,7 +65,7 @@ const exactFieldsToRedact = [
64
65
  */
65
66
  function shouldRedact(field) {
66
67
  // check for exact and fuzzy matches
67
- return exactFieldsToRedact.some(v => field === v) || fuzzyFieldsToRedact.some(v => field.indexOf(v) >= 0);
68
+ return getExactFieldsToRedact().some(v => field === v) || getFuzzyFieldsToRedact().some(v => field.indexOf(v) >= 0);
68
69
  }
69
70
  /**
70
71
  * Try to parse content as a JSON object and
@@ -116,11 +117,23 @@ function removePII(content) {
116
117
  }
117
118
  content = tryParseObjectAndRemovePII(content);
118
119
  // Go through each of the PII matching patterns
119
- HTTP_PII_BLOCKING_PATTERNS.forEach(pattern => {
120
+ getHttpPiiBlockingPatterns().forEach(pattern => {
120
121
  // Replace all matches with the appropriate number of asterisks
121
122
  content = content.replace(pattern, PII_REDACTION_REPLACEMENT_STRING);
122
123
  });
123
124
  return content;
124
125
  }
126
+ function getHttpPiiBlockingPatterns() {
127
+ var _a;
128
+ return (_a = ClientConfig.getInstance().httpPiiBlockingPatterns) !== null && _a !== void 0 ? _a : HTTP_PII_BLOCKING_PATTERNS;
129
+ }
130
+ function getFuzzyFieldsToRedact() {
131
+ var _a;
132
+ return (_a = ClientConfig.getInstance().fuzzyFieldsToRedact) !== null && _a !== void 0 ? _a : fuzzyFieldsToRedact;
133
+ }
134
+ function getExactFieldsToRedact() {
135
+ var _a;
136
+ return (_a = ClientConfig.getInstance().exactFieldsToRedact) !== null && _a !== void 0 ? _a : exactFieldsToRedact;
137
+ }
125
138
 
126
139
  export { removePII, shouldRedact };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ #import <React/RCTEventEmitter.h>
2
+ #import <React/RCTBridgeModule.h>
3
+
4
+ @interface IOSPocEmitter : RCTEventEmitter <RCTBridgeModule>
5
+
6
+ - (void)initialize;
7
+ @end
@@ -0,0 +1,33 @@
1
+ #import "IOSPocEmitter.h"
2
+ @import NoibuSDK;
3
+ @implementation IOSPocEmitter
4
+
5
+ // Module registration
6
+ RCT_EXPORT_MODULE();
7
+
8
+ // Supported events for React Native
9
+ - (NSArray<NSString *> *)supportedEvents {
10
+ return @[@"iosPOCRecordingEvent"];
11
+ }
12
+
13
+ RCT_EXPORT_METHOD(initialize) {
14
+ NSString *NOIBU_API_KEY = @"NOIBU_API_KEY";
15
+ NSString *NOIBU_HOST = @"https://noibu.com/";
16
+ // Create and configure the NoibuConfig object
17
+ NoibuConfig *config = [[NoibuConfig alloc] apiKey:NOIBU_API_KEY host:NOIBU_HOST];
18
+ // config.debug = YES; // Enable debug logging to see transformed events
19
+ // Define the callback for transformed events
20
+ config.onMobileEventTransformed = ^(NSString *transformedData) {
21
+ if ([self bridge]) { // Ensure the bridge is initialized
22
+ [self sendEventWithName:@"iosPOCRecordingEvent" body:@{@"message": transformedData}];
23
+ }
24
+ };
25
+ [[NoibuSDKManager shared] setup:config];
26
+ }
27
+
28
+ // React Native requires this to indicate if the module needs to be initialized on the main thread
29
+ + (BOOL)requiresMainQueueSetup {
30
+ return YES;
31
+ }
32
+
33
+ @end
@@ -0,0 +1,50 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
5
+
6
+ Pod::Spec.new do |s|
7
+ s.name = "noibu-react-native"
8
+ s.version = package["version"]
9
+ s.summary = package["description"]
10
+ s.homepage = "https://www.npmjs.com/package/noibu-react-native"
11
+ s.license = package["license"]
12
+ s.authors = package["author"]
13
+
14
+ s.platforms = { :ios => min_ios_version_supported }
15
+ #s.source = { :git => "https://www.github.com/aleguia.git", :tag => "#{s.version}" }
16
+ s.source = { :path => "." }
17
+
18
+ # Include source files
19
+
20
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
21
+ s.public_header_files = "ios/**/*.{h}" # Expose public headers
22
+
23
+ #s.vendored_frameworks = "ios/SessionRecorder.xcframework"
24
+ #s.vendored_frameworks = "ios/Noibu.xcframework"
25
+
26
+ s.dependency 'NoibuSDK'
27
+ s.pod_target_xcconfig = {
28
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/noibu-react-native/ios/**\""
29
+ }
30
+
31
+ if respond_to?(:install_modules_dependencies, true)
32
+ install_modules_dependencies(s)
33
+ else
34
+ s.dependency "React-Core"
35
+
36
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
37
+ s.compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1'
38
+ s.pod_target_xcconfig = {
39
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
40
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
41
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
42
+ }
43
+ s.dependency "React-Codegen"
44
+ s.dependency "RCT-Folly"
45
+ s.dependency "RCTRequired"
46
+ s.dependency "RCTTypeSafety"
47
+ s.dependency "ReactCommon/turbomodule/core"
48
+ end
49
+ end
50
+ end
package/package.json CHANGED
@@ -1,14 +1,24 @@
1
1
  {
2
2
  "name": "noibu-react-native",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "targetNjsVersion": "1.0.104",
5
5
  "description": "React-Native SDK for NoibuJS to collect errors in React-Native applications",
6
6
  "main": "dist/entry/index.js",
7
7
  "types": "dist/entry/index.d.ts",
8
8
  "files": [
9
- "android/*",
9
+ "android",
10
10
  "dist/*",
11
- "README.md"
11
+ "README.md",
12
+ "CHANGELOG.md",
13
+ "ios",
14
+ "cpp",
15
+ "*.podspec",
16
+ "!ios/build",
17
+ "!android/build",
18
+ "!android/gradle",
19
+ "!android/gradlew",
20
+ "!android/gradlew.bat",
21
+ "!android/local.properties"
12
22
  ],
13
23
  "author": "Noibu Inc",
14
24
  "license": "ISC",
@@ -61,7 +71,7 @@
61
71
  "@tsconfig/react-native": "^3.0.2",
62
72
  "@types/jest": "^29.5.14",
63
73
  "@types/node": "^20.2.3",
64
- "@types/react": "16.14.62",
74
+ "@types/react": "18.2.6",
65
75
  "@types/react-test-renderer": "^18.0.0",
66
76
  "@typescript-eslint/eslint-plugin": "^8.19.1",
67
77
  "@typescript-eslint/parser": "^8.19.1",
@@ -86,5 +96,8 @@
86
96
  "rollup-plugin-dotenv": "^0.5.0",
87
97
  "ts-jest": "^29.2.5",
88
98
  "typescript": "^5.5.3"
99
+ },
100
+ "resolutions": {
101
+ "@types/react": "18.0.30"
89
102
  }
90
103
  }
@@ -1,13 +0,0 @@
1
- build/
2
- .idea
3
- .gradle
4
- local.properties
5
- *.iml
6
- *.hprof
7
- .cxx/
8
- *.keystore
9
- !debug.keystore
10
- gradle
11
- gradle*
12
- !gradle.properties
13
- settings.gradle