@sentry/wizard 4.3.0 → 4.4.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 +4 -0
- package/dist/src/react-native/javascript.d.ts +16 -0
- package/dist/src/react-native/javascript.js +141 -6
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +1 -0
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/react-native/javascript.test.js +406 -0
- package/dist/test/react-native/javascript.test.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.4.0
|
|
4
|
+
|
|
5
|
+
- feat(react-native): Adds wrapping root app component with `Sentry.wrap` ([#835](https://github.com/getsentry/sentry-wizard/pull/835))
|
|
6
|
+
|
|
3
7
|
## 4.3.0
|
|
4
8
|
|
|
5
9
|
- feat: Skip CI prompt if `--coming-from` `vercel` ([#848](https://github.com/getsentry/sentry-wizard/pull/848))
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ProxifiedModule } from 'magicast';
|
|
2
|
+
import * as t from '@babel/types';
|
|
1
3
|
export declare function addSentryInit({ dsn }: {
|
|
2
4
|
dsn: string;
|
|
3
5
|
}): Promise<void>;
|
|
@@ -9,3 +11,17 @@ export declare function doesJsCodeIncludeSdkSentryImport(js: string, { sdkPackag
|
|
|
9
11
|
}): boolean;
|
|
10
12
|
export declare function getSentryInitColoredCodeSnippet(dsn: string): string;
|
|
11
13
|
export declare function getSentryInitPlainTextSnippet(dsn: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* This step should be executed after `addSentryInit`
|
|
16
|
+
*/
|
|
17
|
+
export declare function wrapRootComponent(): Promise<void>;
|
|
18
|
+
export declare enum SentryWrapResult {
|
|
19
|
+
NotFound = "RootComponentNotFound",
|
|
20
|
+
AlreadyWrapped = "AlreadyWrapped",
|
|
21
|
+
Success = "Success"
|
|
22
|
+
}
|
|
23
|
+
export declare function checkAndWrapRootComponent(mod: ProxifiedModule): SentryWrapResult;
|
|
24
|
+
export declare function getDefaultExport(program: t.Program): t.Identifier | t.CallExpression | t.ObjectExpression | t.FunctionDeclaration | t.ArrowFunctionExpression | t.ClassDeclaration | undefined;
|
|
25
|
+
export declare function wrapWithSentry(configObj: t.Identifier | t.CallExpression | t.ObjectExpression | t.FunctionDeclaration | t.ArrowFunctionExpression | t.ClassDeclaration): t.CallExpression;
|
|
26
|
+
export declare function replaceDefaultExport(program: t.Program, wrappedDefaultExport: t.CallExpression): boolean;
|
|
27
|
+
export declare function doesContainSentryWrap(program: t.Program): boolean;
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getSentryInitPlainTextSnippet = exports.getSentryInitColoredCodeSnippet = exports.doesJsCodeIncludeSdkSentryImport = exports.addSentryInitWithSdkImport = exports.addSentryInit = void 0;
|
|
29
|
+
exports.doesContainSentryWrap = exports.replaceDefaultExport = exports.wrapWithSentry = exports.getDefaultExport = exports.checkAndWrapRootComponent = exports.SentryWrapResult = exports.wrapRootComponent = exports.getSentryInitPlainTextSnippet = exports.getSentryInitColoredCodeSnippet = exports.doesJsCodeIncludeSdkSentryImport = exports.addSentryInitWithSdkImport = exports.addSentryInit = void 0;
|
|
30
30
|
/* eslint-disable max-lines */
|
|
31
31
|
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
32
32
|
const prompts_1 = __importDefault(require("@clack/prompts"));
|
|
@@ -39,12 +39,11 @@ const telemetry_1 = require("../telemetry");
|
|
|
39
39
|
const clack_utils_1 = require("../utils/clack-utils");
|
|
40
40
|
const glob_1 = require("./glob");
|
|
41
41
|
const react_native_wizard_1 = require("./react-native-wizard");
|
|
42
|
+
// @ts-ignore - magicast is ESM and TS complains about that. It works though
|
|
43
|
+
const magicast_1 = require("magicast");
|
|
44
|
+
const t = __importStar(require("@babel/types"));
|
|
42
45
|
async function addSentryInit({ dsn }) {
|
|
43
|
-
const
|
|
44
|
-
const suffixGlob = '@(j|t|cj|mj)s?(x)';
|
|
45
|
-
const universalGlob = `@(App|_layout).${suffixGlob}`;
|
|
46
|
-
const jsFileGlob = `${prefixGlob}/+(${universalGlob})`;
|
|
47
|
-
const jsPath = (0, telemetry_1.traceStep)('find-app-js-file', () => (0, glob_1.getFirstMatchedPath)(jsFileGlob));
|
|
46
|
+
const jsPath = getMainAppFilePath();
|
|
48
47
|
Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');
|
|
49
48
|
if (!jsPath) {
|
|
50
49
|
prompts_1.default.log.warn(`Could not find main App file. Place the following code snippet close to the Apps Root component.`);
|
|
@@ -96,4 +95,140 @@ Sentry.init({
|
|
|
96
95
|
});`;
|
|
97
96
|
}
|
|
98
97
|
exports.getSentryInitPlainTextSnippet = getSentryInitPlainTextSnippet;
|
|
98
|
+
function getMainAppFilePath() {
|
|
99
|
+
const prefixGlob = '{.,./src,./app}';
|
|
100
|
+
const suffixGlob = '@(j|t|cj|mj)s?(x)';
|
|
101
|
+
const universalGlob = `@(App|_layout).${suffixGlob}`;
|
|
102
|
+
const jsFileGlob = `${prefixGlob}/+(${universalGlob})`;
|
|
103
|
+
const jsPath = (0, telemetry_1.traceStep)('find-app-js-file', () => (0, glob_1.getFirstMatchedPath)(jsFileGlob));
|
|
104
|
+
return jsPath;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* This step should be executed after `addSentryInit`
|
|
108
|
+
*/
|
|
109
|
+
async function wrapRootComponent() {
|
|
110
|
+
const showInstructions = () => (0, clack_utils_1.showCopyPasteInstructions)('App.js or _layout.tsx', getSentryWrapColoredCodeSnippet());
|
|
111
|
+
const jsPath = getMainAppFilePath();
|
|
112
|
+
Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');
|
|
113
|
+
if (!jsPath) {
|
|
114
|
+
prompts_1.default.log.warn(`Could not find main App file. Please wrap your App's Root component.`);
|
|
115
|
+
await showInstructions();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const jsRelativePath = path.relative(process.cwd(), jsPath);
|
|
119
|
+
const js = fs.readFileSync(jsPath, 'utf-8');
|
|
120
|
+
const mod = (0, magicast_1.parseModule)(js);
|
|
121
|
+
const result = checkAndWrapRootComponent(mod);
|
|
122
|
+
if (result === SentryWrapResult.AlreadyWrapped) {
|
|
123
|
+
Sentry.setTag('app-js-file-status', 'already-includes-sentry-wrap');
|
|
124
|
+
prompts_1.default.log.warn(`${chalk_1.default.cyan(jsRelativePath)} already includes Sentry.wrap. We wont't add it again.`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (result === SentryWrapResult.NotFound) {
|
|
128
|
+
prompts_1.default.log.warn(`Could not find your App's Root component. Please wrap your App's Root component manually.`);
|
|
129
|
+
await showInstructions();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
(0, telemetry_1.traceStep)('add-sentry-wrap', () => {
|
|
133
|
+
prompts_1.default.log.success(`Added ${chalk_1.default.cyan('Sentry.wrap')} to ${chalk_1.default.cyan(jsRelativePath)}.`);
|
|
134
|
+
fs.writeFileSync(jsPath, (0, magicast_1.generateCode)(mod.$ast).code, 'utf-8');
|
|
135
|
+
});
|
|
136
|
+
Sentry.setTag('app-js-file-status', 'added-sentry-wrap');
|
|
137
|
+
prompts_1.default.log.success(chalk_1.default.green(`${chalk_1.default.cyan(jsRelativePath)} changes saved.`));
|
|
138
|
+
}
|
|
139
|
+
exports.wrapRootComponent = wrapRootComponent;
|
|
140
|
+
var SentryWrapResult;
|
|
141
|
+
(function (SentryWrapResult) {
|
|
142
|
+
SentryWrapResult["NotFound"] = "RootComponentNotFound";
|
|
143
|
+
SentryWrapResult["AlreadyWrapped"] = "AlreadyWrapped";
|
|
144
|
+
SentryWrapResult["Success"] = "Success";
|
|
145
|
+
})(SentryWrapResult = exports.SentryWrapResult || (exports.SentryWrapResult = {}));
|
|
146
|
+
function checkAndWrapRootComponent(mod) {
|
|
147
|
+
if (doesContainSentryWrap(mod.$ast)) {
|
|
148
|
+
return SentryWrapResult.AlreadyWrapped;
|
|
149
|
+
}
|
|
150
|
+
const defaultExport = getDefaultExport(mod.$ast);
|
|
151
|
+
if (!defaultExport) {
|
|
152
|
+
return SentryWrapResult.NotFound;
|
|
153
|
+
}
|
|
154
|
+
const wrappedConfig = wrapWithSentry(defaultExport);
|
|
155
|
+
const replacedDefaultExport = replaceDefaultExport(mod.$ast, wrappedConfig);
|
|
156
|
+
if (!replacedDefaultExport) {
|
|
157
|
+
return SentryWrapResult.NotFound;
|
|
158
|
+
}
|
|
159
|
+
return SentryWrapResult.Success;
|
|
160
|
+
}
|
|
161
|
+
exports.checkAndWrapRootComponent = checkAndWrapRootComponent;
|
|
162
|
+
function getDefaultExport(program) {
|
|
163
|
+
for (const node of program.body) {
|
|
164
|
+
if (t.isExportDefaultDeclaration(node) &&
|
|
165
|
+
(t.isIdentifier(node.declaration) ||
|
|
166
|
+
t.isCallExpression(node.declaration) ||
|
|
167
|
+
t.isObjectExpression(node.declaration) ||
|
|
168
|
+
t.isFunctionDeclaration(node.declaration) ||
|
|
169
|
+
t.isArrowFunctionExpression(node.declaration) ||
|
|
170
|
+
t.isClassDeclaration(node.declaration))) {
|
|
171
|
+
Sentry.setTag('app-js-file-status', 'default-export');
|
|
172
|
+
return node.declaration;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
Sentry.setTag('app-js-file-status', 'default-export-not-found');
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
exports.getDefaultExport = getDefaultExport;
|
|
179
|
+
function wrapWithSentry(configObj) {
|
|
180
|
+
if (t.isFunctionDeclaration(configObj)) {
|
|
181
|
+
return t.callExpression(t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')), [
|
|
182
|
+
t.functionExpression(configObj.id, configObj.params, configObj.body, configObj.generator, configObj.async),
|
|
183
|
+
]);
|
|
184
|
+
}
|
|
185
|
+
if (t.isArrowFunctionExpression(configObj)) {
|
|
186
|
+
return t.callExpression(t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')), [configObj]);
|
|
187
|
+
}
|
|
188
|
+
if (t.isClassDeclaration(configObj)) {
|
|
189
|
+
return t.callExpression(t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')), [
|
|
190
|
+
t.classExpression(configObj.id, configObj.superClass, configObj.body, configObj.decorators),
|
|
191
|
+
]);
|
|
192
|
+
}
|
|
193
|
+
return t.callExpression(t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')), [configObj]);
|
|
194
|
+
}
|
|
195
|
+
exports.wrapWithSentry = wrapWithSentry;
|
|
196
|
+
function replaceDefaultExport(program, wrappedDefaultExport) {
|
|
197
|
+
for (const node of program.body) {
|
|
198
|
+
if (t.isExportDefaultDeclaration(node)) {
|
|
199
|
+
node.declaration = wrappedDefaultExport;
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
exports.replaceDefaultExport = replaceDefaultExport;
|
|
206
|
+
function doesContainSentryWrap(program) {
|
|
207
|
+
for (const node of program.body) {
|
|
208
|
+
if (t.isExportDefaultDeclaration(node)) {
|
|
209
|
+
const declaration = node.declaration;
|
|
210
|
+
if (t.isCallExpression(declaration)) {
|
|
211
|
+
const callExpr = declaration;
|
|
212
|
+
if (t.isMemberExpression(callExpr.callee)) {
|
|
213
|
+
const callee = callExpr.callee;
|
|
214
|
+
if (t.isIdentifier(callee.object) &&
|
|
215
|
+
callee.object.name === 'Sentry' &&
|
|
216
|
+
t.isIdentifier(callee.property) &&
|
|
217
|
+
callee.property.name === 'wrap') {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
exports.doesContainSentryWrap = doesContainSentryWrap;
|
|
227
|
+
function getSentryWrapColoredCodeSnippet() {
|
|
228
|
+
return (0, clack_utils_1.makeCodeSnippet)(true, (_unchanged, plus, _minus) => {
|
|
229
|
+
return plus(`import * as Sentry from '@sentry/react-native';
|
|
230
|
+
|
|
231
|
+
export default Sentry.wrap(App);`);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
99
234
|
//# sourceMappingURL=javascript.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"javascript.js","sourceRoot":"","sources":["../../../src/react-native/javascript.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport * as process from 'process';\nimport * as fs from 'fs';\nimport * as Sentry from '@sentry/node';\n\nimport { traceStep } from '../telemetry';\nimport {\n makeCodeSnippet,\n showCopyPasteInstructions,\n} from '../utils/clack-utils';\nimport { getFirstMatchedPath } from './glob';\nimport { RN_SDK_PACKAGE } from './react-native-wizard';\n\nexport async function addSentryInit({ dsn }: { dsn: string }) {\n const prefixGlob = '{.,./src,./app}';\n const suffixGlob = '@(j|t|cj|mj)s?(x)';\n const universalGlob = `@(App|_layout).${suffixGlob}`;\n const jsFileGlob = `${prefixGlob}/+(${universalGlob})`;\n const jsPath = traceStep('find-app-js-file', () =>\n getFirstMatchedPath(jsFileGlob),\n );\n Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');\n if (!jsPath) {\n clack.log.warn(\n `Could not find main App file. Place the following code snippet close to the Apps Root component.`,\n );\n await showCopyPasteInstructions(\n 'App.js or _layout.tsx',\n getSentryInitColoredCodeSnippet(dsn),\n 'This ensures the Sentry SDK is ready to capture errors.',\n );\n return;\n }\n const jsRelativePath = path.relative(process.cwd(), jsPath);\n\n const js = fs.readFileSync(jsPath, 'utf-8');\n const includesSentry = doesJsCodeIncludeSdkSentryImport(js, {\n sdkPackageName: RN_SDK_PACKAGE,\n });\n if (includesSentry) {\n Sentry.setTag('app-js-file-status', 'already-includes-sentry');\n clack.log.warn(\n `${chalk.cyan(\n jsRelativePath,\n )} already includes Sentry. We wont't add it again.`,\n );\n return;\n }\n\n traceStep('add-sentry-init', () => {\n const newContent = addSentryInitWithSdkImport(js, { dsn });\n\n clack.log.success(\n `Added ${chalk.cyan('Sentry.init')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n\n fs.writeFileSync(jsPath, newContent, 'utf-8');\n });\n\n Sentry.setTag('app-js-file-status', 'added-sentry-init');\n clack.log.success(\n chalk.green(`${chalk.cyan(jsRelativePath)} changes saved.`),\n );\n}\n\nexport function addSentryInitWithSdkImport(\n js: string,\n { dsn }: { dsn: string },\n): string {\n return js.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n (match: string) => `${match}\n${getSentryInitPlainTextSnippet(dsn)}`,\n );\n}\n\nexport function doesJsCodeIncludeSdkSentryImport(\n js: string,\n { sdkPackageName }: { sdkPackageName: string },\n): boolean {\n return !!js.match(sdkPackageName);\n}\n\nexport function getSentryInitColoredCodeSnippet(dsn: string) {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(getSentryInitPlainTextSnippet(dsn));\n });\n}\n\nexport function getSentryInitPlainTextSnippet(dsn: string) {\n return `import * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: '${dsn}',\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"javascript.js","sourceRoot":"","sources":["../../../src/react-native/javascript.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport * as process from 'process';\nimport * as fs from 'fs';\nimport * as Sentry from '@sentry/node';\n\nimport { traceStep } from '../telemetry';\nimport {\n makeCodeSnippet,\n showCopyPasteInstructions,\n} from '../utils/clack-utils';\nimport { getFirstMatchedPath } from './glob';\nimport { RN_SDK_PACKAGE } from './react-native-wizard';\n\n// @ts-ignore - magicast is ESM and TS complains about that. It works though\nimport { generateCode, ProxifiedModule, parseModule } from 'magicast';\nimport * as t from '@babel/types';\n\nexport async function addSentryInit({ dsn }: { dsn: string }) {\n const jsPath = getMainAppFilePath();\n Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');\n if (!jsPath) {\n clack.log.warn(\n `Could not find main App file. Place the following code snippet close to the Apps Root component.`,\n );\n await showCopyPasteInstructions(\n 'App.js or _layout.tsx',\n getSentryInitColoredCodeSnippet(dsn),\n 'This ensures the Sentry SDK is ready to capture errors.',\n );\n return;\n }\n const jsRelativePath = path.relative(process.cwd(), jsPath);\n\n const js = fs.readFileSync(jsPath, 'utf-8');\n const includesSentry = doesJsCodeIncludeSdkSentryImport(js, {\n sdkPackageName: RN_SDK_PACKAGE,\n });\n if (includesSentry) {\n Sentry.setTag('app-js-file-status', 'already-includes-sentry');\n clack.log.warn(\n `${chalk.cyan(\n jsRelativePath,\n )} already includes Sentry. We wont't add it again.`,\n );\n return;\n }\n\n traceStep('add-sentry-init', () => {\n const newContent = addSentryInitWithSdkImport(js, { dsn });\n\n clack.log.success(\n `Added ${chalk.cyan('Sentry.init')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n\n fs.writeFileSync(jsPath, newContent, 'utf-8');\n });\n\n Sentry.setTag('app-js-file-status', 'added-sentry-init');\n clack.log.success(\n chalk.green(`${chalk.cyan(jsRelativePath)} changes saved.`),\n );\n}\n\nexport function addSentryInitWithSdkImport(\n js: string,\n { dsn }: { dsn: string },\n): string {\n return js.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n (match: string) => `${match}\n${getSentryInitPlainTextSnippet(dsn)}`,\n );\n}\n\nexport function doesJsCodeIncludeSdkSentryImport(\n js: string,\n { sdkPackageName }: { sdkPackageName: string },\n): boolean {\n return !!js.match(sdkPackageName);\n}\n\nexport function getSentryInitColoredCodeSnippet(dsn: string) {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(getSentryInitPlainTextSnippet(dsn));\n });\n}\n\nexport function getSentryInitPlainTextSnippet(dsn: string) {\n return `import * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: '${dsn}',\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});`;\n}\n\nfunction getMainAppFilePath(): string | undefined {\n const prefixGlob = '{.,./src,./app}';\n const suffixGlob = '@(j|t|cj|mj)s?(x)';\n const universalGlob = `@(App|_layout).${suffixGlob}`;\n const jsFileGlob = `${prefixGlob}/+(${universalGlob})`;\n const jsPath = traceStep('find-app-js-file', () =>\n getFirstMatchedPath(jsFileGlob),\n );\n return jsPath;\n}\n\n/**\n * This step should be executed after `addSentryInit`\n */\nexport async function wrapRootComponent() {\n const showInstructions = () =>\n showCopyPasteInstructions(\n 'App.js or _layout.tsx',\n getSentryWrapColoredCodeSnippet(),\n );\n\n const jsPath = getMainAppFilePath();\n Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');\n if (!jsPath) {\n clack.log.warn(\n `Could not find main App file. Please wrap your App's Root component.`,\n );\n await showInstructions();\n return;\n }\n\n const jsRelativePath = path.relative(process.cwd(), jsPath);\n\n const js = fs.readFileSync(jsPath, 'utf-8');\n\n const mod = parseModule(js);\n const result = checkAndWrapRootComponent(mod);\n\n if (result === SentryWrapResult.AlreadyWrapped) {\n Sentry.setTag('app-js-file-status', 'already-includes-sentry-wrap');\n clack.log.warn(\n `${chalk.cyan(\n jsRelativePath,\n )} already includes Sentry.wrap. We wont't add it again.`,\n );\n return;\n }\n\n if (result === SentryWrapResult.NotFound) {\n clack.log.warn(\n `Could not find your App's Root component. Please wrap your App's Root component manually.`,\n );\n await showInstructions();\n return;\n }\n\n traceStep('add-sentry-wrap', () => {\n clack.log.success(\n `Added ${chalk.cyan('Sentry.wrap')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n\n fs.writeFileSync(jsPath, generateCode(mod.$ast).code, 'utf-8');\n });\n\n Sentry.setTag('app-js-file-status', 'added-sentry-wrap');\n clack.log.success(\n chalk.green(`${chalk.cyan(jsRelativePath)} changes saved.`),\n );\n}\n\nexport enum SentryWrapResult {\n NotFound = 'RootComponentNotFound',\n AlreadyWrapped = 'AlreadyWrapped',\n Success = 'Success',\n}\n\nexport function checkAndWrapRootComponent(\n mod: ProxifiedModule,\n): SentryWrapResult {\n if (doesContainSentryWrap(mod.$ast as t.Program)) {\n return SentryWrapResult.AlreadyWrapped;\n }\n\n const defaultExport = getDefaultExport(mod.$ast as t.Program);\n if (!defaultExport) {\n return SentryWrapResult.NotFound;\n }\n\n const wrappedConfig = wrapWithSentry(defaultExport);\n\n const replacedDefaultExport = replaceDefaultExport(\n mod.$ast as t.Program,\n wrappedConfig,\n );\n\n if (!replacedDefaultExport) {\n return SentryWrapResult.NotFound;\n }\n\n return SentryWrapResult.Success;\n}\n\nexport function getDefaultExport(\n program: t.Program,\n):\n | t.Identifier\n | t.CallExpression\n | t.ObjectExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression\n | t.ClassDeclaration\n | undefined {\n for (const node of program.body) {\n if (\n t.isExportDefaultDeclaration(node) &&\n (t.isIdentifier(node.declaration) ||\n t.isCallExpression(node.declaration) ||\n t.isObjectExpression(node.declaration) ||\n t.isFunctionDeclaration(node.declaration) ||\n t.isArrowFunctionExpression(node.declaration) ||\n t.isClassDeclaration(node.declaration))\n ) {\n Sentry.setTag('app-js-file-status', 'default-export');\n return node.declaration;\n }\n }\n\n Sentry.setTag('app-js-file-status', 'default-export-not-found');\n return undefined;\n}\n\nexport function wrapWithSentry(\n configObj:\n | t.Identifier\n | t.CallExpression\n | t.ObjectExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression\n | t.ClassDeclaration,\n): t.CallExpression {\n if (t.isFunctionDeclaration(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [\n t.functionExpression(\n configObj.id,\n configObj.params,\n configObj.body,\n configObj.generator,\n configObj.async,\n ),\n ],\n );\n }\n\n if (t.isArrowFunctionExpression(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [configObj],\n );\n }\n\n if (t.isClassDeclaration(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [\n t.classExpression(\n configObj.id,\n configObj.superClass,\n configObj.body,\n configObj.decorators,\n ),\n ],\n );\n }\n\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [configObj],\n );\n}\n\nexport function replaceDefaultExport(\n program: t.Program,\n wrappedDefaultExport: t.CallExpression,\n): boolean {\n for (const node of program.body) {\n if (t.isExportDefaultDeclaration(node)) {\n node.declaration = wrappedDefaultExport;\n return true;\n }\n }\n return false;\n}\n\nexport function doesContainSentryWrap(program: t.Program): boolean {\n for (const node of program.body) {\n if (t.isExportDefaultDeclaration(node)) {\n const declaration = node.declaration;\n if (t.isCallExpression(declaration)) {\n const callExpr = declaration;\n if (t.isMemberExpression(callExpr.callee)) {\n const callee = callExpr.callee;\n if (\n t.isIdentifier(callee.object) &&\n callee.object.name === 'Sentry' &&\n t.isIdentifier(callee.property) &&\n callee.property.name === 'wrap'\n ) {\n return true;\n }\n }\n }\n }\n }\n return false;\n}\n\nfunction getSentryWrapColoredCodeSnippet() {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(`import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(App);`);\n });\n}\n"]}
|
|
@@ -163,6 +163,7 @@ Or setup using ${chalk_1.default.cyan('https://docs.sentry.io/platforms/react-na
|
|
|
163
163
|
url: sentryUrl,
|
|
164
164
|
};
|
|
165
165
|
await (0, telemetry_1.traceStep)('patch-app-js', () => (0, javascript_1.addSentryInit)({ dsn: selectedProject.keys[0].dsn.public }));
|
|
166
|
+
await (0, telemetry_1.traceStep)('patch-app-js-wrap', () => (0, javascript_1.wrapRootComponent)());
|
|
166
167
|
if (isExpo) {
|
|
167
168
|
await (0, telemetry_1.traceStep)('patch-expo-app-config', () => (0, expo_1.patchExpoAppConfig)(cliConfig));
|
|
168
169
|
await (0, telemetry_1.traceStep)('add-expo-env-local', () => (0, expo_env_file_1.addExpoEnvLocal)(cliConfig));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native-wizard.js","sourceRoot":"","sources":["../../../src/react-native/react-native-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as fs from 'fs';\n\nimport {\n CliSetupConfigContent,\n abortIfCancelled,\n addSentryCliConfig,\n confirmContinueIfNoOrDirtyGitRepo,\n confirmContinueIfPackageVersionNotSupported,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n printWelcome,\n propertiesCliSetupConfig,\n runPrettierIfInstalled,\n abort,\n} from '../utils/clack-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport { podInstall } from '../apple/cocoapod';\nimport { platform } from 'os';\nimport {\n getValidExistingBuildPhases,\n findBundlePhase,\n patchBundlePhase,\n findDebugFilesUploadPhase,\n addDebugFilesUploadPhaseWithCli,\n writeXcodeProject,\n addSentryWithCliToBundleShellScript,\n addSentryWithBundledScriptsToBundleShellScript,\n addDebugFilesUploadPhaseWithBundledScripts,\n} from './xcode';\nimport {\n doesAppBuildGradleIncludeRNSentryGradlePlugin,\n addRNSentryGradlePlugin,\n writeAppBuildGradle,\n} from './gradle';\nimport { runReactNativeUninstall } from './uninstall';\nimport { APP_BUILD_GRADLE, XCODE_PROJECT, getFirstMatchedPath } from './glob';\nimport { ReactNativeWizardOptions } from './options';\nimport { addSentryInit } from './javascript';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport * as Sentry from '@sentry/node';\nimport { fulfillsVersionRange } from '../utils/semver';\nimport { getIssueStreamUrl } from '../utils/url';\nimport {\n patchMetroConfigWithSentrySerializer,\n patchMetroWithSentryConfig,\n} from './metro';\nimport { patchExpoAppConfig, printSentryExpoMigrationOutro } from './expo';\nimport { addSentryToExpoMetroConfig } from './expo-metro';\nimport { addExpoEnvLocal } from './expo-env-file';\n\nimport xcode from 'xcode';\n\nexport const RN_SDK_PACKAGE = '@sentry/react-native';\nexport const RN_SDK_SUPPORTED_RANGE = '>=5.0.0';\n\nexport const RN_PACKAGE = 'react-native';\nexport const RN_HUMAN_NAME = 'React Native';\n\nexport const SUPPORTED_RN_RANGE = '>=0.69.0';\nexport const SUPPORTED_EXPO_RANGE = '>=50.0.0';\n\n/**\n * The following SDK version ship with bundled Xcode scripts\n * which simplifies the Xcode Build Phases setup.\n */\nexport const XCODE_SCRIPTS_SUPPORTED_SDK_RANGE = '>=5.11.0';\n\n/**\n * The following SDK version ship with Sentry Metro plugin\n */\nexport const SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE = '>=5.11.0';\n\n/**\n * The following SDK version ship with bundled Expo plugin\n */\nexport const EXPO_SUPPORTED_SDK_RANGE = `>=5.16.0`;\n\n// The following SDK version shipped `withSentryConfig`\nexport const METRO_WITH_SENTRY_CONFIG_SUPPORTED_SDK_RANGE = '>=5.17.0';\n\nexport type RNCliSetupConfigContent = Pick<\n Required<CliSetupConfigContent>,\n 'authToken' | 'org' | 'project' | 'url'\n>;\n\nexport async function runReactNativeWizard(\n params: ReactNativeWizardOptions,\n): Promise<void> {\n return withTelemetry(\n {\n enabled: params.telemetryEnabled,\n integration: 'react-native',\n wizardOptions: params,\n },\n () => runReactNativeWizardWithTelemetry(params),\n );\n}\n\nexport async function runReactNativeWizardWithTelemetry(\n options: ReactNativeWizardOptions,\n): Promise<void> {\n if (options.uninstall) {\n Sentry.setTag('uninstall', true);\n return runReactNativeUninstall(options);\n }\n\n const { promoCode, telemetryEnabled, forceInstall } = options;\n\n printWelcome({\n wizardName: 'Sentry React Native Wizard',\n promoCode,\n telemetryEnabled,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo();\n\n const packageJson = await getPackageDotJson();\n const hasInstalled = (dep: string) => hasPackageInstalled(dep, packageJson);\n\n if (hasInstalled('sentry-expo')) {\n Sentry.setTag('has-sentry-expo-installed', true);\n printSentryExpoMigrationOutro();\n return;\n }\n\n await ensurePackageIsInstalled(packageJson, RN_PACKAGE, RN_HUMAN_NAME);\n\n const rnVersion = getPackageVersion(RN_PACKAGE, packageJson);\n if (rnVersion) {\n await confirmContinueIfPackageVersionNotSupported({\n packageName: RN_HUMAN_NAME,\n packageVersion: rnVersion,\n packageId: RN_PACKAGE,\n acceptableVersions: SUPPORTED_RN_RANGE,\n note: `Please upgrade to ${SUPPORTED_RN_RANGE} if you wish to use the Sentry Wizard.\nOr setup using ${chalk.cyan(\n 'https://docs.sentry.io/platforms/react-native/manual-setup/manual-setup/',\n )}`,\n });\n }\n\n await installPackage({\n packageName: RN_SDK_PACKAGE,\n alreadyInstalled: hasPackageInstalled(RN_SDK_PACKAGE, packageJson),\n forceInstall,\n });\n const sdkVersion = getPackageVersion(\n RN_SDK_PACKAGE,\n await getPackageDotJson(),\n );\n if (sdkVersion) {\n await confirmContinueIfPackageVersionNotSupported({\n packageName: 'Sentry React Native SDK',\n packageVersion: sdkVersion,\n packageId: RN_SDK_PACKAGE,\n acceptableVersions: RN_SDK_SUPPORTED_RANGE,\n note: `Please upgrade to ${RN_SDK_SUPPORTED_RANGE} to continue with the wizard in this project.`,\n });\n } else {\n const continueWithoutSdk = await abortIfCancelled(\n clack.confirm({\n message:\n 'Could not detect Sentry React Native SDK version. Do you want to continue anyway?',\n }),\n );\n if (!continueWithoutSdk) {\n await abort(undefined, 0);\n }\n }\n Sentry.setTag(`detected-sentry-react-native-sdk-version`, sdkVersion);\n\n const expoVersion = getPackageVersion('expo', packageJson);\n const isExpo = !!expoVersion;\n if (expoVersion && sdkVersion) {\n await confirmContinueIfPackageVersionNotSupported({\n packageName: 'Sentry React Native SDK',\n packageVersion: sdkVersion,\n packageId: RN_SDK_PACKAGE,\n acceptableVersions: EXPO_SUPPORTED_SDK_RANGE,\n note: `Please upgrade to ${EXPO_SUPPORTED_SDK_RANGE} to continue with the wizard in this Expo project.`,\n });\n await confirmContinueIfPackageVersionNotSupported({\n packageName: 'Expo SDK',\n packageVersion: expoVersion,\n packageId: 'expo',\n acceptableVersions: SUPPORTED_EXPO_RANGE,\n note: `Please upgrade to ${SUPPORTED_EXPO_RANGE} to continue with the wizard in this Expo project.`,\n });\n }\n\n const { selectedProject, authToken, sentryUrl } =\n await getOrAskForProjectData(options, 'react-native');\n const orgSlug = selectedProject.organization.slug;\n const projectSlug = selectedProject.slug;\n const projectId = selectedProject.id;\n const cliConfig: RNCliSetupConfigContent = {\n authToken,\n org: orgSlug,\n project: projectSlug,\n url: sentryUrl,\n };\n\n await traceStep('patch-app-js', () =>\n addSentryInit({ dsn: selectedProject.keys[0].dsn.public }),\n );\n\n if (isExpo) {\n await traceStep('patch-expo-app-config', () =>\n patchExpoAppConfig(cliConfig),\n );\n await traceStep('add-expo-env-local', () => addExpoEnvLocal(cliConfig));\n }\n\n if (isExpo) {\n await traceStep('patch-metro-config', addSentryToExpoMetroConfig);\n } else {\n await traceStep('patch-metro-config', () =>\n addSentryToMetroConfig({ sdkVersion }),\n );\n }\n\n if (fs.existsSync('ios')) {\n Sentry.setTag('patch-ios', true);\n await traceStep('patch-xcode-files', () =>\n patchXcodeFiles(cliConfig, { sdkVersion }),\n );\n }\n\n if (fs.existsSync('android')) {\n Sentry.setTag('patch-android', true);\n await traceStep('patch-android-files', () => patchAndroidFiles(cliConfig));\n }\n\n await runPrettierIfInstalled();\n\n const confirmedFirstException = await confirmFirstSentryException(\n sentryUrl,\n orgSlug,\n projectId,\n );\n\n Sentry.setTag('user-confirmed-first-error', confirmedFirstException);\n\n if (confirmedFirstException) {\n clack.outro(\n `${chalk.green('Everything is set up!')}\n\n ${chalk.dim(\n 'If you encounter any issues, let us know here: https://github.com/getsentry/sentry-react-native/issues',\n )}`,\n );\n } else {\n clack.outro(\n `${chalk.dim(\n 'Let us know here: https://github.com/getsentry/sentry-react-native/issues',\n )}`,\n );\n }\n}\n\nfunction addSentryToMetroConfig({\n sdkVersion,\n}: {\n sdkVersion: string | undefined;\n}) {\n if (\n sdkVersion &&\n fulfillsVersionRange({\n version: sdkVersion,\n acceptableVersions: METRO_WITH_SENTRY_CONFIG_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n return patchMetroWithSentryConfig();\n }\n\n if (\n sdkVersion &&\n fulfillsVersionRange({\n version: sdkVersion,\n acceptableVersions: SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n return patchMetroConfigWithSentrySerializer();\n }\n}\n\nasync function confirmFirstSentryException(\n url: string,\n orgSlug: string,\n projectId: string,\n) {\n const issuesStreamUrl = getIssueStreamUrl({ url, orgSlug, projectId });\n\n clack.log\n .step(`To make sure everything is set up correctly, put the following code snippet into your application.\nThe snippet will create a button that, when tapped, sends a test event to Sentry.\n\nAfter that check your project issues:\n\n${chalk.cyan(issuesStreamUrl)}`);\n\n // We want the code snippet to be easily copy-pasteable, without any clack artifacts\n // eslint-disable-next-line no-console\n console.log(\n chalk.greenBright(`\n<Button title='Try!' onPress={ () => { Sentry.captureException(new Error('First error')) }}/>\n`),\n );\n\n const firstErrorConfirmed = clack.confirm({\n message: `Have you successfully sent a test event?`,\n });\n\n return firstErrorConfirmed;\n}\n\nasync function patchXcodeFiles(\n config: RNCliSetupConfigContent,\n context: {\n sdkVersion: string | undefined;\n },\n) {\n await addSentryCliConfig(config, {\n ...propertiesCliSetupConfig,\n name: 'source maps and iOS debug files',\n filename: 'ios/sentry.properties',\n gitignore: false,\n });\n\n if (platform() === 'darwin' && (await confirmPodInstall())) {\n await traceStep('pod-install', () => podInstall('ios'));\n }\n\n const xcodeProjectPath = traceStep('find-xcode-project', () =>\n getFirstMatchedPath(XCODE_PROJECT),\n );\n Sentry.setTag(\n 'xcode-project-status',\n xcodeProjectPath ? 'found' : 'not-found',\n );\n if (!xcodeProjectPath) {\n clack.log.warn(\n `Could not find Xcode project file using ${chalk.cyan(XCODE_PROJECT)}.`,\n );\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const [xcodeProject, buildPhasesMap] = traceStep(\n 'parse-xcode-project',\n () => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const project = xcode.project(xcodeProjectPath);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n project.parseSync();\n\n const map = getValidExistingBuildPhases(project);\n return [project, map];\n },\n );\n Sentry.setTag('xcode-project-status', 'parsed');\n\n traceStep('patch-bundle-phase', () => {\n const bundlePhase = findBundlePhase(buildPhasesMap);\n Sentry.setTag(\n 'xcode-bundle-phase-status',\n bundlePhase ? 'found' : 'not-found',\n );\n if (\n context.sdkVersion &&\n fulfillsVersionRange({\n version: context.sdkVersion,\n acceptableVersions: XCODE_SCRIPTS_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n patchBundlePhase(\n bundlePhase,\n addSentryWithBundledScriptsToBundleShellScript,\n );\n } else {\n patchBundlePhase(bundlePhase, addSentryWithCliToBundleShellScript);\n }\n Sentry.setTag('xcode-bundle-phase-status', 'patched');\n });\n\n traceStep('add-debug-files-upload-phase', () => {\n const debugFilesUploadPhaseExists =\n !!findDebugFilesUploadPhase(buildPhasesMap);\n Sentry.setTag(\n 'xcode-debug-files-upload-phase-status',\n debugFilesUploadPhaseExists ? 'already-exists' : undefined,\n );\n if (\n context.sdkVersion &&\n fulfillsVersionRange({\n version: context.sdkVersion,\n acceptableVersions: XCODE_SCRIPTS_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n addDebugFilesUploadPhaseWithBundledScripts(xcodeProject, {\n debugFilesUploadPhaseExists,\n });\n } else {\n addDebugFilesUploadPhaseWithCli(xcodeProject, {\n debugFilesUploadPhaseExists,\n });\n }\n Sentry.setTag('xcode-debug-files-upload-phase-status', 'added');\n });\n\n traceStep('write-xcode-project', () => {\n writeXcodeProject(xcodeProjectPath, xcodeProject);\n });\n Sentry.setTag('xcode-project-status', 'patched');\n}\n\nasync function patchAndroidFiles(config: RNCliSetupConfigContent) {\n await addSentryCliConfig(config, {\n ...propertiesCliSetupConfig,\n name: 'source maps and iOS debug files',\n filename: 'android/sentry.properties',\n gitignore: false,\n });\n\n const appBuildGradlePath = traceStep('find-app-build-gradle', () =>\n getFirstMatchedPath(APP_BUILD_GRADLE),\n );\n Sentry.setTag(\n 'app-build-gradle-status',\n appBuildGradlePath ? 'found' : 'not-found',\n );\n if (!appBuildGradlePath) {\n clack.log.warn(\n `Could not find Android ${chalk.cyan(\n 'app/build.gradle',\n )} file using ${chalk.cyan(APP_BUILD_GRADLE)}.`,\n );\n return;\n }\n\n const appBuildGradle = traceStep('read-app-build-gradle', () =>\n fs.readFileSync(appBuildGradlePath, 'utf-8'),\n );\n const includesSentry =\n doesAppBuildGradleIncludeRNSentryGradlePlugin(appBuildGradle);\n if (includesSentry) {\n Sentry.setTag('app-build-gradle-status', 'already-includes-sentry');\n clack.log.warn(\n `Android ${chalk.cyan('app/build.gradle')} file already includes Sentry.`,\n );\n return;\n }\n\n const patchedAppBuildGradle = traceStep('add-rn-sentry-gradle-plugin', () =>\n addRNSentryGradlePlugin(appBuildGradle),\n );\n if (!doesAppBuildGradleIncludeRNSentryGradlePlugin(patchedAppBuildGradle)) {\n Sentry.setTag(\n 'app-build-gradle-status',\n 'failed-to-add-rn-sentry-gradle-plugin',\n );\n clack.log.warn(\n `Could not add Sentry RN Gradle Plugin to ${chalk.cyan(\n 'app/build.gradle',\n )}.`,\n );\n return;\n }\n\n Sentry.setTag('app-build-gradle-status', 'added-rn-sentry-gradle-plugin');\n clack.log.success(\n `Added Sentry RN Gradle Plugin to ${chalk.bold('app/build.gradle')}.`,\n );\n\n traceStep('write-app-build-gradle', () =>\n writeAppBuildGradle(appBuildGradlePath, patchedAppBuildGradle),\n );\n clack.log.success(\n chalk.green(`Android ${chalk.cyan('app/build.gradle')} saved.`),\n );\n}\n\nasync function confirmPodInstall(): Promise<boolean> {\n return traceStep('confirm-pod-install', async () => {\n const continueWithPodInstall = await abortIfCancelled(\n clack.select({\n message: 'Do you want to run `pod install` now?',\n options: [\n {\n value: true,\n label: 'Yes',\n hint: 'Recommended for smaller projects, this might take several minutes',\n },\n { value: false, label: `No, I'll do it later` },\n ],\n initialValue: true,\n }),\n );\n Sentry.setTag('continue-with-pod-install', continueWithPodInstall);\n return continueWithPodInstall;\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"react-native-wizard.js","sourceRoot":"","sources":["../../../src/react-native/react-native-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as fs from 'fs';\n\nimport {\n CliSetupConfigContent,\n abortIfCancelled,\n addSentryCliConfig,\n confirmContinueIfNoOrDirtyGitRepo,\n confirmContinueIfPackageVersionNotSupported,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n printWelcome,\n propertiesCliSetupConfig,\n runPrettierIfInstalled,\n abort,\n} from '../utils/clack-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport { podInstall } from '../apple/cocoapod';\nimport { platform } from 'os';\nimport {\n getValidExistingBuildPhases,\n findBundlePhase,\n patchBundlePhase,\n findDebugFilesUploadPhase,\n addDebugFilesUploadPhaseWithCli,\n writeXcodeProject,\n addSentryWithCliToBundleShellScript,\n addSentryWithBundledScriptsToBundleShellScript,\n addDebugFilesUploadPhaseWithBundledScripts,\n} from './xcode';\nimport {\n doesAppBuildGradleIncludeRNSentryGradlePlugin,\n addRNSentryGradlePlugin,\n writeAppBuildGradle,\n} from './gradle';\nimport { runReactNativeUninstall } from './uninstall';\nimport { APP_BUILD_GRADLE, XCODE_PROJECT, getFirstMatchedPath } from './glob';\nimport { ReactNativeWizardOptions } from './options';\nimport { addSentryInit, wrapRootComponent } from './javascript';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport * as Sentry from '@sentry/node';\nimport { fulfillsVersionRange } from '../utils/semver';\nimport { getIssueStreamUrl } from '../utils/url';\nimport {\n patchMetroConfigWithSentrySerializer,\n patchMetroWithSentryConfig,\n} from './metro';\nimport { patchExpoAppConfig, printSentryExpoMigrationOutro } from './expo';\nimport { addSentryToExpoMetroConfig } from './expo-metro';\nimport { addExpoEnvLocal } from './expo-env-file';\n\nimport xcode from 'xcode';\n\nexport const RN_SDK_PACKAGE = '@sentry/react-native';\nexport const RN_SDK_SUPPORTED_RANGE = '>=5.0.0';\n\nexport const RN_PACKAGE = 'react-native';\nexport const RN_HUMAN_NAME = 'React Native';\n\nexport const SUPPORTED_RN_RANGE = '>=0.69.0';\nexport const SUPPORTED_EXPO_RANGE = '>=50.0.0';\n\n/**\n * The following SDK version ship with bundled Xcode scripts\n * which simplifies the Xcode Build Phases setup.\n */\nexport const XCODE_SCRIPTS_SUPPORTED_SDK_RANGE = '>=5.11.0';\n\n/**\n * The following SDK version ship with Sentry Metro plugin\n */\nexport const SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE = '>=5.11.0';\n\n/**\n * The following SDK version ship with bundled Expo plugin\n */\nexport const EXPO_SUPPORTED_SDK_RANGE = `>=5.16.0`;\n\n// The following SDK version shipped `withSentryConfig`\nexport const METRO_WITH_SENTRY_CONFIG_SUPPORTED_SDK_RANGE = '>=5.17.0';\n\nexport type RNCliSetupConfigContent = Pick<\n Required<CliSetupConfigContent>,\n 'authToken' | 'org' | 'project' | 'url'\n>;\n\nexport async function runReactNativeWizard(\n params: ReactNativeWizardOptions,\n): Promise<void> {\n return withTelemetry(\n {\n enabled: params.telemetryEnabled,\n integration: 'react-native',\n wizardOptions: params,\n },\n () => runReactNativeWizardWithTelemetry(params),\n );\n}\n\nexport async function runReactNativeWizardWithTelemetry(\n options: ReactNativeWizardOptions,\n): Promise<void> {\n if (options.uninstall) {\n Sentry.setTag('uninstall', true);\n return runReactNativeUninstall(options);\n }\n\n const { promoCode, telemetryEnabled, forceInstall } = options;\n\n printWelcome({\n wizardName: 'Sentry React Native Wizard',\n promoCode,\n telemetryEnabled,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo();\n\n const packageJson = await getPackageDotJson();\n const hasInstalled = (dep: string) => hasPackageInstalled(dep, packageJson);\n\n if (hasInstalled('sentry-expo')) {\n Sentry.setTag('has-sentry-expo-installed', true);\n printSentryExpoMigrationOutro();\n return;\n }\n\n await ensurePackageIsInstalled(packageJson, RN_PACKAGE, RN_HUMAN_NAME);\n\n const rnVersion = getPackageVersion(RN_PACKAGE, packageJson);\n if (rnVersion) {\n await confirmContinueIfPackageVersionNotSupported({\n packageName: RN_HUMAN_NAME,\n packageVersion: rnVersion,\n packageId: RN_PACKAGE,\n acceptableVersions: SUPPORTED_RN_RANGE,\n note: `Please upgrade to ${SUPPORTED_RN_RANGE} if you wish to use the Sentry Wizard.\nOr setup using ${chalk.cyan(\n 'https://docs.sentry.io/platforms/react-native/manual-setup/manual-setup/',\n )}`,\n });\n }\n\n await installPackage({\n packageName: RN_SDK_PACKAGE,\n alreadyInstalled: hasPackageInstalled(RN_SDK_PACKAGE, packageJson),\n forceInstall,\n });\n const sdkVersion = getPackageVersion(\n RN_SDK_PACKAGE,\n await getPackageDotJson(),\n );\n if (sdkVersion) {\n await confirmContinueIfPackageVersionNotSupported({\n packageName: 'Sentry React Native SDK',\n packageVersion: sdkVersion,\n packageId: RN_SDK_PACKAGE,\n acceptableVersions: RN_SDK_SUPPORTED_RANGE,\n note: `Please upgrade to ${RN_SDK_SUPPORTED_RANGE} to continue with the wizard in this project.`,\n });\n } else {\n const continueWithoutSdk = await abortIfCancelled(\n clack.confirm({\n message:\n 'Could not detect Sentry React Native SDK version. Do you want to continue anyway?',\n }),\n );\n if (!continueWithoutSdk) {\n await abort(undefined, 0);\n }\n }\n Sentry.setTag(`detected-sentry-react-native-sdk-version`, sdkVersion);\n\n const expoVersion = getPackageVersion('expo', packageJson);\n const isExpo = !!expoVersion;\n if (expoVersion && sdkVersion) {\n await confirmContinueIfPackageVersionNotSupported({\n packageName: 'Sentry React Native SDK',\n packageVersion: sdkVersion,\n packageId: RN_SDK_PACKAGE,\n acceptableVersions: EXPO_SUPPORTED_SDK_RANGE,\n note: `Please upgrade to ${EXPO_SUPPORTED_SDK_RANGE} to continue with the wizard in this Expo project.`,\n });\n await confirmContinueIfPackageVersionNotSupported({\n packageName: 'Expo SDK',\n packageVersion: expoVersion,\n packageId: 'expo',\n acceptableVersions: SUPPORTED_EXPO_RANGE,\n note: `Please upgrade to ${SUPPORTED_EXPO_RANGE} to continue with the wizard in this Expo project.`,\n });\n }\n\n const { selectedProject, authToken, sentryUrl } =\n await getOrAskForProjectData(options, 'react-native');\n const orgSlug = selectedProject.organization.slug;\n const projectSlug = selectedProject.slug;\n const projectId = selectedProject.id;\n const cliConfig: RNCliSetupConfigContent = {\n authToken,\n org: orgSlug,\n project: projectSlug,\n url: sentryUrl,\n };\n\n await traceStep('patch-app-js', () =>\n addSentryInit({ dsn: selectedProject.keys[0].dsn.public }),\n );\n\n await traceStep('patch-app-js-wrap', () => wrapRootComponent());\n\n if (isExpo) {\n await traceStep('patch-expo-app-config', () =>\n patchExpoAppConfig(cliConfig),\n );\n await traceStep('add-expo-env-local', () => addExpoEnvLocal(cliConfig));\n }\n\n if (isExpo) {\n await traceStep('patch-metro-config', addSentryToExpoMetroConfig);\n } else {\n await traceStep('patch-metro-config', () =>\n addSentryToMetroConfig({ sdkVersion }),\n );\n }\n\n if (fs.existsSync('ios')) {\n Sentry.setTag('patch-ios', true);\n await traceStep('patch-xcode-files', () =>\n patchXcodeFiles(cliConfig, { sdkVersion }),\n );\n }\n\n if (fs.existsSync('android')) {\n Sentry.setTag('patch-android', true);\n await traceStep('patch-android-files', () => patchAndroidFiles(cliConfig));\n }\n\n await runPrettierIfInstalled();\n\n const confirmedFirstException = await confirmFirstSentryException(\n sentryUrl,\n orgSlug,\n projectId,\n );\n\n Sentry.setTag('user-confirmed-first-error', confirmedFirstException);\n\n if (confirmedFirstException) {\n clack.outro(\n `${chalk.green('Everything is set up!')}\n\n ${chalk.dim(\n 'If you encounter any issues, let us know here: https://github.com/getsentry/sentry-react-native/issues',\n )}`,\n );\n } else {\n clack.outro(\n `${chalk.dim(\n 'Let us know here: https://github.com/getsentry/sentry-react-native/issues',\n )}`,\n );\n }\n}\n\nfunction addSentryToMetroConfig({\n sdkVersion,\n}: {\n sdkVersion: string | undefined;\n}) {\n if (\n sdkVersion &&\n fulfillsVersionRange({\n version: sdkVersion,\n acceptableVersions: METRO_WITH_SENTRY_CONFIG_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n return patchMetroWithSentryConfig();\n }\n\n if (\n sdkVersion &&\n fulfillsVersionRange({\n version: sdkVersion,\n acceptableVersions: SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n return patchMetroConfigWithSentrySerializer();\n }\n}\n\nasync function confirmFirstSentryException(\n url: string,\n orgSlug: string,\n projectId: string,\n) {\n const issuesStreamUrl = getIssueStreamUrl({ url, orgSlug, projectId });\n\n clack.log\n .step(`To make sure everything is set up correctly, put the following code snippet into your application.\nThe snippet will create a button that, when tapped, sends a test event to Sentry.\n\nAfter that check your project issues:\n\n${chalk.cyan(issuesStreamUrl)}`);\n\n // We want the code snippet to be easily copy-pasteable, without any clack artifacts\n // eslint-disable-next-line no-console\n console.log(\n chalk.greenBright(`\n<Button title='Try!' onPress={ () => { Sentry.captureException(new Error('First error')) }}/>\n`),\n );\n\n const firstErrorConfirmed = clack.confirm({\n message: `Have you successfully sent a test event?`,\n });\n\n return firstErrorConfirmed;\n}\n\nasync function patchXcodeFiles(\n config: RNCliSetupConfigContent,\n context: {\n sdkVersion: string | undefined;\n },\n) {\n await addSentryCliConfig(config, {\n ...propertiesCliSetupConfig,\n name: 'source maps and iOS debug files',\n filename: 'ios/sentry.properties',\n gitignore: false,\n });\n\n if (platform() === 'darwin' && (await confirmPodInstall())) {\n await traceStep('pod-install', () => podInstall('ios'));\n }\n\n const xcodeProjectPath = traceStep('find-xcode-project', () =>\n getFirstMatchedPath(XCODE_PROJECT),\n );\n Sentry.setTag(\n 'xcode-project-status',\n xcodeProjectPath ? 'found' : 'not-found',\n );\n if (!xcodeProjectPath) {\n clack.log.warn(\n `Could not find Xcode project file using ${chalk.cyan(XCODE_PROJECT)}.`,\n );\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const [xcodeProject, buildPhasesMap] = traceStep(\n 'parse-xcode-project',\n () => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const project = xcode.project(xcodeProjectPath);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n project.parseSync();\n\n const map = getValidExistingBuildPhases(project);\n return [project, map];\n },\n );\n Sentry.setTag('xcode-project-status', 'parsed');\n\n traceStep('patch-bundle-phase', () => {\n const bundlePhase = findBundlePhase(buildPhasesMap);\n Sentry.setTag(\n 'xcode-bundle-phase-status',\n bundlePhase ? 'found' : 'not-found',\n );\n if (\n context.sdkVersion &&\n fulfillsVersionRange({\n version: context.sdkVersion,\n acceptableVersions: XCODE_SCRIPTS_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n patchBundlePhase(\n bundlePhase,\n addSentryWithBundledScriptsToBundleShellScript,\n );\n } else {\n patchBundlePhase(bundlePhase, addSentryWithCliToBundleShellScript);\n }\n Sentry.setTag('xcode-bundle-phase-status', 'patched');\n });\n\n traceStep('add-debug-files-upload-phase', () => {\n const debugFilesUploadPhaseExists =\n !!findDebugFilesUploadPhase(buildPhasesMap);\n Sentry.setTag(\n 'xcode-debug-files-upload-phase-status',\n debugFilesUploadPhaseExists ? 'already-exists' : undefined,\n );\n if (\n context.sdkVersion &&\n fulfillsVersionRange({\n version: context.sdkVersion,\n acceptableVersions: XCODE_SCRIPTS_SUPPORTED_SDK_RANGE,\n canBeLatest: true,\n })\n ) {\n addDebugFilesUploadPhaseWithBundledScripts(xcodeProject, {\n debugFilesUploadPhaseExists,\n });\n } else {\n addDebugFilesUploadPhaseWithCli(xcodeProject, {\n debugFilesUploadPhaseExists,\n });\n }\n Sentry.setTag('xcode-debug-files-upload-phase-status', 'added');\n });\n\n traceStep('write-xcode-project', () => {\n writeXcodeProject(xcodeProjectPath, xcodeProject);\n });\n Sentry.setTag('xcode-project-status', 'patched');\n}\n\nasync function patchAndroidFiles(config: RNCliSetupConfigContent) {\n await addSentryCliConfig(config, {\n ...propertiesCliSetupConfig,\n name: 'source maps and iOS debug files',\n filename: 'android/sentry.properties',\n gitignore: false,\n });\n\n const appBuildGradlePath = traceStep('find-app-build-gradle', () =>\n getFirstMatchedPath(APP_BUILD_GRADLE),\n );\n Sentry.setTag(\n 'app-build-gradle-status',\n appBuildGradlePath ? 'found' : 'not-found',\n );\n if (!appBuildGradlePath) {\n clack.log.warn(\n `Could not find Android ${chalk.cyan(\n 'app/build.gradle',\n )} file using ${chalk.cyan(APP_BUILD_GRADLE)}.`,\n );\n return;\n }\n\n const appBuildGradle = traceStep('read-app-build-gradle', () =>\n fs.readFileSync(appBuildGradlePath, 'utf-8'),\n );\n const includesSentry =\n doesAppBuildGradleIncludeRNSentryGradlePlugin(appBuildGradle);\n if (includesSentry) {\n Sentry.setTag('app-build-gradle-status', 'already-includes-sentry');\n clack.log.warn(\n `Android ${chalk.cyan('app/build.gradle')} file already includes Sentry.`,\n );\n return;\n }\n\n const patchedAppBuildGradle = traceStep('add-rn-sentry-gradle-plugin', () =>\n addRNSentryGradlePlugin(appBuildGradle),\n );\n if (!doesAppBuildGradleIncludeRNSentryGradlePlugin(patchedAppBuildGradle)) {\n Sentry.setTag(\n 'app-build-gradle-status',\n 'failed-to-add-rn-sentry-gradle-plugin',\n );\n clack.log.warn(\n `Could not add Sentry RN Gradle Plugin to ${chalk.cyan(\n 'app/build.gradle',\n )}.`,\n );\n return;\n }\n\n Sentry.setTag('app-build-gradle-status', 'added-rn-sentry-gradle-plugin');\n clack.log.success(\n `Added Sentry RN Gradle Plugin to ${chalk.bold('app/build.gradle')}.`,\n );\n\n traceStep('write-app-build-gradle', () =>\n writeAppBuildGradle(appBuildGradlePath, patchedAppBuildGradle),\n );\n clack.log.success(\n chalk.green(`Android ${chalk.cyan('app/build.gradle')} saved.`),\n );\n}\n\nasync function confirmPodInstall(): Promise<boolean> {\n return traceStep('confirm-pod-install', async () => {\n const continueWithPodInstall = await abortIfCancelled(\n clack.select({\n message: 'Do you want to run `pod install` now?',\n options: [\n {\n value: true,\n label: 'Yes',\n hint: 'Recommended for smaller projects, this might take several minutes',\n },\n { value: false, label: `No, I'll do it later` },\n ],\n initialValue: true,\n }),\n );\n Sentry.setTag('continue-with-pod-install', continueWithPodInstall);\n return continueWithPodInstall;\n });\n}\n"]}
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const WIZARD_VERSION = "4.
|
|
1
|
+
export declare const WIZARD_VERSION = "4.4.0";
|
package/dist/src/version.js
CHANGED
package/dist/src/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA,oCAAoC;AACpC,2CAA2C;;;AAE9B,QAAA,cAAc,GAAG,OAAO,CAAC","sourcesContent":["// DO NOT modify this file manually!\n// This is file is updated at release time.\n\nexport const WIZARD_VERSION = '4.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA,oCAAoC;AACpC,2CAA2C;;;AAE9B,QAAA,cAAc,GAAG,OAAO,CAAC","sourcesContent":["// DO NOT modify this file manually!\n// This is file is updated at release time.\n\nexport const WIZARD_VERSION = '4.4.0';\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const javascript_1 = require("../../src/react-native/javascript");
|
|
4
|
+
// @ts-ignore - magicast is ESM and TS complains about that. It works though
|
|
5
|
+
const magicast_1 = require("magicast");
|
|
4
6
|
describe('react-native javascript', () => {
|
|
5
7
|
describe('addSentryInitWithSdkImport', () => {
|
|
6
8
|
it('adds sdk import and sentry init under last import in the file', () => {
|
|
@@ -109,5 +111,409 @@ export default App;`;
|
|
|
109
111
|
})).toBe(false);
|
|
110
112
|
});
|
|
111
113
|
});
|
|
114
|
+
describe('addSentryWrap', () => {
|
|
115
|
+
it('wraps the root app component', () => {
|
|
116
|
+
const mod = (0, magicast_1.parseModule)(`import * as React from 'react';
|
|
117
|
+
import * as Sentry from '@sentry/react-native';
|
|
118
|
+
|
|
119
|
+
import { View } from 'react-native';
|
|
120
|
+
|
|
121
|
+
const App = () => {
|
|
122
|
+
return (
|
|
123
|
+
<View>
|
|
124
|
+
Test App
|
|
125
|
+
</View>
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export default App;`);
|
|
130
|
+
const expectedOutput = `import * as React from 'react';
|
|
131
|
+
import * as Sentry from '@sentry/react-native';
|
|
132
|
+
|
|
133
|
+
import { View } from 'react-native';
|
|
134
|
+
|
|
135
|
+
const App = () => {
|
|
136
|
+
return (
|
|
137
|
+
<View>
|
|
138
|
+
Test App
|
|
139
|
+
</View>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export default Sentry.wrap(App);`;
|
|
144
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
145
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
146
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
147
|
+
});
|
|
148
|
+
it('wraps a wrapped root app component', () => {
|
|
149
|
+
const mod = (0, magicast_1.parseModule)(`import * as React from 'react';
|
|
150
|
+
import * as Sentry from '@sentry/react-native';
|
|
151
|
+
|
|
152
|
+
import { View } from 'react-native';
|
|
153
|
+
|
|
154
|
+
const App = () => {
|
|
155
|
+
return (
|
|
156
|
+
<View>
|
|
157
|
+
Test App
|
|
158
|
+
</View>
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export default AnotheWrapper.wrap(App);`);
|
|
163
|
+
const expectedOutput = `import * as React from 'react';
|
|
164
|
+
import * as Sentry from '@sentry/react-native';
|
|
165
|
+
|
|
166
|
+
import { View } from 'react-native';
|
|
167
|
+
|
|
168
|
+
const App = () => {
|
|
169
|
+
return (
|
|
170
|
+
<View>
|
|
171
|
+
Test App
|
|
172
|
+
</View>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export default Sentry.wrap(AnotheWrapper.wrap(App));`;
|
|
177
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
178
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
179
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
180
|
+
});
|
|
181
|
+
it('wraps a root app named function', () => {
|
|
182
|
+
const mod = (0, magicast_1.parseModule)(`import * as Sentry from '@sentry/react-native';
|
|
183
|
+
|
|
184
|
+
export default function RootLayout() {
|
|
185
|
+
return (
|
|
186
|
+
<View>
|
|
187
|
+
Test App
|
|
188
|
+
</View>
|
|
189
|
+
);
|
|
190
|
+
}`);
|
|
191
|
+
const expectedOutput = `import * as Sentry from '@sentry/react-native';
|
|
192
|
+
|
|
193
|
+
export default Sentry.wrap(function RootLayout() {
|
|
194
|
+
return (
|
|
195
|
+
<View>
|
|
196
|
+
Test App
|
|
197
|
+
</View>
|
|
198
|
+
);
|
|
199
|
+
});`;
|
|
200
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
201
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
202
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
203
|
+
});
|
|
204
|
+
it('wraps a wrapped root app named function', () => {
|
|
205
|
+
const mod = (0, magicast_1.parseModule)(`import * as Sentry from '@sentry/react-native';
|
|
206
|
+
|
|
207
|
+
export default Another.wrapper(function RootLayout() {
|
|
208
|
+
return (
|
|
209
|
+
<View>
|
|
210
|
+
Test App
|
|
211
|
+
</View>
|
|
212
|
+
);
|
|
213
|
+
});`);
|
|
214
|
+
const expectedOutput = `import * as Sentry from '@sentry/react-native';
|
|
215
|
+
|
|
216
|
+
export default Sentry.wrap(Another.wrapper(function RootLayout() {
|
|
217
|
+
return (
|
|
218
|
+
<View>
|
|
219
|
+
Test App
|
|
220
|
+
</View>
|
|
221
|
+
);
|
|
222
|
+
}));`;
|
|
223
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
224
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
225
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
226
|
+
});
|
|
227
|
+
it('wraps a root app anonymous function', () => {
|
|
228
|
+
const mod = (0, magicast_1.parseModule)(`import * as Sentry from '@sentry/react-native';
|
|
229
|
+
|
|
230
|
+
export default () => {
|
|
231
|
+
return (
|
|
232
|
+
<View>
|
|
233
|
+
Test App
|
|
234
|
+
</View>
|
|
235
|
+
);
|
|
236
|
+
}`);
|
|
237
|
+
const expectedOutput = `import * as Sentry from '@sentry/react-native';
|
|
238
|
+
|
|
239
|
+
export default Sentry.wrap(() => {
|
|
240
|
+
return (
|
|
241
|
+
<View>
|
|
242
|
+
Test App
|
|
243
|
+
</View>
|
|
244
|
+
);
|
|
245
|
+
});`;
|
|
246
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
247
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
248
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
249
|
+
});
|
|
250
|
+
it('wraps a wrapped root app anonymous function', () => {
|
|
251
|
+
const mod = (0, magicast_1.parseModule)(`import * as Sentry from '@sentry/react-native';
|
|
252
|
+
|
|
253
|
+
export default Another.wrap(() => {
|
|
254
|
+
return (
|
|
255
|
+
<View>
|
|
256
|
+
Test App
|
|
257
|
+
</View>
|
|
258
|
+
);
|
|
259
|
+
});`);
|
|
260
|
+
const expectedOutput = `import * as Sentry from '@sentry/react-native';
|
|
261
|
+
|
|
262
|
+
export default Sentry.wrap(Another.wrap(() => {
|
|
263
|
+
return (
|
|
264
|
+
<View>
|
|
265
|
+
Test App
|
|
266
|
+
</View>
|
|
267
|
+
);
|
|
268
|
+
}));`;
|
|
269
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
270
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
271
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
272
|
+
});
|
|
273
|
+
it('wraps a complex root function', () => {
|
|
274
|
+
// This is the default export for a new Expo 52 project
|
|
275
|
+
const mod = (0, magicast_1.parseModule)(`import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
|
276
|
+
import { useFonts } from 'expo-font';
|
|
277
|
+
import { Stack } from 'expo-router';
|
|
278
|
+
import * as SplashScreen from 'expo-splash-screen';
|
|
279
|
+
import { StatusBar } from 'expo-status-bar';
|
|
280
|
+
import { useEffect } from 'react';
|
|
281
|
+
import 'react-native-reanimated';
|
|
282
|
+
|
|
283
|
+
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
284
|
+
import * as Sentry from '@sentry/react-native';
|
|
285
|
+
|
|
286
|
+
Sentry.init({
|
|
287
|
+
dsn: 'https://sentry.io/123',
|
|
288
|
+
|
|
289
|
+
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
290
|
+
// spotlight: __DEV__,
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
|
294
|
+
SplashScreen.preventAutoHideAsync();
|
|
295
|
+
|
|
296
|
+
export default function RootLayout() {
|
|
297
|
+
const colorScheme = useColorScheme();
|
|
298
|
+
const [loaded] = useFonts({
|
|
299
|
+
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
useEffect(() => {
|
|
303
|
+
if (loaded) {
|
|
304
|
+
SplashScreen.hideAsync();
|
|
305
|
+
}
|
|
306
|
+
}, [loaded]);
|
|
307
|
+
|
|
308
|
+
if (!loaded) {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
|
314
|
+
<Stack>
|
|
315
|
+
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
|
316
|
+
<Stack.Screen name="+not-found" />
|
|
317
|
+
</Stack>
|
|
318
|
+
<StatusBar style="auto" />
|
|
319
|
+
</ThemeProvider>
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
`);
|
|
323
|
+
const expectedOutput = `import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
|
324
|
+
import { useFonts } from 'expo-font';
|
|
325
|
+
import { Stack } from 'expo-router';
|
|
326
|
+
import * as SplashScreen from 'expo-splash-screen';
|
|
327
|
+
import { StatusBar } from 'expo-status-bar';
|
|
328
|
+
import { useEffect } from 'react';
|
|
329
|
+
import 'react-native-reanimated';
|
|
330
|
+
|
|
331
|
+
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
332
|
+
import * as Sentry from '@sentry/react-native';
|
|
333
|
+
|
|
334
|
+
Sentry.init({
|
|
335
|
+
dsn: 'https://sentry.io/123',
|
|
336
|
+
|
|
337
|
+
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
338
|
+
// spotlight: __DEV__,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
|
342
|
+
SplashScreen.preventAutoHideAsync();
|
|
343
|
+
|
|
344
|
+
export default Sentry.wrap(function RootLayout() {
|
|
345
|
+
const colorScheme = useColorScheme();
|
|
346
|
+
const [loaded] = useFonts({
|
|
347
|
+
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
useEffect(() => {
|
|
351
|
+
if (loaded) {
|
|
352
|
+
SplashScreen.hideAsync();
|
|
353
|
+
}
|
|
354
|
+
}, [loaded]);
|
|
355
|
+
|
|
356
|
+
if (!loaded) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return (
|
|
361
|
+
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
|
362
|
+
<Stack>
|
|
363
|
+
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
|
364
|
+
<Stack.Screen name="+not-found" />
|
|
365
|
+
</Stack>
|
|
366
|
+
<StatusBar style="auto" />
|
|
367
|
+
</ThemeProvider>
|
|
368
|
+
);
|
|
369
|
+
});`;
|
|
370
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
371
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
372
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
373
|
+
});
|
|
374
|
+
it('wraps a root app anonymous complex function', () => {
|
|
375
|
+
const mod = (0, magicast_1.parseModule)(`import * as Sentry from '@sentry/react-native';
|
|
376
|
+
|
|
377
|
+
export default () => {
|
|
378
|
+
const colorScheme = useColorScheme();
|
|
379
|
+
const [loaded] = useFonts({
|
|
380
|
+
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
useEffect(() => {
|
|
384
|
+
if (loaded) {
|
|
385
|
+
SplashScreen.hideAsync();
|
|
386
|
+
}
|
|
387
|
+
}, [loaded]);
|
|
388
|
+
|
|
389
|
+
if (!loaded) {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return (
|
|
394
|
+
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
|
395
|
+
<Stack>
|
|
396
|
+
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
|
397
|
+
<Stack.Screen name="+not-found" />
|
|
398
|
+
</Stack>
|
|
399
|
+
<StatusBar style="auto" />
|
|
400
|
+
</ThemeProvider>
|
|
401
|
+
);
|
|
402
|
+
}`);
|
|
403
|
+
const expectedOutput = `import * as Sentry from '@sentry/react-native';
|
|
404
|
+
|
|
405
|
+
export default Sentry.wrap(() => {
|
|
406
|
+
const colorScheme = useColorScheme();
|
|
407
|
+
const [loaded] = useFonts({
|
|
408
|
+
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
useEffect(() => {
|
|
412
|
+
if (loaded) {
|
|
413
|
+
SplashScreen.hideAsync();
|
|
414
|
+
}
|
|
415
|
+
}, [loaded]);
|
|
416
|
+
|
|
417
|
+
if (!loaded) {
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return (
|
|
422
|
+
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
|
423
|
+
<Stack>
|
|
424
|
+
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
|
425
|
+
<Stack.Screen name="+not-found" />
|
|
426
|
+
</Stack>
|
|
427
|
+
<StatusBar style="auto" />
|
|
428
|
+
</ThemeProvider>
|
|
429
|
+
);
|
|
430
|
+
});`;
|
|
431
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
432
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
433
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
434
|
+
});
|
|
435
|
+
it('wraps a default class export', () => {
|
|
436
|
+
const mod = (0, magicast_1.parseModule)(`import * as Sentry from '@sentry/react-native';
|
|
437
|
+
|
|
438
|
+
export default class RootLayout extends React.Component {
|
|
439
|
+
render() {
|
|
440
|
+
return (
|
|
441
|
+
<View>
|
|
442
|
+
Test App
|
|
443
|
+
</View>
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
}`);
|
|
447
|
+
const expectedOutput = `import * as Sentry from '@sentry/react-native';
|
|
448
|
+
|
|
449
|
+
export default Sentry.wrap(class RootLayout extends React.Component {
|
|
450
|
+
render() {
|
|
451
|
+
return (
|
|
452
|
+
<View>
|
|
453
|
+
Test App
|
|
454
|
+
</View>
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
});`;
|
|
458
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
459
|
+
expect(result).toBe(javascript_1.SentryWrapResult.Success);
|
|
460
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(expectedOutput);
|
|
461
|
+
});
|
|
462
|
+
it('does not wrap a root app component if not found', () => {
|
|
463
|
+
const input = `import * as React from 'react';
|
|
464
|
+
|
|
465
|
+
import { View } from 'react-native';
|
|
466
|
+
|
|
467
|
+
const App = () => {
|
|
468
|
+
return (
|
|
469
|
+
<View>
|
|
470
|
+
Test App
|
|
471
|
+
</View>
|
|
472
|
+
);
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
export { App };`;
|
|
476
|
+
const mod = (0, magicast_1.parseModule)(input);
|
|
477
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
478
|
+
expect(result).toBe(javascript_1.SentryWrapResult.NotFound);
|
|
479
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(input);
|
|
480
|
+
});
|
|
481
|
+
it('does not wrap a root app component if already wrapped', () => {
|
|
482
|
+
const input = `import * as React from 'react';
|
|
483
|
+
import * as Sentry from '@sentry/react-native';
|
|
484
|
+
|
|
485
|
+
import { View } from 'react-native';
|
|
486
|
+
|
|
487
|
+
const App = () => {
|
|
488
|
+
return (
|
|
489
|
+
<View>
|
|
490
|
+
Test App
|
|
491
|
+
</View>
|
|
492
|
+
);
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
export default Sentry.wrap(App);`;
|
|
496
|
+
const mod = (0, magicast_1.parseModule)(input);
|
|
497
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
498
|
+
expect(result).toBe(javascript_1.SentryWrapResult.AlreadyWrapped);
|
|
499
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(input);
|
|
500
|
+
});
|
|
501
|
+
it('does not wrap the root app component in an empty file', () => {
|
|
502
|
+
const mod = (0, magicast_1.parseModule)(``);
|
|
503
|
+
const result = (0, javascript_1.checkAndWrapRootComponent)(mod);
|
|
504
|
+
expect(result).toBe(javascript_1.SentryWrapResult.NotFound);
|
|
505
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe(``);
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
it('does detect Sentry.wrap if exists', () => {
|
|
509
|
+
const mod = (0, magicast_1.parseModule)(`export default Sentry.wrap(App);`);
|
|
510
|
+
const result = (0, javascript_1.doesContainSentryWrap)(mod.$ast);
|
|
511
|
+
expect(result).toBeTruthy();
|
|
512
|
+
});
|
|
513
|
+
it('does not detect Sentry.wrap if not present', () => {
|
|
514
|
+
const mod = (0, magicast_1.parseModule)(`export default App;`);
|
|
515
|
+
const result = (0, javascript_1.doesContainSentryWrap)(mod.$ast);
|
|
516
|
+
expect(result).toBeFalsy();
|
|
517
|
+
});
|
|
112
518
|
});
|
|
113
519
|
//# sourceMappingURL=javascript.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"javascript.test.js","sourceRoot":"","sources":["../../../test/react-native/javascript.test.ts"],"names":[],"mappings":";;AAAA,kEAG2C;AAE3C,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,MAAM,KAAK,GAAG;;;;;;;;;;;;;;oBAcA,CAAC;YAEf,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;oBAsBT,CAAC;YAEf,MAAM,CAAC,IAAA,uCAA0B,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAC5D,cAAc,CACf,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,MAAM,KAAK,GAAG,6BAA6B,CAAC;YAC5C,MAAM,CAAC,IAAA,uCAA0B,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,KAAK,GAAG,EAAE,CAAC;YACjB,MAAM,CAAC,IAAA,uCAA0B,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;oBAeA,CAAC;YAEf,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;oBAeA,CAAC;YAEf,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,KAAK,GAAG,6BAA6B,CAAC;YAC5C,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,KAAK,GAAG,EAAE,CAAC;YACjB,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {\n addSentryInitWithSdkImport,\n doesJsCodeIncludeSdkSentryImport,\n} from '../../src/react-native/javascript';\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 // 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('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"]}
|
|
1
|
+
{"version":3,"file":"javascript.test.js","sourceRoot":"","sources":["../../../test/react-native/javascript.test.ts"],"names":[],"mappings":";;AAAA,kEAM2C;AAC3C,4EAA4E;AAC5E,uCAAqD;AAGrD,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,MAAM,KAAK,GAAG;;;;;;;;;;;;;;oBAcA,CAAC;YAEf,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;oBAsBT,CAAC;YAEf,MAAM,CAAC,IAAA,uCAA0B,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAC5D,cAAc,CACf,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,MAAM,KAAK,GAAG,6BAA6B,CAAC;YAC5C,MAAM,CAAC,IAAA,uCAA0B,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,KAAK,GAAG,EAAE,CAAC;YACjB,MAAM,CAAC,IAAA,uCAA0B,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;oBAeA,CAAC;YAEf,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;oBAeA,CAAC;YAEf,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,KAAK,GAAG,6BAA6B,CAAC;YAC5C,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,KAAK,GAAG,EAAE,CAAC;YACjB,MAAM,CACJ,IAAA,6CAAgC,EAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,sBAAsB;aACvC,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;;;;;;oBAaV,CAAC,CAAC;YAEhB,MAAM,cAAc,GAAG;;;;;;;;;;;;;iCAaI,CAAC;YAE5B,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;;;;;;wCAaU,CAAC,CAAC;YAEpC,MAAM,cAAc,GAAG;;;;;;;;;;;;;qDAawB,CAAC;YAEhD,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;EAQ5B,CAAC,CAAC;YAEE,MAAM,cAAc,GAAG;;;;;;;;IAQzB,CAAC;YAEC,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;IAQ1B,CAAC,CAAC;YAEA,MAAM,cAAc,GAAG;;;;;;;;KAQxB,CAAC;YAEA,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;EAQ5B,CAAC,CAAC;YAEE,MAAM,cAAc,GAAG;;;;;;;;IAQzB,CAAC;YAEC,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;IAQ1B,CAAC,CAAC;YAEA,MAAM,cAAc,GAAG;;;;;;;;KAQxB,CAAC;YAEA,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,uDAAuD;YACvD,MAAM,GAAG,GACP,IAAA,sBAAW,EAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CnB,CAAC,CAAC;YAEG,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8CzB,CAAC;YAEC,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B5B,CAAC,CAAC;YAEE,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BzB,CAAC;YAEC,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;;;EAU5B,CAAC,CAAC;YAEE,MAAM,cAAc,GAAG;;;;;;;;;;IAUzB,CAAC;YAEC,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,KAAK,GAAG;;;;;;;;;;;;gBAYJ,CAAC;YACX,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,KAAK,CAAC,CAAC;YAE/B,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,MAAM,KAAK,GAAG;;;;;;;;;;;;;iCAaa,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,KAAK,CAAC,CAAC;YAE/B,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,cAAc,CAAC,CAAC;YACrD,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,EAAE,CAAC,CAAC;YAE5B,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,GAAG,CAAC,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6BAAgB,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,CAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,kCAAkC,CAAC,CAAC;QAE5D,MAAM,MAAM,GAAG,IAAA,kCAAqB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;QAE5D,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC,qBAAqB,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,IAAA,kCAAqB,EAAC,GAAG,CAAC,IAAiB,CAAC,CAAC;QAE5D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import {\n addSentryInitWithSdkImport,\n checkAndWrapRootComponent,\n doesContainSentryWrap,\n doesJsCodeIncludeSdkSentryImport,\n SentryWrapResult,\n} from '../../src/react-native/javascript';\n// @ts-ignore - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport * as t from '@babel/types';\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 // 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('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 // 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 // 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"]}
|
package/package.json
CHANGED