@sentry/wizard 6.4.0 → 6.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 (75) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/e2e-tests/tests/angular-17.test.js +1 -0
  3. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
  4. package/dist/e2e-tests/tests/angular-19.test.js +1 -0
  5. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
  6. package/dist/e2e-tests/tests/expo.test.js +13 -3
  7. package/dist/e2e-tests/tests/expo.test.js.map +1 -1
  8. package/dist/e2e-tests/tests/nuxt-3.test.js +6 -0
  9. package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
  10. package/dist/e2e-tests/tests/nuxt-4.test.js +6 -0
  11. package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
  12. package/dist/e2e-tests/tests/react-native.test.js +14 -4
  13. package/dist/e2e-tests/tests/react-native.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/remix.test.js +2 -1
  15. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  16. package/dist/e2e-tests/tests/sveltekit-hooks.test.js +13 -2
  17. package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
  18. package/dist/e2e-tests/tests/sveltekit-tracing.test.js +4 -0
  19. package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
  20. package/dist/src/android/android-wizard.js +9 -1
  21. package/dist/src/android/android-wizard.js.map +1 -1
  22. package/dist/src/android/manifest.d.ts +1 -1
  23. package/dist/src/android/manifest.js +2 -2
  24. package/dist/src/android/manifest.js.map +1 -1
  25. package/dist/src/android/templates.d.ts +1 -1
  26. package/dist/src/android/templates.js +4 -1
  27. package/dist/src/android/templates.js.map +1 -1
  28. package/dist/src/angular/codemods/main.js +1 -0
  29. package/dist/src/angular/codemods/main.js.map +1 -1
  30. package/dist/src/apple/templates.js +0 -2
  31. package/dist/src/apple/templates.js.map +1 -1
  32. package/dist/src/nextjs/nextjs-wizard.js +1 -1
  33. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  34. package/dist/src/nextjs/templates.js +6 -4
  35. package/dist/src/nextjs/templates.js.map +1 -1
  36. package/dist/src/nuxt/templates.js +10 -2
  37. package/dist/src/nuxt/templates.js.map +1 -1
  38. package/dist/src/react-native/javascript.d.ts +6 -4
  39. package/dist/src/react-native/javascript.js +11 -7
  40. package/dist/src/react-native/javascript.js.map +1 -1
  41. package/dist/src/react-native/react-native-wizard.js +9 -0
  42. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  43. package/dist/src/react-native/xcode.js +5 -3
  44. package/dist/src/react-native/xcode.js.map +1 -1
  45. package/dist/src/remix/sdk-setup.js +1 -0
  46. package/dist/src/remix/sdk-setup.js.map +1 -1
  47. package/dist/src/sveltekit/sdk-setup/setup.d.ts +6 -0
  48. package/dist/src/sveltekit/sdk-setup/setup.js +4 -1
  49. package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
  50. package/dist/src/sveltekit/templates.js +9 -0
  51. package/dist/src/sveltekit/templates.js.map +1 -1
  52. package/dist/src/utils/clack/index.js +4 -1
  53. package/dist/src/utils/clack/index.js.map +1 -1
  54. package/dist/src/version.d.ts +1 -1
  55. package/dist/src/version.js +1 -1
  56. package/dist/src/version.js.map +1 -1
  57. package/dist/test/angular/angular-wizard.test.js +113 -17
  58. package/dist/test/angular/angular-wizard.test.js.map +1 -1
  59. package/dist/test/apple/code-tools.test.js +0 -3
  60. package/dist/test/apple/code-tools.test.js.map +1 -1
  61. package/dist/test/apple/templates.test.js +0 -4
  62. package/dist/test/apple/templates.test.js.map +1 -1
  63. package/dist/test/nextjs/templates.test.js +33 -22
  64. package/dist/test/nextjs/templates.test.js.map +1 -1
  65. package/dist/test/nuxt/templates.test.js +50 -10
  66. package/dist/test/nuxt/templates.test.js.map +1 -1
  67. package/dist/test/react-native/javascript.test.js +225 -0
  68. package/dist/test/react-native/javascript.test.js.map +1 -1
  69. package/dist/test/react-native/xcode.test.js +20 -2
  70. package/dist/test/react-native/xcode.test.js.map +1 -1
  71. package/dist/test/remix/client-entry.test.js +10 -4
  72. package/dist/test/remix/client-entry.test.js.map +1 -1
  73. package/dist/test/sveltekit/templates.test.js +214 -0
  74. package/dist/test/sveltekit/templates.test.js.map +1 -1
  75. package/package.json +3 -3
@@ -36,6 +36,9 @@ Sentry.init({
36
36
  // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
37
37
  sendDefaultPii: true,
38
38
 
39
+ // Enable Logs
40
+ enableLogs: false,
41
+
39
42
  // uncomment the line below to enable Spotlight (https://spotlightjs.com)
40
43
  // spotlight: __DEV__,
41
44
  });
@@ -81,6 +84,9 @@ Sentry.init({
81
84
  // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
82
85
  sendDefaultPii: true,
83
86
 
87
+ // Enable Logs
88
+ enableLogs: false,
89
+
84
90
  // Configure Session Replay
85
91
  replaysSessionSampleRate: 0.1,
86
92
  replaysOnErrorSampleRate: 1,
@@ -133,6 +139,9 @@ Sentry.init({
133
139
  // Adds more context data to events (IP address, cookies, user, etc.)
134
140
  // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
135
141
  sendDefaultPii: true,
142
+
143
+ // Enable Logs
144
+ enableLogs: false,
136
145
  integrations: [Sentry.feedbackIntegration()],
137
146
 
138
147
  // uncomment the line below to enable Spotlight (https://spotlightjs.com)
@@ -153,6 +162,108 @@ export default App;`;
153
162
  enableFeedbackWidget: true,
154
163
  })).toBe(expectedOutput);
155
164
  });
165
+ (0, vitest_1.it)('adds sdk import and sentry init under last import in the file and enables logs', () => {
166
+ const input = `import * as React from 'react';
167
+
168
+ const test = 'test';
169
+
170
+ import { View } from 'react-native';
171
+
172
+ const App = () => {
173
+ return (
174
+ <View>
175
+ Test App
176
+ </View>
177
+ );
178
+ };
179
+
180
+ export default App;`;
181
+ const expectedOutput = `import * as React from 'react';
182
+
183
+ const test = 'test';
184
+
185
+ import { View } from 'react-native';
186
+ import * as Sentry from '@sentry/react-native';
187
+
188
+ Sentry.init({
189
+ dsn: 'dsn',
190
+
191
+ // Adds more context data to events (IP address, cookies, user, etc.)
192
+ // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
193
+ sendDefaultPii: true,
194
+
195
+ // Enable Logs
196
+ enableLogs: true,
197
+
198
+ // uncomment the line below to enable Spotlight (https://spotlightjs.com)
199
+ // spotlight: __DEV__,
200
+ });
201
+
202
+ const App = () => {
203
+ return (
204
+ <View>
205
+ Test App
206
+ </View>
207
+ );
208
+ };
209
+
210
+ export default App;`;
211
+ (0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
212
+ dsn: 'dsn',
213
+ enableLogs: true,
214
+ })).toBe(expectedOutput);
215
+ });
216
+ (0, vitest_1.it)('adds sdk import and sentry init with logs disabled', () => {
217
+ const input = `import * as React from 'react';
218
+
219
+ const test = 'test';
220
+
221
+ import { View } from 'react-native';
222
+
223
+ const App = () => {
224
+ return (
225
+ <View>
226
+ Test App
227
+ </View>
228
+ );
229
+ };
230
+
231
+ export default App;`;
232
+ const expectedOutput = `import * as React from 'react';
233
+
234
+ const test = 'test';
235
+
236
+ import { View } from 'react-native';
237
+ import * as Sentry from '@sentry/react-native';
238
+
239
+ Sentry.init({
240
+ dsn: 'dsn',
241
+
242
+ // Adds more context data to events (IP address, cookies, user, etc.)
243
+ // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
244
+ sendDefaultPii: true,
245
+
246
+ // Enable Logs
247
+ enableLogs: false,
248
+
249
+ // uncomment the line below to enable Spotlight (https://spotlightjs.com)
250
+ // spotlight: __DEV__,
251
+ });
252
+
253
+ const App = () => {
254
+ return (
255
+ <View>
256
+ Test App
257
+ </View>
258
+ );
259
+ };
260
+
261
+ export default App;`;
262
+ (0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
263
+ dsn: 'dsn',
264
+ enableLogs: false,
265
+ })).toBe(expectedOutput);
266
+ });
156
267
  (0, vitest_1.it)('adds sdk import and sentry init under last import in the file and enables session replay and feedback widget', () => {
157
268
  const input = `import * as React from 'react';
158
269
 
@@ -183,6 +294,9 @@ Sentry.init({
183
294
  // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
184
295
  sendDefaultPii: true,
185
296
 
297
+ // Enable Logs
298
+ enableLogs: false,
299
+
186
300
  // Configure Session Replay
187
301
  replaysSessionSampleRate: 0.1,
188
302
  replaysOnErrorSampleRate: 1,
@@ -207,6 +321,117 @@ export default App;`;
207
321
  enableFeedbackWidget: true,
208
322
  })).toBe(expectedOutput);
209
323
  });
324
+ (0, vitest_1.it)('adds sdk import and sentry init with all features enabled', () => {
325
+ const input = `import * as React from 'react';
326
+
327
+ const test = 'test';
328
+
329
+ import { View } from 'react-native';
330
+
331
+ const App = () => {
332
+ return (
333
+ <View>
334
+ Test App
335
+ </View>
336
+ );
337
+ };
338
+
339
+ export default App;`;
340
+ const expectedOutput = `import * as React from 'react';
341
+
342
+ const test = 'test';
343
+
344
+ import { View } from 'react-native';
345
+ import * as Sentry from '@sentry/react-native';
346
+
347
+ Sentry.init({
348
+ dsn: 'dsn',
349
+
350
+ // Adds more context data to events (IP address, cookies, user, etc.)
351
+ // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
352
+ sendDefaultPii: true,
353
+
354
+ // Enable Logs
355
+ enableLogs: true,
356
+
357
+ // Configure Session Replay
358
+ replaysSessionSampleRate: 0.1,
359
+ replaysOnErrorSampleRate: 1,
360
+ integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],
361
+
362
+ // uncomment the line below to enable Spotlight (https://spotlightjs.com)
363
+ // spotlight: __DEV__,
364
+ });
365
+
366
+ const App = () => {
367
+ return (
368
+ <View>
369
+ Test App
370
+ </View>
371
+ );
372
+ };
373
+
374
+ export default App;`;
375
+ (0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
376
+ dsn: 'dsn',
377
+ enableSessionReplay: true,
378
+ enableFeedbackWidget: true,
379
+ enableLogs: true,
380
+ })).toBe(expectedOutput);
381
+ });
382
+ (0, vitest_1.it)('adds sdk import and sentry init with logs enabled and other features disabled', () => {
383
+ const input = `import * as React from 'react';
384
+
385
+ const test = 'test';
386
+
387
+ import { View } from 'react-native';
388
+
389
+ const App = () => {
390
+ return (
391
+ <View>
392
+ Test App
393
+ </View>
394
+ );
395
+ };
396
+
397
+ export default App;`;
398
+ const expectedOutput = `import * as React from 'react';
399
+
400
+ const test = 'test';
401
+
402
+ import { View } from 'react-native';
403
+ import * as Sentry from '@sentry/react-native';
404
+
405
+ Sentry.init({
406
+ dsn: 'dsn',
407
+
408
+ // Adds more context data to events (IP address, cookies, user, etc.)
409
+ // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
410
+ sendDefaultPii: true,
411
+
412
+ // Enable Logs
413
+ enableLogs: true,
414
+
415
+ // uncomment the line below to enable Spotlight (https://spotlightjs.com)
416
+ // spotlight: __DEV__,
417
+ });
418
+
419
+ const App = () => {
420
+ return (
421
+ <View>
422
+ Test App
423
+ </View>
424
+ );
425
+ };
426
+
427
+ export default App;`;
428
+ (0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
429
+ dsn: 'dsn',
430
+ enableSessionReplay: false,
431
+ enableFeedbackWidget: false,
432
+ enableLogs: true,
433
+ })).toBe(expectedOutput);
434
+ });
210
435
  (0, vitest_1.it)('does not add sdk import and sentry init in the file without imports', () => {
211
436
  const input = `export const test = 'test';`;
212
437
  (0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, { dsn: 'dsn' })).toBe(input);
@@ -1 +1 @@
1
- {"version":3,"file":"javascript.test.js","sourceRoot":"","sources":["../../../test/react-native/javascript.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addSentryInitWithSdkImport,\n checkAndWrapRootComponent,\n doesContainSentryWrap,\n doesJsCodeIncludeSdkSentryImport,\n SentryWrapResult,\n} from '../../src/react-native/javascript';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport * as t from '@babel/types';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('react-native javascript', () => {\n describe('addSentryInitWithSdkImport', () => {\n it('adds sdk import and sentry init under last import in the file', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(\n expectedOutput,\n );\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n integrations: [Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay and feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('does not add sdk import and sentry init in the file without imports', () => {\n const input = `export const test = 'test';`;\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n\n it('does not add sdk import and sentry init in the empty file', () => {\n const input = '';\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n });\n\n describe('doesJsCodeIncludeSdkSentryImport', () => {\n it('returns true if code has sdk import', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns true if code has sdk require', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nconst Sentry = require('@sentry/react-native');\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns false if code does not have sdk import', () => {\n const input = `export const test = 'test';`;\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n\n it('returns false for empty file', () => {\n const input = '';\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n });\n\n describe('addSentryWrap', () => {\n it('wraps the root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default AnotheWrapper.wrap(App);`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(AnotheWrapper.wrap(App));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a complex root function', () => {\n // This is the default export for a new Expo 52 project\n const mod =\n parseModule(`import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}\n`);\n\n const expectedOutput = `import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default Sentry.wrap(function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous complex function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a default class export', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('does not wrap a root app component if not found', () => {\n const input = `import * as React from 'react';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport { App };`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap a root app component if already wrapped', () => {\n const input = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.AlreadyWrapped);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap the root app component in an empty file', () => {\n const mod = parseModule(``);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(``);\n });\n });\n\n it('does detect Sentry.wrap if exists', () => {\n const mod = parseModule(`export default Sentry.wrap(App);`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeTruthy();\n });\n\n it('does not detect Sentry.wrap if not present', () => {\n const mod = parseModule(`export default App;`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeFalsy();\n });\n});\n"]}
1
+ {"version":3,"file":"javascript.test.js","sourceRoot":"","sources":["../../../test/react-native/javascript.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addSentryInitWithSdkImport,\n checkAndWrapRootComponent,\n doesContainSentryWrap,\n doesJsCodeIncludeSdkSentryImport,\n SentryWrapResult,\n} from '../../src/react-native/javascript';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport * as t from '@babel/types';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('react-native javascript', () => {\n describe('addSentryInitWithSdkImport', () => {\n it('adds sdk import and sentry init under last import in the file', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(\n expectedOutput,\n );\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n integrations: [Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables logs', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableLogs: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init with logs disabled', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableLogs: false,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay and feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init with all features enabled', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: true,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n enableFeedbackWidget: true,\n enableLogs: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init with logs enabled and other features disabled', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: false,\n enableFeedbackWidget: false,\n enableLogs: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('does not add sdk import and sentry init in the file without imports', () => {\n const input = `export const test = 'test';`;\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n\n it('does not add sdk import and sentry init in the empty file', () => {\n const input = '';\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n });\n\n describe('doesJsCodeIncludeSdkSentryImport', () => {\n it('returns true if code has sdk import', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns true if code has sdk require', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nconst Sentry = require('@sentry/react-native');\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns false if code does not have sdk import', () => {\n const input = `export const test = 'test';`;\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n\n it('returns false for empty file', () => {\n const input = '';\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n });\n\n describe('addSentryWrap', () => {\n it('wraps the root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default AnotheWrapper.wrap(App);`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(AnotheWrapper.wrap(App));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a complex root function', () => {\n // This is the default export for a new Expo 52 project\n const mod =\n parseModule(`import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}\n`);\n\n const expectedOutput = `import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default Sentry.wrap(function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous complex function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a default class export', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('does not wrap a root app component if not found', () => {\n const input = `import * as React from 'react';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport { App };`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap a root app component if already wrapped', () => {\n const input = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.AlreadyWrapped);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap the root app component in an empty file', () => {\n const mod = parseModule(``);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(``);\n });\n });\n\n it('does detect Sentry.wrap if exists', () => {\n const mod = parseModule(`export default Sentry.wrap(App);`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeTruthy();\n });\n\n it('does not detect Sentry.wrap if not present', () => {\n const mod = parseModule(`export default App;`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeFalsy();\n });\n});\n"]}
@@ -60,9 +60,27 @@ REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
60
60
  const expectedOutput = `set -e
61
61
 
62
62
  WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
63
- REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
63
+ SENTRY_XCODE="../node_modules/@sentry/react-native/scripts/sentry-xcode.sh"
64
+
65
+ /bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"`;
66
+ (0, vitest_1.expect)((0, xcode_1.addSentryWithBundledScriptsToBundleShellScript)(input)).toBe(expectedOutput);
67
+ });
68
+ (0, vitest_1.it)('adds sentry cli to rn bundle build phase for versions of RN that use REACT_NATIVE_PATH env variable', () => {
69
+ const input = `set -e
70
+
71
+ WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
72
+ REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"
73
+
74
+ /bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE"`;
75
+ // actual shell script looks like this:
76
+ // /bin/sh -c "$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\""
77
+ // but during parsing xcode library removes the quotes
78
+ const expectedOutput = `set -e
79
+
80
+ WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
81
+ SENTRY_XCODE="$REACT_NATIVE_PATH/../@sentry/react-native/scripts/sentry-xcode.sh"
64
82
 
65
- /bin/sh -c "$WITH_ENVIRONMENT \\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\\""`;
83
+ /bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"`;
66
84
  (0, vitest_1.expect)((0, xcode_1.addSentryWithBundledScriptsToBundleShellScript)(input)).toBe(expectedOutput);
67
85
  });
68
86
  (0, vitest_1.it)('does not add sentry cli to rn bundle build phase if $REACT_NATIVE_XCODE is not present and shows code snippet', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"xcode.test.js","sourceRoot":"","sources":["../../../test/react-native/xcode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-useless-escape */\nimport { describe, expect, it, afterEach, beforeEach, vi } from 'vitest';\nimport {\n addSentryWithBundledScriptsToBundleShellScript,\n doesBundlePhaseIncludeSentry,\n findBundlePhase,\n findDebugFilesUploadPhase,\n ErrorPatchSnippet,\n} from '../../src/react-native/xcode';\nimport chalk from 'chalk';\nimport { makeCodeSnippet } from '../../src/utils/clack';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n\nvi.mock('@clack/prompts', async () => ({\n __esModule: true,\n ...(await vi.importActual<typeof clack>('@clack/prompts')),\n}));\n\ndescribe('react-native xcode', () => {\n beforeEach(() => {\n vi.spyOn(clack.log, 'error').mockImplementation(() => {\n /* empty */\n });\n });\n\n afterEach(() => {\n vi.clearAllMocks();\n });\n\n describe('addSentryBundledScriptsToBundleShellScript', () => {\n it('adds sentry cli to rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\\\\\"\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('does not add sentry cli to rn bundle build phase if $REACT_NATIVE_XCODE is not present and shows code snippet', () => {\n const input = `set -e\n \n WITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\n REACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n \n /bin/sh -c \"$WITH_ENVIRONMENT $NOT_REACT_NATIVE_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(`WITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT ${plus(\n `\\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh `,\n )}$REACT_NATIVE_XCODE${plus(`\\\\\"`)}\"\n`);\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n\n it('adds sentry cli to expo bundle build phase', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n\\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n const expectedOutput = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\` \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('if patching fails it does not add sentry cli to expo bundle build phase and shows code snippet', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n`;\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(\n `${plus(\n `/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\``,\n )} \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\``,\n );\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n });\n\n describe('findBundlePhase', () => {\n it('returns build phase with react native xcode shell script', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n const expected = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n };\n\n expect(findBundlePhase(inputMap)).toEqual(expected);\n });\n\n it('returns undefined if bundle phase not present', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n // note different path to the script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/unknown/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n expect(findBundlePhase(inputMap)).toBeUndefined();\n });\n });\n\n describe('doesBundlePhaseIncludeSentry', () => {\n it('returns true for script containing sentry cli calling react native xcode command', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$SENTRY_CLI $REACT_NATIVE_XCODE\\\"\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns true for script containing sentry bundled script', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\"\\\\\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns false', () => {\n const input = {\n // note sentry-cli can be part of the script but doesn't call react native xcode script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\nsentry-cli --version\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeFalsy();\n });\n });\n\n describe('findDebugFilesUploadPhase', () => {\n it('returns debug files build phase using debug files command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase with sentry-cli absolute path', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using dsym command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using bundled scripts', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns undefined if build phase not present', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n // sentry-cli present but with different command\n shellScript: 'sentry-cli sourcempas upload',\n },\n };\n\n expect(findDebugFilesUploadPhase(input)).toBeUndefined();\n });\n });\n});\n"]}
1
+ {"version":3,"file":"xcode.test.js","sourceRoot":"","sources":["../../../test/react-native/xcode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-useless-escape */\nimport { describe, expect, it, afterEach, beforeEach, vi } from 'vitest';\nimport {\n addSentryWithBundledScriptsToBundleShellScript,\n doesBundlePhaseIncludeSentry,\n findBundlePhase,\n findDebugFilesUploadPhase,\n ErrorPatchSnippet,\n} from '../../src/react-native/xcode';\nimport chalk from 'chalk';\nimport { makeCodeSnippet } from '../../src/utils/clack';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n\nvi.mock('@clack/prompts', async () => ({\n __esModule: true,\n ...(await vi.importActual<typeof clack>('@clack/prompts')),\n}));\n\ndescribe('react-native xcode', () => {\n beforeEach(() => {\n vi.spyOn(clack.log, 'error').mockImplementation(() => {\n /* empty */\n });\n });\n\n afterEach(() => {\n vi.clearAllMocks();\n });\n\n describe('addSentryBundledScriptsToBundleShellScript', () => {\n it('adds sentry cli to rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nSENTRY_XCODE=\"../node_modules/@sentry/react-native/scripts/sentry-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $SENTRY_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('adds sentry cli to rn bundle build phase for versions of RN that use REACT_NATIVE_PATH env variable', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nSENTRY_XCODE=\"$REACT_NATIVE_PATH/../@sentry/react-native/scripts/sentry-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $SENTRY_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('does not add sentry cli to rn bundle build phase if $REACT_NATIVE_XCODE is not present and shows code snippet', () => {\n const input = `set -e\n \n WITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\n REACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n \n /bin/sh -c \"$WITH_ENVIRONMENT $NOT_REACT_NATIVE_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(`WITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT ${plus(\n `\\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh `,\n )}$REACT_NATIVE_XCODE${plus(`\\\\\"`)}\"\n`);\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n\n it('adds sentry cli to expo bundle build phase', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n\\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n const expectedOutput = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\` \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('if patching fails it does not add sentry cli to expo bundle build phase and shows code snippet', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n`;\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(\n `${plus(\n `/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\``,\n )} \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\``,\n );\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n });\n\n describe('findBundlePhase', () => {\n it('returns build phase with react native xcode shell script', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n const expected = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n };\n\n expect(findBundlePhase(inputMap)).toEqual(expected);\n });\n\n it('returns undefined if bundle phase not present', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n // note different path to the script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/unknown/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n expect(findBundlePhase(inputMap)).toBeUndefined();\n });\n });\n\n describe('doesBundlePhaseIncludeSentry', () => {\n it('returns true for script containing sentry cli calling react native xcode command', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$SENTRY_CLI $REACT_NATIVE_XCODE\\\"\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns true for script containing sentry bundled script', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\"\\\\\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns false', () => {\n const input = {\n // note sentry-cli can be part of the script but doesn't call react native xcode script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\nsentry-cli --version\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeFalsy();\n });\n });\n\n describe('findDebugFilesUploadPhase', () => {\n it('returns debug files build phase using debug files command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase with sentry-cli absolute path', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using dsym command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using bundled scripts', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns undefined if build phase not present', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n // sentry-cli present but with different command\n shellScript: 'sentry-cli sourcempas upload',\n },\n };\n\n expect(findDebugFilesUploadPhase(input)).toBeUndefined();\n });\n });\n});\n"]}
@@ -40,7 +40,8 @@ const vitest_1 = require("vitest");
40
40
  })],
41
41
 
42
42
  replaysSessionSampleRate: 0.1,
43
- replaysOnErrorSampleRate: 1
43
+ replaysOnErrorSampleRate: 1,
44
+ sendDefaultPii: true
44
45
  })"
45
46
  `);
46
47
  });
@@ -66,7 +67,8 @@ const vitest_1 = require("vitest");
66
67
  })],
67
68
 
68
69
  replaysSessionSampleRate: 0.1,
69
- replaysOnErrorSampleRate: 1
70
+ replaysOnErrorSampleRate: 1,
71
+ sendDefaultPii: true
70
72
  })"
71
73
  `);
72
74
  });
@@ -98,7 +100,9 @@ const vitest_1 = require("vitest");
98
100
  useEffect,
99
101
  useLocation,
100
102
  useMatches
101
- })]
103
+ })],
104
+
105
+ sendDefaultPii: true
102
106
  })"
103
107
  `);
104
108
  });
@@ -150,7 +154,9 @@ const vitest_1 = require("vitest");
150
154
  useEffect,
151
155
  useLocation,
152
156
  useMatches
153
- })]
157
+ })],
158
+
159
+ sendDefaultPii: true
154
160
  })"
155
161
  `);
156
162
  });