@sentry/wizard 3.16.4 → 3.17.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.
- package/CHANGELOG.md +11 -0
- package/dist/package.json +2 -2
- package/dist/src/apple/cocoapod.js +2 -0
- package/dist/src/apple/cocoapod.js.map +1 -1
- package/dist/src/react-native/metro.d.ts +13 -0
- package/dist/src/react-native/metro.js +398 -0
- package/dist/src/react-native/metro.js.map +1 -0
- package/dist/src/react-native/react-native-wizard.d.ts +2 -0
- package/dist/src/react-native/react-native-wizard.js +145 -42
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-native/uninstall.js +4 -0
- package/dist/src/react-native/uninstall.js.map +1 -1
- package/dist/src/react-native/xcode.d.ts +7 -3
- package/dist/src/react-native/xcode.js +43 -11
- package/dist/src/react-native/xcode.js.map +1 -1
- package/dist/src/remix/remix-wizard.js +80 -37
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/remix/sdk-setup.d.ts +1 -0
- package/dist/src/remix/sdk-setup.js +21 -1
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js +2 -6
- package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +14 -0
- package/dist/src/utils/ast-utils.js +49 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack-utils.js +0 -1
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/src/utils/types.d.ts +8 -4
- package/dist/src/utils/types.js.map +1 -1
- package/dist/src/utils/url.d.ts +10 -0
- package/dist/src/utils/url.js +19 -0
- package/dist/src/utils/url.js.map +1 -0
- package/dist/test/react-native/metro.test.d.ts +1 -0
- package/dist/test/react-native/metro.test.js +125 -0
- package/dist/test/react-native/metro.test.js.map +1 -0
- package/dist/test/react-native/xcode.test.js +40 -2
- package/dist/test/react-native/xcode.test.js.map +1 -1
- package/package.json +2 -2
- package/src/apple/cocoapod.ts +2 -0
- package/src/react-native/metro.ts +409 -0
- package/src/react-native/react-native-wizard.ts +115 -12
- package/src/react-native/uninstall.ts +3 -0
- package/src/react-native/xcode.ts +70 -12
- package/src/remix/remix-wizard.ts +51 -15
- package/src/remix/sdk-setup.ts +31 -0
- package/src/sourcemaps/sourcemaps-wizard.ts +2 -7
- package/src/utils/ast-utils.ts +52 -0
- package/src/utils/clack-utils.ts +0 -1
- package/src/utils/types.ts +8 -5
- package/src/utils/url.ts +23 -0
- package/test/react-native/metro.test.ts +283 -0
- package/test/react-native/xcode.test.ts +76 -3
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// @ts-ignore - magicast is ESM and TS complains about that. It works though
|
|
2
|
+
import { generateCode, type ProxifiedModule, parseModule } from 'magicast';
|
|
3
|
+
|
|
4
|
+
import * as recast from 'recast';
|
|
5
|
+
import x = recast.types;
|
|
6
|
+
import t = x.namedTypes;
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
addSentrySerializerRequireToMetroConfig,
|
|
10
|
+
addSentrySerializerToMetroConfig,
|
|
11
|
+
getMetroConfigObject,
|
|
12
|
+
removeSentryRequire,
|
|
13
|
+
removeSentrySerializerFromMetroConfig,
|
|
14
|
+
} from '../../src/react-native/metro';
|
|
15
|
+
|
|
16
|
+
describe('patch metro config - sentry serializer', () => {
|
|
17
|
+
describe('addSentrySerializerToMetroConfig', () => {
|
|
18
|
+
it('add to empty config', () => {
|
|
19
|
+
const mod = parseModule(`module.exports = {
|
|
20
|
+
other: 'config'
|
|
21
|
+
}`);
|
|
22
|
+
const configObject = getModuleExportsObject(mod);
|
|
23
|
+
const result = addSentrySerializerToMetroConfig(configObject);
|
|
24
|
+
expect(result).toBe(true);
|
|
25
|
+
expect(generateCode(mod.$ast).code).toBe(`module.exports = {
|
|
26
|
+
other: 'config',
|
|
27
|
+
|
|
28
|
+
serializer: {
|
|
29
|
+
customSerializer: createSentryMetroSerializer()
|
|
30
|
+
}
|
|
31
|
+
}`);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('add to existing serializer config', () => {
|
|
35
|
+
const mod = parseModule(`module.exports = {
|
|
36
|
+
other: 'config',
|
|
37
|
+
serializer: {
|
|
38
|
+
other: 'config'
|
|
39
|
+
}
|
|
40
|
+
}`);
|
|
41
|
+
const configObject = getModuleExportsObject(mod);
|
|
42
|
+
const result = addSentrySerializerToMetroConfig(configObject);
|
|
43
|
+
expect(result).toBe(true);
|
|
44
|
+
expect(generateCode(mod.$ast).code).toBe(`module.exports = {
|
|
45
|
+
other: 'config',
|
|
46
|
+
serializer: {
|
|
47
|
+
other: 'config',
|
|
48
|
+
customSerializer: createSentryMetroSerializer()
|
|
49
|
+
}
|
|
50
|
+
}`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('not add to existing customSerializer config', () => {
|
|
54
|
+
const mod = parseModule(`module.exports = {
|
|
55
|
+
other: 'config',
|
|
56
|
+
serializer: {
|
|
57
|
+
other: 'config',
|
|
58
|
+
customSerializer: 'existing-serializer'
|
|
59
|
+
}
|
|
60
|
+
}`);
|
|
61
|
+
const configObject = getModuleExportsObject(mod);
|
|
62
|
+
const result = addSentrySerializerToMetroConfig(configObject);
|
|
63
|
+
expect(result).toBe(false);
|
|
64
|
+
expect(generateCode(mod.$ast).code).toBe(`module.exports = {
|
|
65
|
+
other: 'config',
|
|
66
|
+
serializer: {
|
|
67
|
+
other: 'config',
|
|
68
|
+
customSerializer: 'existing-serializer'
|
|
69
|
+
}
|
|
70
|
+
}`);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('addSentrySerializerImportToMetroConfig', () => {
|
|
75
|
+
it('add import', () => {
|
|
76
|
+
const mod =
|
|
77
|
+
parseModule(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
|
78
|
+
|
|
79
|
+
module.exports = {
|
|
80
|
+
other: 'config'
|
|
81
|
+
}`);
|
|
82
|
+
const result = addSentrySerializerRequireToMetroConfig(
|
|
83
|
+
mod.$ast as t.Program,
|
|
84
|
+
);
|
|
85
|
+
expect(result).toBe(true);
|
|
86
|
+
expect(generateCode(mod.$ast).code)
|
|
87
|
+
.toBe(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
|
88
|
+
|
|
89
|
+
const {
|
|
90
|
+
createSentryMetroSerializer
|
|
91
|
+
} = require("@sentry/react-native/dist/js/tools/sentryMetroSerializer");
|
|
92
|
+
|
|
93
|
+
module.exports = {
|
|
94
|
+
other: 'config'
|
|
95
|
+
}`);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('getMetroConfigObject', () => {
|
|
100
|
+
it('get config object from variable called config', () => {
|
|
101
|
+
const mod = parseModule(`var config = { some: 'config' };`);
|
|
102
|
+
const configObject = getMetroConfigObject(mod.$ast as t.Program);
|
|
103
|
+
expect(
|
|
104
|
+
((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)
|
|
105
|
+
.name,
|
|
106
|
+
).toBe('some');
|
|
107
|
+
expect(
|
|
108
|
+
(
|
|
109
|
+
(configObject?.properties[0] as t.ObjectProperty)
|
|
110
|
+
.value as t.StringLiteral
|
|
111
|
+
).value,
|
|
112
|
+
).toBe('config');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('get config object from const called config', () => {
|
|
116
|
+
const mod = parseModule(`const config = { some: 'config' };`);
|
|
117
|
+
const configObject = getMetroConfigObject(mod.$ast as t.Program);
|
|
118
|
+
expect(
|
|
119
|
+
((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)
|
|
120
|
+
.name,
|
|
121
|
+
).toBe('some');
|
|
122
|
+
expect(
|
|
123
|
+
(
|
|
124
|
+
(configObject?.properties[0] as t.ObjectProperty)
|
|
125
|
+
.value as t.StringLiteral
|
|
126
|
+
).value,
|
|
127
|
+
).toBe('config');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('get config oject from let called config', () => {
|
|
131
|
+
const mod = parseModule(`let config = { some: 'config' };`);
|
|
132
|
+
const configObject = getMetroConfigObject(mod.$ast as t.Program);
|
|
133
|
+
expect(
|
|
134
|
+
((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)
|
|
135
|
+
.name,
|
|
136
|
+
).toBe('some');
|
|
137
|
+
expect(
|
|
138
|
+
(
|
|
139
|
+
(configObject?.properties[0] as t.ObjectProperty)
|
|
140
|
+
.value as t.StringLiteral
|
|
141
|
+
).value,
|
|
142
|
+
).toBe('config');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('get config object from module.exports', () => {
|
|
146
|
+
const mod = parseModule(`module.exports = { some: 'config' };`);
|
|
147
|
+
const configObject = getMetroConfigObject(mod.$ast as t.Program);
|
|
148
|
+
expect(
|
|
149
|
+
((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)
|
|
150
|
+
.name,
|
|
151
|
+
).toBe('some');
|
|
152
|
+
expect(
|
|
153
|
+
(
|
|
154
|
+
(configObject?.properties[0] as t.ObjectProperty)
|
|
155
|
+
.value as t.StringLiteral
|
|
156
|
+
).value,
|
|
157
|
+
).toBe('config');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe('remove @sentry require', () => {
|
|
162
|
+
it('nothing to remove', () => {
|
|
163
|
+
const mod = parseModule(`let config = { some: 'config' };`);
|
|
164
|
+
const result = removeSentryRequire(mod.$ast as t.Program);
|
|
165
|
+
expect(result).toBe(false);
|
|
166
|
+
expect(generateCode(mod.$ast).code).toBe(
|
|
167
|
+
`let config = { some: 'config' };`,
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('remove metro serializer import', () => {
|
|
172
|
+
const mod = parseModule(`const {
|
|
173
|
+
createSentryMetroSerializer,
|
|
174
|
+
} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');
|
|
175
|
+
let config = { some: 'config' };`);
|
|
176
|
+
const result = removeSentryRequire(mod.$ast as t.Program);
|
|
177
|
+
expect(result).toBe(true);
|
|
178
|
+
expect(generateCode(mod.$ast).code).toBe(
|
|
179
|
+
`let config = { some: 'config' };`,
|
|
180
|
+
);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('remove all sentry imports', () => {
|
|
184
|
+
const mod = parseModule(`const {
|
|
185
|
+
createSentryMetroSerializer,
|
|
186
|
+
} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');
|
|
187
|
+
var Sentry = require('@sentry/react-native');
|
|
188
|
+
let SentryIntegrations = require('@sentry/integrations');
|
|
189
|
+
|
|
190
|
+
let config = { some: 'config' };`);
|
|
191
|
+
const result = removeSentryRequire(mod.$ast as t.Program);
|
|
192
|
+
expect(result).toBe(true);
|
|
193
|
+
expect(generateCode(mod.$ast).code).toBe(
|
|
194
|
+
`let config = { some: 'config' };`,
|
|
195
|
+
);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe('remove sentryMetroSerializer', () => {
|
|
200
|
+
it('no custom serializer to remove', () => {
|
|
201
|
+
const mod = parseModule(`let config = { some: 'config' };`);
|
|
202
|
+
const result = removeSentrySerializerFromMetroConfig(
|
|
203
|
+
mod.$ast as t.Program,
|
|
204
|
+
);
|
|
205
|
+
expect(result).toBe(false);
|
|
206
|
+
expect(generateCode(mod.$ast).code).toBe(
|
|
207
|
+
`let config = { some: 'config' };`,
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('no Sentry custom serializer to remove', () => {
|
|
212
|
+
const mod = parseModule(`let config = {
|
|
213
|
+
serializer: {
|
|
214
|
+
customSerializer: 'existing-serializer',
|
|
215
|
+
other: 'config',
|
|
216
|
+
},
|
|
217
|
+
other: 'config',
|
|
218
|
+
};`);
|
|
219
|
+
const result = removeSentrySerializerFromMetroConfig(
|
|
220
|
+
mod.$ast as t.Program,
|
|
221
|
+
);
|
|
222
|
+
expect(result).toBe(false);
|
|
223
|
+
expect(generateCode(mod.$ast).code).toBe(`let config = {
|
|
224
|
+
serializer: {
|
|
225
|
+
customSerializer: 'existing-serializer',
|
|
226
|
+
other: 'config',
|
|
227
|
+
},
|
|
228
|
+
other: 'config',
|
|
229
|
+
};`);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('Sentry serializer to remove', () => {
|
|
233
|
+
const mod = parseModule(`let config = {
|
|
234
|
+
serializer: {
|
|
235
|
+
customSerializer: createSentryMetroSerializer(),
|
|
236
|
+
other: 'config',
|
|
237
|
+
},
|
|
238
|
+
other: 'config',
|
|
239
|
+
};`);
|
|
240
|
+
const result = removeSentrySerializerFromMetroConfig(
|
|
241
|
+
mod.$ast as t.Program,
|
|
242
|
+
);
|
|
243
|
+
expect(result).toBe(true);
|
|
244
|
+
expect(generateCode(mod.$ast).code).toBe(`let config = {
|
|
245
|
+
serializer: {
|
|
246
|
+
other: 'config'
|
|
247
|
+
},
|
|
248
|
+
other: 'config',
|
|
249
|
+
};`);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('Sentry serializer to remove with wrapped serializer', () => {
|
|
253
|
+
const mod = parseModule(`let config = {
|
|
254
|
+
serializer: {
|
|
255
|
+
customSerializer: createSentryMetroSerializer(wrappedSerializer()),
|
|
256
|
+
other: 'config',
|
|
257
|
+
},
|
|
258
|
+
other: 'config',
|
|
259
|
+
};`);
|
|
260
|
+
const result = removeSentrySerializerFromMetroConfig(
|
|
261
|
+
mod.$ast as t.Program,
|
|
262
|
+
);
|
|
263
|
+
expect(result).toBe(true);
|
|
264
|
+
expect(generateCode(mod.$ast).code).toBe(`let config = {
|
|
265
|
+
serializer: {
|
|
266
|
+
customSerializer: wrappedSerializer(),
|
|
267
|
+
other: 'config',
|
|
268
|
+
},
|
|
269
|
+
other: 'config',
|
|
270
|
+
};`);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
function getModuleExportsObject(
|
|
276
|
+
mod: ProxifiedModule,
|
|
277
|
+
index = 0,
|
|
278
|
+
): t.ObjectExpression {
|
|
279
|
+
return (
|
|
280
|
+
((mod.$ast as t.Program).body[index] as t.ExpressionStatement)
|
|
281
|
+
.expression as t.AssignmentExpression
|
|
282
|
+
).right as t.ObjectExpression;
|
|
283
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-useless-escape */
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
addSentryWithBundledScriptsToBundleShellScript,
|
|
4
|
+
addSentryWithCliToBundleShellScript,
|
|
4
5
|
doesBundlePhaseIncludeSentry,
|
|
5
6
|
findBundlePhase,
|
|
6
7
|
findDebugFilesUploadPhase,
|
|
@@ -8,7 +9,7 @@ import {
|
|
|
8
9
|
} from '../../src/react-native/xcode';
|
|
9
10
|
|
|
10
11
|
describe('react-native xcode', () => {
|
|
11
|
-
describe('
|
|
12
|
+
describe('addSentryWithCliToBundleShellScript', () => {
|
|
12
13
|
it('adds sentry cli to rn bundle build phase', () => {
|
|
13
14
|
const input = `set -e
|
|
14
15
|
|
|
@@ -30,7 +31,31 @@ REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
|
30
31
|
/bin/sh -c "$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh"
|
|
31
32
|
`;
|
|
32
33
|
|
|
33
|
-
expect(
|
|
34
|
+
expect(addSentryWithCliToBundleShellScript(input)).toBe(expectedOutput);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('addSentryBundledScriptsToBundleShellScript', () => {
|
|
39
|
+
it('adds sentry cli to rn bundle build phase', () => {
|
|
40
|
+
const input = `set -e
|
|
41
|
+
|
|
42
|
+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
43
|
+
REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
44
|
+
|
|
45
|
+
/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE"`;
|
|
46
|
+
// actual shell script looks like this:
|
|
47
|
+
// /bin/sh -c "$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\""
|
|
48
|
+
// but during parsing xcode library removes the quotes
|
|
49
|
+
const expectedOutput = `set -e
|
|
50
|
+
|
|
51
|
+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
52
|
+
REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
53
|
+
|
|
54
|
+
/bin/sh -c "$WITH_ENVIRONMENT \\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\\""`;
|
|
55
|
+
|
|
56
|
+
expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(
|
|
57
|
+
expectedOutput,
|
|
58
|
+
);
|
|
34
59
|
});
|
|
35
60
|
});
|
|
36
61
|
|
|
@@ -59,6 +84,23 @@ REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
|
59
84
|
|
|
60
85
|
expect(removeSentryFromBundleShellScript(input)).toBe(expectedOutput);
|
|
61
86
|
});
|
|
87
|
+
|
|
88
|
+
it('removes sentry bundled scripts from rn bundle build phase', () => {
|
|
89
|
+
const input = `set -e
|
|
90
|
+
|
|
91
|
+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
92
|
+
REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
93
|
+
|
|
94
|
+
/bin/sh -c "$WITH_ENVIRONMENT \"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\""`;
|
|
95
|
+
const expectedOutput = `set -e
|
|
96
|
+
|
|
97
|
+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
98
|
+
REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
99
|
+
|
|
100
|
+
/bin/sh -c "$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\""`;
|
|
101
|
+
|
|
102
|
+
expect(removeSentryFromBundleShellScript(input)).toBe(expectedOutput);
|
|
103
|
+
});
|
|
62
104
|
});
|
|
63
105
|
|
|
64
106
|
describe('findBundlePhase', () => {
|
|
@@ -138,6 +180,19 @@ SENTRY_CLI="sentry-cli react-native xcode"
|
|
|
138
180
|
expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();
|
|
139
181
|
});
|
|
140
182
|
|
|
183
|
+
it('returns true for script containing sentry bundled script', () => {
|
|
184
|
+
const input = {
|
|
185
|
+
shellScript: `set -e
|
|
186
|
+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
187
|
+
REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
188
|
+
SENTRY_CLI="sentry-cli react-native xcode"
|
|
189
|
+
|
|
190
|
+
/bin/sh -c "$WITH_ENVIRONMENT \\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE"\\"
|
|
191
|
+
`,
|
|
192
|
+
};
|
|
193
|
+
expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();
|
|
194
|
+
});
|
|
195
|
+
|
|
141
196
|
it('returns false', () => {
|
|
142
197
|
const input = {
|
|
143
198
|
// note sentry-cli can be part of the script but doesn't call react native xcode script
|
|
@@ -221,6 +276,24 @@ sentry-cli upload-dsym path/to/dsym --include-sources
|
|
|
221
276
|
expect(findDebugFilesUploadPhase(input)).toEqual(expected);
|
|
222
277
|
});
|
|
223
278
|
|
|
279
|
+
it('returns debug files build phase using bundled scripts', () => {
|
|
280
|
+
const input = {
|
|
281
|
+
1: {
|
|
282
|
+
shellScript: 'foo',
|
|
283
|
+
},
|
|
284
|
+
2: {
|
|
285
|
+
shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
const expected = [
|
|
289
|
+
'2',
|
|
290
|
+
{
|
|
291
|
+
shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,
|
|
292
|
+
},
|
|
293
|
+
];
|
|
294
|
+
expect(findDebugFilesUploadPhase(input)).toEqual(expected);
|
|
295
|
+
});
|
|
296
|
+
|
|
224
297
|
it('returns undefined if build phase not present', () => {
|
|
225
298
|
const input = {
|
|
226
299
|
1: {
|