@sentry/wizard 6.4.0 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/e2e-tests/tests/angular-17.test.js +1 -0
  3. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
  4. package/dist/e2e-tests/tests/angular-19.test.js +1 -0
  5. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
  6. package/dist/e2e-tests/tests/expo.test.js +13 -3
  7. package/dist/e2e-tests/tests/expo.test.js.map +1 -1
  8. package/dist/e2e-tests/tests/nuxt-3.test.js +6 -0
  9. package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
  10. package/dist/e2e-tests/tests/nuxt-4.test.js +6 -0
  11. package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
  12. package/dist/e2e-tests/tests/react-native.test.js +14 -4
  13. package/dist/e2e-tests/tests/react-native.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/remix.test.js +2 -1
  15. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  16. package/dist/e2e-tests/tests/sveltekit-hooks.test.js +13 -2
  17. package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
  18. package/dist/e2e-tests/tests/sveltekit-tracing.test.js +4 -0
  19. package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
  20. package/dist/src/android/android-wizard.js +9 -1
  21. package/dist/src/android/android-wizard.js.map +1 -1
  22. package/dist/src/android/manifest.d.ts +1 -1
  23. package/dist/src/android/manifest.js +2 -2
  24. package/dist/src/android/manifest.js.map +1 -1
  25. package/dist/src/android/templates.d.ts +1 -1
  26. package/dist/src/android/templates.js +4 -1
  27. package/dist/src/android/templates.js.map +1 -1
  28. package/dist/src/angular/codemods/main.js +1 -0
  29. package/dist/src/angular/codemods/main.js.map +1 -1
  30. package/dist/src/apple/templates.js +0 -2
  31. package/dist/src/apple/templates.js.map +1 -1
  32. package/dist/src/nextjs/nextjs-wizard.js +1 -1
  33. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  34. package/dist/src/nextjs/templates.js +6 -4
  35. package/dist/src/nextjs/templates.js.map +1 -1
  36. package/dist/src/nuxt/templates.js +10 -2
  37. package/dist/src/nuxt/templates.js.map +1 -1
  38. package/dist/src/react-native/javascript.d.ts +6 -4
  39. package/dist/src/react-native/javascript.js +11 -7
  40. package/dist/src/react-native/javascript.js.map +1 -1
  41. package/dist/src/react-native/react-native-wizard.js +9 -0
  42. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  43. package/dist/src/react-native/xcode.js +5 -3
  44. package/dist/src/react-native/xcode.js.map +1 -1
  45. package/dist/src/remix/sdk-setup.js +1 -0
  46. package/dist/src/remix/sdk-setup.js.map +1 -1
  47. package/dist/src/sveltekit/sdk-setup/setup.d.ts +6 -0
  48. package/dist/src/sveltekit/sdk-setup/setup.js +4 -1
  49. package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
  50. package/dist/src/sveltekit/templates.js +9 -0
  51. package/dist/src/sveltekit/templates.js.map +1 -1
  52. package/dist/src/utils/clack/index.js +4 -1
  53. package/dist/src/utils/clack/index.js.map +1 -1
  54. package/dist/src/version.d.ts +1 -1
  55. package/dist/src/version.js +1 -1
  56. package/dist/src/version.js.map +1 -1
  57. package/dist/test/angular/angular-wizard.test.js +113 -17
  58. package/dist/test/angular/angular-wizard.test.js.map +1 -1
  59. package/dist/test/apple/code-tools.test.js +0 -3
  60. package/dist/test/apple/code-tools.test.js.map +1 -1
  61. package/dist/test/apple/templates.test.js +0 -4
  62. package/dist/test/apple/templates.test.js.map +1 -1
  63. package/dist/test/nextjs/templates.test.js +33 -22
  64. package/dist/test/nextjs/templates.test.js.map +1 -1
  65. package/dist/test/nuxt/templates.test.js +50 -10
  66. package/dist/test/nuxt/templates.test.js.map +1 -1
  67. package/dist/test/react-native/javascript.test.js +225 -0
  68. package/dist/test/react-native/javascript.test.js.map +1 -1
  69. package/dist/test/react-native/xcode.test.js +20 -2
  70. package/dist/test/react-native/xcode.test.js.map +1 -1
  71. package/dist/test/remix/client-entry.test.js +10 -4
  72. package/dist/test/remix/client-entry.test.js.map +1 -1
  73. package/dist/test/sveltekit/templates.test.js +214 -0
  74. package/dist/test/sveltekit/templates.test.js.map +1 -1
  75. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"remix.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/remix.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport { Integration } from '../../lib/Constants';\nimport {\n KEYS,\n TEST_ARGS,\n checkEnvBuildPlugin,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n createFile,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport { afterAll, beforeAll, describe, test } from 'vitest';\n\nconst SERVER_TEMPLATE = `import { createRequestHandler } from '@remix-run/express';\nimport { installGlobals } from '@remix-run/node';\nimport compression from 'compression';\nimport express from 'express';\nimport morgan from 'morgan';\n\ninstallGlobals();\n\nconst viteDevServer =\n process.env.NODE_ENV === 'production'\n ? undefined\n : await import('vite').then(vite =>\n vite.createServer({\n server: { middlewareMode: true },\n }),\n );\n\nconst app = express();\n\napp.use(compression());\napp.disable('x-powered-by');\n\nif (viteDevServer) {\n app.use(viteDevServer.middlewares);\n} else {\n app.use('/assets', express.static('build/client/assets', { immutable: true, maxAge: '1y' }));\n}\n\napp.use(express.static('build/client', { maxAge: '1h' }));\napp.use(morgan('tiny'));\n\napp.all(\n '*',\n createRequestHandler({\n build: viteDevServer\n ? () => viteDevServer.ssrLoadModule('virtual:remix/server-build')\n : await import('./build/server/index.js'),\n }),\n);\n\napp.listen(0, () => console.log('Express server listening'));\n`;\n\nasync function runWizardOnRemixProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (\n projectDir: string,\n integration: Integration,\n ) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir);\n let packageManagerPrompted = false;\n\n if (fileModificationFn) {\n fileModificationFn(projectDir, integration);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n packageManagerPrompted = await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n packageManagerPrompted = await wizardInstance.waitForOutput(\n 'Please select your package manager.',\n );\n }\n\n const tracingOptionPrompted =\n packageManagerPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n },\n ));\n\n const replayOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n ));\n\n const logOptionPrompted =\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Logs\", sometimes doesn't work as `Logs` can be printed in bold.\n 'to send your application logs to Sentry?',\n ));\n\n const examplePagePrompted =\n logOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Do you want to create an example page',\n {\n optional: true,\n },\n ));\n\n // After the example page prompt, we send ENTER to accept it\n // Then handle the MCP prompt that comes after\n const mcpPrompted =\n examplePagePrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // This ENTER is for accepting the example page\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n {\n optional: true,\n },\n ));\n\n // Decline MCP config (default is Yes, so press DOWN then ENTER to select No)\n if (mcpPrompted) {\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER],\n 'Sentry has been successfully configured for your Remix project',\n );\n } else {\n // If MCP wasn't prompted, wait for success message directly\n await wizardInstance.waitForOutput(\n 'Sentry has been successfully configured for your Remix project',\n );\n }\n\n wizardInstance.kill();\n}\n\nfunction checkRemixProject(\n projectDir: string,\n integration: Integration,\n options?: {\n devModeExpectedOutput?: string;\n prodModeExpectedOutput?: string;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n });\n\n test('.env-sentry-build-plugin is created and contains the auth token', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n test('example page exists', () => {\n checkFileExists(`${projectDir}/app/routes/sentry-example-page.tsx`);\n });\n\n test('instrumentation.server file exists', () => {\n checkFileExists(`${projectDir}/instrumentation.server.mjs`);\n });\n\n test('entry.client file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/app/entry.client.tsx`, [\n 'import { init, replayIntegration, browserTracingIntegration } from \"@sentry/remix\";',\n `init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n enableLogs: true,\n\n integrations: [browserTracingIntegration({\n useEffect,\n useLocation,\n useMatches\n }), replayIntegration({\n maskAllText: true,\n blockAllMedia: true\n })],\n\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1\n})`,\n ]);\n });\n\n test('entry.server file contains Sentry code', () => {\n checkFileContents(`${projectDir}/app/entry.server.tsx`, [\n 'import * as Sentry from \"@sentry/remix\";',\n `export const handleError = Sentry.wrapHandleErrorWithSentry((error, { request }) => {\n // Custom handleError implementation\n});`,\n ]);\n });\n\n test('instrumentation.server file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/instrumentation.server.mjs`, [\n 'import * as Sentry from \"@sentry/remix\";',\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n enableLogs: true\n})`,\n ]);\n });\n\n test('root file contains Sentry ErrorBoundary and withSentry wrapper', () => {\n checkFileContents(`${projectDir}/app/root.tsx`, [\n 'import { captureRemixErrorBoundaryError, withSentry } from \"@sentry/remix\";',\n `export const ErrorBoundary = () => {\n const error = useRouteError();\n captureRemixErrorBoundaryError(error);\n return <div>Something went wrong</div>;\n};`,\n `export default withSentry(App);`,\n ]);\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n options?.devModeExpectedOutput || 'to expose',\n );\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n options?.prodModeExpectedOutput || '[remix-serve]',\n );\n });\n}\n\ndescribe('Remix', () => {\n describe('with empty project', () => {\n const integration = Integration.remix;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/remix-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnRemixProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkRemixProject(projectDir, integration);\n });\n\n describe('with existing custom Express server', () => {\n const integration = Integration.remix;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/remix-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnRemixProject(projectDir, integration, (projectDir) => {\n createFile(`${projectDir}/server.mjs`, SERVER_TEMPLATE);\n\n modifyFile(`${projectDir}/package.json`, {\n '\"start\": \"remix-serve ./build/server/index.js\"':\n '\"start\": \"node ./server.mjs\"',\n '\"dev\": \"remix vite:dev\"': '\"dev\": \"node ./server.mjs\"',\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkRemixProject(projectDir, integration, {\n devModeExpectedOutput: 'Express server listening',\n prodModeExpectedOutput: 'Express server listening',\n });\n\n test('server.mjs contains instrumentation file import', () => {\n checkFileContents(`${projectDir}/server.mjs`, [\n \"import './instrumentation.server.mjs';\",\n ]);\n });\n });\n});\n"]}
1
+ {"version":3,"file":"remix.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/remix.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport { Integration } from '../../lib/Constants';\nimport {\n KEYS,\n TEST_ARGS,\n checkEnvBuildPlugin,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n createFile,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport { afterAll, beforeAll, describe, test } from 'vitest';\n\nconst SERVER_TEMPLATE = `import { createRequestHandler } from '@remix-run/express';\nimport { installGlobals } from '@remix-run/node';\nimport compression from 'compression';\nimport express from 'express';\nimport morgan from 'morgan';\n\ninstallGlobals();\n\nconst viteDevServer =\n process.env.NODE_ENV === 'production'\n ? undefined\n : await import('vite').then(vite =>\n vite.createServer({\n server: { middlewareMode: true },\n }),\n );\n\nconst app = express();\n\napp.use(compression());\napp.disable('x-powered-by');\n\nif (viteDevServer) {\n app.use(viteDevServer.middlewares);\n} else {\n app.use('/assets', express.static('build/client/assets', { immutable: true, maxAge: '1y' }));\n}\n\napp.use(express.static('build/client', { maxAge: '1h' }));\napp.use(morgan('tiny'));\n\napp.all(\n '*',\n createRequestHandler({\n build: viteDevServer\n ? () => viteDevServer.ssrLoadModule('virtual:remix/server-build')\n : await import('./build/server/index.js'),\n }),\n);\n\napp.listen(0, () => console.log('Express server listening'));\n`;\n\nasync function runWizardOnRemixProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (\n projectDir: string,\n integration: Integration,\n ) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir);\n let packageManagerPrompted = false;\n\n if (fileModificationFn) {\n fileModificationFn(projectDir, integration);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n packageManagerPrompted = await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n packageManagerPrompted = await wizardInstance.waitForOutput(\n 'Please select your package manager.',\n );\n }\n\n const tracingOptionPrompted =\n packageManagerPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n },\n ));\n\n const replayOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n ));\n\n const logOptionPrompted =\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Logs\", sometimes doesn't work as `Logs` can be printed in bold.\n 'to send your application logs to Sentry?',\n ));\n\n const examplePagePrompted =\n logOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Do you want to create an example page',\n {\n optional: true,\n },\n ));\n\n // After the example page prompt, we send ENTER to accept it\n // Then handle the MCP prompt that comes after\n const mcpPrompted =\n examplePagePrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // This ENTER is for accepting the example page\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n {\n optional: true,\n },\n ));\n\n // Decline MCP config (default is Yes, so press DOWN then ENTER to select No)\n if (mcpPrompted) {\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER],\n 'Sentry has been successfully configured for your Remix project',\n );\n } else {\n // If MCP wasn't prompted, wait for success message directly\n await wizardInstance.waitForOutput(\n 'Sentry has been successfully configured for your Remix project',\n );\n }\n\n wizardInstance.kill();\n}\n\nfunction checkRemixProject(\n projectDir: string,\n integration: Integration,\n options?: {\n devModeExpectedOutput?: string;\n prodModeExpectedOutput?: string;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n });\n\n test('.env-sentry-build-plugin is created and contains the auth token', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n test('example page exists', () => {\n checkFileExists(`${projectDir}/app/routes/sentry-example-page.tsx`);\n });\n\n test('instrumentation.server file exists', () => {\n checkFileExists(`${projectDir}/instrumentation.server.mjs`);\n });\n\n test('entry.client file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/app/entry.client.tsx`, [\n 'import { init, replayIntegration, browserTracingIntegration } from \"@sentry/remix\";',\n `init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n enableLogs: true,\n\n integrations: [browserTracingIntegration({\n useEffect,\n useLocation,\n useMatches\n }), replayIntegration({\n maskAllText: true,\n blockAllMedia: true\n })],\n\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n sendDefaultPii: true\n})`,\n ]);\n });\n\n test('entry.server file contains Sentry code', () => {\n checkFileContents(`${projectDir}/app/entry.server.tsx`, [\n 'import * as Sentry from \"@sentry/remix\";',\n `export const handleError = Sentry.wrapHandleErrorWithSentry((error, { request }) => {\n // Custom handleError implementation\n});`,\n ]);\n });\n\n test('instrumentation.server file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/instrumentation.server.mjs`, [\n 'import * as Sentry from \"@sentry/remix\";',\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n enableLogs: true\n})`,\n ]);\n });\n\n test('root file contains Sentry ErrorBoundary and withSentry wrapper', () => {\n checkFileContents(`${projectDir}/app/root.tsx`, [\n 'import { captureRemixErrorBoundaryError, withSentry } from \"@sentry/remix\";',\n `export const ErrorBoundary = () => {\n const error = useRouteError();\n captureRemixErrorBoundaryError(error);\n return <div>Something went wrong</div>;\n};`,\n `export default withSentry(App);`,\n ]);\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n options?.devModeExpectedOutput || 'to expose',\n );\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n options?.prodModeExpectedOutput || '[remix-serve]',\n );\n });\n}\n\ndescribe('Remix', () => {\n describe('with empty project', () => {\n const integration = Integration.remix;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/remix-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnRemixProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkRemixProject(projectDir, integration);\n });\n\n describe('with existing custom Express server', () => {\n const integration = Integration.remix;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/remix-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnRemixProject(projectDir, integration, (projectDir) => {\n createFile(`${projectDir}/server.mjs`, SERVER_TEMPLATE);\n\n modifyFile(`${projectDir}/package.json`, {\n '\"start\": \"remix-serve ./build/server/index.js\"':\n '\"start\": \"node ./server.mjs\"',\n '\"dev\": \"remix vite:dev\"': '\"dev\": \"node ./server.mjs\"',\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkRemixProject(projectDir, integration, {\n devModeExpectedOutput: 'Express server listening',\n prodModeExpectedOutput: 'Express server listening',\n });\n\n test('server.mjs contains instrumentation file import', () => {\n checkFileContents(`${projectDir}/server.mjs`, [\n \"import './instrumentation.server.mjs';\",\n ]);\n });\n });\n});\n"]}
@@ -166,6 +166,10 @@ function checkSvelteKitProject(projectDir, integration, options) {
166
166
 
167
167
  // If you don't want to use Session Replay, just remove the line below:
168
168
  integrations: [replayIntegration()],
169
+
170
+ // Enable sending user PII (Personally Identifiable Information)
171
+ // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii
172
+ sendDefaultPii: true,
169
173
  });`,
170
174
  'export const handleError = handleErrorWithSentry(',
171
175
  ]);
@@ -181,6 +185,11 @@ function checkSvelteKitProject(projectDir, integration, options) {
181
185
  // Enable logs to be sent to Sentry
182
186
  enableLogs: true,
183
187
 
188
+
189
+ // Enable sending user PII (Personally Identifiable Information)
190
+ // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii
191
+ sendDefaultPii: true,
192
+
184
193
  // uncomment the line below to enable Spotlight (https://spotlightjs.com)
185
194
  // spotlight: import.meta.env.DEV,
186
195
  });`,
@@ -213,7 +222,8 @@ function checkSvelteKitProject(projectDir, integration, options) {
213
222
  replaysSessionSampleRate: 0.1,
214
223
  replaysOnErrorSampleRate: 1,
215
224
  integrations: [Sentry.replayIntegration()],
216
- enableLogs: true
225
+ enableLogs: true,
226
+ sendDefaultPii: true
217
227
  })`,
218
228
  'export const handleError = Sentry.handleErrorWithSentry(',
219
229
  ]);
@@ -224,7 +234,8 @@ function checkSvelteKitProject(projectDir, integration, options) {
224
234
  `Sentry.init({
225
235
  dsn: "${utils_1.TEST_ARGS.PROJECT_DSN}",
226
236
  tracesSampleRate: 1,
227
- enableLogs: true
237
+ enableLogs: true,
238
+ sendDefaultPii: true
228
239
  })`,
229
240
  'export const handleError = Sentry.handleErrorWithSentry();',
230
241
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"sveltekit-hooks.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/sveltekit-hooks.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport { Integration } from '../../lib/Constants';\nimport {\n KEYS,\n TEST_ARGS,\n checkEnvBuildPlugin,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n createFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport { afterAll, beforeAll, describe, test } from 'vitest';\n\nconst SERVER_HOOK_TEMPLATE = `import type { Handle } from '@sveltejs/kit';\n\nexport const handle: Handle = async ({ event, resolve }) => {\n\tif (event.url.pathname.startsWith('/custom')) {\n\t\treturn new Response('custom response');\n\t}\n\n\tconst response = await resolve(event);\n\treturn response;\n};\n`;\nconst CLIENT_HOOK_TEMPLATE = `\nexport async function handleError({ error, event }) {\n // you can capture the \\`error\\` and \\`event\\` from the client\n // but it only runs if the unexpected error comes from \\`+ page.ts\\`\n console.log(error)\n\n return {\n // don't show sensitive data to the user\n message: 'Yikes! 💩',\n }\n}\n`;\n\nasync function runWizardOnSvelteKitProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (\n projectDir: string,\n integration: Integration,\n ) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir);\n let kitVersionPrompted = false;\n\n if (fileModificationFn) {\n fileModificationFn(projectDir, integration);\n\n // As we modified project, we have a warning prompt before we get the package manager prompt\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n kitVersionPrompted = await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n \"It seems you're using a SvelteKit version\",\n );\n } else {\n kitVersionPrompted = await wizardInstance.waitForOutput(\n \"It seems you're using a SvelteKit version\",\n );\n }\n\n const packageManagerPrompted =\n kitVersionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Select \"Yes, Continue\" to perform hooks-based SDK setup\n [KEYS.DOWN, KEYS.DOWN, KEYS.ENTER],\n 'Please select your package manager.',\n ));\n\n const tracingOptionPrompted =\n packageManagerPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n },\n ));\n\n const replayOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n ));\n\n const logsOptionPrompted =\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Logs\", sometimes doesn't work as `Logs` can be printed in bold.\n 'to send your application logs to Sentry?',\n ));\n\n const examplePagePrompted =\n logsOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Do you want to create an example page',\n {\n optional: true,\n },\n ));\n\n // After the example page prompt, we send ENTER to accept it\n // Then handle the MCP prompt that comes after\n const mcpPrompted =\n examplePagePrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // This ENTER is for accepting the example page\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n {\n optional: true,\n },\n ));\n\n // Decline MCP config (default is Yes, so press DOWN then ENTER to select No)\n if (mcpPrompted) {\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER],\n 'Successfully installed the Sentry SvelteKit SDK!',\n );\n } else {\n // If MCP wasn't prompted, wait for success message directly\n await wizardInstance.waitForOutput(\n 'Successfully installed the Sentry SvelteKit SDK!',\n );\n }\n\n wizardInstance.kill();\n}\n\nfunction checkSvelteKitProject(\n projectDir: string,\n integration: Integration,\n options?: {\n devModeExpectedOutput: string;\n prodModeExpectedOutput: string;\n },\n) {\n test('should have the correct package.json', () => {\n checkPackageJson(projectDir, integration);\n });\n\n test('should have the correct .env.sentry-build-plugin', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n test('example page exists', () => {\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+page.svelte'),\n );\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+server.js'),\n );\n });\n\n test('vite.config contains sentry plugin', () => {\n checkFileContents(\n path.resolve(projectDir, 'vite.config.ts'),\n `plugins: [sentrySvelteKit({\n sourceMapsUploadOptions: {\n`,\n );\n });\n\n test('hook files created', () => {\n checkFileExists(path.resolve(projectDir, 'src/hooks.server.ts'));\n checkFileExists(path.resolve(projectDir, 'src/hooks.client.ts'));\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n options?.devModeExpectedOutput || 'ready in',\n );\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n options?.prodModeExpectedOutput || 'to expose',\n 'preview',\n );\n });\n}\n\ndescribe('Sveltekit', () => {\n describe('without existing hooks', () => {\n const integration = Integration.sveltekit;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/sveltekit-hooks-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnSvelteKitProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkSvelteKitProject(projectDir, integration);\n\n test('hooks.client.ts contains sentry', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.client.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // If the entire session is not sampled, use the below sample rate to sample\n // sessions when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // If you don't want to use Session Replay, just remove the line below:\n integrations: [replayIntegration()],\n});`,\n 'export const handleError = handleErrorWithSentry(',\n ]);\n });\n\n test('hooks.server.ts contains sentry', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.server.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n});`,\n 'export const handleError = handleErrorWithSentry();',\n ]);\n });\n });\n\n describe('with existing hooks', () => {\n const integration = Integration.sveltekit;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/sveltekit-hooks-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnSvelteKitProject(\n projectDir,\n integration,\n (projectDir) => {\n createFile(\n path.resolve(projectDir, 'src/hooks.server.ts'),\n SERVER_HOOK_TEMPLATE,\n );\n\n createFile(\n path.resolve(projectDir, 'src/hooks.client.ts'),\n CLIENT_HOOK_TEMPLATE,\n );\n },\n );\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkSvelteKitProject(projectDir, integration);\n\n // These are removed from the common tests as the content is different\n // when the hooks are merged instead of created from the template\n test('hooks.client.ts contains sentry instrumentation', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.client.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.replayIntegration()],\n enableLogs: true\n})`,\n 'export const handleError = Sentry.handleErrorWithSentry(',\n ]);\n });\n\n test('hooks.server.ts contains sentry init', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.server.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n enableLogs: true\n})`,\n 'export const handleError = Sentry.handleErrorWithSentry();',\n ]);\n });\n });\n});\n"]}
1
+ {"version":3,"file":"sveltekit-hooks.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/sveltekit-hooks.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport { Integration } from '../../lib/Constants';\nimport {\n KEYS,\n TEST_ARGS,\n checkEnvBuildPlugin,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n createFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport { afterAll, beforeAll, describe, test } from 'vitest';\n\nconst SERVER_HOOK_TEMPLATE = `import type { Handle } from '@sveltejs/kit';\n\nexport const handle: Handle = async ({ event, resolve }) => {\n\tif (event.url.pathname.startsWith('/custom')) {\n\t\treturn new Response('custom response');\n\t}\n\n\tconst response = await resolve(event);\n\treturn response;\n};\n`;\nconst CLIENT_HOOK_TEMPLATE = `\nexport async function handleError({ error, event }) {\n // you can capture the \\`error\\` and \\`event\\` from the client\n // but it only runs if the unexpected error comes from \\`+ page.ts\\`\n console.log(error)\n\n return {\n // don't show sensitive data to the user\n message: 'Yikes! 💩',\n }\n}\n`;\n\nasync function runWizardOnSvelteKitProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (\n projectDir: string,\n integration: Integration,\n ) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir);\n let kitVersionPrompted = false;\n\n if (fileModificationFn) {\n fileModificationFn(projectDir, integration);\n\n // As we modified project, we have a warning prompt before we get the package manager prompt\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n kitVersionPrompted = await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n \"It seems you're using a SvelteKit version\",\n );\n } else {\n kitVersionPrompted = await wizardInstance.waitForOutput(\n \"It seems you're using a SvelteKit version\",\n );\n }\n\n const packageManagerPrompted =\n kitVersionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Select \"Yes, Continue\" to perform hooks-based SDK setup\n [KEYS.DOWN, KEYS.DOWN, KEYS.ENTER],\n 'Please select your package manager.',\n ));\n\n const tracingOptionPrompted =\n packageManagerPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n },\n ));\n\n const replayOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n ));\n\n const logsOptionPrompted =\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Logs\", sometimes doesn't work as `Logs` can be printed in bold.\n 'to send your application logs to Sentry?',\n ));\n\n const examplePagePrompted =\n logsOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Do you want to create an example page',\n {\n optional: true,\n },\n ));\n\n // After the example page prompt, we send ENTER to accept it\n // Then handle the MCP prompt that comes after\n const mcpPrompted =\n examplePagePrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // This ENTER is for accepting the example page\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n {\n optional: true,\n },\n ));\n\n // Decline MCP config (default is Yes, so press DOWN then ENTER to select No)\n if (mcpPrompted) {\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER],\n 'Successfully installed the Sentry SvelteKit SDK!',\n );\n } else {\n // If MCP wasn't prompted, wait for success message directly\n await wizardInstance.waitForOutput(\n 'Successfully installed the Sentry SvelteKit SDK!',\n );\n }\n\n wizardInstance.kill();\n}\n\nfunction checkSvelteKitProject(\n projectDir: string,\n integration: Integration,\n options?: {\n devModeExpectedOutput: string;\n prodModeExpectedOutput: string;\n },\n) {\n test('should have the correct package.json', () => {\n checkPackageJson(projectDir, integration);\n });\n\n test('should have the correct .env.sentry-build-plugin', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n test('example page exists', () => {\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+page.svelte'),\n );\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+server.js'),\n );\n });\n\n test('vite.config contains sentry plugin', () => {\n checkFileContents(\n path.resolve(projectDir, 'vite.config.ts'),\n `plugins: [sentrySvelteKit({\n sourceMapsUploadOptions: {\n`,\n );\n });\n\n test('hook files created', () => {\n checkFileExists(path.resolve(projectDir, 'src/hooks.server.ts'));\n checkFileExists(path.resolve(projectDir, 'src/hooks.client.ts'));\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n options?.devModeExpectedOutput || 'ready in',\n );\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n options?.prodModeExpectedOutput || 'to expose',\n 'preview',\n );\n });\n}\n\ndescribe('Sveltekit', () => {\n describe('without existing hooks', () => {\n const integration = Integration.sveltekit;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/sveltekit-hooks-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnSvelteKitProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkSvelteKitProject(projectDir, integration);\n\n test('hooks.client.ts contains sentry', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.client.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // If the entire session is not sampled, use the below sample rate to sample\n // sessions when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // If you don't want to use Session Replay, just remove the line below:\n integrations: [replayIntegration()],\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n});`,\n 'export const handleError = handleErrorWithSentry(',\n ]);\n });\n\n test('hooks.server.ts contains sentry', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.server.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n});`,\n 'export const handleError = handleErrorWithSentry();',\n ]);\n });\n });\n\n describe('with existing hooks', () => {\n const integration = Integration.sveltekit;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/sveltekit-hooks-test-app',\n );\n\n beforeAll(async () => {\n await runWizardOnSvelteKitProject(\n projectDir,\n integration,\n (projectDir) => {\n createFile(\n path.resolve(projectDir, 'src/hooks.server.ts'),\n SERVER_HOOK_TEMPLATE,\n );\n\n createFile(\n path.resolve(projectDir, 'src/hooks.client.ts'),\n CLIENT_HOOK_TEMPLATE,\n );\n },\n );\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkSvelteKitProject(projectDir, integration);\n\n // These are removed from the common tests as the content is different\n // when the hooks are merged instead of created from the template\n test('hooks.client.ts contains sentry instrumentation', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.client.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.replayIntegration()],\n enableLogs: true,\n sendDefaultPii: true\n})`,\n 'export const handleError = Sentry.handleErrorWithSentry(',\n ]);\n });\n\n test('hooks.server.ts contains sentry init', () => {\n checkFileContents(path.resolve(projectDir, 'src/hooks.server.ts'), [\n `import * as Sentry from '@sentry/sveltekit';`,\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",\n tracesSampleRate: 1,\n enableLogs: true,\n sendDefaultPii: true\n})`,\n 'export const handleError = Sentry.handleErrorWithSentry();',\n ]);\n });\n });\n});\n"]}
@@ -120,6 +120,10 @@ const clifty_1 = require("clifty");
120
120
 
121
121
  // If you don't want to use Session Replay, just remove the line below:
122
122
  integrations: [replayIntegration()],
123
+
124
+ // Enable sending user PII (Personally Identifiable Information)
125
+ // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii
126
+ sendDefaultPii: true,
123
127
  });
124
128
 
125
129
  // If you have a custom error handler, pass it to \`handleErrorWithSentry\`
@@ -1 +1 @@
1
- {"version":3,"file":"sveltekit-tracing.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/sveltekit-tracing.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { Integration } from '../../lib/Constants';\nimport {\n checkEnvBuildPlugin,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n getWizardCommand,\n initGit,\n revertLocalChanges,\n TEST_ARGS,\n} from '../utils';\nimport { afterAll, beforeAll, describe, expect, it } from 'vitest';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\ndescribe('Sveltekit with instrumentation and tracing', () => {\n describe('without existing files', () => {\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/sveltekit-tracing-test-app',\n );\n\n const integration = Integration.sveltekit;\n let wizardExitCode: number;\n\n beforeAll(async () => {\n initGit(projectDir);\n revertLocalChanges(projectDir);\n\n wizardExitCode = await withEnv({\n cwd: projectDir,\n })\n .defineInteraction()\n .expectOutput(\n 'The Sentry SvelteKit Wizard will help you set up Sentry for your application',\n )\n .step('package installation', ({ expectOutput, whenAsked }) => {\n whenAsked('Please select your package manager.').respondWith(\n KEYS.DOWN,\n KEYS.ENTER,\n );\n expectOutput('Installing @sentry/sveltekit');\n })\n .step('SDK setup', ({ whenAsked }) => {\n whenAsked('Do you want to enable Tracing', {\n timeout: 90_000, // package installation can take a while in CI\n }).respondWith(KEYS.ENTER);\n whenAsked('Do you want to enable Session Replay').respondWith(\n KEYS.ENTER,\n );\n whenAsked('Do you want to enable Logs').respondWith(KEYS.ENTER);\n })\n .whenAsked('Do you want to create an example page')\n .respondWith(KEYS.ENTER)\n .whenAsked(\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n )\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput('Successfully installed the Sentry SvelteKit SDK!')\n .run(getWizardCommand(integration));\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n it('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n it('adds the SDK dependency to package.json', () => {\n checkPackageJson(projectDir, integration);\n });\n\n it('adds the .env.sentry-build-plugin', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n it('adds the example page', () => {\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+page.svelte'),\n );\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+server.js'),\n );\n });\n\n it('adds the sentry plugin to vite.config.ts', () => {\n const viteConfig = fs.readFileSync(\n path.resolve(projectDir, 'vite.config.ts'),\n );\n expect(viteConfig.toString()).toMatchInlineSnapshot(`\n \"import { sentrySvelteKit } from \"@sentry/sveltekit\";\n import { sveltekit } from '@sveltejs/kit/vite';\n import { defineConfig } from 'vite';\n\n export default defineConfig({\n \tplugins: [sentrySvelteKit({\n sourceMapsUploadOptions: {\n org: \"${TEST_ARGS.ORG_SLUG}\",\n project: \"${TEST_ARGS.PROJECT_SLUG}\"\n }\n }), sveltekit()]\n });\"\n `);\n });\n\n it('creates the hook files', () => {\n const clientHooks = fs.readFileSync(\n path.resolve(projectDir, 'src/hooks.client.ts'),\n );\n const serverHooks = fs.readFileSync(\n path.resolve(projectDir, 'src/hooks.server.ts'),\n );\n\n expect(clientHooks.toString()).toMatchInlineSnapshot(`\n \"import { handleErrorWithSentry, replayIntegration } from \"@sentry/sveltekit\";\n import * as Sentry from '@sentry/sveltekit';\n\n Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // If the entire session is not sampled, use the below sample rate to sample\n // sessions when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // If you don't want to use Session Replay, just remove the line below:\n integrations: [replayIntegration()],\n });\n\n // If you have a custom error handler, pass it to \\`handleErrorWithSentry\\`\n export const handleError = handleErrorWithSentry();\n \"\n `);\n\n expect(serverHooks.toString()).toMatchInlineSnapshot(`\n \"import {sequence} from \"@sveltejs/kit/hooks\";\n import * as Sentry from \"@sentry/sveltekit\";\n export const handle = sequence(Sentry.sentryHandle(), async ({ event, resolve }) => {\n const response = await resolve(event);\n return response;\n });\n export const handleError = Sentry.handleErrorWithSentry();\"\n `);\n });\n\n it('creates the insturmentation.server file', () => {\n const instrumentationServer = fs.readFileSync(\n path.resolve(projectDir, 'src/instrumentation.server.ts'),\n );\n\n expect(instrumentationServer.toString()).toMatchInlineSnapshot(`\n \"import * as Sentry from '@sentry/sveltekit';\n\n Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n });\"\n `);\n });\n\n it('enables tracing and instrumentation in svelte.config.js', () => {\n const svelteConfig = fs.readFileSync(\n path.resolve(projectDir, 'svelte.config.js'),\n );\n expect(svelteConfig.toString()).toMatchInlineSnapshot(`\n \"import adapter from '@sveltejs/adapter-node';\n import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\n /** @type {import('@sveltejs/kit').Config} */\n const config = {\n // Consult https://svelte.dev/docs/kit/integrations#preprocessors\n // for more information about preprocessors\n preprocess: vitePreprocess(),\n\n kit: {\n // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.\n // If your environment is not supported, or you settled on a specific environment, switch out the adapter.\n // See https://svelte.dev/docs/kit/adapters for more information about adapters.\n adapter: adapter(),\n experimental: {\n remoteFunctions: true,\n\n tracing: {\n server: true,\n },\n\n instrumentation: {\n server: true,\n },\n },\n },\n };\n\n export default config;\"\n `);\n });\n\n // checkSvelteKitProject(projectDir, integration);\n it('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n it('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(projectDir, 'ready in');\n });\n\n it('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(projectDir, 'to expose', 'preview');\n });\n });\n});\n"]}
1
+ {"version":3,"file":"sveltekit-tracing.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/sveltekit-tracing.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { Integration } from '../../lib/Constants';\nimport {\n checkEnvBuildPlugin,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n getWizardCommand,\n initGit,\n revertLocalChanges,\n TEST_ARGS,\n} from '../utils';\nimport { afterAll, beforeAll, describe, expect, it } from 'vitest';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\ndescribe('Sveltekit with instrumentation and tracing', () => {\n describe('without existing files', () => {\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/sveltekit-tracing-test-app',\n );\n\n const integration = Integration.sveltekit;\n let wizardExitCode: number;\n\n beforeAll(async () => {\n initGit(projectDir);\n revertLocalChanges(projectDir);\n\n wizardExitCode = await withEnv({\n cwd: projectDir,\n })\n .defineInteraction()\n .expectOutput(\n 'The Sentry SvelteKit Wizard will help you set up Sentry for your application',\n )\n .step('package installation', ({ expectOutput, whenAsked }) => {\n whenAsked('Please select your package manager.').respondWith(\n KEYS.DOWN,\n KEYS.ENTER,\n );\n expectOutput('Installing @sentry/sveltekit');\n })\n .step('SDK setup', ({ whenAsked }) => {\n whenAsked('Do you want to enable Tracing', {\n timeout: 90_000, // package installation can take a while in CI\n }).respondWith(KEYS.ENTER);\n whenAsked('Do you want to enable Session Replay').respondWith(\n KEYS.ENTER,\n );\n whenAsked('Do you want to enable Logs').respondWith(KEYS.ENTER);\n })\n .whenAsked('Do you want to create an example page')\n .respondWith(KEYS.ENTER)\n .whenAsked(\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n )\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput('Successfully installed the Sentry SvelteKit SDK!')\n .run(getWizardCommand(integration));\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n it('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n it('adds the SDK dependency to package.json', () => {\n checkPackageJson(projectDir, integration);\n });\n\n it('adds the .env.sentry-build-plugin', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n it('adds the example page', () => {\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+page.svelte'),\n );\n checkFileExists(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+server.js'),\n );\n });\n\n it('adds the sentry plugin to vite.config.ts', () => {\n const viteConfig = fs.readFileSync(\n path.resolve(projectDir, 'vite.config.ts'),\n );\n expect(viteConfig.toString()).toMatchInlineSnapshot(`\n \"import { sentrySvelteKit } from \"@sentry/sveltekit\";\n import { sveltekit } from '@sveltejs/kit/vite';\n import { defineConfig } from 'vite';\n\n export default defineConfig({\n \tplugins: [sentrySvelteKit({\n sourceMapsUploadOptions: {\n org: \"${TEST_ARGS.ORG_SLUG}\",\n project: \"${TEST_ARGS.PROJECT_SLUG}\"\n }\n }), sveltekit()]\n });\"\n `);\n });\n\n it('creates the hook files', () => {\n const clientHooks = fs.readFileSync(\n path.resolve(projectDir, 'src/hooks.client.ts'),\n );\n const serverHooks = fs.readFileSync(\n path.resolve(projectDir, 'src/hooks.server.ts'),\n );\n\n expect(clientHooks.toString()).toMatchInlineSnapshot(`\n \"import { handleErrorWithSentry, replayIntegration } from \"@sentry/sveltekit\";\n import * as Sentry from '@sentry/sveltekit';\n\n Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // If the entire session is not sampled, use the below sample rate to sample\n // sessions when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // If you don't want to use Session Replay, just remove the line below:\n integrations: [replayIntegration()],\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n // If you have a custom error handler, pass it to \\`handleErrorWithSentry\\`\n export const handleError = handleErrorWithSentry();\n \"\n `);\n\n expect(serverHooks.toString()).toMatchInlineSnapshot(`\n \"import {sequence} from \"@sveltejs/kit/hooks\";\n import * as Sentry from \"@sentry/sveltekit\";\n export const handle = sequence(Sentry.sentryHandle(), async ({ event, resolve }) => {\n const response = await resolve(event);\n return response;\n });\n export const handleError = Sentry.handleErrorWithSentry();\"\n `);\n });\n\n it('creates the insturmentation.server file', () => {\n const instrumentationServer = fs.readFileSync(\n path.resolve(projectDir, 'src/instrumentation.server.ts'),\n );\n\n expect(instrumentationServer.toString()).toMatchInlineSnapshot(`\n \"import * as Sentry from '@sentry/sveltekit';\n\n Sentry.init({\n dsn: '${TEST_ARGS.PROJECT_DSN}',\n\n tracesSampleRate: 1.0,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n });\"\n `);\n });\n\n it('enables tracing and instrumentation in svelte.config.js', () => {\n const svelteConfig = fs.readFileSync(\n path.resolve(projectDir, 'svelte.config.js'),\n );\n expect(svelteConfig.toString()).toMatchInlineSnapshot(`\n \"import adapter from '@sveltejs/adapter-node';\n import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\n /** @type {import('@sveltejs/kit').Config} */\n const config = {\n // Consult https://svelte.dev/docs/kit/integrations#preprocessors\n // for more information about preprocessors\n preprocess: vitePreprocess(),\n\n kit: {\n // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.\n // If your environment is not supported, or you settled on a specific environment, switch out the adapter.\n // See https://svelte.dev/docs/kit/adapters for more information about adapters.\n adapter: adapter(),\n experimental: {\n remoteFunctions: true,\n\n tracing: {\n server: true,\n },\n\n instrumentation: {\n server: true,\n },\n },\n },\n };\n\n export default config;\"\n `);\n });\n\n // checkSvelteKitProject(projectDir, integration);\n it('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n it('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(projectDir, 'ready in');\n });\n\n it('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(projectDir, 'to expose', 'preview');\n });\n });\n});\n"]}
@@ -74,6 +74,14 @@ async function runAndroidWizardWithTelemetry(options) {
74
74
  }
75
75
  const appFile = await (0, telemetry_1.traceStep)('Select App File', () => gradle.selectAppFile(buildGradleFiles));
76
76
  const { selectedProject, selfHosted, sentryUrl, authToken } = await (0, clack_1.getOrAskForProjectData)(options, 'android');
77
+ // Ask if user wants to enable Sentry Logs
78
+ const enableLogs = await (0, clack_1.abortIfCancelled)(clack.confirm({
79
+ message: 'Do you want to enable Logs? (See https://docs.sentry.io/platforms/android/logs/)',
80
+ }));
81
+ Sentry.setTag('enable-logs', enableLogs);
82
+ if (enableLogs) {
83
+ clack.log.info('Logs will be enabled with default settings. You can send logs using the Sentry.logger() APIs or use one of the integrations: https://docs.sentry.io/platforms/android/logs/#integrations.');
84
+ }
77
85
  // ======== STEP 1. Add Sentry Gradle Plugin to build.gradle(.kts) ============
78
86
  clack.log.step(`Adding ${chalk_1.default.bold('Sentry Gradle plugin')} to your app's ${chalk_1.default.cyan('build.gradle')} file.`);
79
87
  const pluginAdded = await (0, telemetry_1.traceStep)('Add Gradle Plugin', () => gradle.addGradlePlugin(appFile, selectedProject.organization.slug, selectedProject.slug));
@@ -85,7 +93,7 @@ async function runAndroidWizardWithTelemetry(options) {
85
93
  clack.log.step(`Configuring Sentry SDK via ${chalk_1.default.cyan('AndroidManifest.xml')}`);
86
94
  const appDir = path.dirname(appFile);
87
95
  const manifestFile = path.join(appDir, 'src', 'main', 'AndroidManifest.xml');
88
- const manifestUpdated = (0, telemetry_1.traceStep)('Update Android Manifest', () => manifest.addManifestSnippet(manifestFile, selectedProject.keys[0].dsn.public));
96
+ const manifestUpdated = (0, telemetry_1.traceStep)('Update Android Manifest', () => manifest.addManifestSnippet(manifestFile, selectedProject.keys[0].dsn.public, enableLogs));
89
97
  if (!manifestUpdated) {
90
98
  clack.log.warn("Could not configure the Sentry SDK. You'll have to do it manually.\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#configure");
91
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"android-wizard.js","sourceRoot":"","sources":["../../../src/android/android-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport {\n CliSetupConfig,\n abort,\n addSentryCliConfig,\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n printWelcome,\n propertiesCliSetupConfig,\n} from '../utils/clack';\nimport { WizardOptions } from '../utils/types';\nimport { offerProjectScopedMcpConfig } from '../utils/clack/mcp-config';\nimport * as codetools from './code-tools';\nimport * as gradle from './gradle';\nimport * as manifest from './manifest';\n\nconst proguardMappingCliSetupConfig: CliSetupConfig = {\n ...propertiesCliSetupConfig,\n name: 'proguard mappings',\n};\n\nexport async function runAndroidWizard(options: WizardOptions): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'android',\n wizardOptions: options,\n },\n () => runAndroidWizardWithTelemetry(options),\n );\n}\n\nasync function runAndroidWizardWithTelemetry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Android Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\n\n const projectDir = process.cwd();\n const buildGradleFiles = findFilesWithExtensions(projectDir, [\n '.gradle',\n 'gradle.kts',\n ]);\n\n if (!buildGradleFiles || buildGradleFiles.length === 0) {\n clack.log.error(\n 'No Gradle project found. Please run this command from the root of your project.',\n );\n Sentry.captureException('No Gradle project found');\n await abort();\n return;\n }\n\n const appFile = await traceStep('Select App File', () =>\n gradle.selectAppFile(buildGradleFiles),\n );\n\n const { selectedProject, selfHosted, sentryUrl, authToken } =\n await getOrAskForProjectData(options, 'android');\n\n // ======== STEP 1. Add Sentry Gradle Plugin to build.gradle(.kts) ============\n clack.log.step(\n `Adding ${chalk.bold('Sentry Gradle plugin')} to your app's ${chalk.cyan(\n 'build.gradle',\n )} file.`,\n );\n const pluginAdded = await traceStep('Add Gradle Plugin', () =>\n gradle.addGradlePlugin(\n appFile,\n selectedProject.organization.slug,\n selectedProject.slug,\n ),\n );\n if (!pluginAdded) {\n clack.log.warn(\n \"Could not add Sentry Gradle plugin to your app's build.gradle file. You'll have to add it manually.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#install\",\n );\n }\n Sentry.setTag('gradle-plugin-added', pluginAdded);\n\n // ======== STEP 2. Configure Sentry SDK via AndroidManifest ============\n clack.log.step(\n `Configuring Sentry SDK via ${chalk.cyan('AndroidManifest.xml')}`,\n );\n const appDir = path.dirname(appFile);\n const manifestFile = path.join(appDir, 'src', 'main', 'AndroidManifest.xml');\n\n const manifestUpdated = traceStep('Update Android Manifest', () =>\n manifest.addManifestSnippet(\n manifestFile,\n selectedProject.keys[0].dsn.public,\n ),\n );\n if (!manifestUpdated) {\n clack.log.warn(\n \"Could not configure the Sentry SDK. You'll have to do it manually.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#configure\",\n );\n }\n Sentry.setTag('android-manifest-updated', manifestUpdated);\n\n // ======== STEP 3. Patch Main Activity with a test error snippet ============\n clack.log.step(\n `Patching ${chalk.bold('Main Activity')} with a test error snippet.`,\n );\n const mainActivity = traceStep('Find Main Activity', () =>\n manifest.getMainActivity(manifestFile),\n );\n let packageName = mainActivity.packageName;\n if (!packageName) {\n // if no package name in AndroidManifest, look into gradle script\n packageName = gradle.getNamespace(appFile);\n }\n const activityName = mainActivity.activityName;\n Sentry.setTag('has-activity-name', !!activityName);\n Sentry.setTag('has-package-name', !!packageName);\n if (!activityName || !packageName) {\n clack.log.warn(\n \"Could not find Activity with intent action MAIN. You'll have to manually verify the setup.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#verify\",\n );\n Sentry.captureException('Could not find Main Activity');\n } else {\n const packageNameStable = packageName;\n const activityFile = traceStep('Find Main Activity Source File', () =>\n codetools.findActivitySourceFile(appDir, packageNameStable, activityName),\n );\n\n const activityPatched = traceStep('Patch Main Activity', () =>\n codetools.patchMainActivity(activityFile),\n );\n if (!activityPatched) {\n clack.log.warn(\n \"Could not patch main activity. You'll have to manually verify the setup.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#verify\",\n );\n }\n Sentry.setTag('main-activity-patched', activityPatched);\n }\n\n // ======== STEP 4. Add sentry-cli config file ============\n clack.log.step(\n `Configuring ${chalk.bold('proguard mappings upload')} via the ${chalk.cyan(\n 'sentry.properties',\n )} file.`,\n );\n\n await addSentryCliConfig({ authToken }, proguardMappingCliSetupConfig);\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 // ======== OUTRO ========\n const issuesPageLink = selfHosted\n ? `${sentryUrl}organizations/${selectedProject.organization.slug}/issues/?project=${selectedProject.id}`\n : `https://${selectedProject.organization.slug}.sentry.io/issues/?project=${selectedProject.id}`;\n\n clack.outro(`\n${chalk.greenBright('Successfully installed the Sentry Android SDK!')}\n\n${chalk.cyan(\n `You can validate your setup by launching your application and checking Sentry issues page afterwards\n${issuesPageLink}`,\n)}\n\nCheck out the SDK documentation for further configuration:\nhttps://docs.sentry.io/platforms/android/\n `);\n}\n\n//find files with the given extension\nfunction findFilesWithExtensions(\n dir: string,\n extensions: string[],\n filesWithExtensions: string[] = [],\n): string[] {\n const cwd = process.cwd();\n const files = fs.readdirSync(dir, { withFileTypes: true });\n for (const file of files) {\n if (file.isDirectory()) {\n const childDir = path.join(dir, file.name);\n findFilesWithExtensions(childDir, extensions, filesWithExtensions);\n } else if (extensions.some((ext) => file.name.endsWith(ext))) {\n filesWithExtensions.push(path.relative(cwd, path.join(dir, file.name)));\n }\n }\n return filesWithExtensions;\n}\n"]}
1
+ {"version":3,"file":"android-wizard.js","sourceRoot":"","sources":["../../../src/android/android-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport {\n CliSetupConfig,\n abort,\n abortIfCancelled,\n addSentryCliConfig,\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n printWelcome,\n propertiesCliSetupConfig,\n} from '../utils/clack';\nimport { WizardOptions } from '../utils/types';\nimport { offerProjectScopedMcpConfig } from '../utils/clack/mcp-config';\nimport * as codetools from './code-tools';\nimport * as gradle from './gradle';\nimport * as manifest from './manifest';\n\nconst proguardMappingCliSetupConfig: CliSetupConfig = {\n ...propertiesCliSetupConfig,\n name: 'proguard mappings',\n};\n\nexport async function runAndroidWizard(options: WizardOptions): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'android',\n wizardOptions: options,\n },\n () => runAndroidWizardWithTelemetry(options),\n );\n}\n\nasync function runAndroidWizardWithTelemetry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Android Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\n\n const projectDir = process.cwd();\n const buildGradleFiles = findFilesWithExtensions(projectDir, [\n '.gradle',\n 'gradle.kts',\n ]);\n\n if (!buildGradleFiles || buildGradleFiles.length === 0) {\n clack.log.error(\n 'No Gradle project found. Please run this command from the root of your project.',\n );\n Sentry.captureException('No Gradle project found');\n await abort();\n return;\n }\n\n const appFile = await traceStep('Select App File', () =>\n gradle.selectAppFile(buildGradleFiles),\n );\n\n const { selectedProject, selfHosted, sentryUrl, authToken } =\n await getOrAskForProjectData(options, 'android');\n\n // Ask if user wants to enable Sentry Logs\n const enableLogs = await abortIfCancelled(\n clack.confirm({\n message:\n 'Do you want to enable Logs? (See https://docs.sentry.io/platforms/android/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 or use one of the integrations: https://docs.sentry.io/platforms/android/logs/#integrations.',\n );\n }\n\n // ======== STEP 1. Add Sentry Gradle Plugin to build.gradle(.kts) ============\n clack.log.step(\n `Adding ${chalk.bold('Sentry Gradle plugin')} to your app's ${chalk.cyan(\n 'build.gradle',\n )} file.`,\n );\n const pluginAdded = await traceStep('Add Gradle Plugin', () =>\n gradle.addGradlePlugin(\n appFile,\n selectedProject.organization.slug,\n selectedProject.slug,\n ),\n );\n if (!pluginAdded) {\n clack.log.warn(\n \"Could not add Sentry Gradle plugin to your app's build.gradle file. You'll have to add it manually.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#install\",\n );\n }\n Sentry.setTag('gradle-plugin-added', pluginAdded);\n\n // ======== STEP 2. Configure Sentry SDK via AndroidManifest ============\n clack.log.step(\n `Configuring Sentry SDK via ${chalk.cyan('AndroidManifest.xml')}`,\n );\n const appDir = path.dirname(appFile);\n const manifestFile = path.join(appDir, 'src', 'main', 'AndroidManifest.xml');\n\n const manifestUpdated = traceStep('Update Android Manifest', () =>\n manifest.addManifestSnippet(\n manifestFile,\n selectedProject.keys[0].dsn.public,\n enableLogs,\n ),\n );\n if (!manifestUpdated) {\n clack.log.warn(\n \"Could not configure the Sentry SDK. You'll have to do it manually.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#configure\",\n );\n }\n Sentry.setTag('android-manifest-updated', manifestUpdated);\n\n // ======== STEP 3. Patch Main Activity with a test error snippet ============\n clack.log.step(\n `Patching ${chalk.bold('Main Activity')} with a test error snippet.`,\n );\n const mainActivity = traceStep('Find Main Activity', () =>\n manifest.getMainActivity(manifestFile),\n );\n let packageName = mainActivity.packageName;\n if (!packageName) {\n // if no package name in AndroidManifest, look into gradle script\n packageName = gradle.getNamespace(appFile);\n }\n const activityName = mainActivity.activityName;\n Sentry.setTag('has-activity-name', !!activityName);\n Sentry.setTag('has-package-name', !!packageName);\n if (!activityName || !packageName) {\n clack.log.warn(\n \"Could not find Activity with intent action MAIN. You'll have to manually verify the setup.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#verify\",\n );\n Sentry.captureException('Could not find Main Activity');\n } else {\n const packageNameStable = packageName;\n const activityFile = traceStep('Find Main Activity Source File', () =>\n codetools.findActivitySourceFile(appDir, packageNameStable, activityName),\n );\n\n const activityPatched = traceStep('Patch Main Activity', () =>\n codetools.patchMainActivity(activityFile),\n );\n if (!activityPatched) {\n clack.log.warn(\n \"Could not patch main activity. You'll have to manually verify the setup.\\nPlease follow the instructions at https://docs.sentry.io/platforms/android/#verify\",\n );\n }\n Sentry.setTag('main-activity-patched', activityPatched);\n }\n\n // ======== STEP 4. Add sentry-cli config file ============\n clack.log.step(\n `Configuring ${chalk.bold('proguard mappings upload')} via the ${chalk.cyan(\n 'sentry.properties',\n )} file.`,\n );\n\n await addSentryCliConfig({ authToken }, proguardMappingCliSetupConfig);\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 // ======== OUTRO ========\n const issuesPageLink = selfHosted\n ? `${sentryUrl}organizations/${selectedProject.organization.slug}/issues/?project=${selectedProject.id}`\n : `https://${selectedProject.organization.slug}.sentry.io/issues/?project=${selectedProject.id}`;\n\n clack.outro(`\n${chalk.greenBright('Successfully installed the Sentry Android SDK!')}\n\n${chalk.cyan(\n `You can validate your setup by launching your application and checking Sentry issues page afterwards\n${issuesPageLink}`,\n)}\n\nCheck out the SDK documentation for further configuration:\nhttps://docs.sentry.io/platforms/android/\n `);\n}\n\n//find files with the given extension\nfunction findFilesWithExtensions(\n dir: string,\n extensions: string[],\n filesWithExtensions: string[] = [],\n): string[] {\n const cwd = process.cwd();\n const files = fs.readdirSync(dir, { withFileTypes: true });\n for (const file of files) {\n if (file.isDirectory()) {\n const childDir = path.join(dir, file.name);\n findFilesWithExtensions(childDir, extensions, filesWithExtensions);\n } else if (extensions.some((ext) => file.name.endsWith(ext))) {\n filesWithExtensions.push(path.relative(cwd, path.join(dir, file.name)));\n }\n }\n return filesWithExtensions;\n}\n"]}
@@ -18,7 +18,7 @@
18
18
  * @param dsn
19
19
  * @returns true if successfully patched the manifest, false otherwise
20
20
  */
21
- export declare function addManifestSnippet(manifestFile: string, dsn: string): boolean;
21
+ export declare function addManifestSnippet(manifestFile: string, dsn: string, enableLogs: boolean): boolean;
22
22
  /**
23
23
  * There might be multiple <activity> in the manifest, as well as multiple <activity-alias> with category LAUNCHER,
24
24
  * but only one main activity with action MAIN. We are looking for this one by parsing xml and walking it.
@@ -56,7 +56,7 @@ const chalk_1 = __importDefault(require("chalk"));
56
56
  * @param dsn
57
57
  * @returns true if successfully patched the manifest, false otherwise
58
58
  */
59
- function addManifestSnippet(manifestFile, dsn) {
59
+ function addManifestSnippet(manifestFile, dsn, enableLogs) {
60
60
  if (!fs.existsSync(manifestFile)) {
61
61
  clack.log.warn('AndroidManifest.xml not found.');
62
62
  Sentry.captureException('No AndroidManifest file');
@@ -76,7 +76,7 @@ function addManifestSnippet(manifestFile, dsn) {
76
76
  }
77
77
  const insertionIndex = applicationMatch.index;
78
78
  const newContent = manifestContent.slice(0, insertionIndex) +
79
- (0, templates_1.manifest)(dsn) +
79
+ (0, templates_1.manifest)(dsn, enableLogs) +
80
80
  manifestContent.slice(insertionIndex);
81
81
  fs.writeFileSync(manifestFile, newContent, 'utf8');
82
82
  clack.log.success(chalk_1.default.greenBright(`Updated ${chalk_1.default.bold('AndroidManifest.xml')} with the Sentry SDK configuration.`));
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/android/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport { manifest } from './templates';\nimport xml, { Attributes, ElementCompact } from 'xml-js';\nimport chalk from 'chalk';\n\n/**\n * Looks for the closing </application> tag in the manifest and adds the Sentry config after it.\n *\n * For example:\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\">\n *\n * <application>\n * ...\n * // this is what we add and more\n * <meta-data android:name=\"io.sentry.dsn\" android:value=\"__dsn__\" />\n * </application> <!-- we are looking for this one\n * </manifest>\n * ```\n *\n * @param manifestFile the path to the main AndroidManifest.xml file\n * @param dsn\n * @returns true if successfully patched the manifest, false otherwise\n */\nexport function addManifestSnippet(manifestFile: string, dsn: string): boolean {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return false;\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n\n if (/android:name=\"io\\.sentry[^\"]*\"/i.test(manifestContent)) {\n // sentry is already configured\n clack.log.success(chalk.greenBright('Sentry SDK is already configured.'));\n return true;\n }\n\n const applicationMatch = /<\\/application>/i.exec(manifestContent);\n if (!applicationMatch) {\n clack.log.warn('<application> tag not found within the manifest.');\n Sentry.captureException('No <application> tag');\n return false;\n }\n\n const insertionIndex = applicationMatch.index;\n const newContent =\n manifestContent.slice(0, insertionIndex) +\n manifest(dsn) +\n manifestContent.slice(insertionIndex);\n fs.writeFileSync(manifestFile, newContent, 'utf8');\n\n clack.log.success(\n chalk.greenBright(\n `Updated ${chalk.bold(\n 'AndroidManifest.xml',\n )} with the Sentry SDK configuration.`,\n ),\n );\n\n return true;\n}\n\n/**\n * There might be multiple <activity> in the manifest, as well as multiple <activity-alias> with category LAUNCHER,\n * but only one main activity with action MAIN. We are looking for this one by parsing xml and walking it.\n *\n * In addition, older Android versions required to specify the packag name in the manifest,\n * while the new ones - in the Gradle config. So we are just sanity checking if the package name\n * is in the manifest and returning it as well.\n *\n * For example:\n *\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\"\n * package=\"com.example.sample\">\n *\n * <application>\n * <activity\n * android:name=\"ui.MainActivity\"\n * ...other props>\n * <intent-filter>\n * <action android:name=\"android.intent.action.MAIN\" /> <!-- we are looking for this one\n *\n * <category android:name=\"android.intent.category.LAUNCHER\" />\n * </intent-filter>\n * </activity>\n * </application>\n * </manifest>\n * ```\n *\n * @param manifestFile path to the AndroidManifest.xml file\n * @returns package name (if available in the manifest) + the main activity name\n */\nexport function getMainActivity(manifestFile: string): {\n packageName?: string;\n activityName?: string;\n} {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return {};\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n const converted: ElementCompact = xml.xml2js(manifestContent, {\n compact: true,\n });\n const activities: ElementCompact[] | ElementCompact | undefined =\n converted.manifest?.application?.activity;\n const packageName: string | undefined =\n converted.manifest?._attributes?.['package'];\n\n if (!activities) {\n clack.log.warn('No activity found in AndroidManifest.');\n Sentry.captureException('No Activity');\n return {};\n }\n\n let mainActivity;\n if (Array.isArray(activities)) {\n const withIntentFilter = activities.filter((a) => !!a['intent-filter']);\n mainActivity = withIntentFilter.find((a) => isMainActivity(a));\n } else if (isMainActivity(activities)) {\n mainActivity = activities;\n }\n\n if (!mainActivity) {\n clack.log.warn('No main activity found in AndroidManifest.');\n Sentry.captureException('No Main Activity');\n return {};\n }\n\n const attrs = mainActivity._attributes;\n const activityName = attrs?.['android:name'] as string | undefined;\n return { packageName: packageName, activityName: activityName };\n}\n\nfunction isMainActivity(activity: ElementCompact): boolean {\n const intentFilters: ElementCompact[] | ElementCompact =\n activity['intent-filter'];\n if (Array.isArray(intentFilters)) {\n return intentFilters.some((i) => {\n const action: ElementCompact[] | ElementCompact | undefined = i.action;\n return hasMainAction(action);\n });\n } else {\n const action: ElementCompact[] | ElementCompact | undefined =\n intentFilters.action;\n return hasMainAction(action);\n }\n}\n\nfunction hasMainAction(\n action: ElementCompact[] | ElementCompact | undefined,\n): boolean {\n if (!action) {\n return false;\n }\n\n function isMain(attrs?: Attributes): boolean {\n return attrs?.['android:name'] === 'android.intent.action.MAIN';\n }\n\n if (Array.isArray(action)) {\n return action.some((c) => {\n return isMain(c._attributes);\n });\n } else {\n return isMain(action._attributes);\n }\n}\n"]}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/android/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as fs from 'fs';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport { manifest } from './templates';\nimport xml, { Attributes, ElementCompact } from 'xml-js';\nimport chalk from 'chalk';\n\n/**\n * Looks for the closing </application> tag in the manifest and adds the Sentry config after it.\n *\n * For example:\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\">\n *\n * <application>\n * ...\n * // this is what we add and more\n * <meta-data android:name=\"io.sentry.dsn\" android:value=\"__dsn__\" />\n * </application> <!-- we are looking for this one\n * </manifest>\n * ```\n *\n * @param manifestFile the path to the main AndroidManifest.xml file\n * @param dsn\n * @returns true if successfully patched the manifest, false otherwise\n */\nexport function addManifestSnippet(\n manifestFile: string,\n dsn: string,\n enableLogs: boolean,\n): boolean {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return false;\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n\n if (/android:name=\"io\\.sentry[^\"]*\"/i.test(manifestContent)) {\n // sentry is already configured\n clack.log.success(chalk.greenBright('Sentry SDK is already configured.'));\n return true;\n }\n\n const applicationMatch = /<\\/application>/i.exec(manifestContent);\n if (!applicationMatch) {\n clack.log.warn('<application> tag not found within the manifest.');\n Sentry.captureException('No <application> tag');\n return false;\n }\n\n const insertionIndex = applicationMatch.index;\n const newContent =\n manifestContent.slice(0, insertionIndex) +\n manifest(dsn, enableLogs) +\n manifestContent.slice(insertionIndex);\n fs.writeFileSync(manifestFile, newContent, 'utf8');\n\n clack.log.success(\n chalk.greenBright(\n `Updated ${chalk.bold(\n 'AndroidManifest.xml',\n )} with the Sentry SDK configuration.`,\n ),\n );\n\n return true;\n}\n\n/**\n * There might be multiple <activity> in the manifest, as well as multiple <activity-alias> with category LAUNCHER,\n * but only one main activity with action MAIN. We are looking for this one by parsing xml and walking it.\n *\n * In addition, older Android versions required to specify the packag name in the manifest,\n * while the new ones - in the Gradle config. So we are just sanity checking if the package name\n * is in the manifest and returning it as well.\n *\n * For example:\n *\n * ```xml\n * <manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n * xmlns:tools=\"http://schemas.android.com/tools\"\n * package=\"com.example.sample\">\n *\n * <application>\n * <activity\n * android:name=\"ui.MainActivity\"\n * ...other props>\n * <intent-filter>\n * <action android:name=\"android.intent.action.MAIN\" /> <!-- we are looking for this one\n *\n * <category android:name=\"android.intent.category.LAUNCHER\" />\n * </intent-filter>\n * </activity>\n * </application>\n * </manifest>\n * ```\n *\n * @param manifestFile path to the AndroidManifest.xml file\n * @returns package name (if available in the manifest) + the main activity name\n */\nexport function getMainActivity(manifestFile: string): {\n packageName?: string;\n activityName?: string;\n} {\n if (!fs.existsSync(manifestFile)) {\n clack.log.warn('AndroidManifest.xml not found.');\n Sentry.captureException('No AndroidManifest file');\n return {};\n }\n\n const manifestContent = fs.readFileSync(manifestFile, 'utf8');\n const converted: ElementCompact = xml.xml2js(manifestContent, {\n compact: true,\n });\n const activities: ElementCompact[] | ElementCompact | undefined =\n converted.manifest?.application?.activity;\n const packageName: string | undefined =\n converted.manifest?._attributes?.['package'];\n\n if (!activities) {\n clack.log.warn('No activity found in AndroidManifest.');\n Sentry.captureException('No Activity');\n return {};\n }\n\n let mainActivity;\n if (Array.isArray(activities)) {\n const withIntentFilter = activities.filter((a) => !!a['intent-filter']);\n mainActivity = withIntentFilter.find((a) => isMainActivity(a));\n } else if (isMainActivity(activities)) {\n mainActivity = activities;\n }\n\n if (!mainActivity) {\n clack.log.warn('No main activity found in AndroidManifest.');\n Sentry.captureException('No Main Activity');\n return {};\n }\n\n const attrs = mainActivity._attributes;\n const activityName = attrs?.['android:name'] as string | undefined;\n return { packageName: packageName, activityName: activityName };\n}\n\nfunction isMainActivity(activity: ElementCompact): boolean {\n const intentFilters: ElementCompact[] | ElementCompact =\n activity['intent-filter'];\n if (Array.isArray(intentFilters)) {\n return intentFilters.some((i) => {\n const action: ElementCompact[] | ElementCompact | undefined = i.action;\n return hasMainAction(action);\n });\n } else {\n const action: ElementCompact[] | ElementCompact | undefined =\n intentFilters.action;\n return hasMainAction(action);\n }\n}\n\nfunction hasMainAction(\n action: ElementCompact[] | ElementCompact | undefined,\n): boolean {\n if (!action) {\n return false;\n }\n\n function isMain(attrs?: Attributes): boolean {\n return attrs?.['android:name'] === 'android.intent.action.MAIN';\n }\n\n if (Array.isArray(action)) {\n return action.some((c) => {\n return isMain(c._attributes);\n });\n } else {\n return isMain(action._attributes);\n }\n}\n"]}
@@ -2,7 +2,7 @@ export declare const pluginsBlock: (version?: string) => string;
2
2
  export declare const pluginsBlockKts: (version?: string) => string;
3
3
  export declare const plugin: (version?: string) => string;
4
4
  export declare const pluginKts: (version?: string) => string;
5
- export declare const manifest: (dsn: string) => string;
5
+ export declare const manifest: (dsn: string, enableLogs: boolean) => string;
6
6
  export declare const sentryImport = "import io.sentry.Sentry;\n";
7
7
  export declare const sentryImportKt = "import io.sentry.Sentry\n";
8
8
  export declare const testErrorSnippet = "\n // waiting for view to draw to better represent a captured error with a screenshot\n findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(() -> {\n try {\n throw new Exception(\"This app uses Sentry! :)\");\n } catch (Exception e) {\n Sentry.captureException(e);\n }\n });\n";
@@ -23,7 +23,7 @@ const pluginKts = (version = '3.12.0') => `
23
23
  id("io.sentry.android.gradle") version "${version}"
24
24
  `;
25
25
  exports.pluginKts = pluginKts;
26
- const manifest = (dsn) => `
26
+ const manifest = (dsn, enableLogs) => `
27
27
  <!-- Required: set your sentry.io project identifier (DSN) -->
28
28
  <meta-data android:name="io.sentry.dsn" android:value="${dsn}" />
29
29
  <!-- Add data like request headers, user ip address and device name, see https://docs.sentry.io/platforms/android/data-management/data-collected/ for more info -->
@@ -38,6 +38,9 @@ const manifest = (dsn) => `
38
38
 
39
39
  <!-- enable the performance API by setting a sample-rate, adjust in production env -->
40
40
  <meta-data android:name="io.sentry.traces.sample-rate" android:value="1.0" />
41
+ ${enableLogs
42
+ ? ' <!-- enable Sentry Logs -->\n <meta-data android:name="io.sentry.logs.enabled" android:value="true" />'
43
+ : ''}
41
44
  `;
42
45
  exports.manifest = manifest;
43
46
  exports.sentryImport = `import io.sentry.Sentry;\n`;
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/android/templates.ts"],"names":[],"mappings":";;;AAAO,MAAM,YAAY,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;;6CAEP,OAAO;;;CAGnD,CAAC;AALW,QAAA,YAAY,gBAKvB;AAEK,MAAM,eAAe,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;;8CAET,OAAO;;;CAGpD,CAAC;AALW,QAAA,eAAe,mBAK1B;AAEK,MAAM,MAAM,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;6CACD,OAAO;CACnD,CAAC;AAFW,QAAA,MAAM,UAEjB;AAEK,MAAM,SAAS,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;8CACH,OAAO;CACpD,CAAC;AAFW,QAAA,SAAS,aAEpB;AAEK,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC;;6DAEoB,GAAG;;;;;;;;;;;;;CAa/D,CAAC;AAfW,QAAA,QAAQ,YAenB;AAEW,QAAA,YAAY,GAAG,4BAA4B,CAAC;AAE5C,QAAA,cAAc,GAAG,2BAA2B,CAAC;AAE7C,QAAA,gBAAgB,GAAG;;;;;;;;;CAS/B,CAAC;AAEW,QAAA,kBAAkB,GAAG;;;;;;;;;CASjC,CAAC;AAEK,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAE,EAAE,CAAC;;;aAG1D,OAAO;qBACC,WAAW;;;;;;CAM/B,CAAC;AAVW,QAAA,aAAa,iBAUxB;AAEK,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAE,EAAE,CAAC;;;eAG3D,OAAO;uBACC,WAAW;;;;;;CAMjC,CAAC;AAVW,QAAA,gBAAgB,oBAU3B","sourcesContent":["export const pluginsBlock = (version = '3.12.0') => `\nplugins {\n id 'io.sentry.android.gradle' version '${version}'\n}\n\n`;\n\nexport const pluginsBlockKts = (version = '3.12.0') => `\nplugins {\n id(\"io.sentry.android.gradle\") version \"${version}\"\n}\n\n`;\n\nexport const plugin = (version = '3.12.0') => `\n id 'io.sentry.android.gradle' version '${version}'\n`;\n\nexport const pluginKts = (version = '3.12.0') => `\n id(\"io.sentry.android.gradle\") version \"${version}\"\n`;\n\nexport const manifest = (dsn: string) => `\n <!-- Required: set your sentry.io project identifier (DSN) -->\n <meta-data android:name=\"io.sentry.dsn\" android:value=\"${dsn}\" />\n <!-- Add data like request headers, user ip address and device name, see https://docs.sentry.io/platforms/android/data-management/data-collected/ for more info -->\n <meta-data android:name=\"io.sentry.send-default-pii\" android:value=\"true\" />\n\n <!-- enable automatic breadcrumbs for user interactions (clicks, swipes, scrolls) -->\n <meta-data android:name=\"io.sentry.traces.user-interaction.enable\" android:value=\"true\" />\n <!-- enable screenshot for crashes (could contain sensitive/PII data) -->\n <meta-data android:name=\"io.sentry.attach-screenshot\" android:value=\"true\" />\n <!-- enable view hierarchy for crashes -->\n <meta-data android:name=\"io.sentry.attach-view-hierarchy\" android:value=\"true\" />\n\n <!-- enable the performance API by setting a sample-rate, adjust in production env -->\n <meta-data android:name=\"io.sentry.traces.sample-rate\" android:value=\"1.0\" />\n`;\n\nexport const sentryImport = `import io.sentry.Sentry;\\n`;\n\nexport const sentryImportKt = `import io.sentry.Sentry\\n`;\n\nexport const testErrorSnippet = `\n // waiting for view to draw to better represent a captured error with a screenshot\n findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(() -> {\n try {\n throw new Exception(\"This app uses Sentry! :)\");\n } catch (Exception e) {\n Sentry.captureException(e);\n }\n });\n`;\n\nexport const testErrorSnippetKt = `\n // waiting for view to draw to better represent a captured error with a screenshot\n findViewById<android.view.View>(android.R.id.content).viewTreeObserver.addOnGlobalLayoutListener {\n try {\n throw Exception(\"This app uses Sentry! :)\")\n } catch (e: Exception) {\n Sentry.captureException(e)\n }\n }\n`;\n\nexport const sourceContext = (orgSlug: string, projectSlug: string) => `\n\nsentry {\n org = \"${orgSlug}\"\n projectName = \"${projectSlug}\"\n\n // this will upload your source code to Sentry to show it as part of the stack traces\n // disable if you don't want to expose your sources\n includeSourceContext = true\n}\n`;\n\nexport const sourceContextKts = (orgSlug: string, projectSlug: string) => `\n\nsentry {\n org.set(\"${orgSlug}\")\n projectName.set(\"${projectSlug}\")\n\n // this will upload your source code to Sentry to show it as part of the stack traces\n // disable if you don't want to expose your sources\n includeSourceContext.set(true)\n}\n`;\n"]}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/android/templates.ts"],"names":[],"mappings":";;;AAAO,MAAM,YAAY,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;;6CAEP,OAAO;;;CAGnD,CAAC;AALW,QAAA,YAAY,gBAKvB;AAEK,MAAM,eAAe,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;;8CAET,OAAO;;;CAGpD,CAAC;AALW,QAAA,eAAe,mBAK1B;AAEK,MAAM,MAAM,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;6CACD,OAAO;CACnD,CAAC;AAFW,QAAA,MAAM,UAEjB;AAEK,MAAM,SAAS,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE,CAAC;8CACH,OAAO;CACpD,CAAC;AAFW,QAAA,SAAS,aAEpB;AAEK,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,UAAmB,EAAE,EAAE,CAAC;;6DAED,GAAG;;;;;;;;;;;;;EAc9D,UAAU;IACR,CAAC,CAAC,+GAA+G;IACjH,CAAC,CAAC,EACN;CACC,CAAC;AApBW,QAAA,QAAQ,YAoBnB;AAEW,QAAA,YAAY,GAAG,4BAA4B,CAAC;AAE5C,QAAA,cAAc,GAAG,2BAA2B,CAAC;AAE7C,QAAA,gBAAgB,GAAG;;;;;;;;;CAS/B,CAAC;AAEW,QAAA,kBAAkB,GAAG;;;;;;;;;CASjC,CAAC;AAEK,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAE,EAAE,CAAC;;;aAG1D,OAAO;qBACC,WAAW;;;;;;CAM/B,CAAC;AAVW,QAAA,aAAa,iBAUxB;AAEK,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAE,EAAE,CAAC;;;eAG3D,OAAO;uBACC,WAAW;;;;;;CAMjC,CAAC;AAVW,QAAA,gBAAgB,oBAU3B","sourcesContent":["export const pluginsBlock = (version = '3.12.0') => `\nplugins {\n id 'io.sentry.android.gradle' version '${version}'\n}\n\n`;\n\nexport const pluginsBlockKts = (version = '3.12.0') => `\nplugins {\n id(\"io.sentry.android.gradle\") version \"${version}\"\n}\n\n`;\n\nexport const plugin = (version = '3.12.0') => `\n id 'io.sentry.android.gradle' version '${version}'\n`;\n\nexport const pluginKts = (version = '3.12.0') => `\n id(\"io.sentry.android.gradle\") version \"${version}\"\n`;\n\nexport const manifest = (dsn: string, enableLogs: boolean) => `\n <!-- Required: set your sentry.io project identifier (DSN) -->\n <meta-data android:name=\"io.sentry.dsn\" android:value=\"${dsn}\" />\n <!-- Add data like request headers, user ip address and device name, see https://docs.sentry.io/platforms/android/data-management/data-collected/ for more info -->\n <meta-data android:name=\"io.sentry.send-default-pii\" android:value=\"true\" />\n\n <!-- enable automatic breadcrumbs for user interactions (clicks, swipes, scrolls) -->\n <meta-data android:name=\"io.sentry.traces.user-interaction.enable\" android:value=\"true\" />\n <!-- enable screenshot for crashes (could contain sensitive/PII data) -->\n <meta-data android:name=\"io.sentry.attach-screenshot\" android:value=\"true\" />\n <!-- enable view hierarchy for crashes -->\n <meta-data android:name=\"io.sentry.attach-view-hierarchy\" android:value=\"true\" />\n\n <!-- enable the performance API by setting a sample-rate, adjust in production env -->\n <meta-data android:name=\"io.sentry.traces.sample-rate\" android:value=\"1.0\" />\n${\n enableLogs\n ? ' <!-- enable Sentry Logs -->\\n <meta-data android:name=\"io.sentry.logs.enabled\" android:value=\"true\" />'\n : ''\n}\n`;\n\nexport const sentryImport = `import io.sentry.Sentry;\\n`;\n\nexport const sentryImportKt = `import io.sentry.Sentry\\n`;\n\nexport const testErrorSnippet = `\n // waiting for view to draw to better represent a captured error with a screenshot\n findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(() -> {\n try {\n throw new Exception(\"This app uses Sentry! :)\");\n } catch (Exception e) {\n Sentry.captureException(e);\n }\n });\n`;\n\nexport const testErrorSnippetKt = `\n // waiting for view to draw to better represent a captured error with a screenshot\n findViewById<android.view.View>(android.R.id.content).viewTreeObserver.addOnGlobalLayoutListener {\n try {\n throw Exception(\"This app uses Sentry! :)\")\n } catch (e: Exception) {\n Sentry.captureException(e)\n }\n }\n`;\n\nexport const sourceContext = (orgSlug: string, projectSlug: string) => `\n\nsentry {\n org = \"${orgSlug}\"\n projectName = \"${projectSlug}\"\n\n // this will upload your source code to Sentry to show it as part of the stack traces\n // disable if you don't want to expose your sources\n includeSourceContext = true\n}\n`;\n\nexport const sourceContextKts = (orgSlug: string, projectSlug: string) => `\n\nsentry {\n org.set(\"${orgSlug}\")\n projectName.set(\"${projectSlug}\")\n\n // this will upload your source code to Sentry to show it as part of the stack traces\n // disable if you don't want to expose your sources\n includeSourceContext.set(true)\n}\n`;\n"]}
@@ -47,6 +47,7 @@ function getInitCallArgs(dsn, selectedFeatures) {
47
47
  if (selectedFeatures.logs) {
48
48
  initCallArgs.enableLogs = true;
49
49
  }
50
+ initCallArgs.sendDefaultPii = true;
50
51
  return initCallArgs;
51
52
  }
52
53
  exports.getInitCallArgs = getInitCallArgs;
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../src/angular/codemods/main.ts"],"names":[],"mappings":";;;AAEA,uCAMkB;AAElB,SAAgB,iBAAiB;AAC/B,8DAA8D;AAC9D,oBAA0C,EAC1C,GAAW,EACX,gBAIC;IAGD,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC;QAChC,IAAI,EAAE,iBAAiB;QACvB,QAAQ,EAAE,GAAG;QACb,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IAEH,cAAc,CAAC,oBAAoB,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAE5D,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AApBD,8CAoBC;AAED,SAAgB,cAAc;AAC5B,8DAA8D;AAC9D,oBAA0C,EAC1C,GAAW,EACX,gBAIC;IAED,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC5D,sHAAsH;IACtH,MAAM,QAAQ,GAAG,mBAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACpE,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAe,CAAC;IAErE,MAAM,sBAAsB,GAAG,6BAA6B,CAC1D,uBAAuB,CACxB,CAAC;IAEF,uBAAuB,CAAC,IAAI,CAAC,MAAM,CACjC,sBAAsB,EACtB,CAAC;IACD,gFAAgF;IAChF,qHAAqH;IACrH,IAAA,uBAAY,EAAC,QAAQ,CAAC,CAAC,IAAI,CAC5B,CAAC;AACJ,CAAC;AA1BD,wCA0BC;AAOD,SAAgB,eAAe,CAC7B,GAAW,EACX,gBAIC;IAED,MAAM,YAAY,GAAiB;QACjC,GAAG;KACJ,CAAC;IAEF,IAAI,gBAAgB,CAAC,MAAM,IAAI,gBAAgB,CAAC,WAAW,EAAE;QAC3D,YAAY,CAAC,YAAY,GAAG,EAAE,CAAC;QAE/B,IAAI,gBAAgB,CAAC,WAAW,EAAE;YAChC,YAAY,CAAC,YAAY,CAAC,IAAI,CAC5B,mBAAQ,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAC1D,CAAC;YACF,YAAY,CAAC,gBAAgB,GAAG,GAAG,CAAC;SACrC;QAED,IAAI,gBAAgB,CAAC,MAAM,EAAE;YAC3B,YAAY,CAAC,YAAY,CAAC,IAAI,CAC5B,mBAAQ,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAClD,CAAC;YAEF,YAAY,CAAC,wBAAwB,GAAG,GAAG,CAAC;YAC5C,YAAY,CAAC,wBAAwB,GAAG,GAAG,CAAC;SAC7C;KACF;IAED,IAAI,gBAAgB,CAAC,IAAI,EAAE;QACzB,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC;KAChC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AArCD,0CAqCC;AAED;;GAEG;AACH,SAAgB,6BAA6B,CAC3C,yBAAkC;IAElC,KAAK,IAAI,CAAC,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACnE,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE;YAClE,OAAO,CAAC,GAAG,CAAC,CAAC;SACd;KACF;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAVD,sEAUC","sourcesContent":["import type { Program } from '@babel/types';\n\nimport {\n builders,\n generateCode,\n Proxified,\n type ProxifiedModule,\n // @ts-expect-error - magicast is ESM and TS complains about that. It works though\n} from 'magicast';\n\nexport function updateAppEntryMod(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppModuleMod: ProxifiedModule<any>,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ProxifiedModule<any> {\n originalAppModuleMod.imports.$add({\n from: '@sentry/angular',\n imported: '*',\n local: 'Sentry',\n });\n\n insertInitCall(originalAppModuleMod, dsn, selectedFeatures);\n\n return originalAppModuleMod;\n}\n\nexport function insertInitCall(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppModuleMod: ProxifiedModule<any>,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): void {\n const initCallArgs = getInitCallArgs(dsn, selectedFeatures);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- builders return Proxified which defaults to any\n const initCall = builders.functionCall('Sentry.init', initCallArgs);\n const originalAppModuleModAst = originalAppModuleMod.$ast as Program;\n\n const initCallInsertionIndex = getAfterImportsInsertionIndex(\n originalAppModuleModAst,\n );\n\n originalAppModuleModAst.body.splice(\n initCallInsertionIndex,\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- builders return Proxified which defaults to any.\n generateCode(initCall).code,\n );\n}\n\ntype InitCallArgs = Record<\n string,\n string | number | boolean | Array<Proxified>\n>;\n\nexport function getInitCallArgs(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): InitCallArgs {\n const initCallArgs: InitCallArgs = {\n dsn,\n };\n\n if (selectedFeatures.replay || selectedFeatures.performance) {\n initCallArgs.integrations = [];\n\n if (selectedFeatures.performance) {\n initCallArgs.integrations.push(\n builders.functionCall('Sentry.browserTracingIntegration'),\n );\n initCallArgs.tracesSampleRate = 1.0;\n }\n\n if (selectedFeatures.replay) {\n initCallArgs.integrations.push(\n builders.functionCall('Sentry.replayIntegration'),\n );\n\n initCallArgs.replaysSessionSampleRate = 0.1;\n initCallArgs.replaysOnErrorSampleRate = 1.0;\n }\n }\n\n if (selectedFeatures.logs) {\n initCallArgs.enableLogs = true;\n }\n\n return initCallArgs;\n}\n\n/**\n * We want to insert the handleError function just after all imports\n */\nexport function getAfterImportsInsertionIndex(\n originalEntryServerModAST: Program,\n): number {\n for (let x = originalEntryServerModAST.body.length - 1; x >= 0; x--) {\n if (originalEntryServerModAST.body[x].type === 'ImportDeclaration') {\n return x + 1;\n }\n }\n\n return 0;\n}\n"]}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../src/angular/codemods/main.ts"],"names":[],"mappings":";;;AAEA,uCAMkB;AAElB,SAAgB,iBAAiB;AAC/B,8DAA8D;AAC9D,oBAA0C,EAC1C,GAAW,EACX,gBAIC;IAGD,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC;QAChC,IAAI,EAAE,iBAAiB;QACvB,QAAQ,EAAE,GAAG;QACb,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IAEH,cAAc,CAAC,oBAAoB,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAE5D,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AApBD,8CAoBC;AAED,SAAgB,cAAc;AAC5B,8DAA8D;AAC9D,oBAA0C,EAC1C,GAAW,EACX,gBAIC;IAED,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC5D,sHAAsH;IACtH,MAAM,QAAQ,GAAG,mBAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACpE,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAe,CAAC;IAErE,MAAM,sBAAsB,GAAG,6BAA6B,CAC1D,uBAAuB,CACxB,CAAC;IAEF,uBAAuB,CAAC,IAAI,CAAC,MAAM,CACjC,sBAAsB,EACtB,CAAC;IACD,gFAAgF;IAChF,qHAAqH;IACrH,IAAA,uBAAY,EAAC,QAAQ,CAAC,CAAC,IAAI,CAC5B,CAAC;AACJ,CAAC;AA1BD,wCA0BC;AAOD,SAAgB,eAAe,CAC7B,GAAW,EACX,gBAIC;IAED,MAAM,YAAY,GAAiB;QACjC,GAAG;KACJ,CAAC;IAEF,IAAI,gBAAgB,CAAC,MAAM,IAAI,gBAAgB,CAAC,WAAW,EAAE;QAC3D,YAAY,CAAC,YAAY,GAAG,EAAE,CAAC;QAE/B,IAAI,gBAAgB,CAAC,WAAW,EAAE;YAChC,YAAY,CAAC,YAAY,CAAC,IAAI,CAC5B,mBAAQ,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAC1D,CAAC;YACF,YAAY,CAAC,gBAAgB,GAAG,GAAG,CAAC;SACrC;QAED,IAAI,gBAAgB,CAAC,MAAM,EAAE;YAC3B,YAAY,CAAC,YAAY,CAAC,IAAI,CAC5B,mBAAQ,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAClD,CAAC;YAEF,YAAY,CAAC,wBAAwB,GAAG,GAAG,CAAC;YAC5C,YAAY,CAAC,wBAAwB,GAAG,GAAG,CAAC;SAC7C;KACF;IAED,IAAI,gBAAgB,CAAC,IAAI,EAAE;QACzB,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC;KAChC;IAED,YAAY,CAAC,cAAc,GAAG,IAAI,CAAC;IAEnC,OAAO,YAAY,CAAC;AACtB,CAAC;AAvCD,0CAuCC;AAED;;GAEG;AACH,SAAgB,6BAA6B,CAC3C,yBAAkC;IAElC,KAAK,IAAI,CAAC,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACnE,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE;YAClE,OAAO,CAAC,GAAG,CAAC,CAAC;SACd;KACF;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAVD,sEAUC","sourcesContent":["import type { Program } from '@babel/types';\n\nimport {\n builders,\n generateCode,\n Proxified,\n type ProxifiedModule,\n // @ts-expect-error - magicast is ESM and TS complains about that. It works though\n} from 'magicast';\n\nexport function updateAppEntryMod(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppModuleMod: ProxifiedModule<any>,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ProxifiedModule<any> {\n originalAppModuleMod.imports.$add({\n from: '@sentry/angular',\n imported: '*',\n local: 'Sentry',\n });\n\n insertInitCall(originalAppModuleMod, dsn, selectedFeatures);\n\n return originalAppModuleMod;\n}\n\nexport function insertInitCall(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppModuleMod: ProxifiedModule<any>,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): void {\n const initCallArgs = getInitCallArgs(dsn, selectedFeatures);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- builders return Proxified which defaults to any\n const initCall = builders.functionCall('Sentry.init', initCallArgs);\n const originalAppModuleModAst = originalAppModuleMod.$ast as Program;\n\n const initCallInsertionIndex = getAfterImportsInsertionIndex(\n originalAppModuleModAst,\n );\n\n originalAppModuleModAst.body.splice(\n initCallInsertionIndex,\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- builders return Proxified which defaults to any.\n generateCode(initCall).code,\n );\n}\n\ntype InitCallArgs = Record<\n string,\n string | number | boolean | Array<Proxified>\n>;\n\nexport function getInitCallArgs(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): InitCallArgs {\n const initCallArgs: InitCallArgs = {\n dsn,\n };\n\n if (selectedFeatures.replay || selectedFeatures.performance) {\n initCallArgs.integrations = [];\n\n if (selectedFeatures.performance) {\n initCallArgs.integrations.push(\n builders.functionCall('Sentry.browserTracingIntegration'),\n );\n initCallArgs.tracesSampleRate = 1.0;\n }\n\n if (selectedFeatures.replay) {\n initCallArgs.integrations.push(\n builders.functionCall('Sentry.replayIntegration'),\n );\n\n initCallArgs.replaysSessionSampleRate = 0.1;\n initCallArgs.replaysOnErrorSampleRate = 1.0;\n }\n }\n\n if (selectedFeatures.logs) {\n initCallArgs.enableLogs = true;\n }\n\n initCallArgs.sendDefaultPii = true;\n\n return initCallArgs;\n}\n\n/**\n * We want to insert the handleError function just after all imports\n */\nexport function getAfterImportsInsertionIndex(\n originalEntryServerModAST: Program,\n): number {\n for (let x = originalEntryServerModAST.body.length - 1; x >= 0; x--) {\n if (originalEntryServerModAST.body[x].type === 'ImportDeclaration') {\n return x + 1;\n }\n }\n\n return 0;\n}\n"]}
@@ -28,7 +28,6 @@ exports.scriptInputPath = '"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Co
28
28
  function getSwiftSnippet(dsn, enableLogs) {
29
29
  let snippet = ` SentrySDK.start { options in
30
30
  options.dsn = "${dsn}"
31
- options.debug = true // Enabled debug when first installing is always helpful
32
31
 
33
32
  // Adds IP for users.
34
33
  // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
@@ -63,7 +62,6 @@ exports.getSwiftSnippet = getSwiftSnippet;
63
62
  function getObjcSnippet(dsn, enableLogs) {
64
63
  let snippet = ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {
65
64
  options.dsn = @"${dsn}";
66
- options.debug = YES; // Enabled debug when first installing is always helpful
67
65
 
68
66
  // Adds IP for users.
69
67
  // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/apple/templates.ts"],"names":[],"mappings":";;;AAAA,SAAgB,oBAAoB,CAClC,OAAe,EACf,WAAmB,EACnB,YAAqB,EACrB,mBAA4B;IAE5B,6CAA6C;IAC7C,MAAM,eAAe,GAAG,mBAAmB;QACzC,CAAC,CAAC;;;;CAIL;QACG,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,0FAA0F,eAAe;;sBAE5F,OAAO;0BACH,WAAW;0CAEjC,YAAY,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EACxC;;;;;;;CAOD,CAAC;AACF,CAAC;AA5BD,oDA4BC;AAEY,QAAA,eAAe,GAC1B,6FAA6F,CAAC;AAEhG,SAAgB,eAAe,CAAC,GAAW,EAAE,UAAmB;IAC9D,IAAI,OAAO,GAAG;6BACa,GAAG;;;;;;;;;;;;;;;;;;;sGAmBsE,CAAC;IAErG,IAAI,UAAU,EAAE;QACd,OAAO,IAAI;;;mDAGoC,CAAC;KACjD;IAED,OAAO,IAAI;;;iEAGoD,CAAC;IAEhE,OAAO,OAAO,CAAC;AACjB,CAAC;AApCD,0CAoCC;AAED,SAAgB,cAAc,CAAC,GAAW,EAAE,UAAmB;IAC7D,IAAI,OAAO,GAAG;0BACU,GAAG;;;;;;;;;;;;;;;;;;;oGAmBuE,CAAC;IAEnG,IAAI,UAAU,EAAE;QACd,OAAO,IAAI;;;+CAGgC,CAAC;KAC7C;IAED,OAAO,IAAI;;;2DAG8C,CAAC;IAE1D,OAAO,OAAO,CAAC;AACjB,CAAC;AApCD,wCAoCC;AAED,SAAgB,kBAAkB,CAAC,GAAW,EAAE,OAAe;IAC7D,OAAO;mBACU,GAAG;uBACC,OAAO;;MAExB,CAAC;AACP,CAAC;AAND,gDAMC","sourcesContent":["export function getRunScriptTemplate(\n orgSlug: string,\n projectSlug: string,\n uploadSource: boolean,\n includeHomebrewPath: boolean,\n): string {\n // eslint-disable-next-line no-useless-escape\n const includeHomebrew = includeHomebrewPath\n ? `\nif [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n`\n : '';\n return `# This script is responsible for uploading debug symbols and source context for Sentry.${includeHomebrew}\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=${orgSlug}\n export SENTRY_PROJECT=${projectSlug}\n ERROR=$(sentry-cli debug-files upload ${\n uploadSource ? '--include-sources ' : ''\n }\"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`;\n}\n\nexport const scriptInputPath =\n '\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}\"';\n\nexport function getSwiftSnippet(dsn: string, enableLogs: boolean): string {\n let snippet = ` SentrySDK.start { options in\n options.dsn = \"${dsn}\"\n options.debug = true // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = true\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = {\n $0.sessionSampleRate = 1.0 // We recommend adjusting this value in production.\n $0.lifecycle = .trace\n }\n\n // Uncomment the following lines to add more data to your events\n // options.attachScreenshot = true // This adds a screenshot to the error events\n // options.attachViewHierarchy = true // This adds the view hierarchy to the error events`;\n\n if (enableLogs) {\n snippet += `\n \n // Enable experimental logging features\n options.experimental.enableLogs = true`;\n }\n\n snippet += `\n }\n // Remove the next line after confirming that your Sentry integration is working.\n SentrySDK.capture(message: \"This app uses Sentry! :)\")\\n`;\n\n return snippet;\n}\n\nexport function getObjcSnippet(dsn: string, enableLogs: boolean): string {\n let snippet = ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {\n options.dsn = @\"${dsn}\";\n options.debug = YES; // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = YES;\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = @1.0;\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = ^(SentryProfileOptions *profiling) {\n profiling.sessionSampleRate = 1.0; // We recommend adjusting this value in production.\n profiling.lifecycle = SentryProfilingLifecycleTrace;\n };\n\n //Uncomment the following lines to add more data to your events\n //options.attachScreenshot = YES; //This will add a screenshot to the error events\n //options.attachViewHierarchy = YES; //This will add the view hierarchy to the error events`;\n\n if (enableLogs) {\n snippet += `\n \n // Enable experimental logging features\n options.experimental.enableLogs = YES;`;\n }\n\n snippet += `\n }];\n //Remove the next line after confirming that your Sentry integration is working.\n [SentrySDK captureMessage:@\"This app uses Sentry!\"];\\n`;\n\n return snippet;\n}\n\nexport function getFastlaneSnippet(org: string, project: string): string {\n return ` sentry_cli(\n org_slug: '${org}',\n project_slug: '${project}',\n include_sources: true\n )`;\n}\n"]}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/apple/templates.ts"],"names":[],"mappings":";;;AAAA,SAAgB,oBAAoB,CAClC,OAAe,EACf,WAAmB,EACnB,YAAqB,EACrB,mBAA4B;IAE5B,6CAA6C;IAC7C,MAAM,eAAe,GAAG,mBAAmB;QACzC,CAAC,CAAC;;;;CAIL;QACG,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,0FAA0F,eAAe;;sBAE5F,OAAO;0BACH,WAAW;0CAEjC,YAAY,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EACxC;;;;;;;CAOD,CAAC;AACF,CAAC;AA5BD,oDA4BC;AAEY,QAAA,eAAe,GAC1B,6FAA6F,CAAC;AAEhG,SAAgB,eAAe,CAAC,GAAW,EAAE,UAAmB;IAC9D,IAAI,OAAO,GAAG;6BACa,GAAG;;;;;;;;;;;;;;;;;;sGAkBsE,CAAC;IAErG,IAAI,UAAU,EAAE;QACd,OAAO,IAAI;;;mDAGoC,CAAC;KACjD;IAED,OAAO,IAAI;;;iEAGoD,CAAC;IAEhE,OAAO,OAAO,CAAC;AACjB,CAAC;AAnCD,0CAmCC;AAED,SAAgB,cAAc,CAAC,GAAW,EAAE,UAAmB;IAC7D,IAAI,OAAO,GAAG;0BACU,GAAG;;;;;;;;;;;;;;;;;;oGAkBuE,CAAC;IAEnG,IAAI,UAAU,EAAE;QACd,OAAO,IAAI;;;+CAGgC,CAAC;KAC7C;IAED,OAAO,IAAI;;;2DAG8C,CAAC;IAE1D,OAAO,OAAO,CAAC;AACjB,CAAC;AAnCD,wCAmCC;AAED,SAAgB,kBAAkB,CAAC,GAAW,EAAE,OAAe;IAC7D,OAAO;mBACU,GAAG;uBACC,OAAO;;MAExB,CAAC;AACP,CAAC;AAND,gDAMC","sourcesContent":["export function getRunScriptTemplate(\n orgSlug: string,\n projectSlug: string,\n uploadSource: boolean,\n includeHomebrewPath: boolean,\n): string {\n // eslint-disable-next-line no-useless-escape\n const includeHomebrew = includeHomebrewPath\n ? `\nif [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n`\n : '';\n return `# This script is responsible for uploading debug symbols and source context for Sentry.${includeHomebrew}\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=${orgSlug}\n export SENTRY_PROJECT=${projectSlug}\n ERROR=$(sentry-cli debug-files upload ${\n uploadSource ? '--include-sources ' : ''\n }\"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`;\n}\n\nexport const scriptInputPath =\n '\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}\"';\n\nexport function getSwiftSnippet(dsn: string, enableLogs: boolean): string {\n let snippet = ` SentrySDK.start { options in\n options.dsn = \"${dsn}\"\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = true\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = {\n $0.sessionSampleRate = 1.0 // We recommend adjusting this value in production.\n $0.lifecycle = .trace\n }\n\n // Uncomment the following lines to add more data to your events\n // options.attachScreenshot = true // This adds a screenshot to the error events\n // options.attachViewHierarchy = true // This adds the view hierarchy to the error events`;\n\n if (enableLogs) {\n snippet += `\n \n // Enable experimental logging features\n options.experimental.enableLogs = true`;\n }\n\n snippet += `\n }\n // Remove the next line after confirming that your Sentry integration is working.\n SentrySDK.capture(message: \"This app uses Sentry! :)\")\\n`;\n\n return snippet;\n}\n\nexport function getObjcSnippet(dsn: string, enableLogs: boolean): string {\n let snippet = ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {\n options.dsn = @\"${dsn}\";\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = YES;\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = @1.0;\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = ^(SentryProfileOptions *profiling) {\n profiling.sessionSampleRate = 1.0; // We recommend adjusting this value in production.\n profiling.lifecycle = SentryProfilingLifecycleTrace;\n };\n\n //Uncomment the following lines to add more data to your events\n //options.attachScreenshot = YES; //This will add a screenshot to the error events\n //options.attachViewHierarchy = YES; //This will add the view hierarchy to the error events`;\n\n if (enableLogs) {\n snippet += `\n \n // Enable experimental logging features\n options.experimental.enableLogs = YES;`;\n }\n\n snippet += `\n }];\n //Remove the next line after confirming that your Sentry integration is working.\n [SentrySDK captureMessage:@\"This app uses Sentry!\"];\\n`;\n\n return snippet;\n}\n\nexport function getFastlaneSnippet(org: string, project: string): string {\n return ` sentry_cli(\n org_slug: '${org}',\n project_slug: '${project}',\n include_sources: true\n )`;\n}\n"]}
@@ -204,7 +204,7 @@ async function runNextjsWizardWithTelemetry(options) {
204
204
  const isLikelyUsingTurbopack = await checkIfLikelyIsUsingTurbopack();
205
205
  if (isLikelyUsingTurbopack || isLikelyUsingTurbopack === null) {
206
206
  await (0, clack_1.abortIfCancelled)(prompts_1.default.select({
207
- message: `Warning: The Sentry SDK is only compatible with Turbopack on Next.js version 15.3.0 (or 15.3.0-canary.8) or later. ${chalk_1.default.bold(`If you are using Turbopack with an older Next.js version, temporarily remove \`--turbo\` or \`--turbopack\` from your dev command until you have verified the SDK is working as expected. Note that the SDK will continue to work for non-Turbopack production builds.`)}`,
207
+ message: 'Warning: The Sentry SDK is only compatible with Turbopack on Next.js version 15.4.1 or later.',
208
208
  options: [
209
209
  {
210
210
  label: 'I understand.',