@sentry/wizard 6.10.0 → 6.12.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 +69 -0
- package/dist/ci-ensure-runtime-loaded.sh +82 -0
- package/dist/e2e-tests/tests/angular-17.test.js +72 -82
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +71 -80
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/cloudflare-worker.test.d.ts +1 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js +69 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js.map +1 -0
- package/dist/e2e-tests/tests/cloudflare-wrangler-sourcemaps.test.js +2 -5
- package/dist/e2e-tests/tests/cloudflare-wrangler-sourcemaps.test.js.map +1 -1
- package/dist/e2e-tests/tests/expo.test.js +36 -61
- package/dist/e2e-tests/tests/expo.test.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.js +63 -70
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/e2e-tests/tests/help-message.test.js +2 -2
- package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs-14.test.js +48 -76
- package/dist/e2e-tests/tests/nextjs-14.test.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs-15.test.js +89 -99
- package/dist/e2e-tests/tests/nextjs-15.test.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs-16.test.js +48 -45
- package/dist/e2e-tests/tests/nextjs-16.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-3.test.js +45 -58
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-4.test.js +59 -73
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js +6 -8
- package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-native.test.js +44 -80
- package/dist/e2e-tests/tests/react-native.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.d.ts +1 -0
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +96 -0
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -0
- package/dist/e2e-tests/tests/react-router.test.js +165 -145
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +162 -132
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js +48 -36
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +5 -7
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
- package/dist/e2e-tests/utils/index.d.ts +15 -43
- package/dist/e2e-tests/utils/index.js +95 -185
- package/dist/e2e-tests/utils/index.js.map +1 -1
- package/dist/get-e2e-test-matrix.mjs +11 -0
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +5 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/src/android/android-wizard.js +2 -4
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/angular/angular-wizard.js +4 -6
- package/dist/src/angular/angular-wizard.js.map +1 -1
- package/dist/src/angular/sdk-setup.js +1 -1
- package/dist/src/angular/sdk-setup.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +2 -4
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/code-tools.js +17 -3
- package/dist/src/apple/code-tools.js.map +1 -1
- package/dist/src/apple/configure-package-manager.js +18 -5
- package/dist/src/apple/configure-package-manager.js.map +1 -1
- package/dist/src/cloudflare/cloudflare-wizard.d.ts +3 -0
- package/dist/src/cloudflare/cloudflare-wizard.js +104 -0
- package/dist/src/cloudflare/cloudflare-wizard.js.map +1 -0
- package/dist/src/cloudflare/sdk-setup.d.ts +8 -0
- package/dist/src/cloudflare/sdk-setup.js +47 -0
- package/dist/src/cloudflare/sdk-setup.js.map +1 -0
- package/dist/src/cloudflare/templates.d.ts +5 -0
- package/dist/src/cloudflare/templates.js +50 -0
- package/dist/src/cloudflare/templates.js.map +1 -0
- package/dist/src/cloudflare/wrangler/create-wrangler-config.d.ts +4 -0
- package/dist/src/cloudflare/wrangler/create-wrangler-config.js +27 -0
- package/dist/src/cloudflare/wrangler/create-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/ensure-wrangler-config.d.ts +4 -0
- package/dist/src/cloudflare/wrangler/ensure-wrangler-config.js +25 -0
- package/dist/src/cloudflare/wrangler/ensure-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/find-wrangler-config.d.ts +4 -0
- package/dist/src/cloudflare/wrangler/find-wrangler-config.js +23 -0
- package/dist/src/cloudflare/wrangler/find-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.d.ts +6 -0
- package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.js +52 -0
- package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/update-wrangler-config.d.ts +17 -0
- package/dist/src/cloudflare/wrangler/update-wrangler-config.js +173 -0
- package/dist/src/cloudflare/wrangler/update-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrap-worker.d.ts +33 -0
- package/dist/src/cloudflare/wrap-worker.js +116 -0
- package/dist/src/cloudflare/wrap-worker.js.map +1 -0
- package/dist/src/flutter/flutter-wizard.js +3 -6
- package/dist/src/flutter/flutter-wizard.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +0 -2
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nuxt/nuxt-wizard.js +3 -5
- package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
- package/dist/src/react-native/expo.d.ts +6 -0
- package/dist/src/react-native/expo.js +27 -1
- package/dist/src/react-native/expo.js.map +1 -1
- package/dist/src/react-native/git.d.ts +5 -0
- package/dist/src/react-native/git.js +32 -1
- package/dist/src/react-native/git.js.map +1 -1
- package/dist/src/react-native/javascript.js +3 -1
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +14 -10
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
- package/dist/src/react-router/codemods/client.entry.js +69 -12
- package/dist/src/react-router/codemods/client.entry.js.map +1 -1
- package/dist/src/react-router/codemods/react-router-config.js +1 -1
- package/dist/src/react-router/codemods/react-router-config.js.map +1 -1
- package/dist/src/react-router/codemods/root.js +1 -2
- package/dist/src/react-router/codemods/root.js.map +1 -1
- package/dist/src/react-router/codemods/server-entry.d.ts +1 -1
- package/dist/src/react-router/codemods/server-entry.js +39 -4
- package/dist/src/react-router/codemods/server-entry.js.map +1 -1
- package/dist/src/react-router/codemods/vite.js +46 -1
- package/dist/src/react-router/codemods/vite.js.map +1 -1
- package/dist/src/react-router/react-router-wizard.js +55 -10
- package/dist/src/react-router/react-router-wizard.js.map +1 -1
- package/dist/src/react-router/sdk-setup.d.ts +5 -3
- package/dist/src/react-router/sdk-setup.js +35 -9
- package/dist/src/react-router/sdk-setup.js.map +1 -1
- package/dist/src/react-router/templates.d.ts +2 -2
- package/dist/src/react-router/templates.js +72 -2
- package/dist/src/react-router/templates.js.map +1 -1
- package/dist/src/remix/remix-wizard.js +2 -4
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/run.d.ts +1 -1
- package/dist/src/run.js +5 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/vite.js +1 -1
- package/dist/src/sourcemaps/tools/vite.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +2 -4
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/abort-if-sportlight-not-supported.d.ts +5 -0
- package/dist/src/utils/abort-if-sportlight-not-supported.js +40 -0
- package/dist/src/utils/abort-if-sportlight-not-supported.js.map +1 -0
- package/dist/src/utils/ast-utils.d.ts +11 -1
- package/dist/src/utils/ast-utils.js +19 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +2 -2
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/utils/clack/mcp-config.js +117 -59
- package/dist/src/utils/clack/mcp-config.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/angular/angular-wizard.test.js +2 -4
- package/dist/test/angular/angular-wizard.test.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +78 -0
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/apple/configure-package-manager.test.d.ts +1 -0
- package/dist/test/apple/configure-package-manager.test.js +161 -0
- package/dist/test/apple/configure-package-manager.test.js.map +1 -0
- package/dist/test/cloudflare/create-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/create-wrangler-config.test.js +48 -0
- package/dist/test/cloudflare/create-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/ensure-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/ensure-wrangler-config.test.js +61 -0
- package/dist/test/cloudflare/ensure-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/find-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/find-wrangler-config.test.js +77 -0
- package/dist/test/cloudflare/find-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.js +81 -0
- package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/sdk-setup.test.d.ts +1 -0
- package/dist/test/cloudflare/sdk-setup.test.js +170 -0
- package/dist/test/cloudflare/sdk-setup.test.js.map +1 -0
- package/dist/test/cloudflare/templates.test.d.ts +1 -0
- package/dist/test/cloudflare/templates.test.js +122 -0
- package/dist/test/cloudflare/templates.test.js.map +1 -0
- package/dist/test/cloudflare/update-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/update-wrangler-config.test.js +216 -0
- package/dist/test/cloudflare/update-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/wrap-worker.test.d.ts +1 -0
- package/dist/test/cloudflare/wrap-worker.test.js +206 -0
- package/dist/test/cloudflare/wrap-worker.test.js.map +1 -0
- package/dist/test/react-native/expo.test.js +140 -0
- package/dist/test/react-native/expo.test.js.map +1 -1
- package/dist/test/react-native/git.test.d.ts +1 -0
- package/dist/test/react-native/git.test.js +160 -0
- package/dist/test/react-native/git.test.js.map +1 -0
- package/dist/test/react-router/codemods/client-entry.test.js +29 -0
- package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/root.test.js +4 -0
- package/dist/test/react-router/codemods/root.test.js.map +1 -1
- package/dist/test/react-router/codemods/server-entry.test.js +70 -0
- package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/vite.test.js +89 -0
- package/dist/test/react-router/codemods/vite.test.js.map +1 -1
- package/dist/test/react-router/sdk-setup.test.js +64 -8
- package/dist/test/react-router/sdk-setup.test.js.map +1 -1
- package/dist/test/react-router/templates.test.js +50 -0
- package/dist/test/react-router/templates.test.js.map +1 -1
- package/dist/test/sourcemaps/tools/vite.test.js +12 -8
- package/dist/test/sourcemaps/tools/vite.test.js.map +1 -1
- package/dist/test/utils/ast-utils.test.js +22 -0
- package/dist/test/utils/ast-utils.test.js.map +1 -1
- package/dist/test/utils/clack/mcp-config.test.js +176 -51
- package/dist/test/utils/clack/mcp-config.test.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/react-native/git.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAEzB,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAEjC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD;;;;;;;;;;;;OAYG;IACH,IAAI;QACF,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,kBAAkB,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;KACb;IAAC,MAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AApBD,wCAoBC","sourcesContent":["import * as fs from 'fs';\n\nconst GITIGNORE_FILENAME = '.gitignore';\n\nexport async function addToGitignore(filepath: string): Promise<boolean> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(GITIGNORE_FILENAME, `\\n${filepath}\\n`);\n return true;\n } catch {\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/react-native/git.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAEzB,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAEjC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD;;;;;;;;;;;;OAYG;IACH,IAAI;QACF,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,kBAAkB,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;KACb;IAAC,MAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AApBD,wCAoBC;AAED;;;GAGG;AACI,MAAM,mBAAmB,GAAG,KAAK,EAAE,MAAc,EAAoB,EAAE;IAC5E,IAAI;QACF,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE;YAC7D,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QAEH,4CAA4C;QAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEzD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACzB,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAErD,IAAI,CAAC,kBAAkB,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBAC/D,OAAO,KAAK,CAAC;aACd;YAED,MAAM,QAAQ,GAAG;gBACf,MAAM;gBACN,GAAG,MAAM,GAAG;gBACZ,GAAG,MAAM,IAAI;gBACb,IAAI,MAAM,EAAE;gBACZ,IAAI,MAAM,GAAG,EAAE,gDAAgD;aAChE,CAAC;YAEF,OAAO,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;KACJ;IAAC,MAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC,CAAC;AA7BW,QAAA,mBAAmB,uBA6B9B","sourcesContent":["import * as fs from 'fs';\n\nconst GITIGNORE_FILENAME = '.gitignore';\n\nexport async function addToGitignore(filepath: string): Promise<boolean> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(GITIGNORE_FILENAME, `\\n${filepath}\\n`);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Checks if gitignore file contains ios and android folders\n * Processes line by line, ignoring comments and checking for exact patterns\n */\nexport const isFolderInGitignore = async (folder: string): Promise<boolean> => {\n try {\n const content = await fs.promises.readFile(GITIGNORE_FILENAME, {\n encoding: 'utf-8',\n });\n\n // Split by lines and normalize line endings\n const lines = content.replace(/\\r\\n/g, '\\n').split('\\n');\n\n return lines.some((line) => {\n const lineWithoutComment = line.split('#')[0].trim();\n\n if (!lineWithoutComment || !lineWithoutComment.includes(folder)) {\n return false;\n }\n\n const patterns = [\n folder, // Exact match: ios\n `${folder}/`, // Folder with trailing slash: ios/\n `${folder}/*`, // Folder with wildcard: ios/*\n `/${folder}`, // Folder with leading slash: /ios\n `/${folder}/`, // Folder with leading and trailing slash: /ios/\n ];\n\n return patterns.includes(lineWithoutComment);\n });\n } catch {\n return false;\n }\n};\n"]}
|
|
@@ -39,6 +39,7 @@ const telemetry_1 = require("../telemetry");
|
|
|
39
39
|
const clack_1 = require("../utils/clack");
|
|
40
40
|
const glob_1 = require("./glob");
|
|
41
41
|
const react_native_wizard_1 = require("./react-native-wizard");
|
|
42
|
+
const ast_utils_1 = require("../utils/ast-utils");
|
|
42
43
|
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
|
|
43
44
|
const magicast_1 = require("magicast");
|
|
44
45
|
const t = __importStar(require("@babel/types"));
|
|
@@ -173,7 +174,8 @@ async function wrapRootComponent() {
|
|
|
173
174
|
}
|
|
174
175
|
(0, telemetry_1.traceStep)('add-sentry-wrap', () => {
|
|
175
176
|
try {
|
|
176
|
-
|
|
177
|
+
const code = (0, ast_utils_1.preserveTrailingNewline)(js, (0, magicast_1.generateCode)(mod.$ast).code);
|
|
178
|
+
fs.writeFileSync(jsPath, code, 'utf-8');
|
|
177
179
|
prompts_1.default.log.success(`Added ${chalk_1.default.cyan('Sentry.wrap')} to ${chalk_1.default.cyan(jsRelativePath)}.`);
|
|
178
180
|
}
|
|
179
181
|
catch (error) {
|
|
@@ -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-expect-error - 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 { makeCodeSnippet, showCopyPasteInstructions } from '../utils/clack';\nimport { getFirstMatchedPath } from './glob';\nimport { RN_SDK_PACKAGE } from './react-native-wizard';\n\n// @ts-expect-error - 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 const sessionReplaySampleRate = 0.1;\nexport const sessionReplayOnErrorSampleRate = 1.0;\n\nexport async function addSentryInit({\n dsn,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n}: {\n dsn: string;\n enableSessionReplay?: boolean;\n enableFeedbackWidget?: boolean;\n enableLogs?: boolean;\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. Place the following code snippet close to the Apps Root component.`,\n );\n Sentry.captureException('Could not find main App file.');\n await showCopyPasteInstructions({\n filename: 'App.js or _layout.tsx',\n codeSnippet: getSentryInitColoredCodeSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n ),\n hint: '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, {\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n });\n\n try {\n fs.writeFileSync(jsPath, newContent, 'utf-8');\n clack.log.success(\n `Added ${chalk.cyan('Sentry.init')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n } catch (error) {\n clack.log.error(`Error while writing ${jsPath}`);\n Sentry.captureException('Error while writing app.js');\n }\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 {\n dsn,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n }: {\n dsn: string;\n enableSessionReplay?: boolean;\n enableFeedbackWidget?: boolean;\n enableLogs?: boolean;\n },\n): string {\n return js.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n (match: string) => `${match}\n${getSentryInitPlainTextSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n)}`,\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(\n dsn: string,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n) {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(\n getSentryInitPlainTextSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n ),\n );\n });\n}\n\nexport function getSentryInitPlainTextSnippet(\n dsn: string,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n) {\n return `import * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: '${dsn}',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: ${enableLogs ? 'true' : 'false'},\n${\n enableSessionReplay\n ? `\n // Configure Session Replay\n replaysSessionSampleRate: ${sessionReplaySampleRate},\n replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate},\n`\n : ''\n}${getSentryIntegrationsPlainTextSnippet(\n enableSessionReplay,\n enableFeedbackWidget,\n )}\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});`;\n}\n\nexport function getSentryIntegrationsPlainTextSnippet(\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n) {\n if (!enableSessionReplay && !enableFeedbackWidget) {\n return '';\n }\n return ` integrations: [${\n enableSessionReplay ? 'Sentry.mobileReplayIntegration()' : ''\n }${enableSessionReplay && enableFeedbackWidget ? ', ' : ''}${\n enableFeedbackWidget ? 'Sentry.feedbackIntegration()' : ''\n }],\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 filename: 'App.js or _layout.tsx',\n codeSnippet: 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 try {\n fs.writeFileSync(jsPath, generateCode(mod.$ast).code, 'utf-8');\n clack.log.success(\n `Added ${chalk.cyan('Sentry.wrap')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n } catch (error) {\n clack.log.error(`Error while writing ${jsPath}`);\n Sentry.captureException('Error while writing app.js');\n return;\n }\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"]}
|
|
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-expect-error - 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 { makeCodeSnippet, showCopyPasteInstructions } from '../utils/clack';\nimport { getFirstMatchedPath } from './glob';\nimport { RN_SDK_PACKAGE } from './react-native-wizard';\nimport { preserveTrailingNewline } from '../utils/ast-utils';\n\n// @ts-expect-error - 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 const sessionReplaySampleRate = 0.1;\nexport const sessionReplayOnErrorSampleRate = 1.0;\n\nexport async function addSentryInit({\n dsn,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n}: {\n dsn: string;\n enableSessionReplay?: boolean;\n enableFeedbackWidget?: boolean;\n enableLogs?: boolean;\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. Place the following code snippet close to the Apps Root component.`,\n );\n Sentry.captureException('Could not find main App file.');\n await showCopyPasteInstructions({\n filename: 'App.js or _layout.tsx',\n codeSnippet: getSentryInitColoredCodeSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n ),\n hint: '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, {\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n });\n\n try {\n fs.writeFileSync(jsPath, newContent, 'utf-8');\n clack.log.success(\n `Added ${chalk.cyan('Sentry.init')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n } catch (error) {\n clack.log.error(`Error while writing ${jsPath}`);\n Sentry.captureException('Error while writing app.js');\n }\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 {\n dsn,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n }: {\n dsn: string;\n enableSessionReplay?: boolean;\n enableFeedbackWidget?: boolean;\n enableLogs?: boolean;\n },\n): string {\n return js.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n (match: string) => `${match}\n${getSentryInitPlainTextSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n)}`,\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(\n dsn: string,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n) {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(\n getSentryInitPlainTextSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n ),\n );\n });\n}\n\nexport function getSentryInitPlainTextSnippet(\n dsn: string,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n enableLogs = false,\n) {\n return `import * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: '${dsn}',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: ${enableLogs ? 'true' : 'false'},\n${\n enableSessionReplay\n ? `\n // Configure Session Replay\n replaysSessionSampleRate: ${sessionReplaySampleRate},\n replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate},\n`\n : ''\n}${getSentryIntegrationsPlainTextSnippet(\n enableSessionReplay,\n enableFeedbackWidget,\n )}\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});`;\n}\n\nexport function getSentryIntegrationsPlainTextSnippet(\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n) {\n if (!enableSessionReplay && !enableFeedbackWidget) {\n return '';\n }\n return ` integrations: [${\n enableSessionReplay ? 'Sentry.mobileReplayIntegration()' : ''\n }${enableSessionReplay && enableFeedbackWidget ? ', ' : ''}${\n enableFeedbackWidget ? 'Sentry.feedbackIntegration()' : ''\n }],\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 filename: 'App.js or _layout.tsx',\n codeSnippet: 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 try {\n const code = preserveTrailingNewline(js, generateCode(mod.$ast).code);\n fs.writeFileSync(jsPath, code, 'utf-8');\n clack.log.success(\n `Added ${chalk.cyan('Sentry.wrap')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n } catch (error) {\n clack.log.error(`Error while writing ${jsPath}`);\n Sentry.captureException('Error while writing app.js');\n return;\n }\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"]}
|
|
@@ -49,6 +49,7 @@ const javascript_1 = require("./javascript");
|
|
|
49
49
|
const metro_1 = require("./metro");
|
|
50
50
|
const xcode_1 = require("./xcode");
|
|
51
51
|
const xcode_2 = __importDefault(require("xcode"));
|
|
52
|
+
const abort_if_sportlight_not_supported_1 = require("../utils/abort-if-sportlight-not-supported");
|
|
52
53
|
exports.RN_SDK_PACKAGE = '@sentry/react-native';
|
|
53
54
|
exports.RN_SDK_SUPPORTED_RANGE = '>=6.12.0';
|
|
54
55
|
exports.RN_PACKAGE = 'react-native';
|
|
@@ -130,10 +131,7 @@ Or setup using ${chalk_1.default.cyan('https://docs.sentry.io/platforms/react-na
|
|
|
130
131
|
}
|
|
131
132
|
const projectData = await (0, clack_1.getOrAskForProjectData)(options, 'react-native');
|
|
132
133
|
if (projectData.spotlight) {
|
|
133
|
-
|
|
134
|
-
prompts_1.default.log.info('Spotlight is currently only available for Next.js.');
|
|
135
|
-
await (0, clack_1.abort)('Exiting wizard', 0);
|
|
136
|
-
return;
|
|
134
|
+
return (0, abort_if_sportlight_not_supported_1.abortIfSpotlightNotSupported)('React Native');
|
|
137
135
|
}
|
|
138
136
|
const { selectedProject, authToken, sentryUrl } = projectData;
|
|
139
137
|
const orgSlug = selectedProject.organization.slug;
|
|
@@ -187,13 +185,19 @@ Or setup using ${chalk_1.default.cyan('https://docs.sentry.io/platforms/react-na
|
|
|
187
185
|
else {
|
|
188
186
|
await (0, telemetry_1.traceStep)('patch-metro-config', metro_1.patchMetroWithSentryConfig);
|
|
189
187
|
}
|
|
190
|
-
if (
|
|
191
|
-
Sentry.setTag('
|
|
192
|
-
|
|
188
|
+
if (isExpo && (await (0, expo_1.isExpoCNG)())) {
|
|
189
|
+
Sentry.setTag('expo-cng', true);
|
|
190
|
+
prompts_1.default.log.info(`Detected Expo Continuous Native Generation (CNG) setup. Skipping native files patching.`);
|
|
193
191
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
else {
|
|
193
|
+
if (fs.existsSync('ios')) {
|
|
194
|
+
Sentry.setTag('patch-ios', true);
|
|
195
|
+
await (0, telemetry_1.traceStep)('patch-xcode-files', () => patchXcodeFiles(cliConfig));
|
|
196
|
+
}
|
|
197
|
+
if (fs.existsSync('android')) {
|
|
198
|
+
Sentry.setTag('patch-android', true);
|
|
199
|
+
await (0, telemetry_1.traceStep)('patch-android-files', () => patchAndroidFiles(cliConfig));
|
|
200
|
+
}
|
|
197
201
|
}
|
|
198
202
|
await (0, clack_1.runPrettierIfInstalled)({ cwd: undefined });
|
|
199
203
|
// Offer optional project-scoped MCP config for Sentry with org and project scope
|
|
@@ -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-expect-error - 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 * as Sentry from '@sentry/node';\nimport { platform } from 'os';\nimport { podInstall } from '../apple/cocoapod';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport { offerProjectScopedMcpConfig } from '../utils/clack/mcp-config';\nimport {\n CliSetupConfigContent,\n abort,\n abortIfCancelled,\n addSentryCliConfig,\n confirmContinueIfNoOrDirtyGitRepo,\n confirmContinueIfPackageVersionNotSupported,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n printWelcome,\n propertiesCliSetupConfig,\n runPrettierIfInstalled,\n} from '../utils/clack';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport { getIssueStreamUrl } from '../utils/url';\nimport { patchExpoAppConfig, printSentryExpoMigrationOutro } from './expo';\nimport { addExpoEnvLocal } from './expo-env-file';\nimport { addSentryToExpoMetroConfig } from './expo-metro';\nimport { APP_BUILD_GRADLE, XCODE_PROJECT, getFirstMatchedPath } from './glob';\nimport {\n addRNSentryGradlePlugin,\n doesAppBuildGradleIncludeRNSentryGradlePlugin,\n writeAppBuildGradle,\n} from './gradle';\nimport {\n addSentryInit,\n sessionReplayOnErrorSampleRate,\n sessionReplaySampleRate,\n wrapRootComponent,\n} from './javascript';\nimport { patchMetroWithSentryConfig } from './metro';\nimport { ReactNativeWizardOptions } from './options';\nimport {\n addDebugFilesUploadPhaseWithBundledScripts,\n addSentryWithBundledScriptsToBundleShellScript,\n findBundlePhase,\n findDebugFilesUploadPhase,\n getValidExistingBuildPhases,\n patchBundlePhase,\n writeXcodeProject,\n} from './xcode';\n\nimport xcode from 'xcode';\n\nexport const RN_SDK_PACKAGE = '@sentry/react-native';\nexport const RN_SDK_SUPPORTED_RANGE = '>=6.12.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\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 const { promoCode, telemetryEnabled, forceInstall } = options;\n\n printWelcome({\n wizardName: 'Sentry React Native Wizard',\n promoCode,\n telemetryEnabled,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\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) {\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 projectData = await getOrAskForProjectData(options, 'react-native');\n\n if (projectData.spotlight) {\n clack.log.warn('Spotlight mode is not yet supported for React Native.');\n clack.log.info('Spotlight is currently only available for Next.js.');\n await abort('Exiting wizard', 0);\n return;\n }\n\n const { selectedProject, authToken, sentryUrl } = projectData;\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 // Ask if user wants to enable Session Replay\n const enableSessionReplay = await abortIfCancelled(\n clack.confirm({\n message:\n 'Do you want to enable Session Replay to help debug issues? (See https://docs.sentry.io/platforms/react-native/session-replay/)',\n }),\n );\n Sentry.setTag('enable-session-replay', enableSessionReplay);\n\n if (enableSessionReplay) {\n clack.log.info(\n `Session Replay will be enabled with default settings (replaysSessionSampleRate: ${sessionReplaySampleRate}, replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate}).`,\n );\n clack.log.message(\n 'By default, all text content, images, and webviews will be masked for privacy. You can customize this in your code later.',\n );\n }\n\n // Ask if user wants to enable the Feedback Widget\n const enableFeedbackWidget = await abortIfCancelled(\n clack.confirm({\n message:\n 'Do you want to enable the Feedback Widget to collect feedback from your users? (See https://docs.sentry.io/platforms/react-native/user-feedback/)',\n }),\n );\n Sentry.setTag('enable-feedback-widget', enableFeedbackWidget);\n\n if (enableFeedbackWidget) {\n clack.log.info(\n `The Feedback Widget will be enabled with default settings. You can show the widget by calling Sentry.showFeedbackWidget() in your code.`,\n );\n }\n\n // Ask if user wants to enable Logs\n const enableLogs = await abortIfCancelled(\n clack.confirm({\n message:\n 'Do you want to enable Logs? (See https://docs.sentry.io/platforms/react-native/logs/)',\n }),\n );\n Sentry.setTag('enable-logs', enableLogs);\n\n if (enableLogs) {\n clack.log.info(\n `Logs will be enabled with default settings. You can send logs using the Sentry.logger APIs.`,\n );\n }\n\n await traceStep('patch-app-js', () =>\n addSentryInit({\n dsn: selectedProject.keys[0].dsn.public,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n }),\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', patchMetroWithSentryConfig);\n }\n\n if (fs.existsSync('ios')) {\n Sentry.setTag('patch-ios', true);\n await traceStep('patch-xcode-files', () => patchXcodeFiles(cliConfig));\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({ cwd: undefined });\n\n // Offer optional project-scoped MCP config for Sentry with org and project scope\n await offerProjectScopedMcpConfig(\n selectedProject.organization.slug,\n selectedProject.slug,\n );\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\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(config: RNCliSetupConfigContent) {\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 await traceStep('patch-bundle-phase', async () => {\n const bundlePhase = findBundlePhase(buildPhasesMap);\n Sentry.setTag(\n 'xcode-bundle-phase-status',\n bundlePhase ? 'found' : 'not-found',\n );\n\n await patchBundlePhase(\n bundlePhase,\n addSentryWithBundledScriptsToBundleShellScript,\n );\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\n addDebugFilesUploadPhaseWithBundledScripts(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-expect-error - 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 * as Sentry from '@sentry/node';\nimport { platform } from 'os';\nimport { podInstall } from '../apple/cocoapod';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport { offerProjectScopedMcpConfig } from '../utils/clack/mcp-config';\nimport {\n CliSetupConfigContent,\n abort,\n abortIfCancelled,\n addSentryCliConfig,\n confirmContinueIfNoOrDirtyGitRepo,\n confirmContinueIfPackageVersionNotSupported,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n printWelcome,\n propertiesCliSetupConfig,\n runPrettierIfInstalled,\n} from '../utils/clack';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport { getIssueStreamUrl } from '../utils/url';\nimport {\n isExpoCNG,\n patchExpoAppConfig,\n printSentryExpoMigrationOutro,\n} from './expo';\nimport { addExpoEnvLocal } from './expo-env-file';\nimport { addSentryToExpoMetroConfig } from './expo-metro';\nimport { APP_BUILD_GRADLE, XCODE_PROJECT, getFirstMatchedPath } from './glob';\nimport {\n addRNSentryGradlePlugin,\n doesAppBuildGradleIncludeRNSentryGradlePlugin,\n writeAppBuildGradle,\n} from './gradle';\nimport {\n addSentryInit,\n sessionReplayOnErrorSampleRate,\n sessionReplaySampleRate,\n wrapRootComponent,\n} from './javascript';\nimport { patchMetroWithSentryConfig } from './metro';\nimport { ReactNativeWizardOptions } from './options';\nimport {\n addDebugFilesUploadPhaseWithBundledScripts,\n addSentryWithBundledScriptsToBundleShellScript,\n findBundlePhase,\n findDebugFilesUploadPhase,\n getValidExistingBuildPhases,\n patchBundlePhase,\n writeXcodeProject,\n} from './xcode';\n\nimport xcode from 'xcode';\nimport { abortIfSpotlightNotSupported } from '../utils/abort-if-sportlight-not-supported';\n\nexport const RN_SDK_PACKAGE = '@sentry/react-native';\nexport const RN_SDK_SUPPORTED_RANGE = '>=6.12.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\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 const { promoCode, telemetryEnabled, forceInstall } = options;\n\n printWelcome({\n wizardName: 'Sentry React Native Wizard',\n promoCode,\n telemetryEnabled,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\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) {\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 projectData = await getOrAskForProjectData(options, 'react-native');\n\n if (projectData.spotlight) {\n return abortIfSpotlightNotSupported('React Native');\n }\n\n const { selectedProject, authToken, sentryUrl } = projectData;\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 // Ask if user wants to enable Session Replay\n const enableSessionReplay = await abortIfCancelled(\n clack.confirm({\n message:\n 'Do you want to enable Session Replay to help debug issues? (See https://docs.sentry.io/platforms/react-native/session-replay/)',\n }),\n );\n Sentry.setTag('enable-session-replay', enableSessionReplay);\n\n if (enableSessionReplay) {\n clack.log.info(\n `Session Replay will be enabled with default settings (replaysSessionSampleRate: ${sessionReplaySampleRate}, replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate}).`,\n );\n clack.log.message(\n 'By default, all text content, images, and webviews will be masked for privacy. You can customize this in your code later.',\n );\n }\n\n // Ask if user wants to enable the Feedback Widget\n const enableFeedbackWidget = await abortIfCancelled(\n clack.confirm({\n message:\n 'Do you want to enable the Feedback Widget to collect feedback from your users? (See https://docs.sentry.io/platforms/react-native/user-feedback/)',\n }),\n );\n Sentry.setTag('enable-feedback-widget', enableFeedbackWidget);\n\n if (enableFeedbackWidget) {\n clack.log.info(\n `The Feedback Widget will be enabled with default settings. You can show the widget by calling Sentry.showFeedbackWidget() in your code.`,\n );\n }\n\n // Ask if user wants to enable Logs\n const enableLogs = await abortIfCancelled(\n clack.confirm({\n message:\n 'Do you want to enable Logs? (See https://docs.sentry.io/platforms/react-native/logs/)',\n }),\n );\n Sentry.setTag('enable-logs', enableLogs);\n\n if (enableLogs) {\n clack.log.info(\n `Logs will be enabled with default settings. You can send logs using the Sentry.logger APIs.`,\n );\n }\n\n await traceStep('patch-app-js', () =>\n addSentryInit({\n dsn: selectedProject.keys[0].dsn.public,\n enableSessionReplay,\n enableFeedbackWidget,\n enableLogs,\n }),\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', patchMetroWithSentryConfig);\n }\n\n if (isExpo && (await isExpoCNG())) {\n Sentry.setTag('expo-cng', true);\n clack.log.info(\n `Detected Expo Continuous Native Generation (CNG) setup. Skipping native files patching.`,\n );\n } else {\n if (fs.existsSync('ios')) {\n Sentry.setTag('patch-ios', true);\n await traceStep('patch-xcode-files', () => patchXcodeFiles(cliConfig));\n }\n\n if (fs.existsSync('android')) {\n Sentry.setTag('patch-android', true);\n await traceStep('patch-android-files', () =>\n patchAndroidFiles(cliConfig),\n );\n }\n }\n\n await runPrettierIfInstalled({ cwd: undefined });\n\n // Offer optional project-scoped MCP config for Sentry with org and project scope\n await offerProjectScopedMcpConfig(\n selectedProject.organization.slug,\n selectedProject.slug,\n );\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\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(config: RNCliSetupConfigContent) {\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 await traceStep('patch-bundle-phase', async () => {\n const bundlePhase = findBundlePhase(buildPhasesMap);\n Sentry.setTag(\n 'xcode-bundle-phase-status',\n bundlePhase ? 'found' : 'not-found',\n );\n\n await patchBundlePhase(\n bundlePhase,\n addSentryWithBundledScriptsToBundleShellScript,\n );\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\n addDebugFilesUploadPhaseWithBundledScripts(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 +1 @@
|
|
|
1
|
-
export declare function instrumentClientEntry(clientEntryPath: string, dsn: string, enableTracing: boolean, enableReplay: boolean, enableLogs: boolean): Promise<void>;
|
|
1
|
+
export declare function instrumentClientEntry(clientEntryPath: string, dsn: string, enableTracing: boolean, enableReplay: boolean, enableLogs: boolean, useInstrumentationAPI?: boolean): Promise<void>;
|
|
@@ -38,7 +38,7 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
38
38
|
const magicast_1 = require("magicast");
|
|
39
39
|
const ast_utils_1 = require("../../utils/ast-utils");
|
|
40
40
|
const utils_1 = require("./utils");
|
|
41
|
-
async function instrumentClientEntry(clientEntryPath, dsn, enableTracing, enableReplay, enableLogs) {
|
|
41
|
+
async function instrumentClientEntry(clientEntryPath, dsn, enableTracing, enableReplay, enableLogs, useInstrumentationAPI = false) {
|
|
42
42
|
const clientEntryAst = await (0, magicast_1.loadFile)(clientEntryPath);
|
|
43
43
|
if ((0, ast_utils_1.hasSentryContent)(clientEntryAst.$ast)) {
|
|
44
44
|
const filename = path.basename(clientEntryPath);
|
|
@@ -50,27 +50,84 @@ async function instrumentClientEntry(clientEntryPath, dsn, enableTracing, enable
|
|
|
50
50
|
imported: '*',
|
|
51
51
|
local: 'Sentry',
|
|
52
52
|
});
|
|
53
|
-
|
|
54
|
-
if (enableTracing) {
|
|
55
|
-
integrations
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
let initContent;
|
|
54
|
+
if (useInstrumentationAPI && enableTracing) {
|
|
55
|
+
const integrations = ['tracing'];
|
|
56
|
+
if (enableReplay) {
|
|
57
|
+
integrations.push('Sentry.replayIntegration()');
|
|
58
|
+
}
|
|
59
|
+
initContent = `
|
|
60
|
+
const tracing = Sentry.reactRouterTracingIntegration({ useInstrumentationAPI: true });
|
|
61
|
+
|
|
62
|
+
Sentry.init({
|
|
63
|
+
dsn: "${dsn}",
|
|
64
|
+
sendDefaultPii: true,
|
|
65
|
+
integrations: [${integrations.join(', ')}],
|
|
66
|
+
${enableLogs ? 'enableLogs: true,' : ''}
|
|
67
|
+
tracesSampleRate: 1.0,
|
|
68
|
+
tracePropagationTargets: [/^\\//, /^https:\\/\\/yourserver\\.io\\/api/],${enableReplay
|
|
69
|
+
? '\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1.0,'
|
|
70
|
+
: ''}
|
|
71
|
+
});`;
|
|
59
72
|
}
|
|
60
|
-
|
|
73
|
+
else {
|
|
74
|
+
const integrations = [];
|
|
75
|
+
if (enableTracing) {
|
|
76
|
+
integrations.push('Sentry.reactRouterTracingIntegration()');
|
|
77
|
+
}
|
|
78
|
+
if (enableReplay) {
|
|
79
|
+
integrations.push('Sentry.replayIntegration()');
|
|
80
|
+
}
|
|
81
|
+
initContent = `
|
|
61
82
|
Sentry.init({
|
|
62
83
|
dsn: "${dsn}",
|
|
63
84
|
sendDefaultPii: true,
|
|
64
85
|
integrations: [${integrations.join(', ')}],
|
|
65
86
|
${enableLogs ? 'enableLogs: true,' : ''}
|
|
66
87
|
tracesSampleRate: ${enableTracing ? '1.0' : '0'},${enableTracing
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
? '\n tracePropagationTargets: [/^\\//, /^https:\\/\\/yourserver\\.io\\/api/],'
|
|
89
|
+
: ''}${enableReplay
|
|
90
|
+
? '\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1.0,'
|
|
91
|
+
: ''}
|
|
71
92
|
});`;
|
|
93
|
+
}
|
|
72
94
|
clientEntryAst.$ast.body.splice((0, utils_1.getAfterImportsInsertionIndex)(clientEntryAst.$ast), 0, ...recast.parse(initContent).program.body);
|
|
95
|
+
if (useInstrumentationAPI && enableTracing) {
|
|
96
|
+
const hydratedRouterFound = addInstrumentationPropsToHydratedRouter(clientEntryAst.$ast);
|
|
97
|
+
if (!hydratedRouterFound) {
|
|
98
|
+
prompts_1.default.log.warn(`Could not find ${chalk_1.default.cyan('HydratedRouter')} component in your client entry file.\n` +
|
|
99
|
+
`To use the Instrumentation API, manually add the ${chalk_1.default.cyan('unstable_instrumentations')} prop:\n` +
|
|
100
|
+
` ${chalk_1.default.green('<HydratedRouter unstable_instrumentations={[tracing.clientInstrumentation]} />')}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
73
103
|
await (0, magicast_1.writeFile)(clientEntryAst.$ast, clientEntryPath);
|
|
74
104
|
}
|
|
75
105
|
exports.instrumentClientEntry = instrumentClientEntry;
|
|
106
|
+
function addInstrumentationPropsToHydratedRouter(ast) {
|
|
107
|
+
let found = false;
|
|
108
|
+
recast.visit(ast, {
|
|
109
|
+
visitJSXElement(path) {
|
|
110
|
+
const openingElement = path.node.openingElement;
|
|
111
|
+
if (openingElement.name.type === 'JSXIdentifier' &&
|
|
112
|
+
openingElement.name.name === 'HydratedRouter') {
|
|
113
|
+
found = true;
|
|
114
|
+
const hasInstrumentationsProp = openingElement.attributes?.some((attr) => attr.type === 'JSXAttribute' &&
|
|
115
|
+
attr.name.type === 'JSXIdentifier' &&
|
|
116
|
+
attr.name.name === 'unstable_instrumentations');
|
|
117
|
+
if (!hasInstrumentationsProp) {
|
|
118
|
+
const instrumentationsProp = recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('unstable_instrumentations'), recast.types.builders.jsxExpressionContainer(recast.types.builders.arrayExpression([
|
|
119
|
+
recast.types.builders.memberExpression(recast.types.builders.identifier('tracing'), recast.types.builders.identifier('clientInstrumentation')),
|
|
120
|
+
])));
|
|
121
|
+
if (!openingElement.attributes) {
|
|
122
|
+
openingElement.attributes = [];
|
|
123
|
+
}
|
|
124
|
+
openingElement.attributes.push(instrumentationsProp);
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
this.traverse(path);
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
return found;
|
|
132
|
+
}
|
|
76
133
|
//# sourceMappingURL=client.entry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.entry.js","sourceRoot":"","sources":["../../../../src/react-router/codemods/client.entry.ts"],"names":[],"mappings":";AAAA,0DAA0D;AAC1D,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE/D,+CAAiC;AACjC,2CAA6B;AAG7B,+EAA+E;AAC/E,6DAAmC;AACnC,kDAA0B;AAE1B,kFAAkF;AAClF,uCAA+C;AAC/C,qDAAyD;AACzD,mCAAwD;AAEjD,KAAK,UAAU,qBAAqB,CACzC,eAAuB,EACvB,GAAW,EACX,aAAsB,EACtB,YAAqB,EACrB,UAAmB;
|
|
1
|
+
{"version":3,"file":"client.entry.js","sourceRoot":"","sources":["../../../../src/react-router/codemods/client.entry.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\nimport * as recast from 'recast';\nimport * as path from 'path';\nimport type { namedTypes as t } from 'ast-types';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { loadFile, writeFile } from 'magicast';\nimport { hasSentryContent } from '../../utils/ast-utils';\nimport { getAfterImportsInsertionIndex } from './utils';\n\nexport async function instrumentClientEntry(\n clientEntryPath: string,\n dsn: string,\n enableTracing: boolean,\n enableReplay: boolean,\n enableLogs: boolean,\n useInstrumentationAPI = false,\n): Promise<void> {\n const clientEntryAst = await loadFile(clientEntryPath);\n\n if (hasSentryContent(clientEntryAst.$ast as t.Program)) {\n const filename = path.basename(clientEntryPath);\n clack.log.info(`Sentry initialization found in ${chalk.cyan(filename)}`);\n return;\n }\n\n clientEntryAst.imports.$add({\n from: '@sentry/react-router',\n imported: '*',\n local: 'Sentry',\n });\n\n let initContent: string;\n\n if (useInstrumentationAPI && enableTracing) {\n const integrations = ['tracing'];\n if (enableReplay) {\n integrations.push('Sentry.replayIntegration()');\n }\n\n initContent = `\nconst tracing = Sentry.reactRouterTracingIntegration({ useInstrumentationAPI: true });\n\nSentry.init({\n dsn: \"${dsn}\",\n sendDefaultPii: true,\n integrations: [${integrations.join(', ')}],\n ${enableLogs ? 'enableLogs: true,' : ''}\n tracesSampleRate: 1.0,\n tracePropagationTargets: [/^\\\\//, /^https:\\\\/\\\\/yourserver\\\\.io\\\\/api/],${\n enableReplay\n ? '\\n replaysSessionSampleRate: 0.1,\\n replaysOnErrorSampleRate: 1.0,'\n : ''\n }\n});`;\n } else {\n const integrations = [];\n if (enableTracing) {\n integrations.push('Sentry.reactRouterTracingIntegration()');\n }\n if (enableReplay) {\n integrations.push('Sentry.replayIntegration()');\n }\n\n initContent = `\nSentry.init({\n dsn: \"${dsn}\",\n sendDefaultPii: true,\n integrations: [${integrations.join(', ')}],\n ${enableLogs ? 'enableLogs: true,' : ''}\n tracesSampleRate: ${enableTracing ? '1.0' : '0'},${\n enableTracing\n ? '\\n tracePropagationTargets: [/^\\\\//, /^https:\\\\/\\\\/yourserver\\\\.io\\\\/api/],'\n : ''\n }${\n enableReplay\n ? '\\n replaysSessionSampleRate: 0.1,\\n replaysOnErrorSampleRate: 1.0,'\n : ''\n }\n});`;\n }\n\n (clientEntryAst.$ast as t.Program).body.splice(\n getAfterImportsInsertionIndex(clientEntryAst.$ast as t.Program),\n 0,\n ...recast.parse(initContent).program.body,\n );\n\n if (useInstrumentationAPI && enableTracing) {\n const hydratedRouterFound = addInstrumentationPropsToHydratedRouter(\n clientEntryAst.$ast as t.Program,\n );\n\n if (!hydratedRouterFound) {\n clack.log.warn(\n `Could not find ${chalk.cyan(\n 'HydratedRouter',\n )} component in your client entry file.\\n` +\n `To use the Instrumentation API, manually add the ${chalk.cyan(\n 'unstable_instrumentations',\n )} prop:\\n` +\n ` ${chalk.green(\n '<HydratedRouter unstable_instrumentations={[tracing.clientInstrumentation]} />',\n )}`,\n );\n }\n }\n\n await writeFile(clientEntryAst.$ast, clientEntryPath);\n}\n\nfunction addInstrumentationPropsToHydratedRouter(ast: t.Program): boolean {\n let found = false;\n\n recast.visit(ast, {\n visitJSXElement(path) {\n const openingElement = path.node.openingElement;\n\n if (\n openingElement.name.type === 'JSXIdentifier' &&\n openingElement.name.name === 'HydratedRouter'\n ) {\n found = true;\n\n const hasInstrumentationsProp = openingElement.attributes?.some(\n (attr) =>\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === 'unstable_instrumentations',\n );\n\n if (!hasInstrumentationsProp) {\n const instrumentationsProp = recast.types.builders.jsxAttribute(\n recast.types.builders.jsxIdentifier('unstable_instrumentations'),\n recast.types.builders.jsxExpressionContainer(\n recast.types.builders.arrayExpression([\n recast.types.builders.memberExpression(\n recast.types.builders.identifier('tracing'),\n recast.types.builders.identifier('clientInstrumentation'),\n ),\n ]),\n ),\n );\n\n if (!openingElement.attributes) {\n openingElement.attributes = [];\n }\n openingElement.attributes.push(instrumentationsProp);\n }\n\n return false;\n }\n\n this.traverse(path);\n },\n });\n\n return found;\n}\n"]}
|
|
@@ -170,7 +170,7 @@ export default {
|
|
|
170
170
|
if (!success) {
|
|
171
171
|
throw new Error('Failed to modify React Router config structure');
|
|
172
172
|
}
|
|
173
|
-
const code = (0, magicast_1.generateCode)(mod.$ast).code;
|
|
173
|
+
const code = (0, ast_utils_1.preserveTrailingNewline)(configContent, (0, magicast_1.generateCode)(mod.$ast).code);
|
|
174
174
|
await fs.promises.writeFile(configPath, code);
|
|
175
175
|
return { ssrWasChanged };
|
|
176
176
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-router-config.js","sourceRoot":"","sources":["../../../../src/react-router/codemods/react-router-config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { namedTypes as t } from 'ast-types';\nimport * as recast from 'recast';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { parseModule, generateCode } from 'magicast';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nimport { findProperty } from '../../utils/ast-utils';\n\n/**\n * Extracts the ObjectExpression from various export patterns.\n * Supports: direct object, `satisfies Config`, and `as Config` patterns.\n */\nfunction extractConfigObject(\n declaration: t.Declaration | t.Expression,\n): t.ObjectExpression | undefined {\n if (declaration.type === 'ObjectExpression') {\n return declaration as t.ObjectExpression;\n }\n\n if (\n declaration.type === 'TSSatisfiesExpression' ||\n declaration.type === 'TSAsExpression'\n ) {\n const expr = (declaration as t.TSSatisfiesExpression | t.TSAsExpression)\n .expression;\n return expr.type === 'ObjectExpression' ? expr : undefined;\n }\n\n return undefined;\n}\n\n/**\n * Creates an identifier property for object literals.\n */\nfunction createIdentifierProperty(name: string): t.Property {\n const b = recast.types.builders;\n return b.property('init', b.identifier(name), b.identifier(name));\n}\n\nexport function addSentryBuildEndToReactRouterConfig(program: t.Program): {\n success: boolean;\n ssrWasChanged: boolean;\n} {\n const b = recast.types.builders;\n let ssrWasChanged = false;\n\n const defaultExport = program.body.find(\n (node) => node.type === 'ExportDefaultDeclaration',\n ) as t.ExportDefaultDeclaration | undefined;\n\n if (!defaultExport) {\n return { success: false, ssrWasChanged: false };\n }\n\n const configObj = extractConfigObject(defaultExport.declaration);\n\n if (!configObj) {\n return { success: false, ssrWasChanged: false };\n }\n\n const buildEndProp = findProperty(configObj, 'buildEnd');\n\n if (buildEndProp) {\n throw new Error(\n 'A buildEnd hook already exists in your React Router config.',\n );\n }\n\n const ssrProp = findProperty(configObj, 'ssr');\n\n if (!ssrProp) {\n const ssrProperty = b.objectProperty(\n b.identifier('ssr'),\n b.booleanLiteral(true),\n );\n ssrProperty.comments = [\n {\n type: 'CommentLine',\n value:\n ' SSR is required for Sentry sourcemap uploads to work correctly',\n } as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n ];\n configObj.properties.unshift(ssrProperty);\n ssrWasChanged = true;\n } else if (\n ssrProp.value.type === 'BooleanLiteral' ||\n ssrProp.value.type === 'Literal'\n ) {\n const wasExplicitlyFalse = ssrProp.value.value === false;\n\n if (wasExplicitlyFalse) {\n ssrWasChanged = true;\n }\n\n ssrProp.value = b.booleanLiteral(true);\n\n if (wasExplicitlyFalse) {\n ssrProp.comments = [\n {\n type: 'CommentLine',\n value:\n ' Changed to true - SSR is required for Sentry sourcemap uploads',\n } as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n ];\n }\n }\n\n const paramNames = ['viteConfig', 'reactRouterConfig', 'buildManifest'];\n\n const buildEndFunction = b.arrowFunctionExpression(\n [b.objectPattern(paramNames.map(createIdentifierProperty))],\n b.blockStatement([\n b.expressionStatement(\n b.awaitExpression(\n b.callExpression(b.identifier('sentryOnBuildEnd'), [\n b.objectExpression(paramNames.map(createIdentifierProperty)),\n ]),\n ),\n ),\n ]),\n );\n buildEndFunction.async = true;\n\n configObj.properties.push(\n b.objectProperty(b.identifier('buildEnd'), buildEndFunction),\n );\n\n return { success: true, ssrWasChanged };\n}\n\nexport function hasReactRouterSentryContent(program: t.Program): boolean {\n let hasSentry = false;\n\n recast.visit(program, {\n visitIdentifier(path) {\n if (path.node.name === 'sentryOnBuildEnd') {\n hasSentry = true;\n return false; // stop traversal\n }\n this.traverse(path);\n },\n });\n\n return hasSentry;\n}\n\nexport async function instrumentReactRouterConfig(\n isTS: boolean,\n): Promise<{ ssrWasChanged: boolean }> {\n const configFilename = `react-router.config.${isTS ? 'ts' : 'js'}`;\n const configPath = path.join(process.cwd(), configFilename);\n\n if (!fs.existsSync(configPath)) {\n const defaultConfig = isTS\n ? `import type { Config } from \"@react-router/dev/config\";\nimport { sentryOnBuildEnd } from \"@sentry/react-router\";\n\nexport default {\n ssr: true,\n buildEnd: async ({ viteConfig, reactRouterConfig, buildManifest }) => {\n await sentryOnBuildEnd({ viteConfig, reactRouterConfig, buildManifest });\n },\n} satisfies Config;\n`\n : `import { sentryOnBuildEnd } from \"@sentry/react-router\";\n\nexport default {\n ssr: true,\n buildEnd: async ({ viteConfig, reactRouterConfig, buildManifest }) => {\n await sentryOnBuildEnd({ viteConfig, reactRouterConfig, buildManifest });\n },\n};\n`;\n await fs.promises.writeFile(configPath, defaultConfig);\n return { ssrWasChanged: false };\n }\n\n const configContent = await fs.promises.readFile(configPath, 'utf-8');\n const filename = chalk.cyan(configFilename);\n\n const mod = parseModule(configContent);\n\n if (hasReactRouterSentryContent(mod.$ast as t.Program)) {\n clack.log.info(`${filename} already contains sentryOnBuildEnd.`);\n return { ssrWasChanged: false };\n }\n\n mod.imports.$add({\n from: '@sentry/react-router',\n imported: 'sentryOnBuildEnd',\n local: 'sentryOnBuildEnd',\n });\n\n const { success, ssrWasChanged } = addSentryBuildEndToReactRouterConfig(\n mod.$ast as t.Program,\n );\n\n if (!success) {\n throw new Error('Failed to modify React Router config structure');\n }\n\n const code = generateCode(mod.$ast).code;\n await fs.promises.writeFile(configPath, code);\n\n return { ssrWasChanged };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"react-router-config.js","sourceRoot":"","sources":["../../../../src/react-router/codemods/react-router-config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { namedTypes as t } from 'ast-types';\nimport * as recast from 'recast';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { parseModule, generateCode } from 'magicast';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nimport { findProperty, preserveTrailingNewline } from '../../utils/ast-utils';\n\n/**\n * Extracts the ObjectExpression from various export patterns.\n * Supports: direct object, `satisfies Config`, and `as Config` patterns.\n */\nfunction extractConfigObject(\n declaration: t.Declaration | t.Expression,\n): t.ObjectExpression | undefined {\n if (declaration.type === 'ObjectExpression') {\n return declaration as t.ObjectExpression;\n }\n\n if (\n declaration.type === 'TSSatisfiesExpression' ||\n declaration.type === 'TSAsExpression'\n ) {\n const expr = (declaration as t.TSSatisfiesExpression | t.TSAsExpression)\n .expression;\n return expr.type === 'ObjectExpression' ? expr : undefined;\n }\n\n return undefined;\n}\n\n/**\n * Creates an identifier property for object literals.\n */\nfunction createIdentifierProperty(name: string): t.Property {\n const b = recast.types.builders;\n return b.property('init', b.identifier(name), b.identifier(name));\n}\n\nexport function addSentryBuildEndToReactRouterConfig(program: t.Program): {\n success: boolean;\n ssrWasChanged: boolean;\n} {\n const b = recast.types.builders;\n let ssrWasChanged = false;\n\n const defaultExport = program.body.find(\n (node) => node.type === 'ExportDefaultDeclaration',\n ) as t.ExportDefaultDeclaration | undefined;\n\n if (!defaultExport) {\n return { success: false, ssrWasChanged: false };\n }\n\n const configObj = extractConfigObject(defaultExport.declaration);\n\n if (!configObj) {\n return { success: false, ssrWasChanged: false };\n }\n\n const buildEndProp = findProperty(configObj, 'buildEnd');\n\n if (buildEndProp) {\n throw new Error(\n 'A buildEnd hook already exists in your React Router config.',\n );\n }\n\n const ssrProp = findProperty(configObj, 'ssr');\n\n if (!ssrProp) {\n const ssrProperty = b.objectProperty(\n b.identifier('ssr'),\n b.booleanLiteral(true),\n );\n ssrProperty.comments = [\n {\n type: 'CommentLine',\n value:\n ' SSR is required for Sentry sourcemap uploads to work correctly',\n } as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n ];\n configObj.properties.unshift(ssrProperty);\n ssrWasChanged = true;\n } else if (\n ssrProp.value.type === 'BooleanLiteral' ||\n ssrProp.value.type === 'Literal'\n ) {\n const wasExplicitlyFalse = ssrProp.value.value === false;\n\n if (wasExplicitlyFalse) {\n ssrWasChanged = true;\n }\n\n ssrProp.value = b.booleanLiteral(true);\n\n if (wasExplicitlyFalse) {\n ssrProp.comments = [\n {\n type: 'CommentLine',\n value:\n ' Changed to true - SSR is required for Sentry sourcemap uploads',\n } as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n ];\n }\n }\n\n const paramNames = ['viteConfig', 'reactRouterConfig', 'buildManifest'];\n\n const buildEndFunction = b.arrowFunctionExpression(\n [b.objectPattern(paramNames.map(createIdentifierProperty))],\n b.blockStatement([\n b.expressionStatement(\n b.awaitExpression(\n b.callExpression(b.identifier('sentryOnBuildEnd'), [\n b.objectExpression(paramNames.map(createIdentifierProperty)),\n ]),\n ),\n ),\n ]),\n );\n buildEndFunction.async = true;\n\n configObj.properties.push(\n b.objectProperty(b.identifier('buildEnd'), buildEndFunction),\n );\n\n return { success: true, ssrWasChanged };\n}\n\nexport function hasReactRouterSentryContent(program: t.Program): boolean {\n let hasSentry = false;\n\n recast.visit(program, {\n visitIdentifier(path) {\n if (path.node.name === 'sentryOnBuildEnd') {\n hasSentry = true;\n return false; // stop traversal\n }\n this.traverse(path);\n },\n });\n\n return hasSentry;\n}\n\nexport async function instrumentReactRouterConfig(\n isTS: boolean,\n): Promise<{ ssrWasChanged: boolean }> {\n const configFilename = `react-router.config.${isTS ? 'ts' : 'js'}`;\n const configPath = path.join(process.cwd(), configFilename);\n\n if (!fs.existsSync(configPath)) {\n const defaultConfig = isTS\n ? `import type { Config } from \"@react-router/dev/config\";\nimport { sentryOnBuildEnd } from \"@sentry/react-router\";\n\nexport default {\n ssr: true,\n buildEnd: async ({ viteConfig, reactRouterConfig, buildManifest }) => {\n await sentryOnBuildEnd({ viteConfig, reactRouterConfig, buildManifest });\n },\n} satisfies Config;\n`\n : `import { sentryOnBuildEnd } from \"@sentry/react-router\";\n\nexport default {\n ssr: true,\n buildEnd: async ({ viteConfig, reactRouterConfig, buildManifest }) => {\n await sentryOnBuildEnd({ viteConfig, reactRouterConfig, buildManifest });\n },\n};\n`;\n await fs.promises.writeFile(configPath, defaultConfig);\n return { ssrWasChanged: false };\n }\n\n const configContent = await fs.promises.readFile(configPath, 'utf-8');\n const filename = chalk.cyan(configFilename);\n\n const mod = parseModule(configContent);\n\n if (hasReactRouterSentryContent(mod.$ast as t.Program)) {\n clack.log.info(`${filename} already contains sentryOnBuildEnd.`);\n return { ssrWasChanged: false };\n }\n\n mod.imports.$add({\n from: '@sentry/react-router',\n imported: 'sentryOnBuildEnd',\n local: 'sentryOnBuildEnd',\n });\n\n const { success, ssrWasChanged } = addSentryBuildEndToReactRouterConfig(\n mod.$ast as t.Program,\n );\n\n if (!success) {\n throw new Error('Failed to modify React Router config structure');\n }\n\n const code = preserveTrailingNewline(\n configContent,\n generateCode(mod.$ast).code,\n );\n await fs.promises.writeFile(configPath, code);\n\n return { ssrWasChanged };\n}\n"]}
|
|
@@ -51,8 +51,7 @@ function hasCaptureExceptionCall(node) {
|
|
|
51
51
|
return found;
|
|
52
52
|
}
|
|
53
53
|
function addCaptureExceptionCall(functionNode) {
|
|
54
|
-
const captureExceptionCall = recast.parse(`Sentry.captureException(error)
|
|
55
|
-
.program.body[0];
|
|
54
|
+
const captureExceptionCall = recast.parse(`if (error && error instanceof Error) {\n Sentry.captureException(error);\n}`).program.body[0];
|
|
56
55
|
const functionBody = (0, ast_utils_1.safeGetFunctionBody)(functionNode);
|
|
57
56
|
if (functionBody) {
|
|
58
57
|
if (!(0, ast_utils_1.safeInsertBeforeReturn)(functionBody, captureExceptionCall)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../../../src/react-router/codemods/root.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+DAA+D;AAC/D,4DAA4D;AAC5D,sDAAsD;AACtD,0DAA0D;AAC1D,+CAAiC;AACjC,2CAA6B;AAK7B,uCAIkB;AAElB,4CAAuD;AACvD,qDAI+B;AAC/B,6CAA0C;AAE1C,SAAS,uBAAuB,CAAC,IAAY;IAC3C,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE;QACjB,mBAAmB,CAAC,IAAI;YACtB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YACjC,IACE,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB;gBACjC,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,QAAQ;gBAChC,MAAM,CAAC,QAAQ,EAAE,IAAI,KAAK,kBAAkB,CAAC;gBAC/C,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC,EACpE;gBACA,KAAK,GAAG,IAAI,CAAC;aACd;YACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;KACF,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,uBAAuB,CAAC,YAAoB;IACnD,MAAM,oBAAoB,GAAG,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC;SACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEnB,MAAM,YAAY,GAAG,IAAA,+BAAmB,EAAC,YAAY,CAAC,CAAC;IACvD,IAAI,YAAY,EAAE;QAChB,IAAI,CAAC,IAAA,kCAAsB,EAAC,YAAY,EAAE,oBAAoB,CAAC,EAAE;YAC/D,YAAY,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;SACzC;KACF;SAAM;QACL,IAAA,aAAK,EAAC,qDAAqD,CAAC,CAAC;KAC9D;AACH,CAAC;AAED,SAAS,0BAA0B,CACjC,YAAsC;IAEtC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;QACvC,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC;QAE5C,IAAI,CAAC,WAAW,EAAE;YAChB,OAAO,WAAW,CAAC,UAAU,EAAE,IAAI,CACjC,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,KAAK,iBAAiB;gBAC/B,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,YAAY;gBACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,eAAe,CACzC,CAAC;SACH;QAED,IAAI,WAAW,CAAC,IAAI,KAAK,qBAAqB,EAAE;YAC9C,OAAO,WAAW,CAAC,EAAE,EAAE,IAAI,KAAK,eAAe,CAAC;SACjD;QAED,IAAI,WAAW,CAAC,IAAI,KAAK,qBAAqB,EAAE;YAC9C,OAAO,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC5C,+DAA+D;gBAC/D,OAAO,IAAI,CAAC,EAAE,EAAE,IAAI,KAAK,eAAe,CAAC;YAC3C,CAAC,CAAC,CAAC;SACJ;QAED,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,cAAc,CAAC,YAAoB;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,MAAM,IAAA,mBAAQ,EAAC,QAAQ,CAAC,CAAC;IAE9C,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,IAAiB,CAAC;IAC1D,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CACzC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,wBAAwB,CACrB,CAAC;IAE9B,MAAM,kBAAkB,GAAG,0BAA0B,CAAC,YAAY,CAAC,CAAC;IACpE,MAAM,gBAAgB,GAAG,IAAA,4BAAgB,EAAC,YAAY,CAAC,IAAiB,CAAC,CAAC;IAE1E,IAAI,CAAC,gBAAgB,EAAE;QACrB,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;YACxB,IAAI,EAAE,sBAAsB;YAC5B,QAAQ,EAAE,GAAG;YACb,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;KACJ;IAED,IAAI,CAAC,kBAAkB,EAAE;QACvB,MAAM,6BAA6B,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CACpE,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,QAAQ,KAAK,sBAAsB;YACxC,IAAI,CAAC,IAAI,KAAK,cAAc,CAC/B,CAAC;QAEF,IAAI,CAAC,6BAA6B,EAAE;YAClC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;gBACxB,IAAI,EAAE,cAAc;gBACpB,QAAQ,EAAE,sBAAsB;gBAChC,KAAK,EAAE,sBAAsB;aAC9B,CAAC,CAAC;SACJ;QAED,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE;YAC9B,6BAA6B,CAAC,IAAI;gBAChC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,mCAAuB,CAAC,CAAC,OAAO;qBACjE,IAAI,CAAC,CAAC,CAAC,CAAC;gBAEX,IAAI,CAAC,YAAY,CACf,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,CAC/D,CAAC;gBAEF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;SACF,CAAC,CAAC;KACJ;SAAM;QACL,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE;YAC9B,2BAA2B,CAAC,IAAI;gBAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;gBAC3C,IAAI,CAAC,WAAW,EAAE;oBAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACpB,OAAO;iBACR;gBAED,IAAI,oBAAoB,GAAG,IAAI,CAAC;gBAEhC,IACE,WAAW,CAAC,IAAI,KAAK,qBAAqB;oBAC1C,WAAW,CAAC,EAAE,EAAE,IAAI,KAAK,eAAe,EACxC;oBACA,oBAAoB,GAAG,WAAW,CAAC;iBACpC;qBAAM,IACL,WAAW,CAAC,IAAI,KAAK,qBAAqB;oBAC1C,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,KAAK,eAAe,EAC3D;oBACA,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC9C,IACE,IAAI;wBACJ,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAoB;4BACjC,IAAI,CAAC,IAAI,KAAK,yBAAyB,CAAC,EAC1C;wBACA,oBAAoB,GAAG,IAAI,CAAC;qBAC7B;iBACF;gBAED,IACE,oBAAoB;oBACpB,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,EAC9C;oBACA,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;iBAC/C;gBAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;YAED,wBAAwB,CAAC,IAAI;gBAC3B,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,KAAK,eAAe,EAAE;oBAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC7C,IACE,IAAI;wBACJ,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAoB;4BACjC,IAAI,CAAC,IAAI,KAAK,yBAAyB,CAAC;wBAC1C,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAC9B;wBACA,uBAAuB,CAAC,IAAI,CAAC,CAAC;qBAC/B;iBACF;gBACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;YAED,wBAAwB,CAAC,IAAI;gBAC3B,IACE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,KAAK,eAAe;oBACvC,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EACpC;oBACA,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;iBACrC;gBACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;SACF,CAAC,CAAC;KACJ;IAED,MAAM,IAAA,oBAAS,EAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAnHD,wCAmHC","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\nimport * as recast from 'recast';\nimport * as path from 'path';\n\nimport type { ExportNamedDeclaration } from '@babel/types';\nimport type { namedTypes as t } from 'ast-types';\n\nimport {\n loadFile,\n writeFile,\n // @ts-expect-error - magicast is ESM and TS complains about that. It works though\n} from 'magicast';\n\nimport { ERROR_BOUNDARY_TEMPLATE } from '../templates';\nimport {\n hasSentryContent,\n safeGetFunctionBody,\n safeInsertBeforeReturn,\n} from '../../utils/ast-utils';\nimport { debug } from '../../utils/debug';\n\nfunction hasCaptureExceptionCall(node: t.Node): boolean {\n let found = false;\n recast.visit(node, {\n visitCallExpression(path) {\n const callee = path.value.callee;\n if (\n (callee.type === 'MemberExpression' &&\n callee.object?.name === 'Sentry' &&\n callee.property?.name === 'captureException') ||\n (callee.type === 'Identifier' && callee.name === 'captureException')\n ) {\n found = true;\n }\n this.traverse(path);\n },\n });\n return found;\n}\n\nfunction addCaptureExceptionCall(functionNode: t.Node): void {\n const captureExceptionCall = recast.parse(`Sentry.captureException(error);`)\n .program.body[0];\n\n const functionBody = safeGetFunctionBody(functionNode);\n if (functionBody) {\n if (!safeInsertBeforeReturn(functionBody, captureExceptionCall)) {\n functionBody.push(captureExceptionCall);\n }\n } else {\n debug('Could not safely access ErrorBoundary function body');\n }\n}\n\nfunction findErrorBoundaryInExports(\n namedExports: ExportNamedDeclaration[],\n): boolean {\n return namedExports.some((namedExport) => {\n const declaration = namedExport.declaration;\n\n if (!declaration) {\n return namedExport.specifiers?.some(\n (spec) =>\n spec.type === 'ExportSpecifier' &&\n spec.exported?.type === 'Identifier' &&\n spec.exported.name === 'ErrorBoundary',\n );\n }\n\n if (declaration.type === 'FunctionDeclaration') {\n return declaration.id?.name === 'ErrorBoundary';\n }\n\n if (declaration.type === 'VariableDeclaration') {\n return declaration.declarations.some((decl) => {\n // @ts-expect-error - id should always have a name in this case\n return decl.id?.name === 'ErrorBoundary';\n });\n }\n\n return false;\n });\n}\n\nexport async function instrumentRoot(rootFileName: string): Promise<void> {\n const filePath = path.join(process.cwd(), 'app', rootFileName);\n const rootRouteAst = await loadFile(filePath);\n\n const exportsAst = rootRouteAst.exports.$ast as t.Program;\n const namedExports = exportsAst.body.filter(\n (node) => node.type === 'ExportNamedDeclaration',\n ) as ExportNamedDeclaration[];\n\n const foundErrorBoundary = findErrorBoundaryInExports(namedExports);\n const alreadyHasSentry = hasSentryContent(rootRouteAst.$ast as t.Program);\n\n if (!alreadyHasSentry) {\n rootRouteAst.imports.$add({\n from: '@sentry/react-router',\n imported: '*',\n local: 'Sentry',\n });\n }\n\n if (!foundErrorBoundary) {\n const hasIsRouteErrorResponseImport = rootRouteAst.imports.$items.some(\n (item) =>\n item.imported === 'isRouteErrorResponse' &&\n item.from === 'react-router',\n );\n\n if (!hasIsRouteErrorResponseImport) {\n rootRouteAst.imports.$add({\n from: 'react-router',\n imported: 'isRouteErrorResponse',\n local: 'isRouteErrorResponse',\n });\n }\n\n recast.visit(rootRouteAst.$ast, {\n visitExportDefaultDeclaration(path) {\n const implementation = recast.parse(ERROR_BOUNDARY_TEMPLATE).program\n .body[0];\n\n path.insertBefore(\n recast.types.builders.exportDeclaration(false, implementation),\n );\n\n this.traverse(path);\n },\n });\n } else {\n recast.visit(rootRouteAst.$ast, {\n visitExportNamedDeclaration(path) {\n const declaration = path.value.declaration;\n if (!declaration) {\n this.traverse(path);\n return;\n }\n\n let functionToInstrument = null;\n\n if (\n declaration.type === 'FunctionDeclaration' &&\n declaration.id?.name === 'ErrorBoundary'\n ) {\n functionToInstrument = declaration;\n } else if (\n declaration.type === 'VariableDeclaration' &&\n declaration.declarations?.[0]?.id?.name === 'ErrorBoundary'\n ) {\n const init = declaration.declarations[0].init;\n if (\n init &&\n (init.type === 'FunctionExpression' ||\n init.type === 'ArrowFunctionExpression')\n ) {\n functionToInstrument = init;\n }\n }\n\n if (\n functionToInstrument &&\n !hasCaptureExceptionCall(functionToInstrument)\n ) {\n addCaptureExceptionCall(functionToInstrument);\n }\n\n this.traverse(path);\n },\n\n visitVariableDeclaration(path) {\n if (path.value.declarations?.[0]?.id?.name === 'ErrorBoundary') {\n const init = path.value.declarations[0].init;\n if (\n init &&\n (init.type === 'FunctionExpression' ||\n init.type === 'ArrowFunctionExpression') &&\n !hasCaptureExceptionCall(init)\n ) {\n addCaptureExceptionCall(init);\n }\n }\n this.traverse(path);\n },\n\n visitFunctionDeclaration(path) {\n if (\n path.value.id?.name === 'ErrorBoundary' &&\n !hasCaptureExceptionCall(path.value)\n ) {\n addCaptureExceptionCall(path.value);\n }\n this.traverse(path);\n },\n });\n }\n\n await writeFile(rootRouteAst.$ast, filePath);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../../../src/react-router/codemods/root.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\nimport * as recast from 'recast';\nimport * as path from 'path';\n\nimport type { ExportNamedDeclaration } from '@babel/types';\nimport type { namedTypes as t } from 'ast-types';\n\nimport {\n loadFile,\n writeFile,\n // @ts-expect-error - magicast is ESM and TS complains about that. It works though\n} from 'magicast';\n\nimport { ERROR_BOUNDARY_TEMPLATE } from '../templates';\nimport {\n hasSentryContent,\n safeGetFunctionBody,\n safeInsertBeforeReturn,\n} from '../../utils/ast-utils';\nimport { debug } from '../../utils/debug';\n\nfunction hasCaptureExceptionCall(node: t.Node): boolean {\n let found = false;\n recast.visit(node, {\n visitCallExpression(path) {\n const callee = path.value.callee;\n if (\n (callee.type === 'MemberExpression' &&\n callee.object?.name === 'Sentry' &&\n callee.property?.name === 'captureException') ||\n (callee.type === 'Identifier' && callee.name === 'captureException')\n ) {\n found = true;\n }\n this.traverse(path);\n },\n });\n return found;\n}\n\nfunction addCaptureExceptionCall(functionNode: t.Node): void {\n const captureExceptionCall = recast.parse(\n `if (error && error instanceof Error) {\\n Sentry.captureException(error);\\n}`,\n ).program.body[0];\n\n const functionBody = safeGetFunctionBody(functionNode);\n if (functionBody) {\n if (!safeInsertBeforeReturn(functionBody, captureExceptionCall)) {\n functionBody.push(captureExceptionCall);\n }\n } else {\n debug('Could not safely access ErrorBoundary function body');\n }\n}\n\nfunction findErrorBoundaryInExports(\n namedExports: ExportNamedDeclaration[],\n): boolean {\n return namedExports.some((namedExport) => {\n const declaration = namedExport.declaration;\n\n if (!declaration) {\n return namedExport.specifiers?.some(\n (spec) =>\n spec.type === 'ExportSpecifier' &&\n spec.exported?.type === 'Identifier' &&\n spec.exported.name === 'ErrorBoundary',\n );\n }\n\n if (declaration.type === 'FunctionDeclaration') {\n return declaration.id?.name === 'ErrorBoundary';\n }\n\n if (declaration.type === 'VariableDeclaration') {\n return declaration.declarations.some((decl) => {\n // @ts-expect-error - id should always have a name in this case\n return decl.id?.name === 'ErrorBoundary';\n });\n }\n\n return false;\n });\n}\n\nexport async function instrumentRoot(rootFileName: string): Promise<void> {\n const filePath = path.join(process.cwd(), 'app', rootFileName);\n const rootRouteAst = await loadFile(filePath);\n\n const exportsAst = rootRouteAst.exports.$ast as t.Program;\n const namedExports = exportsAst.body.filter(\n (node) => node.type === 'ExportNamedDeclaration',\n ) as ExportNamedDeclaration[];\n\n const foundErrorBoundary = findErrorBoundaryInExports(namedExports);\n const alreadyHasSentry = hasSentryContent(rootRouteAst.$ast as t.Program);\n\n if (!alreadyHasSentry) {\n rootRouteAst.imports.$add({\n from: '@sentry/react-router',\n imported: '*',\n local: 'Sentry',\n });\n }\n\n if (!foundErrorBoundary) {\n const hasIsRouteErrorResponseImport = rootRouteAst.imports.$items.some(\n (item) =>\n item.imported === 'isRouteErrorResponse' &&\n item.from === 'react-router',\n );\n\n if (!hasIsRouteErrorResponseImport) {\n rootRouteAst.imports.$add({\n from: 'react-router',\n imported: 'isRouteErrorResponse',\n local: 'isRouteErrorResponse',\n });\n }\n\n recast.visit(rootRouteAst.$ast, {\n visitExportDefaultDeclaration(path) {\n const implementation = recast.parse(ERROR_BOUNDARY_TEMPLATE).program\n .body[0];\n\n path.insertBefore(\n recast.types.builders.exportDeclaration(false, implementation),\n );\n\n this.traverse(path);\n },\n });\n } else {\n recast.visit(rootRouteAst.$ast, {\n visitExportNamedDeclaration(path) {\n const declaration = path.value.declaration;\n if (!declaration) {\n this.traverse(path);\n return;\n }\n\n let functionToInstrument = null;\n\n if (\n declaration.type === 'FunctionDeclaration' &&\n declaration.id?.name === 'ErrorBoundary'\n ) {\n functionToInstrument = declaration;\n } else if (\n declaration.type === 'VariableDeclaration' &&\n declaration.declarations?.[0]?.id?.name === 'ErrorBoundary'\n ) {\n const init = declaration.declarations[0].init;\n if (\n init &&\n (init.type === 'FunctionExpression' ||\n init.type === 'ArrowFunctionExpression')\n ) {\n functionToInstrument = init;\n }\n }\n\n if (\n functionToInstrument &&\n !hasCaptureExceptionCall(functionToInstrument)\n ) {\n addCaptureExceptionCall(functionToInstrument);\n }\n\n this.traverse(path);\n },\n\n visitVariableDeclaration(path) {\n if (path.value.declarations?.[0]?.id?.name === 'ErrorBoundary') {\n const init = path.value.declarations[0].init;\n if (\n init &&\n (init.type === 'FunctionExpression' ||\n init.type === 'ArrowFunctionExpression') &&\n !hasCaptureExceptionCall(init)\n ) {\n addCaptureExceptionCall(init);\n }\n }\n this.traverse(path);\n },\n\n visitFunctionDeclaration(path) {\n if (\n path.value.id?.name === 'ErrorBoundary' &&\n !hasCaptureExceptionCall(path.value)\n ) {\n addCaptureExceptionCall(path.value);\n }\n this.traverse(path);\n },\n });\n }\n\n await writeFile(rootRouteAst.$ast, filePath);\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ProxifiedModule } from 'magicast';
|
|
2
|
-
export declare function instrumentServerEntry(serverEntryPath: string): Promise<void>;
|
|
2
|
+
export declare function instrumentServerEntry(serverEntryPath: string, useInstrumentationAPI?: boolean): Promise<void>;
|
|
3
3
|
export declare function instrumentHandleRequest(originalEntryServerMod: ProxifiedModule<any>): void;
|
|
4
4
|
export declare function instrumentHandleError(originalEntryServerMod: ProxifiedModule<any>): void;
|