@nativescript-community/sentry 3.1.5 → 4.6.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 (105) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -6
  3. package/client.d.ts +38 -3
  4. package/client.js +143 -5
  5. package/client.js.map +1 -1
  6. package/index.d.ts +7 -11
  7. package/index.js +28 -12
  8. package/index.js.map +1 -1
  9. package/integrations/debugsymbolicator.d.ts +4 -4
  10. package/integrations/debugsymbolicator.js +11 -22
  11. package/integrations/debugsymbolicator.js.map +1 -1
  12. package/integrations/devicecontext.js +22 -5
  13. package/integrations/devicecontext.js.map +1 -1
  14. package/integrations/eventorigin.d.ts +7 -7
  15. package/integrations/eventorigin.js +9 -9
  16. package/integrations/eventorigin.js.map +1 -1
  17. package/integrations/nativescripterrorhandlers.d.ts +15 -5
  18. package/integrations/nativescripterrorhandlers.js +55 -44
  19. package/integrations/nativescripterrorhandlers.js.map +1 -1
  20. package/integrations/release.js +10 -8
  21. package/integrations/release.js.map +1 -1
  22. package/integrations/sdkinfo.d.ts +4 -1
  23. package/integrations/sdkinfo.js +17 -10
  24. package/integrations/sdkinfo.js.map +1 -1
  25. package/measurement.d.ts +4 -0
  26. package/measurement.js +50 -0
  27. package/measurement.js.map +1 -0
  28. package/measurements.d.ts +4 -0
  29. package/measurements.js +50 -0
  30. package/measurements.js.map +1 -0
  31. package/misc.d.ts +8 -0
  32. package/misc.js +17 -0
  33. package/misc.js.map +1 -0
  34. package/options.d.ts +125 -0
  35. package/options.js +2 -0
  36. package/options.js.map +1 -0
  37. package/package.json +9 -12
  38. package/platforms/android/buildscript.gradle +6 -2
  39. package/platforms/android/include.gradle +1 -1
  40. package/platforms/android/sentry.aar +0 -0
  41. package/platforms/ios/Podfile +1 -1
  42. package/platforms/ios/src/NSSentry.h +8 -3
  43. package/platforms/ios/src/NSSentry.m +41 -0
  44. package/scope.d.ts +1 -45
  45. package/scope.js +90 -68
  46. package/scope.js.map +1 -1
  47. package/sdk.d.ts +27 -3
  48. package/sdk.js +105 -30
  49. package/sdk.js.map +1 -1
  50. package/tracing/index.d.ts +2 -1
  51. package/tracing/index.js +14 -6
  52. package/tracing/index.js.map +1 -1
  53. package/tracing/nativeframes.d.ts +68 -0
  54. package/tracing/nativeframes.js +175 -0
  55. package/tracing/nativeframes.js.map +1 -0
  56. package/tracing/nstracing.d.ts +98 -47
  57. package/tracing/nstracing.js +164 -44
  58. package/tracing/nstracing.js.map +1 -1
  59. package/tracing/routingInstrumentation.d.ts +46 -0
  60. package/tracing/routingInstrumentation.js +33 -0
  61. package/tracing/routingInstrumentation.js.map +1 -0
  62. package/tracing/stalltracking.d.ts +92 -0
  63. package/tracing/stalltracking.js +258 -0
  64. package/tracing/stalltracking.js.map +1 -0
  65. package/tracing/types.d.ts +13 -0
  66. package/tracing/types.js +2 -0
  67. package/tracing/types.js.map +1 -0
  68. package/tracing/utils.d.ts +22 -1
  69. package/tracing/utils.js +51 -2
  70. package/tracing/utils.js.map +1 -1
  71. package/transports/TextEncoder.d.ts +2 -0
  72. package/transports/TextEncoder.js +12 -0
  73. package/transports/TextEncoder.js.map +1 -0
  74. package/transports/native.d.ts +20 -8
  75. package/transports/native.js +21 -13
  76. package/transports/native.js.map +1 -1
  77. package/utils/envelope.d.ts +11 -0
  78. package/utils/envelope.js +21 -0
  79. package/utils/envelope.js.map +1 -0
  80. package/utils/outcome.d.ts +5 -0
  81. package/utils/outcome.js +19 -0
  82. package/utils/outcome.js.map +1 -0
  83. package/utils/safe.d.ts +17 -0
  84. package/utils/safe.js +46 -0
  85. package/utils/safe.js.map +1 -0
  86. package/vendor/buffer/index.d.ts +1 -0
  87. package/vendor/buffer/index.js +2 -0
  88. package/vendor/buffer/index.js.map +1 -0
  89. package/vendor/buffer/utf8ToBytes.d.ts +9 -0
  90. package/vendor/buffer/utf8ToBytes.js +81 -0
  91. package/vendor/buffer/utf8ToBytes.js.map +1 -0
  92. package/vendor/index.d.ts +1 -0
  93. package/vendor/index.js +2 -0
  94. package/vendor/index.js.map +1 -0
  95. package/version.d.ts +2 -1
  96. package/version.js +2 -1
  97. package/version.js.map +1 -1
  98. package/wrapper.android.d.ts +30 -0
  99. package/wrapper.android.js +952 -0
  100. package/wrapper.android.js.map +1 -0
  101. package/wrapper.d.ts +88 -0
  102. package/wrapper.ios.d.ts +34 -0
  103. package/wrapper.ios.js +497 -0
  104. package/wrapper.ios.js.map +1 -0
  105. package/pnpm-lock.yaml +0 -914
@@ -0,0 +1,952 @@
1
+ import { createArrayBuffer, pointsFromBuffer } from '@nativescript-community/arraybuffers';
2
+ import { Application, Utils } from '@nativescript/core';
3
+ import { SentryError } from '@sentry/utils';
4
+ import { convertNativescriptFramesToSentryFrames, parseErrorStack } from './integrations/debugsymbolicator';
5
+ import { isHardCrash } from './misc';
6
+ import { rewriteFrameIntegration } from './sdk';
7
+ import { utf8ToBytes } from './vendor';
8
+ import { SDK_NAME } from './version';
9
+ let encoder;
10
+ function strToTypedArray(str) {
11
+ if (!encoder) {
12
+ const charset = java.nio.charset.Charset.forName('UTF-8');
13
+ encoder = charset.newEncoder();
14
+ }
15
+ return new Uint8Array(ArrayBuffer.from(encoder.encode(java.nio.CharBuffer.wrap(str))));
16
+ }
17
+ function concatTypedArrays(a, b) {
18
+ if (!b || b.length === 0)
19
+ return a;
20
+ if (!a || a.length === 0)
21
+ return b;
22
+ const c = createArrayBuffer(a.length + b.length, true, false);
23
+ c.set(a, 0);
24
+ c.set(b, a.length);
25
+ return c;
26
+ }
27
+ export var NATIVE;
28
+ (function (NATIVE) {
29
+ let enableNative = true;
30
+ const _DisabledNativeError = new SentryError('Native is disabled');
31
+ let frameMetricsAggregator;
32
+ function isNativeTransportAvailable() {
33
+ return enableNative;
34
+ }
35
+ NATIVE.isNativeTransportAvailable = isNativeTransportAvailable;
36
+ const mJsModuleIdPattern = new RegExp('(?:^|[/\\\\])(\\d+\\.js)$');
37
+ function stackFrameToModuleId(frame) {
38
+ if (!!frame.file) {
39
+ const matcher = mJsModuleIdPattern.exec(frame.file);
40
+ if (matcher) {
41
+ return matcher[1] + ':';
42
+ }
43
+ }
44
+ return '';
45
+ }
46
+ function convertToNativeStacktrace(stack) {
47
+ if (!stack) {
48
+ return null;
49
+ }
50
+ const nStackTrace = new io.sentry.protocol.SentryStackTrace();
51
+ const frames = new java.util.ArrayList();
52
+ for (let i = 0; i < stack.length; i++) {
53
+ const frame = stack[i];
54
+ const fileName = frame.file || frame.filename || '';
55
+ const methodName = frame.methodName || frame.function || '';
56
+ const lineNumber = frame.lineNumber || frame.lineno || 0;
57
+ const column = frame.column || frame.colno || 0;
58
+ const stackFrame = new io.sentry.protocol.SentryStackFrame();
59
+ stackFrame.setModule('');
60
+ stackFrame.setFunction(methodName.length > 0 ? methodName.split('.').pop() : methodName);
61
+ stackFrame.setFilename(stackFrameToModuleId(frame));
62
+ stackFrame.setLineno(new java.lang.Integer(lineNumber));
63
+ stackFrame.setColno(new java.lang.Integer(column));
64
+ stackFrame.setAbsPath(fileName);
65
+ stackFrame.setPlatform('javascript');
66
+ stackFrame.setInApp(new java.lang.Boolean(frame.in_app || false));
67
+ frames.add(stackFrame);
68
+ }
69
+ nStackTrace.setFrames(frames);
70
+ return nStackTrace;
71
+ }
72
+ function addExceptionInterface(nEvent, type, value, stack) {
73
+ const exceptions = nEvent.getExceptions() || new java.util.ArrayList();
74
+ const nException = new io.sentry.protocol.SentryException();
75
+ nException.setType(type);
76
+ nException.setValue(value);
77
+ nException.setModule('');
78
+ // nException.setModule('com.tns');
79
+ nException.setThreadId(new java.lang.Long(java.lang.Thread.currentThread().getId()));
80
+ nException.setStacktrace(convertToNativeStacktrace(stack));
81
+ exceptions.add(nException);
82
+ nEvent.setExceptions(exceptions);
83
+ }
84
+ /**
85
+ * Get breadcrumbs (removes breadcrumbs from handled exceptions on Android)
86
+ *
87
+ * We do this to avoid duplicate breadcrumbs on Android as sentry-android applies the breadcrumbs
88
+ * from the native scope onto every envelope sent through it. This scope will contain the breadcrumbs
89
+ * sent through the scope sync feature. This causes duplicate breadcrumbs.
90
+ * We then remove the breadcrumbs in all cases but if it is handled == false,
91
+ * this is a signal that the app would crash and android would lose the breadcrumbs by the time the app is restarted to read
92
+ * the envelope.
93
+ */
94
+ function _getBreadcrumbs(event) {
95
+ const breadcrumbs = event.breadcrumbs;
96
+ const hardCrashed = isHardCrash(event);
97
+ // if (event.breadcrumbs && !hardCrashed) {
98
+ // breadcrumbs = undefined;
99
+ // }
100
+ breadcrumbs && breadcrumbs.forEach(b => {
101
+ // fix for native SDK not supporting number
102
+ b.timestamp = new Date(b.timestamp * 1000).toISOString();
103
+ });
104
+ return breadcrumbs && breadcrumbs.length ? breadcrumbs : undefined;
105
+ }
106
+ /**
107
+ * Convert js severity level in event.level and event.breadcrumbs to more widely supported levels.
108
+ * @param event
109
+ * @returns Event with more widely supported Severity level strings
110
+ */
111
+ function _processLevels(event) {
112
+ var _a;
113
+ const processed = Object.assign(Object.assign({}, event), { level: event.level ? _processLevel(event.level) : undefined, breadcrumbs: (_a = event.breadcrumbs) === null || _a === void 0 ? void 0 : _a.map((breadcrumb) => (Object.assign(Object.assign({}, breadcrumb), { level: breadcrumb.level
114
+ ? _processLevel(breadcrumb.level)
115
+ : undefined }))) });
116
+ return processed;
117
+ }
118
+ /**
119
+ * Convert js severity level which has critical and log to more widely supported levels.
120
+ * @param level
121
+ * @returns More widely supported Severity level strings
122
+ */
123
+ function _processLevel(level) {
124
+ if (level === 'log') {
125
+ return 'debug';
126
+ }
127
+ else if (level === 'critical') {
128
+ return 'fatal';
129
+ }
130
+ return level;
131
+ }
132
+ /**
133
+ * Gets the event from envelopeItem and applies the level filter to the selected event.
134
+ * @param data An envelope item containing the event.
135
+ * @returns The event from envelopeItem or undefined.
136
+ */
137
+ function _processItem(item) {
138
+ const [itemHeader, itemPayload] = item;
139
+ if (itemHeader.type === 'event' || itemHeader.type === 'transaction') {
140
+ const event = _processLevels(itemPayload);
141
+ // fix for native SDK
142
+ event.timestamp = new Date(event.timestamp * 1000).toISOString();
143
+ if ('message' in event) {
144
+ // @ts-ignore Android still uses the old message object, without this the serialization of events will break.
145
+ event.message = { message: event.message };
146
+ }
147
+ event.breadcrumbs = _getBreadcrumbs(event);
148
+ return [itemHeader, event];
149
+ }
150
+ return item;
151
+ }
152
+ async function sendEnvelope(envelope) {
153
+ if (!enableNative) {
154
+ console.warn('Event was skipped as native SDK is not enabled.');
155
+ return;
156
+ }
157
+ const envelopeBytes = prepareEnvelopeNative(envelope);
158
+ // const envelopeBytesNative = prepareEnvelopeNative(envelope);
159
+ await captureEnvelope(envelopeBytes);
160
+ if (sentryOptions.flushSendEvent) {
161
+ flush(0);
162
+ }
163
+ }
164
+ NATIVE.sendEnvelope = sendEnvelope;
165
+ function prepareEnvelope(envelope) {
166
+ const [EOL] = utf8ToBytes('\n');
167
+ const [envelopeHeader, envelopeItems] = envelope;
168
+ const headerString = JSON.stringify(envelopeHeader);
169
+ const envelopeBytes = utf8ToBytes(headerString);
170
+ envelopeBytes.push(EOL);
171
+ let hardCrashed = false;
172
+ for (const rawItem of envelopeItems) {
173
+ const [itemHeader, itemPayload] = _processItem(rawItem);
174
+ let bytesPayload = [];
175
+ if (typeof itemPayload === 'string') {
176
+ bytesPayload = utf8ToBytes(itemPayload);
177
+ }
178
+ else if (itemPayload instanceof Uint8Array) {
179
+ bytesPayload = [...itemPayload];
180
+ }
181
+ else if (itemPayload instanceof ArrayBuffer) {
182
+ bytesPayload = [...new Uint8Array(itemPayload)];
183
+ }
184
+ else {
185
+ bytesPayload = utf8ToBytes(JSON.stringify(itemPayload));
186
+ if (!hardCrashed) {
187
+ hardCrashed = isHardCrash(itemPayload);
188
+ }
189
+ }
190
+ // Content type is not inside BaseEnvelopeItemHeaders.
191
+ itemHeader.content_type = 'application/json';
192
+ itemHeader.length = bytesPayload.length;
193
+ const serializedItemHeader = JSON.stringify(itemHeader) + '\n';
194
+ envelopeBytes.push(...utf8ToBytes(serializedItemHeader));
195
+ // envelopeBytes.push(EOL);
196
+ envelopeBytes.push(...bytesPayload);
197
+ envelopeBytes.push(EOL);
198
+ }
199
+ return envelopeBytes;
200
+ }
201
+ NATIVE.prepareEnvelope = prepareEnvelope;
202
+ function prepareEnvelopeNative(envelope) {
203
+ const [envelopeHeader, envelopeItems] = envelope;
204
+ const headerString = JSON.stringify(envelopeHeader);
205
+ let envelopeBytes = strToTypedArray(headerString + '\n');
206
+ let hardCrashed = false;
207
+ for (const rawItem of envelopeItems) {
208
+ const [itemHeader, itemPayload] = _processItem(rawItem);
209
+ let bytesPayload;
210
+ if (typeof itemPayload === 'string') {
211
+ bytesPayload = strToTypedArray(itemPayload);
212
+ }
213
+ else if (itemPayload instanceof Uint8Array) {
214
+ bytesPayload = itemPayload;
215
+ }
216
+ else {
217
+ bytesPayload = strToTypedArray(JSON.stringify(itemPayload));
218
+ if (!hardCrashed) {
219
+ hardCrashed = isHardCrash(itemPayload);
220
+ }
221
+ }
222
+ // Content type is not inside BaseEnvelopeItemHeaders.
223
+ itemHeader.content_type = 'application/json';
224
+ itemHeader.length = bytesPayload.length;
225
+ const serializedItemHeaderBytes = strToTypedArray(JSON.stringify(itemHeader) + '\n');
226
+ const rawItemBytes = createArrayBuffer(serializedItemHeaderBytes.length + bytesPayload.length + 1, true, false);
227
+ rawItemBytes.set(serializedItemHeaderBytes, 0);
228
+ rawItemBytes.set(bytesPayload, serializedItemHeaderBytes.length);
229
+ rawItemBytes[serializedItemHeaderBytes.length + bytesPayload.length] = '\n'.charCodeAt(0);
230
+ envelopeBytes = concatTypedArrays(envelopeBytes, rawItemBytes);
231
+ }
232
+ return envelopeBytes;
233
+ }
234
+ NATIVE.prepareEnvelopeNative = prepareEnvelopeNative;
235
+ // export async function sendEvent(event: Event): Promise<Response> {
236
+ // try {
237
+ // // Process and convert deprecated levels
238
+ // const nEvent = new io.sentry.SentryEvent();
239
+ // if (event.event_id) {
240
+ // nEvent.setEventId(new io.sentry.protocol.SentryId(event.event_id));
241
+ // }
242
+ // if (event.breadcrumbs) {
243
+ // const breadcrumbs = event.breadcrumbs;
244
+ // const eventBreadcrumbs = new java.util.ArrayList<io.sentry.Breadcrumb>();
245
+ // for (let i = 0; i < breadcrumbs.length; i++) {
246
+ // const breadcrumb = breadcrumbs[i];
247
+ // const nBreadcumb = new io.sentry.Breadcrumb();
248
+ // if (breadcrumb.category) {
249
+ // nBreadcumb.setCategory(breadcrumb.category);
250
+ // }
251
+ // if (breadcrumb.type) {
252
+ // const typeString = breadcrumb.type.toUpperCase();
253
+ // try {
254
+ // nBreadcumb.setType(typeString);
255
+ // } catch (e) {
256
+ // // don't copy over invalid breadcrumb 'type' value
257
+ // }
258
+ // }
259
+ // if (breadcrumb.level) {
260
+ // nBreadcumb.setLevel(eventLevel(breadcrumb.level));
261
+ // }
262
+ // try {
263
+ // if (breadcrumb.data) {
264
+ // Object.keys(breadcrumb.data).forEach((k) => {
265
+ // let value = breadcrumb.data[k];
266
+ // // in case a `status_code` entry got accidentally stringified as a float
267
+ // if (k === 'status_code' && typeof value === 'string' && value.endsWith('.0')) {
268
+ // value = value.replace('.0', '');
269
+ // } else if (typeof value === 'boolean') {
270
+ // value = new java.lang.Boolean(value);
271
+ // } else if (typeof value === 'number') {
272
+ // value = value.toString();
273
+ // } else if (Array.isArray(value)) {
274
+ // value = new org.json.JSONArray(JSON.stringify(value));
275
+ // } else if (value && typeof value === 'object') {
276
+ // value = new org.json.JSONObject(JSON.stringify(value));
277
+ // }
278
+ // nBreadcumb.setData(k, value);
279
+ // });
280
+ // }
281
+ // } catch (e) {
282
+ // console.warn('Discarded breadcrumb.data since it was not an object');
283
+ // }
284
+ // if (breadcrumb.message) {
285
+ // nBreadcumb.setMessage(breadcrumb.message);
286
+ // } else {
287
+ // nBreadcumb.setMessage('');
288
+ // }
289
+ // eventBreadcrumbs.add(i, nBreadcumb);
290
+ // }
291
+ // if (eventBreadcrumbs.size() > 0) {
292
+ // nEvent.setBreadcrumbs(eventBreadcrumbs);
293
+ // }
294
+ // }
295
+ // if (event.message) {
296
+ // const nMsg = new io.sentry.protocol.Message();
297
+ // nMsg.setMessage(event.message || '');
298
+ // nEvent.setMessage(nMsg);
299
+ // }
300
+ // if (event.logger) {
301
+ // nEvent.setLogger(event.logger);
302
+ // }
303
+ // if (event.user) {
304
+ // nEvent.setUser(getUser(event.user));
305
+ // }
306
+ // if (event.extra) {
307
+ // Object.keys(event.extra).forEach((k) => {
308
+ // const value = event.extra[k];
309
+ // nEvent.setExtra(k, typeof value === 'string' ? value : JSON.stringify(value));
310
+ // });
311
+ // }
312
+ // if (event.fingerprint) {
313
+ // const fingerprint: string[] = event.fingerprint;
314
+ // const print = new java.util.ArrayList();
315
+ // for (let i = 0; i < fingerprint.length; ++i) {
316
+ // print.add(fingerprint[i]);
317
+ // }
318
+ // nEvent.setFingerprints(print);
319
+ // }
320
+ // if (event.tags) {
321
+ // Object.keys(event.tags).forEach((k) => {
322
+ // const value = event.tags[k];
323
+ // nEvent.setTag(k, (value || 'INVALID_TAG').toString());
324
+ // });
325
+ // }
326
+ // if (event.exception) {
327
+ // const exceptionValues: any[] = event.exception.values;
328
+ // const exception = exceptionValues[0];
329
+ // if (exception.stacktrace) {
330
+ // const stacktrace = exception.stacktrace;
331
+ // const frames = stacktrace.frames;
332
+ // if (exception.value) {
333
+ // addExceptionInterface(nEvent, exception.type, exception.value, frames);
334
+ // } else {
335
+ // // We use type/type here since this indicates an Unhandled Promise Rejection
336
+ // // https://github.com/getsentry/react-native-sentry/issues/353
337
+ // addExceptionInterface(nEvent, exception.type, exception.type, frames);
338
+ // }
339
+ // }
340
+ // }
341
+ // if (event.environment) {
342
+ // nEvent.setEnvironment(event.environment);
343
+ // }
344
+ // if (event.platform) {
345
+ // nEvent.setPlatform(event.platform);
346
+ // }
347
+ // if (event.release) {
348
+ // nEvent.setRelease(event.release);
349
+ // }
350
+ // if (event.dist) {
351
+ // nEvent.setDist(event.dist);
352
+ // }
353
+ // if (event.level) {
354
+ // nEvent.setLevel(eventLevel(event.level));
355
+ // }
356
+ // if (event.contexts) {
357
+ // Object.keys(event.contexts).forEach((k) => {
358
+ // // const value = event.contexts[k];
359
+ // // const context = new io.sentry.protocol.Contexts();
360
+ // // nEvent.setTag(k, value || 'INVALID_TAG');
361
+ // });
362
+ // }
363
+ // if (event.sdk) {
364
+ // const sdk = event.sdk;
365
+ // const nSdk = new io.sentry.protocol.SdkVersion();
366
+ // nSdk.setName(sdk.name);
367
+ // nSdk.setVersion(sdk.version);
368
+ // if (sdk.integrations) {
369
+ // const integrations: string[] = sdk.integrations;
370
+ // for (let i = 0; i < integrations.length; ++i) {
371
+ // nSdk.addIntegration(integrations[i]);
372
+ // }
373
+ // }
374
+ // nEvent.setSdk(nSdk);
375
+ // }
376
+ // const id = io.sentry.Sentry.captureEvent(nEvent);
377
+ // flush(0);
378
+ // return({ status: 'success', id } as any);
379
+ // }catch(err) {
380
+ // console.error('error sending sentry event', err, err.stack);
381
+ // throw(err);
382
+ // };
383
+ // }
384
+ async function captureEnvelope(envelope, { store } = {}) {
385
+ try {
386
+ const outboxPath = new java.io.File(nSentryOptions.getOutboxPath(), java.util.UUID.randomUUID().toString());
387
+ const out = new java.io.FileOutputStream(outboxPath);
388
+ if (ArrayBuffer.isView(envelope)) {
389
+ out.write(pointsFromBuffer(envelope, true, false));
390
+ }
391
+ else if (Array.isArray(envelope)) {
392
+ out.write(envelope);
393
+ }
394
+ else {
395
+ out.write(new java.lang.String(envelope).getBytes(java.nio.charset.Charset.forName('UTF-8')));
396
+ }
397
+ return true;
398
+ }
399
+ catch (err) {
400
+ console.error('captureEnvelope error', err, err.stack);
401
+ return false;
402
+ }
403
+ }
404
+ NATIVE.captureEnvelope = captureEnvelope;
405
+ function flush(timeout = 0) {
406
+ console.log('flush', timeout);
407
+ io.sentry.Sentry.flush(timeout);
408
+ }
409
+ NATIVE.flush = flush;
410
+ let initialized = false;
411
+ let sentryOptions;
412
+ let nSentryOptions;
413
+ function addPackages(event, sdk) {
414
+ const eventSdk = event.getSdk();
415
+ if (eventSdk && sdk && eventSdk.getName() === SDK_NAME) {
416
+ const sentryPackages = sdk.getPackages();
417
+ if (sentryPackages != null) {
418
+ for (let index = 0; index < sentryPackages.size(); index++) {
419
+ const sentryPackage = sentryPackages.get(index);
420
+ eventSdk.addPackage(sentryPackage.getName(), sentryPackage.getVersion());
421
+ }
422
+ }
423
+ const integrations = sdk.getIntegrations();
424
+ if (integrations != null) {
425
+ for (let index = 0; index < integrations.size(); index++) {
426
+ eventSdk.addIntegration(integrations.get(index));
427
+ }
428
+ }
429
+ event.setSdk(eventSdk);
430
+ }
431
+ }
432
+ async function initNativeSdk(originalOptions = {}) {
433
+ if (initialized) {
434
+ return (true);
435
+ }
436
+ try {
437
+ const options = Object.assign({ enableNative: true, autoInitializeNativeSdk: true }, originalOptions);
438
+ if (!options.enableNative) {
439
+ if (options.enableNativeNagger) {
440
+ console.warn('Note: Native Sentry SDK is disabled.');
441
+ }
442
+ enableNative = false;
443
+ return false;
444
+ }
445
+ if (!options.autoInitializeNativeSdk) {
446
+ if (options.enableNativeNagger) {
447
+ console.warn('Note: Native Sentry SDK was not initialized automatically, you will need to initialize it manually. If you wish to disable the native SDK and get rid of this warning, pass enableNative: false');
448
+ }
449
+ return false;
450
+ }
451
+ if (!options.dsn) {
452
+ console.warn('Warning: No DSN was provided. The Sentry SDK will be disabled. Native SDK will also not be initalized.');
453
+ return false;
454
+ }
455
+ io.sentry.android.core.SentryAndroid.init(Utils.android.getApplicationContext(), new io.sentry.Sentry.OptionsConfiguration({
456
+ configure(config) {
457
+ // config.setLogger(new io.sentry.SystemOutLogger());
458
+ try {
459
+ if (options.dsn) {
460
+ config.setDsn(options.dsn);
461
+ }
462
+ else {
463
+ config.setDsn('');
464
+ }
465
+ if (options.sendClientReports) {
466
+ // config.setSendClientReports(options.sendClientReports);
467
+ }
468
+ if (options.maxBreadcrumbs) {
469
+ config.setMaxBreadcrumbs(options.maxBreadcrumbs);
470
+ }
471
+ if (options.maxCacheItems) {
472
+ config.setMaxCacheItems(options.maxCacheItems);
473
+ }
474
+ if (!!options.environment) {
475
+ config.setEnvironment(options.environment);
476
+ }
477
+ else {
478
+ config.setEnvironment('javascript');
479
+ }
480
+ if (!!options.debug) {
481
+ io.sentry.Sentry.setLevel(io.sentry.SentryLevel.DEBUG);
482
+ config.setDebug(options.debug);
483
+ }
484
+ if (!!options.release) {
485
+ config.setRelease(options.release);
486
+ }
487
+ if (!!options.dist) {
488
+ config.setDist(options.dist);
489
+ }
490
+ if (options.enableAutoSessionTracking !== undefined) {
491
+ config.setEnableAutoSessionTracking(options.enableAutoSessionTracking);
492
+ }
493
+ if (options.sessionTrackingIntervalMillis !== undefined) {
494
+ config.setSessionTrackingIntervalMillis(options.sessionTrackingIntervalMillis);
495
+ }
496
+ if (options.shutdownTimeout !== undefined) {
497
+ config.setShutdownTimeoutMillis(options.shutdownTimeout);
498
+ }
499
+ if (options.enableNdkScopeSync !== undefined) {
500
+ config.setEnableScopeSync(options.enableNdkScopeSync);
501
+ }
502
+ if (options.attachStacktrace !== undefined) {
503
+ config.setAttachStacktrace(options.attachStacktrace);
504
+ }
505
+ if (options.attachThreads !== undefined) {
506
+ // JS use top level stacktraces and android attaches Threads which hides them so
507
+ // by default we hide.
508
+ config.setAttachThreads(options.attachThreads);
509
+ }
510
+ if (options.sendDefaultPii !== undefined) {
511
+ config.setSendDefaultPii(options.sendDefaultPii);
512
+ }
513
+ // if (options.enableAutoPerformanceTracking === true) {
514
+ // frameMetricsAggregator = new androidx.core.app.FrameMetricsAggregator();
515
+ // const currentActivity = Application.android.foregroundActivity;
516
+ // if (frameMetricsAggregator != null && currentActivity != null) {
517
+ // try {
518
+ // frameMetricsAggregator.add(currentActivity);
519
+ // } catch (err) {
520
+ // // throws ConcurrentModification when calling addOnFrameMetricsAvailableListener
521
+ // // this is a best effort since we can't reproduce it
522
+ // }
523
+ // }
524
+ // } else {
525
+ // disableNativeFramesTracking();
526
+ // }
527
+ // config.setEnableNdk(true);
528
+ if (options.enableNativeCrashHandling === false) {
529
+ const integrations = config.getIntegrations();
530
+ const size = integrations.size();
531
+ for (let index = size - 1; index >= 0; index--) {
532
+ const inte = integrations.get(index);
533
+ if (inte instanceof io.sentry.UncaughtExceptionHandlerIntegration ||
534
+ inte instanceof io.sentry.android.core.AnrIntegration ||
535
+ inte instanceof io.sentry.android.core.NdkIntegration) {
536
+ integrations.remove(index);
537
+ }
538
+ }
539
+ }
540
+ config.setTransportFactory(new io.sentry.ITransportFactory({
541
+ create(sopt, requestDetails) {
542
+ const map = requestDetails.getHeaders();
543
+ map.put('X-Forwarded-Protocol', 'https');
544
+ if (options.headers) {
545
+ Object.keys(options.headers).forEach(k => {
546
+ map.put(k, options.headers[k]);
547
+ });
548
+ }
549
+ return new io.sentry.transport.AsyncHttpTransport(sopt, new io.sentry.transport.RateLimiter(sopt), sopt.getTransportGate(), requestDetails);
550
+ }
551
+ }));
552
+ config.setBeforeSend(new io.sentry.SentryOptions.BeforeSendCallback({
553
+ execute(event, hint) {
554
+ if (options.beforeSend) {
555
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
556
+ options.beforeSend(event, hint);
557
+ }
558
+ // we use this callback to actually try and get the JS stack when a native error is catched
559
+ try {
560
+ const ex = event.getExceptions().get(0);
561
+ if (ex && ex.getType() === 'NativeScriptException') {
562
+ let mechanism = event.getThrowable && event.getThrowable();
563
+ if (!mechanism) {
564
+ const privateMethod = io.sentry.SentryEvent.class.getDeclaredMethod('getThrowable', null);
565
+ privateMethod.setAccessible(true);
566
+ mechanism = privateMethod.invoke(event, null);
567
+ }
568
+ let throwable;
569
+ if (mechanism instanceof io.sentry.exception.ExceptionMechanismException) {
570
+ throwable = mechanism.getThrowable();
571
+ }
572
+ else if (mechanism instanceof com.tns.NativeScriptException) {
573
+ throwable = mechanism;
574
+ }
575
+ if (throwable) {
576
+ const jsStackTrace = (throwable).getIncomingStackTrace();
577
+ if (jsStackTrace) {
578
+ const stack = parseErrorStack({ stack: jsStackTrace });
579
+ const convertedFrames = convertNativescriptFramesToSentryFrames(stack);
580
+ convertedFrames.forEach((frame) => rewriteFrameIntegration._iteratee(frame));
581
+ addExceptionInterface(event, 'Error', throwable.getMessage(), convertedFrames.reverse());
582
+ }
583
+ }
584
+ }
585
+ }
586
+ catch (e) { }
587
+ setEventOriginTag(event);
588
+ addPackages(event, config.getSdkVersion());
589
+ return event;
590
+ },
591
+ }));
592
+ nSentryOptions = config;
593
+ sentryOptions = options;
594
+ }
595
+ catch (err) {
596
+ console.error('Error starting Sentry', err);
597
+ throw err;
598
+ }
599
+ },
600
+ }));
601
+ initialized = true;
602
+ }
603
+ catch (e) {
604
+ console.error('Catching on startWithOptions, calling callback', e);
605
+ throw (e);
606
+ }
607
+ return (true);
608
+ }
609
+ NATIVE.initNativeSdk = initNativeSdk;
610
+ function disableNativeFramesTracking() {
611
+ if (frameMetricsAggregator) {
612
+ frameMetricsAggregator.stop();
613
+ frameMetricsAggregator = null;
614
+ }
615
+ }
616
+ NATIVE.disableNativeFramesTracking = disableNativeFramesTracking;
617
+ function setEventOriginTag(event) {
618
+ const sdk = event.getSdk();
619
+ if (sdk != null) {
620
+ switch (sdk.getName()) {
621
+ // If the event is from capacitor js, it gets set there and we do not handle it
622
+ // here.
623
+ case 'sentry.native':
624
+ setEventEnvironmentTag(event, 'native');
625
+ break;
626
+ case 'sentry.java.android':
627
+ setEventEnvironmentTag(event, 'java');
628
+ break;
629
+ default:
630
+ setEventEnvironmentTag(event, 'nativescript');
631
+ break;
632
+ }
633
+ }
634
+ }
635
+ function setEventEnvironmentTag(event, environment) {
636
+ event.setTag('event.origin', 'android');
637
+ event.setTag('event.environment', environment);
638
+ }
639
+ function enableNativeFramesTracking() {
640
+ if (!frameMetricsAggregator) {
641
+ frameMetricsAggregator = new androidx.core.app.FrameMetricsAggregator();
642
+ const currentActivity = Application.android.foregroundActivity;
643
+ if (frameMetricsAggregator != null && currentActivity != null) {
644
+ try {
645
+ frameMetricsAggregator.add(currentActivity);
646
+ }
647
+ catch (err) {
648
+ // throws ConcurrentModification when calling addOnFrameMetricsAvailableListener
649
+ // this is a best effort since we can't reproduce it
650
+ }
651
+ }
652
+ }
653
+ }
654
+ NATIVE.enableNativeFramesTracking = enableNativeFramesTracking;
655
+ // export function setLogLevel(level: number) {
656
+ // switch (level) {
657
+ // case 1:
658
+ // io.sentry.Sentry.setLevel(null);
659
+ // break;
660
+ // case 2:
661
+ // io.sentry.Sentry.setLevel(io.sentry.SentryLevel.ERROR);
662
+ // break;
663
+ // case 3:
664
+ // io.sentry.Sentry.setLevel(io.sentry.SentryLevel.DEBUG);
665
+ // break;
666
+ // case 4:
667
+ // io.sentry.Sentry.setLevel(io.sentry.SentryLevel.INFO);
668
+ // break;
669
+ // }
670
+ // }
671
+ function fetchNativeSdkInfo() {
672
+ return null;
673
+ }
674
+ NATIVE.fetchNativeSdkInfo = fetchNativeSdkInfo;
675
+ let nativeRelease;
676
+ function fetchNativeRelease() {
677
+ if (!enableNative) {
678
+ throw _DisabledNativeError;
679
+ }
680
+ if (!nativeRelease) {
681
+ const context = Utils.ad.getApplicationContext();
682
+ const packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
683
+ nativeRelease = {
684
+ 'id': packageInfo.packageName,
685
+ 'version': packageInfo.versionName,
686
+ 'build': packageInfo.versionCode + ''
687
+ };
688
+ }
689
+ return nativeRelease;
690
+ }
691
+ NATIVE.fetchNativeRelease = fetchNativeRelease;
692
+ function closeNativeSdk() {
693
+ io.sentry.Sentry.close();
694
+ }
695
+ NATIVE.closeNativeSdk = closeNativeSdk;
696
+ function nativeCrash() {
697
+ throw new java.lang.RuntimeException('TEST - Sentry Client Crash');
698
+ }
699
+ NATIVE.nativeCrash = nativeCrash;
700
+ async function fetchNativeDeviceContexts() {
701
+ return {};
702
+ // return new Promise((resolve) => {
703
+ // const nEvent = new io.sentry.SentryEvent();
704
+ // const params = {};
705
+ // const it = nEvent.getContexts().entrySet().iterator();
706
+ // let value, pair, key;
707
+ // while (it.hasNext()) {
708
+ // pair = it.next();
709
+ // value = pair.getValue();
710
+ // key = pair.getKey();
711
+ // params[key] = getJSHashMap(value);
712
+ // }
713
+ // resolve(params);
714
+ // });
715
+ }
716
+ NATIVE.fetchNativeDeviceContexts = fetchNativeDeviceContexts;
717
+ // export function captureUserFeedback(feedback: UserFeedback) {
718
+ // if (!enableNative) {
719
+ // return;
720
+ // }
721
+ // const userFeedback = new io.sentry.UserFeedback(new io.sentry.protocol.SentryId(feedback.eventId));
722
+ // if (feedback.comments) {
723
+ // userFeedback.setComments(feedback.comments);
724
+ // }
725
+ // if (feedback.email) {
726
+ // userFeedback.setEmail(feedback.email);
727
+ // }
728
+ // if (feedback.name) {
729
+ // userFeedback.setName(feedback.name);
730
+ // }
731
+ // io.sentry.Sentry.captureUserFeedback(userFeedback);
732
+ // }
733
+ // export function setUser(user: User | null, otherUserKeys) {
734
+ // if (!enableNative) {
735
+ // return;
736
+ // }
737
+ // io.sentry.Sentry.configureScope(new io.sentry.ScopeCallback({
738
+ // run(scope) {
739
+ // if (user == null && otherUserKeys == null) {
740
+ // scope.setUser(null);
741
+ // } else {
742
+ // const userInstance = new io.sentry.protocol.User();
743
+ // if (user) {
744
+ // if (user.email) {
745
+ // userInstance.setEmail(user.email);
746
+ // }
747
+ // if (user.id) {
748
+ // userInstance.setId(user.id);
749
+ // }
750
+ // if (user.username) {
751
+ // userInstance.setUsername(user.username);
752
+ // }
753
+ // if (user.ip_address) {
754
+ // userInstance.setIpAddress(user.ip_address);
755
+ // }
756
+ // }
757
+ // if (otherUserKeys ) {
758
+ // userInstance.setOthers(getNativeHashMap(otherUserKeys));
759
+ // }
760
+ // scope.setUser(userInstance);
761
+ // }
762
+ // }
763
+ // }));
764
+ // }
765
+ // export function setTag(key: string, value: string) {
766
+ // if (!enableNative) {
767
+ // return;
768
+ // }
769
+ // io.sentry.Sentry.configureScope(new io.sentry.ScopeCallback({
770
+ // run(scope) {
771
+ // scope.setTag(key, value);
772
+ // }
773
+ // }));
774
+ // }
775
+ // export function setExtra(key: string, extra: string) {
776
+ // if (!enableNative) {
777
+ // return;
778
+ // }
779
+ // io.sentry.Sentry.configureScope(new io.sentry.ScopeCallback({
780
+ // run(scope) {
781
+ // scope.setExtra(key, extra);
782
+ // }
783
+ // }));
784
+ // }
785
+ // export function withScope(callback: (scope: Scope) => void) {
786
+ // io.sentry.Sentry.withScope(new io.sentry.ScopeCallback({
787
+ // run(nscope) {
788
+ // // nscope is ignored
789
+ // console.log('native withScope', nscope);
790
+ // callback(nscope as any);
791
+ // }
792
+ // }));
793
+ // }
794
+ // export function addBreadcrumb(breadcrumb: Breadcrumb, maxBreadcrumbs?: number) {
795
+ // if (!enableNative) {
796
+ // return;
797
+ // }
798
+ // io.sentry.Sentry.configureScope(new io.sentry.ScopeCallback({
799
+ // run(scope) {
800
+ // try {
801
+ // console.log('addBreadcrumb', breadcrumb, scope);
802
+ // const breadcrumbInstance = new io.sentry.Breadcrumb();
803
+ // if (breadcrumb.message) {
804
+ // breadcrumbInstance.setMessage(breadcrumb.message);
805
+ // }
806
+ // if (breadcrumb.type) {
807
+ // breadcrumbInstance.setType(breadcrumb.type);
808
+ // }
809
+ // if (breadcrumb.category) {
810
+ // breadcrumbInstance.setCategory(breadcrumb.category);
811
+ // }
812
+ // if (breadcrumb.level) {
813
+ // breadcrumbInstance.setLevel(eventLevel(breadcrumb.level));
814
+ // }
815
+ // if (breadcrumb.data) {
816
+ // Object.keys(breadcrumb.data).forEach(key => {
817
+ // breadcrumbInstance.setData(key, breadcrumb.data[key]);
818
+ // });
819
+ // }
820
+ // scope.addBreadcrumb(breadcrumbInstance);
821
+ // } catch (error) {
822
+ // console.error('addBreadcrumb', error, error.stack);
823
+ // }
824
+ // }
825
+ // }));
826
+ // }
827
+ // export function addAttachment(attachment: Attachment) {
828
+ // if (!enableNative) {
829
+ // return;
830
+ // }
831
+ // io.sentry.Sentry.configureScope(new io.sentry.ScopeCallback({
832
+ // run(scope) {
833
+ // console.log('addAttachment', attachment, scope);
834
+ // try {
835
+ // if (attachment.data) {
836
+ // if (typeof attachment.data === 'string') {
837
+ // attachment.data = new TextEncoder().encode(attachment.data);
838
+ // }
839
+ // const bytes = pointsFromBuffer(attachment.data, true, false);
840
+ // console.log('addAttachment', typeof attachment.data, attachment.data.length, bytes, bytes.length);
841
+ // scope.addAttachment(new io.sentry.Attachment(bytes, attachment.filename));
842
+ // } else {
843
+ // scope.addAttachment(new io.sentry.Attachment(attachment.filename));
844
+ // }
845
+ // } catch (error) {
846
+ // console.error('addAttachment', error, error.stack);
847
+ // }
848
+ // }
849
+ // }));
850
+ // }
851
+ // export function clearBreadcrumbs() {
852
+ // if (!enableNative) {
853
+ // return;
854
+ // }
855
+ // io.sentry.Sentry.configureScope(new io.sentry.ScopeCallback({
856
+ // run(scope) {
857
+ // scope.clearBreadcrumbs();
858
+ // }
859
+ // }));
860
+ // }
861
+ // export function setContext(key: string, context: { [key: string]: any } | null) {
862
+ // if (!enableNative) {
863
+ // return;
864
+ // }
865
+ // io.sentry.Sentry.configureScope(new io.sentry.ScopeCallback({
866
+ // run(scope) {
867
+ // scope.setContexts(key, getNativeHashMap(context));
868
+ // }
869
+ // }));
870
+ // }
871
+ function isFrameMetricsAggregatorAvailable() {
872
+ return frameMetricsAggregator != null;
873
+ }
874
+ // 700ms to constitute frozen frames.
875
+ const FROZEN_FRAME_THRESHOLD = 700;
876
+ // 16ms (slower than 60fps) to constitute slow frames.
877
+ const SLOW_FRAME_THRESHOLD = 16;
878
+ async function fetchNativeFrames() {
879
+ if (!isFrameMetricsAggregatorAvailable()) {
880
+ return null;
881
+ }
882
+ else {
883
+ try {
884
+ let totalFrames = 0;
885
+ let slowFrames = 0;
886
+ let frozenFrames = 0;
887
+ const framesRates = frameMetricsAggregator.getMetrics();
888
+ if (framesRates != null) {
889
+ const totalIndexArray = framesRates[androidx.core.app.FrameMetricsAggregator.TOTAL_INDEX];
890
+ if (totalIndexArray != null) {
891
+ for (let i = 0; i < totalIndexArray.size(); i++) {
892
+ const frameTime = totalIndexArray.keyAt(i);
893
+ const numFrames = totalIndexArray.valueAt(i);
894
+ totalFrames += numFrames;
895
+ // hard coded values, its also in the official android docs and frame metrics
896
+ // API
897
+ if (frameTime > FROZEN_FRAME_THRESHOLD) {
898
+ // frozen frames, threshold is 700ms
899
+ frozenFrames += numFrames;
900
+ }
901
+ else if (frameTime > SLOW_FRAME_THRESHOLD) {
902
+ // slow frames, above 16ms, 60 frames/second
903
+ slowFrames += numFrames;
904
+ }
905
+ }
906
+ }
907
+ }
908
+ if (totalFrames === 0 && slowFrames === 0 && frozenFrames === 0) {
909
+ return null;
910
+ }
911
+ return {
912
+ totalFrames,
913
+ slowFrames,
914
+ frozenFrames
915
+ };
916
+ }
917
+ catch (err) {
918
+ console.warn('Error fetching native frames.', err);
919
+ }
920
+ return null;
921
+ }
922
+ }
923
+ NATIVE.fetchNativeFrames = fetchNativeFrames;
924
+ let didFetchAppStart = false;
925
+ async function fetchNativeAppStart() {
926
+ const appStartInstance = io.sentry.android.core.AppStartState.getInstance();
927
+ const appStartTime = appStartInstance.getAppStartTime();
928
+ const isColdStart = appStartInstance.isColdStart();
929
+ const wasFetched = didFetchAppStart;
930
+ // This is always set to true, as we would only allow an app start fetch to only
931
+ // happen once in the case of a JS bundle reload, we do not want it to be
932
+ // instrumented again.
933
+ didFetchAppStart = true;
934
+ if (appStartTime == null) {
935
+ console.warn("App start won't be sent due to missing appStartTime.");
936
+ return null;
937
+ }
938
+ else if (isColdStart == null) {
939
+ console.warn("App start won't be sent due to missing isColdStart.");
940
+ return null;
941
+ }
942
+ else {
943
+ return {
944
+ appStartTime: appStartTime.getTime(),
945
+ isColdStart,
946
+ didFetchAppStart: wasFetched
947
+ };
948
+ }
949
+ }
950
+ NATIVE.fetchNativeAppStart = fetchNativeAppStart;
951
+ })(NATIVE || (NATIVE = {}));
952
+ //# sourceMappingURL=wrapper.android.js.map