@sentry/wizard 4.7.0 → 4.8.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 (110) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +19 -19
  3. package/dist/e2e-tests/tests/angular-17.test.d.ts +1 -0
  4. package/dist/e2e-tests/tests/angular-17.test.js +196 -0
  5. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -0
  6. package/dist/e2e-tests/tests/angular-19.test.d.ts +1 -0
  7. package/dist/e2e-tests/tests/angular-19.test.js +194 -0
  8. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -0
  9. package/dist/e2e-tests/tests/expo.test.d.ts +1 -0
  10. package/dist/e2e-tests/tests/expo.test.js +95 -0
  11. package/dist/e2e-tests/tests/expo.test.js.map +1 -0
  12. package/dist/e2e-tests/tests/help-message.test.js +2 -2
  13. package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/react-native.test.d.ts +1 -0
  15. package/dist/e2e-tests/tests/react-native.test.js +97 -0
  16. package/dist/e2e-tests/tests/react-native.test.js.map +1 -0
  17. package/dist/e2e-tests/tests/remix.test.js +4 -4
  18. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  19. package/dist/e2e-tests/tests/sveltekit.test.js +2 -2
  20. package/dist/e2e-tests/tests/sveltekit.test.js.map +1 -1
  21. package/dist/e2e-tests/utils/index.d.ts +7 -0
  22. package/dist/e2e-tests/utils/index.js +18 -1
  23. package/dist/e2e-tests/utils/index.js.map +1 -1
  24. package/dist/lib/Constants.d.ts +1 -0
  25. package/dist/lib/Constants.js +3 -0
  26. package/dist/lib/Constants.js.map +1 -1
  27. package/dist/src/angular/angular-wizard.d.ts +3 -0
  28. package/dist/src/angular/angular-wizard.js +186 -0
  29. package/dist/src/angular/angular-wizard.js.map +1 -0
  30. package/dist/src/angular/codemods/app-config.d.ts +3 -0
  31. package/dist/src/angular/codemods/app-config.js +211 -0
  32. package/dist/src/angular/codemods/app-config.js.map +1 -0
  33. package/dist/src/angular/codemods/main.d.ts +20 -0
  34. package/dist/src/angular/codemods/main.js +62 -0
  35. package/dist/src/angular/codemods/main.js.map +1 -0
  36. package/dist/src/angular/codemods/sourcemaps.d.ts +21 -0
  37. package/dist/src/angular/codemods/sourcemaps.js +94 -0
  38. package/dist/src/angular/codemods/sourcemaps.js.map +1 -0
  39. package/dist/src/angular/example-component.d.ts +8 -0
  40. package/dist/src/angular/example-component.js +286 -0
  41. package/dist/src/angular/example-component.js.map +1 -0
  42. package/dist/src/angular/sdk-setup.d.ts +6 -0
  43. package/dist/src/angular/sdk-setup.js +99 -0
  44. package/dist/src/angular/sdk-setup.js.map +1 -0
  45. package/dist/src/flutter/flutter-wizard.js +10 -2
  46. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  47. package/dist/src/nextjs/nextjs-wizard.js +26 -12
  48. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  49. package/dist/src/nextjs/templates.js +56 -7
  50. package/dist/src/nextjs/templates.js.map +1 -1
  51. package/dist/src/nuxt/templates.js +30 -0
  52. package/dist/src/nuxt/templates.js.map +1 -1
  53. package/dist/src/react-native/expo-metro.js +4 -1
  54. package/dist/src/react-native/expo-metro.js.map +1 -1
  55. package/dist/src/react-native/expo.js +5 -1
  56. package/dist/src/react-native/expo.js.map +1 -1
  57. package/dist/src/react-native/javascript.js +9 -2
  58. package/dist/src/react-native/javascript.js.map +1 -1
  59. package/dist/src/react-native/metro.js +8 -2
  60. package/dist/src/react-native/metro.js.map +1 -1
  61. package/dist/src/react-native/xcode.js +5 -1
  62. package/dist/src/react-native/xcode.js.map +1 -1
  63. package/dist/src/remix/sdk-example.js +30 -1
  64. package/dist/src/remix/sdk-example.js.map +1 -1
  65. package/dist/src/remix/sdk-setup.js +11 -5
  66. package/dist/src/remix/sdk-setup.js.map +1 -1
  67. package/dist/src/run.d.ts +1 -1
  68. package/dist/src/run.js +5 -0
  69. package/dist/src/run.js.map +1 -1
  70. package/dist/src/sourcemaps/sourcemaps-wizard.d.ts +1 -1
  71. package/dist/src/sourcemaps/sourcemaps-wizard.js +35 -20
  72. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  73. package/dist/src/sourcemaps/tools/angular.d.ts +1 -0
  74. package/dist/src/sourcemaps/tools/angular.js +7 -7
  75. package/dist/src/sourcemaps/tools/angular.js.map +1 -1
  76. package/dist/src/sourcemaps/tools/sentry-cli.d.ts +5 -1
  77. package/dist/src/sourcemaps/tools/sentry-cli.js +6 -3
  78. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  79. package/dist/src/sourcemaps/tools/tsc.js +5 -1
  80. package/dist/src/sourcemaps/tools/tsc.js.map +1 -1
  81. package/dist/src/sourcemaps/tools/vite.js +4 -1
  82. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  83. package/dist/src/sourcemaps/tools/webpack.js +4 -1
  84. package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
  85. package/dist/src/sveltekit/sdk-example.js +1 -1
  86. package/dist/src/sveltekit/sdk-example.js.map +1 -1
  87. package/dist/src/sveltekit/sveltekit-wizard.js +2 -2
  88. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  89. package/dist/src/sveltekit/templates.js +28 -1
  90. package/dist/src/sveltekit/templates.js.map +1 -1
  91. package/dist/src/utils/clack/index.d.ts +11 -3
  92. package/dist/src/utils/clack/index.js +9 -3
  93. package/dist/src/utils/clack/index.js.map +1 -1
  94. package/dist/src/version.d.ts +1 -1
  95. package/dist/src/version.js +1 -1
  96. package/dist/src/version.js.map +1 -1
  97. package/dist/test/angular/angular-wizard.test.d.ts +1 -0
  98. package/dist/test/angular/angular-wizard.test.js +27 -0
  99. package/dist/test/angular/angular-wizard.test.js.map +1 -0
  100. package/dist/test/angular/codemods/sourcemaps.test.d.ts +1 -0
  101. package/dist/test/angular/codemods/sourcemaps.test.js +237 -0
  102. package/dist/test/angular/codemods/sourcemaps.test.js.map +1 -0
  103. package/dist/test/angular/example-component.test.d.ts +1 -0
  104. package/dist/test/angular/example-component.test.js +105 -0
  105. package/dist/test/angular/example-component.test.js.map +1 -0
  106. package/dist/test/react-native/metro.test.js +113 -0
  107. package/dist/test/react-native/metro.test.js.map +1 -1
  108. package/dist/test/remix/client-entry.test.js +10 -10
  109. package/dist/test/remix/client-entry.test.js.map +1 -1
  110. package/package.json +1 -1
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const vitest_1 = require("vitest");
27
+ const sourcemaps_1 = require("../../../src/angular/codemods/sourcemaps");
28
+ const AngularSourceMapsWizard = __importStar(require("../../../src/sourcemaps/tools/angular"));
29
+ const { readFileSyncMock, writeFileSyncMock } = vitest_1.vi.hoisted(() => {
30
+ return {
31
+ readFileSyncMock: vitest_1.vi.fn(),
32
+ writeFileSyncMock: vitest_1.vi.fn(),
33
+ };
34
+ });
35
+ vitest_1.vi.mock('fs', async () => {
36
+ return {
37
+ ...(await vitest_1.vi.importActual('fs')),
38
+ readFileSync: readFileSyncMock,
39
+ writeFileSync: writeFileSyncMock,
40
+ };
41
+ });
42
+ (0, vitest_1.describe)('addSourcemapEntryToAngularJSON', () => {
43
+ const configureAngularSourcemapGenerationFlowSpy = vitest_1.vi
44
+ .spyOn(AngularSourceMapsWizard, 'configureAngularSourcemapGenerationFlow')
45
+ .mockImplementation(() => Promise.resolve());
46
+ (0, vitest_1.beforeEach)(() => {
47
+ vitest_1.vi.clearAllMocks();
48
+ });
49
+ (0, vitest_1.it)('reads and writes the `angular.json` file correctly', async () => {
50
+ const angularJsonPath = 'angular.json';
51
+ const angularJsonContent = JSON.stringify({
52
+ projects: {
53
+ project1: {
54
+ architect: {
55
+ build: {
56
+ configurations: {
57
+ production: {
58
+ someKey: 'someValue',
59
+ },
60
+ },
61
+ },
62
+ },
63
+ },
64
+ },
65
+ });
66
+ readFileSyncMock.mockReturnValue(angularJsonContent);
67
+ await (0, sourcemaps_1.addSourcemapEntryToAngularJSON)();
68
+ (0, vitest_1.expect)(readFileSyncMock).toHaveBeenCalledWith(vitest_1.expect.stringContaining(angularJsonPath), 'utf-8');
69
+ (0, vitest_1.expect)(writeFileSyncMock).toHaveBeenCalledWith(vitest_1.expect.stringContaining(angularJsonPath), JSON.stringify({
70
+ projects: {
71
+ project1: {
72
+ architect: {
73
+ build: {
74
+ configurations: {
75
+ production: {
76
+ someKey: 'someValue',
77
+ sourceMap: true,
78
+ },
79
+ },
80
+ },
81
+ },
82
+ },
83
+ },
84
+ }, null, 2));
85
+ });
86
+ (0, vitest_1.it)('falls back to printing copy/paste instructions when reading fails', async () => {
87
+ readFileSyncMock.mockImplementation(() => {
88
+ throw new Error('File not found');
89
+ });
90
+ await (0, sourcemaps_1.addSourcemapEntryToAngularJSON)();
91
+ (0, vitest_1.expect)(configureAngularSourcemapGenerationFlowSpy).toHaveBeenCalledOnce();
92
+ (0, vitest_1.expect)(writeFileSyncMock).not.toHaveBeenCalled();
93
+ });
94
+ (0, vitest_1.it)('falls back to printing copy/paste instructions when writing fails', async () => {
95
+ const angularJsonContent = JSON.stringify({
96
+ projects: {
97
+ project1: {},
98
+ },
99
+ });
100
+ readFileSyncMock.mockReturnValue(angularJsonContent);
101
+ writeFileSyncMock.mockImplementation(() => {
102
+ throw new Error('Write failed');
103
+ });
104
+ await (0, sourcemaps_1.addSourcemapEntryToAngularJSON)();
105
+ (0, vitest_1.expect)(configureAngularSourcemapGenerationFlowSpy).toHaveBeenCalledOnce();
106
+ (0, vitest_1.expect)(writeFileSyncMock).toHaveBeenCalled();
107
+ });
108
+ (0, vitest_1.it)('falls back to printing copy/paste instructions when angular.json` has no projects', async () => {
109
+ const angularJsonContent = JSON.stringify({
110
+ projects: {},
111
+ });
112
+ readFileSyncMock.mockReturnValue(angularJsonContent);
113
+ await (0, sourcemaps_1.addSourcemapEntryToAngularJSON)();
114
+ (0, vitest_1.expect)(configureAngularSourcemapGenerationFlowSpy).toHaveBeenCalledOnce();
115
+ (0, vitest_1.expect)(writeFileSyncMock).not.toHaveBeenCalled();
116
+ });
117
+ });
118
+ (0, vitest_1.describe)('addSourceMapsSetting', () => {
119
+ (0, vitest_1.it)('adds sourceMap setting to angular.json', () => {
120
+ const angularJson = {
121
+ projects: {
122
+ project1: {
123
+ architect: {
124
+ build: {
125
+ configurations: {
126
+ production: {},
127
+ },
128
+ },
129
+ },
130
+ },
131
+ project2: {
132
+ architect: {},
133
+ },
134
+ },
135
+ };
136
+ const updatedAngularJson = (0, sourcemaps_1.addSourceMapsSetting)(angularJson);
137
+ (0, vitest_1.expect)(updatedAngularJson).toEqual({
138
+ projects: {
139
+ project1: {
140
+ architect: {
141
+ build: {
142
+ configurations: {
143
+ production: { sourceMap: true },
144
+ },
145
+ },
146
+ },
147
+ },
148
+ project2: {
149
+ architect: {
150
+ build: {
151
+ configurations: {
152
+ production: {
153
+ sourceMap: true,
154
+ },
155
+ },
156
+ },
157
+ },
158
+ },
159
+ },
160
+ });
161
+ });
162
+ (0, vitest_1.it)('returns `undefined` if no projects are found', () => {
163
+ const angularJson = {};
164
+ const updatedAngularJson = (0, sourcemaps_1.addSourceMapsSetting)(angularJson);
165
+ (0, vitest_1.expect)(updatedAngularJson).toBeUndefined();
166
+ });
167
+ (0, vitest_1.it)('returns `undefined` if projects have no architect', () => {
168
+ const angularJson = {
169
+ projects: {},
170
+ };
171
+ const updatedAngularJson = (0, sourcemaps_1.addSourceMapsSetting)(angularJson);
172
+ (0, vitest_1.expect)(updatedAngularJson).toBeUndefined();
173
+ });
174
+ vitest_1.it.each([
175
+ {
176
+ projects: {
177
+ project1: {
178
+ architect: {
179
+ build: {
180
+ configurations: {
181
+ production: {},
182
+ },
183
+ },
184
+ },
185
+ },
186
+ },
187
+ },
188
+ {
189
+ projects: {
190
+ project1: {
191
+ architect: {
192
+ build: {
193
+ configurations: {},
194
+ },
195
+ },
196
+ },
197
+ },
198
+ },
199
+ {
200
+ projects: {
201
+ project1: {
202
+ architect: {
203
+ build: {},
204
+ },
205
+ },
206
+ },
207
+ },
208
+ {
209
+ projects: {
210
+ project1: {
211
+ architect: {},
212
+ },
213
+ },
214
+ },
215
+ {
216
+ projects: {
217
+ project1: {},
218
+ },
219
+ },
220
+ ])('handles incomplete project declarations (%s)', (angularJson) => {
221
+ const updatedAngularJson = (0, sourcemaps_1.addSourceMapsSetting)(angularJson);
222
+ (0, vitest_1.expect)(updatedAngularJson).toEqual({
223
+ projects: {
224
+ project1: {
225
+ architect: {
226
+ build: {
227
+ configurations: {
228
+ production: { sourceMap: true },
229
+ },
230
+ },
231
+ },
232
+ },
233
+ },
234
+ });
235
+ });
236
+ });
237
+ //# sourceMappingURL=sourcemaps.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourcemaps.test.js","sourceRoot":"","sources":["../../../../test/angular/codemods/sourcemaps.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, vi, expect, beforeEach } from 'vitest';\nimport {\n addSourcemapEntryToAngularJSON,\n addSourceMapsSetting,\n} from '../../../src/angular/codemods/sourcemaps';\n\nimport * as AngularSourceMapsWizard from '../../../src/sourcemaps/tools/angular';\n\nconst { readFileSyncMock, writeFileSyncMock } = vi.hoisted(() => {\n return {\n readFileSyncMock: vi.fn(),\n writeFileSyncMock: vi.fn(),\n };\n});\n\nvi.mock('fs', async () => {\n return {\n ...(await vi.importActual('fs')),\n readFileSync: readFileSyncMock,\n writeFileSync: writeFileSyncMock,\n };\n});\n\ndescribe('addSourcemapEntryToAngularJSON', () => {\n const configureAngularSourcemapGenerationFlowSpy = vi\n .spyOn(AngularSourceMapsWizard, 'configureAngularSourcemapGenerationFlow')\n .mockImplementation(() => Promise.resolve());\n\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n it('reads and writes the `angular.json` file correctly', async () => {\n const angularJsonPath = 'angular.json';\n const angularJsonContent = JSON.stringify({\n projects: {\n project1: {\n architect: {\n build: {\n configurations: {\n production: {\n someKey: 'someValue',\n },\n },\n },\n },\n },\n },\n });\n\n readFileSyncMock.mockReturnValue(angularJsonContent);\n\n await addSourcemapEntryToAngularJSON();\n\n expect(readFileSyncMock).toHaveBeenCalledWith(\n expect.stringContaining(angularJsonPath),\n 'utf-8',\n );\n expect(writeFileSyncMock).toHaveBeenCalledWith(\n expect.stringContaining(angularJsonPath),\n JSON.stringify(\n {\n projects: {\n project1: {\n architect: {\n build: {\n configurations: {\n production: {\n someKey: 'someValue',\n sourceMap: true,\n },\n },\n },\n },\n },\n },\n },\n null,\n 2,\n ),\n );\n });\n\n it('falls back to printing copy/paste instructions when reading fails', async () => {\n readFileSyncMock.mockImplementation(() => {\n throw new Error('File not found');\n });\n\n await addSourcemapEntryToAngularJSON();\n\n expect(configureAngularSourcemapGenerationFlowSpy).toHaveBeenCalledOnce();\n expect(writeFileSyncMock).not.toHaveBeenCalled();\n });\n\n it('falls back to printing copy/paste instructions when writing fails', async () => {\n const angularJsonContent = JSON.stringify({\n projects: {\n project1: {},\n },\n });\n\n readFileSyncMock.mockReturnValue(angularJsonContent);\n writeFileSyncMock.mockImplementation(() => {\n throw new Error('Write failed');\n });\n\n await addSourcemapEntryToAngularJSON();\n\n expect(configureAngularSourcemapGenerationFlowSpy).toHaveBeenCalledOnce();\n expect(writeFileSyncMock).toHaveBeenCalled();\n });\n\n it('falls back to printing copy/paste instructions when angular.json` has no projects', async () => {\n const angularJsonContent = JSON.stringify({\n projects: {},\n });\n\n readFileSyncMock.mockReturnValue(angularJsonContent);\n\n await addSourcemapEntryToAngularJSON();\n\n expect(configureAngularSourcemapGenerationFlowSpy).toHaveBeenCalledOnce();\n expect(writeFileSyncMock).not.toHaveBeenCalled();\n });\n});\n\ndescribe('addSourceMapsSetting', () => {\n it('adds sourceMap setting to angular.json', () => {\n const angularJson = {\n projects: {\n project1: {\n architect: {\n build: {\n configurations: {\n production: {},\n },\n },\n },\n },\n project2: {\n architect: {},\n },\n },\n };\n\n const updatedAngularJson = addSourceMapsSetting(angularJson);\n\n expect(updatedAngularJson).toEqual({\n projects: {\n project1: {\n architect: {\n build: {\n configurations: {\n production: { sourceMap: true },\n },\n },\n },\n },\n project2: {\n architect: {\n build: {\n configurations: {\n production: {\n sourceMap: true,\n },\n },\n },\n },\n },\n },\n });\n });\n\n it('returns `undefined` if no projects are found', () => {\n const angularJson = {};\n\n const updatedAngularJson = addSourceMapsSetting(angularJson);\n\n expect(updatedAngularJson).toBeUndefined();\n });\n\n it('returns `undefined` if projects have no architect', () => {\n const angularJson = {\n projects: {},\n };\n\n const updatedAngularJson = addSourceMapsSetting(angularJson);\n\n expect(updatedAngularJson).toBeUndefined();\n });\n\n it.each([\n {\n projects: {\n project1: {\n architect: {\n build: {\n configurations: {\n production: {},\n },\n },\n },\n },\n },\n },\n {\n projects: {\n project1: {\n architect: {\n build: {\n configurations: {},\n },\n },\n },\n },\n },\n {\n projects: {\n project1: {\n architect: {\n build: {},\n },\n },\n },\n },\n {\n projects: {\n project1: {\n architect: {},\n },\n },\n },\n {\n projects: {\n project1: {},\n },\n },\n ])('handles incomplete project declarations (%s)', (angularJson) => {\n const updatedAngularJson = addSourceMapsSetting(angularJson);\n\n expect(updatedAngularJson).toEqual({\n projects: {\n project1: {\n architect: {\n build: {\n configurations: {\n production: { sourceMap: true },\n },\n },\n },\n },\n },\n });\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const vitest_1 = require("vitest");
27
+ const example_component_1 = require("../../src/angular/example-component");
28
+ const clackUtils = __importStar(require("../../src/utils/clack"));
29
+ const fsMocks = vitest_1.vi.hoisted(() => ({
30
+ existsSyncMock: vitest_1.vi.fn(() => true),
31
+ writeFileSyncMock: vitest_1.vi.fn(),
32
+ mkdirSyncMock: vitest_1.vi.fn(),
33
+ }));
34
+ vitest_1.vi.mock('fs', () => ({
35
+ existsSync: fsMocks.existsSyncMock,
36
+ writeFileSync: fsMocks.writeFileSyncMock,
37
+ mkdirSync: fsMocks.mkdirSyncMock,
38
+ }));
39
+ vitest_1.vi.mock('@clack/prompts', () => ({
40
+ log: {
41
+ info: vitest_1.vi.fn(),
42
+ success: vitest_1.vi.fn(),
43
+ warn: vitest_1.vi.fn(),
44
+ error: vitest_1.vi.fn(),
45
+ step: vitest_1.vi.fn(),
46
+ },
47
+ outro: vitest_1.vi.fn(),
48
+ text: vitest_1.vi.fn(),
49
+ confirm: vitest_1.vi.fn(),
50
+ cancel: vitest_1.vi.fn(),
51
+ // passthrough for abortIfCancelled
52
+ isCancel: vitest_1.vi.fn().mockReturnValue(false),
53
+ spinner: vitest_1.vi
54
+ .fn()
55
+ .mockImplementation(() => ({ start: vitest_1.vi.fn(), stop: vitest_1.vi.fn() })),
56
+ select: vitest_1.vi.fn(),
57
+ }));
58
+ (0, vitest_1.describe)('createExampleComponent', () => {
59
+ const showCopyPasteSnippetSpy = vitest_1.vi.spyOn(clackUtils, 'showCopyPasteInstructions');
60
+ (0, vitest_1.beforeEach)(() => {
61
+ vitest_1.vi.clearAllMocks();
62
+ });
63
+ (0, vitest_1.it)('creates an example component file', async () => {
64
+ const options = {
65
+ url: 'https://sentry.io',
66
+ orgSlug: 'myOrg',
67
+ projectId: '123456789',
68
+ };
69
+ // Mock the abortIfCancelled function to return the appRootPath
70
+ vitest_1.vi.spyOn(clackUtils, 'abortIfCancelled').mockResolvedValue('src/app');
71
+ // Mock the getSentryExampleComponentCode function
72
+ const exampleComponentCode = (0, example_component_1.getSentryExampleComponentCode)(options);
73
+ // Call the function to create the example component
74
+ await (0, example_component_1.createExampleComponent)(options);
75
+ (0, vitest_1.expect)(fsMocks.writeFileSyncMock).toHaveBeenCalledWith('./src/app/sentry-example.component.ts', exampleComponentCode);
76
+ (0, vitest_1.expect)(showCopyPasteSnippetSpy).toHaveBeenCalledWith({
77
+ codeSnippet: `import { SentryExample } from './sentry-example.component'
78
+
79
+ @Component({
80
+ selector: 'app-root',
81
+ standalone: true,
82
+ imports: [RouterOutlet, SentryExample],
83
+ template: \`
84
+ <div class="app">
85
+ <h1>Your Application</h1>
86
+ <app-sentry-example></app-sentry-example>
87
+ </div>
88
+ \`,
89
+ })
90
+ `,
91
+ instructions: 'Add the example component one of your pages or components (for example, in app.component.ts).',
92
+ });
93
+ });
94
+ });
95
+ (0, vitest_1.describe)('getSentryExampleComponentCode', () => {
96
+ (0, vitest_1.it)('includes the correct issue stream URL', () => {
97
+ const exampleComponentCode = (0, example_component_1.getSentryExampleComponentCode)({
98
+ orgSlug: 'myOrg',
99
+ projectId: '123456789',
100
+ url: 'https://sentry.io',
101
+ });
102
+ (0, vitest_1.expect)(exampleComponentCode).toContain('https://myorg.sentry.io/issues/?project=123456789');
103
+ });
104
+ });
105
+ //# sourceMappingURL=example-component.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example-component.test.js","sourceRoot":"","sources":["../../../test/angular/example-component.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { beforeEach, describe, expect, it, vi } from 'vitest';\nimport {\n createExampleComponent,\n getSentryExampleComponentCode,\n} from '../../src/angular/example-component';\n\nimport * as clackUtils from '../../src/utils/clack';\n\nconst fsMocks = vi.hoisted(() => ({\n existsSyncMock: vi.fn(() => true),\n writeFileSyncMock: vi.fn(),\n mkdirSyncMock: vi.fn(),\n}));\n\nvi.mock('fs', () => ({\n existsSync: fsMocks.existsSyncMock,\n writeFileSync: fsMocks.writeFileSyncMock,\n mkdirSync: fsMocks.mkdirSyncMock,\n}));\n\nvi.mock('@clack/prompts', () => ({\n log: {\n info: vi.fn(),\n success: vi.fn(),\n warn: vi.fn(),\n error: vi.fn(),\n step: vi.fn(),\n },\n outro: vi.fn(),\n text: vi.fn(),\n confirm: vi.fn(),\n cancel: vi.fn(),\n // passthrough for abortIfCancelled\n isCancel: vi.fn().mockReturnValue(false),\n spinner: vi\n .fn()\n .mockImplementation(() => ({ start: vi.fn(), stop: vi.fn() })),\n select: vi.fn(),\n}));\n\ndescribe('createExampleComponent', () => {\n const showCopyPasteSnippetSpy = vi.spyOn(\n clackUtils,\n 'showCopyPasteInstructions',\n );\n\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n it('creates an example component file', async () => {\n const options = {\n url: 'https://sentry.io',\n orgSlug: 'myOrg',\n projectId: '123456789',\n };\n\n // Mock the abortIfCancelled function to return the appRootPath\n vi.spyOn(clackUtils, 'abortIfCancelled').mockResolvedValue('src/app');\n\n // Mock the getSentryExampleComponentCode function\n const exampleComponentCode = getSentryExampleComponentCode(options);\n\n // Call the function to create the example component\n await createExampleComponent(options);\n\n expect(fsMocks.writeFileSyncMock).toHaveBeenCalledWith(\n './src/app/sentry-example.component.ts',\n exampleComponentCode,\n );\n expect(showCopyPasteSnippetSpy).toHaveBeenCalledWith({\n codeSnippet: `import { SentryExample } from './sentry-example.component'\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet, SentryExample],\n template: \\`\n <div class=\"app\">\n <h1>Your Application</h1>\n <app-sentry-example></app-sentry-example>\n </div>\n \\`,\n})\n`,\n instructions:\n 'Add the example component one of your pages or components (for example, in app.component.ts).',\n });\n });\n});\n\ndescribe('getSentryExampleComponentCode', () => {\n it('includes the correct issue stream URL', () => {\n const exampleComponentCode = getSentryExampleComponentCode({\n orgSlug: 'myOrg',\n projectId: '123456789',\n url: 'https://sentry.io',\n });\n expect(exampleComponentCode).toContain(\n 'https://myorg.sentry.io/issues/?project=123456789',\n );\n });\n});\n"]}
@@ -98,6 +98,119 @@ module.exports = testConfig;`);
98
98
  const testConfig = {};
99
99
 
100
100
  module.exports = withSentryConfig(testConfig);`);
101
+ });
102
+ (0, vitest_1.it)('patches custom react native metro config', async () => {
103
+ const mod = (0, magicast_1.parseModule)(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
104
+
105
+ const defaultConfig = getDefaultConfig(__dirname);
106
+ const {assetExts, sourceExts} = defaultConfig.resolver;
107
+ /**
108
+ * Metro configuration
109
+ * https://facebook.github.io/metro/docs/configuration
110
+ *
111
+ * @type {import('metro-config').MetroConfig}
112
+ */
113
+
114
+ const jsoMetroPlugin = require('obfuscator-io-metro-plugin')(
115
+ {
116
+ // for these option look javascript-obfuscator library options from above url
117
+ compact: false,
118
+ sourceMap: false,
119
+ controlFlowFlattening: true,
120
+ controlFlowFlatteningThreshold: 1,
121
+ numbersToExpressions: true,
122
+ simplify: true,
123
+ stringArrayShuffle: true,
124
+ splitStrings: true,
125
+ stringArrayThreshold: 1,
126
+ },
127
+ {
128
+ runInDev: false /* optional */,
129
+ logObfuscatedFiles: true /* optional generated files will be located at ./.jso */,
130
+ // source Map generated after obfuscation is not useful right now
131
+ sourceMapLocation:
132
+ './index.android.bundle.map' /* optional only works if sourceMap: true in obfuscation option */,
133
+ },
134
+ );
135
+
136
+ const config = {
137
+ transformer: {
138
+ babelTransformerPath: require.resolve('react-native-svg-transformer'),
139
+ getTransformOptions: async () => ({
140
+ transform: {
141
+ experimentalImportSupport: false,
142
+ inlineRequires: true,
143
+ },
144
+ }),
145
+ },
146
+ resolver: {
147
+ assetExts: assetExts.filter(ext => ext !== 'svg'),
148
+ sourceExts: [...sourceExts, 'svg'],
149
+ },
150
+ ...jsoMetroPlugin,
151
+ };
152
+
153
+ module.exports = mergeConfig(getDefaultConfig(__dirname), config);`);
154
+ const result = await (0, metro_1.patchMetroWithSentryConfigInMemory)(mod, async () => {
155
+ /* noop */
156
+ });
157
+ (0, vitest_1.expect)(result).toBe(true);
158
+ (0, vitest_1.expect)((0, magicast_1.generateCode)(mod.$ast).code)
159
+ .toBe(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
160
+
161
+ const {
162
+ withSentryConfig
163
+ } = require("@sentry/react-native/metro");
164
+
165
+ const defaultConfig = getDefaultConfig(__dirname);
166
+ const {assetExts, sourceExts} = defaultConfig.resolver;
167
+ /**
168
+ * Metro configuration
169
+ * https://facebook.github.io/metro/docs/configuration
170
+ *
171
+ * @type {import('metro-config').MetroConfig}
172
+ */
173
+
174
+ const jsoMetroPlugin = require('obfuscator-io-metro-plugin')(
175
+ {
176
+ // for these option look javascript-obfuscator library options from above url
177
+ compact: false,
178
+ sourceMap: false,
179
+ controlFlowFlattening: true,
180
+ controlFlowFlatteningThreshold: 1,
181
+ numbersToExpressions: true,
182
+ simplify: true,
183
+ stringArrayShuffle: true,
184
+ splitStrings: true,
185
+ stringArrayThreshold: 1,
186
+ },
187
+ {
188
+ runInDev: false /* optional */,
189
+ logObfuscatedFiles: true /* optional generated files will be located at ./.jso */,
190
+ // source Map generated after obfuscation is not useful right now
191
+ sourceMapLocation:
192
+ './index.android.bundle.map' /* optional only works if sourceMap: true in obfuscation option */,
193
+ },
194
+ );
195
+
196
+ const config = {
197
+ transformer: {
198
+ babelTransformerPath: require.resolve('react-native-svg-transformer'),
199
+ getTransformOptions: async () => ({
200
+ transform: {
201
+ experimentalImportSupport: false,
202
+ inlineRequires: true,
203
+ },
204
+ }),
205
+ },
206
+ resolver: {
207
+ assetExts: assetExts.filter(ext => ext !== 'svg'),
208
+ sourceExts: [...sourceExts, 'svg'],
209
+ },
210
+ ...jsoMetroPlugin,
211
+ };
212
+
213
+ module.exports = withSentryConfig(mergeConfig(getDefaultConfig(__dirname), config));`);
101
214
  });
102
215
  (0, vitest_1.it)('does not patch react native metro config exported as factory function', async () => {
103
216
  const mod = (0, magicast_1.parseModule)(`module.exports = () => ({});`);
@@ -1 +1 @@
1
- {"version":3,"file":"metro.test.js","sourceRoot":"","sources":["../../../test/react-native/metro.test.ts"],"names":[],"mappings":";;AAAA,kFAAkF;AAClF,uCAA2E;AAM3E,wDAOsC;AACtC,mCAA8C;AAE9C,IAAA,iBAAQ,EAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,IAAA,iBAAQ,EAAC,oCAAoC,EAAE,GAAG,EAAE;QAClD,IAAA,WAAE,EAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,GAAG,GACP,IAAA,sBAAW,EAAC;;;;;;;;;;mEAU+C,CAAC,CAAC;YAE/D,MAAM,MAAM,GAAG,MAAM,IAAA,0CAAkC,EAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBACtE,UAAU;YACZ,CAAC,CAAC,CAAC;YACH,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;iBAChC,IAAI,CAAC;;;;;;;;;;;;;;qFAcuE,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;;;;;;;;;GAgB3B,CAAC,CAAC;YAEC,MAAM,MAAM,GAAG,MAAM,IAAA,0CAAkC,EAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBACtE,UAAU;YACZ,CAAC,CAAC,CAAC;YACH,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;IAoB3C,CAAC,CAAC;QACF,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;6BAED,CAAC,CAAC;YAEzB,MAAM,MAAM,GAAG,MAAM,IAAA,0CAAkC,EAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBACtE,UAAU;YACZ,CAAC,CAAC,CAAC;YACH,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;;+CAMA,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;YACrF,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,8BAA8B,CAAC,CAAC;YAExD,MAAM,MAAM,GAAG,MAAM,IAAA,0CAAkC,EAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBACtE,UAAU;YACZ,CAAC,CAAC,CAAC;YACH,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,IAAA,WAAE,EAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;QAEtB,CAAC,CAAC;YACJ,MAAM,YAAY,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAA,wCAAgC,EAAC,YAAY,CAAC,CAAC;YAC9D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;;EAM7C,CAAC,CAAC;QACA,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;EAK5B,CAAC,CAAC;YACE,MAAM,YAAY,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAA,wCAAgC,EAAC,YAAY,CAAC,CAAC;YAC9D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;;EAM7C,CAAC,CAAC;QACA,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;EAM5B,CAAC,CAAC;YACE,MAAM,YAAY,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAA,wCAAgC,EAAC,YAAY,CAAC,CAAC;YAC9D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;;EAM7C,CAAC,CAAC;QACA,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,wCAAwC,EAAE,GAAG,EAAE;QACtD,IAAA,WAAE,EAAC,YAAY,EAAE,GAAG,EAAE;YACpB,MAAM,GAAG,GACP,IAAA,sBAAW,EAAC;;;;EAIlB,CAAC,CAAC;YACE,MAAM,MAAM,GAAG,IAAA,+CAAuC,EACpD,GAAG,CAAC,IAAiB,CACtB,CAAC;YACF,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;iBAChC,IAAI,CAAC;;;;;;;;EAQZ,CAAC,CAAC;QACA,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,kCAAkC,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,IAAA,4BAAoB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;YACjE,IAAA,eAAM,EACH,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA,CAAC,GAAoB;iBACpE,IAAI,CACR,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACf,IAAA,eAAM,EAEF,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA;iBAC9C,KACJ,CAAC,KAAK,CACR,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,oCAAoC,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAG,IAAA,4BAAoB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;YACjE,IAAA,eAAM,EACH,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA,CAAC,GAAoB;iBACpE,IAAI,CACR,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACf,IAAA,eAAM,EAEF,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA;iBAC9C,KACJ,CAAC,KAAK,CACR,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,kCAAkC,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,IAAA,4BAAoB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;YACjE,IAAA,eAAM,EACH,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA,CAAC,GAAoB;iBACpE,IAAI,CACR,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACf,IAAA,eAAM,EAEF,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA;iBAC9C,KACJ,CAAC,KAAK,CACR,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,sCAAsC,CAAC,CAAC;YAChE,MAAM,YAAY,GAAG,IAAA,4BAAoB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;YACjE,IAAA,eAAM,EACH,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA,CAAC,GAAoB;iBACpE,IAAI,CACR,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACf,IAAA,eAAM,EAEF,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAsB,CAAA;iBAC9C,KACJ,CAAC,KAAK,CACR,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,IAAA,WAAE,EAAC,mBAAmB,EAAE,GAAG,EAAE;YAC3B,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,kCAAkC,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAG,IAAA,2BAAmB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;YAC1D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtC,kCAAkC,CACnC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;iCAGG,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,IAAA,2BAAmB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;YAC1D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtC,kCAAkC,CACnC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;iCAMG,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,IAAA,2BAAmB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;YAC1D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtC,kCAAkC,CACnC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,8BAA8B,EAAE,GAAG,EAAE;QAC5C,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,kCAAkC,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAG,IAAA,6CAAqC,EAClD,GAAG,CAAC,IAAiB,CACtB,CAAC;YACF,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtC,kCAAkC,CACnC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;GAM3B,CAAC,CAAC;YACC,MAAM,MAAM,GAAG,IAAA,6CAAqC,EAClD,GAAG,CAAC,IAAiB,CACtB,CAAC;YACF,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;;GAM5C,CAAC,CAAC;QACD,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;GAM3B,CAAC,CAAC;YACC,MAAM,MAAM,GAAG,IAAA,6CAAqC,EAClD,GAAG,CAAC,IAAiB,CACtB,CAAC;YACF,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;GAK5C,CAAC,CAAC;QACD,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;GAM3B,CAAC,CAAC;YACC,MAAM,MAAM,GAAG,IAAA,6CAAqC,EAClD,GAAG,CAAC,IAAiB,CACtB,CAAC;YACF,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;;;;;GAM5C,CAAC,CAAC;QACD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAS,sBAAsB,CAC7B,GAAoB,EACpB,KAAK,GAAG,CAAC;IAET,OACI,GAAG,CAAC,IAAkB,CAAC,IAAI,CAAC,KAAK,CAA2B;SAC3D,UACJ,CAAC,KAA2B,CAAC;AAChC,CAAC","sourcesContent":["// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, type ProxifiedModule, parseModule } from 'magicast';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nimport {\n addSentrySerializerRequireToMetroConfig,\n addSentrySerializerToMetroConfig,\n getMetroConfigObject,\n patchMetroWithSentryConfigInMemory,\n removeSentryRequire,\n removeSentrySerializerFromMetroConfig,\n} from '../../src/react-native/metro';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('patch metro config - sentry serializer', () => {\n describe('patchMetroWithSentryConfigInMemory', () => {\n it('patches react native 0.72 default metro config', async () => {\n const mod =\n parseModule(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\n\n/**\n * Metro configuration\n * https://reactnative.dev/docs/metro\n *\n * @type {import('metro-config').MetroConfig}\n */\nconst config = {};\n\nmodule.exports = mergeConfig(getDefaultConfig(__dirname), config);`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code)\n .toBe(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\n\nconst {\n withSentryConfig\n} = require(\"@sentry/react-native/metro\");\n\n/**\n * Metro configuration\n * https://reactnative.dev/docs/metro\n *\n * @type {import('metro-config').MetroConfig}\n */\nconst config = {};\n\nmodule.exports = withSentryConfig(mergeConfig(getDefaultConfig(__dirname), config));`);\n });\n\n it('patches react native 0.65 default metro config', async () => {\n const mod = parseModule(`/**\n* Metro configuration for React Native\n* https://github.com/facebook/react-native\n*\n* @format\n*/\n\nmodule.exports = {\n transformer: {\n getTransformOptions: async () => ({\n transform: {\n experimentalImportSupport: false,\n inlineRequires: true,\n },\n }),\n },\n};`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`const {\n withSentryConfig\n} = require(\"@sentry/react-native/metro\");\n\n/**\n* Metro configuration for React Native\n* https://github.com/facebook/react-native\n*\n* @format\n*/\n\nmodule.exports = withSentryConfig({\n transformer: {\n getTransformOptions: async () => ({\n transform: {\n experimentalImportSupport: false,\n inlineRequires: true,\n },\n }),\n },\n});`);\n });\n\n it('patches react native metro config exported variable', async () => {\n const mod = parseModule(`const testConfig = {};\n\nmodule.exports = testConfig;`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`const {\n withSentryConfig\n} = require(\"@sentry/react-native/metro\");\n\nconst testConfig = {};\n\nmodule.exports = withSentryConfig(testConfig);`);\n });\n\n it('does not patch react native metro config exported as factory function', async () => {\n const mod = parseModule(`module.exports = () => ({});`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = () => ({});`);\n });\n });\n\n describe('addSentrySerializerToMetroConfig', () => {\n it('add to empty config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config'\n }`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n\n serializer: {\n customSerializer: createSentryMetroSerializer()\n }\n}`);\n });\n\n it('add to existing serializer config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config'\n }\n}`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: createSentryMetroSerializer()\n }\n}`);\n });\n\n it('not add to existing customSerializer config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}`);\n });\n });\n\n describe('addSentrySerializerImportToMetroConfig', () => {\n it('add import', () => {\n const mod =\n parseModule(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nmodule.exports = {\n other: 'config'\n}`);\n const result = addSentrySerializerRequireToMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code)\n .toBe(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nconst {\n createSentryMetroSerializer\n} = require(\"@sentry/react-native/dist/js/tools/sentryMetroSerializer\");\n\nmodule.exports = {\n other: 'config'\n}`);\n });\n });\n\n describe('getMetroConfigObject', () => {\n it('get config object from variable called config', () => {\n const mod = parseModule(`var config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config object from const called config', () => {\n const mod = parseModule(`const config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config oject from let called config', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config object from module.exports', () => {\n const mod = parseModule(`module.exports = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n });\n\n describe('remove @sentry require', () => {\n it('nothing to remove', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('remove metro serializer import', () => {\n const mod = parseModule(`const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nlet config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('remove all sentry imports', () => {\n const mod = parseModule(`const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nvar Sentry = require('@sentry/react-native');\nlet SentryIntegrations = require('@sentry/integrations');\n\nlet config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n });\n\n describe('remove sentryMetroSerializer', () => {\n it('no custom serializer to remove', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('no Sentry custom serializer to remove', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};`);\n });\n\n it('Sentry serializer to remove', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(),\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n other: 'config'\n },\n other: 'config',\n};`);\n });\n\n it('Sentry serializer to remove with wrapped serializer', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(wrappedSerializer()),\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n customSerializer: wrappedSerializer(),\n other: 'config',\n },\n other: 'config',\n};`);\n });\n });\n});\n\nfunction getModuleExportsObject(\n mod: ProxifiedModule,\n index = 0,\n): t.ObjectExpression {\n return (\n ((mod.$ast as t.Program).body[index] as t.ExpressionStatement)\n .expression as t.AssignmentExpression\n ).right as t.ObjectExpression;\n}\n"]}
1
+ {"version":3,"file":"metro.test.js","sourceRoot":"","sources":["../../../test/react-native/metro.test.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, type ProxifiedModule, parseModule } from 'magicast';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nimport {\n addSentrySerializerRequireToMetroConfig,\n addSentrySerializerToMetroConfig,\n getMetroConfigObject,\n patchMetroWithSentryConfigInMemory,\n removeSentryRequire,\n removeSentrySerializerFromMetroConfig,\n} from '../../src/react-native/metro';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('patch metro config - sentry serializer', () => {\n describe('patchMetroWithSentryConfigInMemory', () => {\n it('patches react native 0.72 default metro config', async () => {\n const mod =\n parseModule(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\n\n/**\n * Metro configuration\n * https://reactnative.dev/docs/metro\n *\n * @type {import('metro-config').MetroConfig}\n */\nconst config = {};\n\nmodule.exports = mergeConfig(getDefaultConfig(__dirname), config);`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code)\n .toBe(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\n\nconst {\n withSentryConfig\n} = require(\"@sentry/react-native/metro\");\n\n/**\n * Metro configuration\n * https://reactnative.dev/docs/metro\n *\n * @type {import('metro-config').MetroConfig}\n */\nconst config = {};\n\nmodule.exports = withSentryConfig(mergeConfig(getDefaultConfig(__dirname), config));`);\n });\n\n it('patches react native 0.65 default metro config', async () => {\n const mod = parseModule(`/**\n* Metro configuration for React Native\n* https://github.com/facebook/react-native\n*\n* @format\n*/\n\nmodule.exports = {\n transformer: {\n getTransformOptions: async () => ({\n transform: {\n experimentalImportSupport: false,\n inlineRequires: true,\n },\n }),\n },\n};`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`const {\n withSentryConfig\n} = require(\"@sentry/react-native/metro\");\n\n/**\n* Metro configuration for React Native\n* https://github.com/facebook/react-native\n*\n* @format\n*/\n\nmodule.exports = withSentryConfig({\n transformer: {\n getTransformOptions: async () => ({\n transform: {\n experimentalImportSupport: false,\n inlineRequires: true,\n },\n }),\n },\n});`);\n });\n\n it('patches react native metro config exported variable', async () => {\n const mod = parseModule(`const testConfig = {};\n\nmodule.exports = testConfig;`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`const {\n withSentryConfig\n} = require(\"@sentry/react-native/metro\");\n\nconst testConfig = {};\n\nmodule.exports = withSentryConfig(testConfig);`);\n });\n\n it('patches custom react native metro config', async () => {\n const mod =\n parseModule(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\n\nconst defaultConfig = getDefaultConfig(__dirname);\nconst {assetExts, sourceExts} = defaultConfig.resolver;\n/**\n * Metro configuration\n * https://facebook.github.io/metro/docs/configuration\n *\n * @type {import('metro-config').MetroConfig}\n */\n\nconst jsoMetroPlugin = require('obfuscator-io-metro-plugin')(\n {\n // for these option look javascript-obfuscator library options from above url\n compact: false,\n sourceMap: false,\n controlFlowFlattening: true,\n controlFlowFlatteningThreshold: 1,\n numbersToExpressions: true,\n simplify: true,\n stringArrayShuffle: true,\n splitStrings: true,\n stringArrayThreshold: 1,\n },\n {\n runInDev: false /* optional */,\n logObfuscatedFiles: true /* optional generated files will be located at ./.jso */,\n // source Map generated after obfuscation is not useful right now\n sourceMapLocation:\n './index.android.bundle.map' /* optional only works if sourceMap: true in obfuscation option */,\n },\n);\n\nconst config = {\n transformer: {\n babelTransformerPath: require.resolve('react-native-svg-transformer'),\n getTransformOptions: async () => ({\n transform: {\n experimentalImportSupport: false,\n inlineRequires: true,\n },\n }),\n },\n resolver: {\n assetExts: assetExts.filter(ext => ext !== 'svg'),\n sourceExts: [...sourceExts, 'svg'],\n },\n ...jsoMetroPlugin,\n};\n\nmodule.exports = mergeConfig(getDefaultConfig(__dirname), config);`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code)\n .toBe(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\n\nconst {\n withSentryConfig\n} = require(\"@sentry/react-native/metro\");\n\nconst defaultConfig = getDefaultConfig(__dirname);\nconst {assetExts, sourceExts} = defaultConfig.resolver;\n/**\n * Metro configuration\n * https://facebook.github.io/metro/docs/configuration\n *\n * @type {import('metro-config').MetroConfig}\n */\n\nconst jsoMetroPlugin = require('obfuscator-io-metro-plugin')(\n {\n // for these option look javascript-obfuscator library options from above url\n compact: false,\n sourceMap: false,\n controlFlowFlattening: true,\n controlFlowFlatteningThreshold: 1,\n numbersToExpressions: true,\n simplify: true,\n stringArrayShuffle: true,\n splitStrings: true,\n stringArrayThreshold: 1,\n },\n {\n runInDev: false /* optional */,\n logObfuscatedFiles: true /* optional generated files will be located at ./.jso */,\n // source Map generated after obfuscation is not useful right now\n sourceMapLocation:\n './index.android.bundle.map' /* optional only works if sourceMap: true in obfuscation option */,\n },\n);\n\nconst config = {\n transformer: {\n babelTransformerPath: require.resolve('react-native-svg-transformer'),\n getTransformOptions: async () => ({\n transform: {\n experimentalImportSupport: false,\n inlineRequires: true,\n },\n }),\n },\n resolver: {\n assetExts: assetExts.filter(ext => ext !== 'svg'),\n sourceExts: [...sourceExts, 'svg'],\n },\n ...jsoMetroPlugin,\n};\n\nmodule.exports = withSentryConfig(mergeConfig(getDefaultConfig(__dirname), config));`);\n });\n\n it('does not patch react native metro config exported as factory function', async () => {\n const mod = parseModule(`module.exports = () => ({});`);\n\n const result = await patchMetroWithSentryConfigInMemory(mod, async () => {\n /* noop */\n });\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = () => ({});`);\n });\n });\n\n describe('addSentrySerializerToMetroConfig', () => {\n it('add to empty config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config'\n }`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n\n serializer: {\n customSerializer: createSentryMetroSerializer()\n }\n}`);\n });\n\n it('add to existing serializer config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config'\n }\n}`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: createSentryMetroSerializer()\n }\n}`);\n });\n\n it('not add to existing customSerializer config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}`);\n });\n });\n\n describe('addSentrySerializerImportToMetroConfig', () => {\n it('add import', () => {\n const mod =\n parseModule(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nmodule.exports = {\n other: 'config'\n}`);\n const result = addSentrySerializerRequireToMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code)\n .toBe(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nconst {\n createSentryMetroSerializer\n} = require(\"@sentry/react-native/dist/js/tools/sentryMetroSerializer\");\n\nmodule.exports = {\n other: 'config'\n}`);\n });\n });\n\n describe('getMetroConfigObject', () => {\n it('get config object from variable called config', () => {\n const mod = parseModule(`var config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config object from const called config', () => {\n const mod = parseModule(`const config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config oject from let called config', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config object from module.exports', () => {\n const mod = parseModule(`module.exports = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n });\n\n describe('remove @sentry require', () => {\n it('nothing to remove', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('remove metro serializer import', () => {\n const mod = parseModule(`const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nlet config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('remove all sentry imports', () => {\n const mod = parseModule(`const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nvar Sentry = require('@sentry/react-native');\nlet SentryIntegrations = require('@sentry/integrations');\n\nlet config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n });\n\n describe('remove sentryMetroSerializer', () => {\n it('no custom serializer to remove', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('no Sentry custom serializer to remove', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};`);\n });\n\n it('Sentry serializer to remove', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(),\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n other: 'config'\n },\n other: 'config',\n};`);\n });\n\n it('Sentry serializer to remove with wrapped serializer', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(wrappedSerializer()),\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n customSerializer: wrappedSerializer(),\n other: 'config',\n },\n other: 'config',\n};`);\n });\n });\n});\n\nfunction getModuleExportsObject(\n mod: ProxifiedModule,\n index = 0,\n): t.ObjectExpression {\n return (\n ((mod.$ast as t.Program).body[index] as t.ExpressionStatement)\n .expression as t.AssignmentExpression\n ).right as t.ObjectExpression;\n}\n"]}