@sentry/wizard 6.11.0 → 6.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js +5 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js.map +1 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js +2 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.d.ts +1 -0
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +96 -0
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -0
- package/dist/e2e-tests/tests/react-router.test.js +3 -1
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +2 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
- package/dist/src/apple/code-tools.js +17 -3
- package/dist/src/apple/code-tools.js.map +1 -1
- package/dist/src/apple/configure-package-manager.js +18 -5
- package/dist/src/apple/configure-package-manager.js.map +1 -1
- package/dist/src/cloudflare/cloudflare-wizard.js +5 -0
- package/dist/src/cloudflare/cloudflare-wizard.js.map +1 -1
- package/dist/src/cloudflare/sdk-setup.d.ts +1 -0
- package/dist/src/cloudflare/sdk-setup.js.map +1 -1
- package/dist/src/cloudflare/templates.d.ts +1 -0
- package/dist/src/cloudflare/templates.js +7 -1
- package/dist/src/cloudflare/templates.js.map +1 -1
- package/dist/src/cloudflare/wrap-worker.d.ts +1 -0
- package/dist/src/cloudflare/wrap-worker.js +7 -0
- package/dist/src/cloudflare/wrap-worker.js.map +1 -1
- package/dist/src/react-native/expo.d.ts +6 -0
- package/dist/src/react-native/expo.js +27 -1
- package/dist/src/react-native/expo.js.map +1 -1
- package/dist/src/react-native/git.d.ts +5 -0
- package/dist/src/react-native/git.js +32 -1
- package/dist/src/react-native/git.js.map +1 -1
- package/dist/src/react-native/javascript.js +3 -1
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +12 -6
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
- package/dist/src/react-router/codemods/client.entry.js +69 -12
- package/dist/src/react-router/codemods/client.entry.js.map +1 -1
- package/dist/src/react-router/codemods/react-router-config.js +1 -1
- package/dist/src/react-router/codemods/react-router-config.js.map +1 -1
- package/dist/src/react-router/codemods/root.js +1 -2
- package/dist/src/react-router/codemods/root.js.map +1 -1
- package/dist/src/react-router/codemods/server-entry.d.ts +1 -1
- package/dist/src/react-router/codemods/server-entry.js +39 -4
- package/dist/src/react-router/codemods/server-entry.js.map +1 -1
- package/dist/src/react-router/codemods/vite.js +46 -1
- package/dist/src/react-router/codemods/vite.js.map +1 -1
- package/dist/src/react-router/react-router-wizard.js +52 -5
- package/dist/src/react-router/react-router-wizard.js.map +1 -1
- package/dist/src/react-router/sdk-setup.d.ts +4 -2
- package/dist/src/react-router/sdk-setup.js +32 -5
- package/dist/src/react-router/sdk-setup.js.map +1 -1
- package/dist/src/react-router/templates.d.ts +2 -2
- package/dist/src/react-router/templates.js +72 -2
- package/dist/src/react-router/templates.js.map +1 -1
- package/dist/src/sourcemaps/tools/vite.js +1 -1
- package/dist/src/sourcemaps/tools/vite.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +10 -0
- package/dist/src/utils/ast-utils.js +19 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +78 -0
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/apple/configure-package-manager.test.d.ts +1 -0
- package/dist/test/apple/configure-package-manager.test.js +161 -0
- package/dist/test/apple/configure-package-manager.test.js.map +1 -0
- package/dist/test/cloudflare/sdk-setup.test.js +20 -2
- package/dist/test/cloudflare/sdk-setup.test.js.map +1 -1
- package/dist/test/cloudflare/templates.test.js +54 -0
- package/dist/test/cloudflare/templates.test.js.map +1 -1
- package/dist/test/cloudflare/wrap-worker.test.js +74 -11
- package/dist/test/cloudflare/wrap-worker.test.js.map +1 -1
- package/dist/test/react-native/expo.test.js +140 -0
- package/dist/test/react-native/expo.test.js.map +1 -1
- package/dist/test/react-native/git.test.d.ts +1 -0
- package/dist/test/react-native/git.test.js +160 -0
- package/dist/test/react-native/git.test.js.map +1 -0
- package/dist/test/react-router/codemods/client-entry.test.js +29 -0
- package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/root.test.js +4 -0
- package/dist/test/react-router/codemods/root.test.js.map +1 -1
- package/dist/test/react-router/codemods/server-entry.test.js +70 -0
- package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/vite.test.js +89 -0
- package/dist/test/react-router/codemods/vite.test.js.map +1 -1
- package/dist/test/react-router/sdk-setup.test.js +62 -6
- package/dist/test/react-router/sdk-setup.test.js.map +1 -1
- package/dist/test/react-router/templates.test.js +50 -0
- package/dist/test/react-router/templates.test.js.map +1 -1
- package/dist/test/sourcemaps/tools/vite.test.js +12 -8
- package/dist/test/sourcemaps/tools/vite.test.js.map +1 -1
- package/dist/test/utils/ast-utils.test.js +22 -0
- package/dist/test/utils/ast-utils.test.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 6.12.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- (cloudflare) Add enableLogs when setting up Cloudflare by @JPeer264 in [#1191](https://github.com/getsentry/sentry-wizard/pull/1191)
|
|
8
|
+
- (react-native) Skip patch native files when expo CNG by @uragirii in [#1211](https://github.com/getsentry/sentry-wizard/pull/1211)
|
|
9
|
+
- (react-router) Add React Router Instrumentation API support by @onurtemizkan in [#1209](https://github.com/getsentry/sentry-wizard/pull/1209)
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
#### Apple
|
|
14
|
+
|
|
15
|
+
- Show deprecation warning for CocoaPods package manager by @itaybre in [#1229](https://github.com/getsentry/sentry-wizard/pull/1229)
|
|
16
|
+
- Prevent duplicate init() in SwiftUI apps with existing initializer by @betegon in [#1188](https://github.com/getsentry/sentry-wizard/pull/1188)
|
|
17
|
+
|
|
18
|
+
#### Other
|
|
19
|
+
|
|
20
|
+
- (release) Add semver fields to changelog categories by @BYK in [#1193](https://github.com/getsentry/sentry-wizard/pull/1193)
|
|
21
|
+
- Preserve trailing newlines when modifying config files by @andreiborza in [#1208](https://github.com/getsentry/sentry-wizard/pull/1208)
|
|
22
|
+
|
|
23
|
+
### Internal Changes
|
|
24
|
+
|
|
25
|
+
#### Agents
|
|
26
|
+
|
|
27
|
+
- Init dotagents by @chargome in [#1232](https://github.com/getsentry/sentry-wizard/pull/1232)
|
|
28
|
+
- Use `AGENTS.md` with symlinks by @chargome in [#1233](https://github.com/getsentry/sentry-wizard/pull/1233)
|
|
29
|
+
|
|
30
|
+
#### Deps
|
|
31
|
+
|
|
32
|
+
- Bump devalue from 5.6.2 to 5.6.3 in /e2e-tests/test-applications/cloudflare-wrangler-sourcemaps-test-app by @dependabot in [#1228](https://github.com/getsentry/sentry-wizard/pull/1228)
|
|
33
|
+
- Bump rollup from 4.50.1 to 4.59.0 by @dependabot in [#1231](https://github.com/getsentry/sentry-wizard/pull/1231)
|
|
34
|
+
- Bump rollup from 4.41.0 to 4.59.0 in /e2e-tests/test-applications/cloudflare-wrangler-sourcemaps-test-app by @dependabot in [#1230](https://github.com/getsentry/sentry-wizard/pull/1230)
|
|
35
|
+
- Bump next from 16.0.10 to 16.1.5 in /e2e-tests/test-applications/nextjs-16-test-app by @dependabot in [#1206](https://github.com/getsentry/sentry-wizard/pull/1206)
|
|
36
|
+
- Bump next from 15.5.9 to 15.5.10 in /e2e-tests/test-applications/nextjs-15-test-app by @dependabot in [#1224](https://github.com/getsentry/sentry-wizard/pull/1224)
|
|
37
|
+
- Bump axios from 1.12.0 to 1.13.5 by @dependabot in [#1222](https://github.com/getsentry/sentry-wizard/pull/1222)
|
|
38
|
+
- Bump lodash from 4.17.21 to 4.17.23 by @dependabot in [#1204](https://github.com/getsentry/sentry-wizard/pull/1204)
|
|
39
|
+
|
|
40
|
+
#### Release
|
|
41
|
+
|
|
42
|
+
- Fix changelog-preview permissions by @BYK in [#1205](https://github.com/getsentry/sentry-wizard/pull/1205)
|
|
43
|
+
- Switch from action-prepare-release to Craft by @BYK in [#1186](https://github.com/getsentry/sentry-wizard/pull/1186)
|
|
44
|
+
|
|
45
|
+
#### Other
|
|
46
|
+
|
|
47
|
+
- (deps-dev) Bump wrangler from 4.16.0 to 4.59.1 in /e2e-tests/test-applications/cloudflare-wrangler-sourcemaps-test-app by @dependabot in [#1203](https://github.com/getsentry/sentry-wizard/pull/1203)
|
|
48
|
+
- (publish) Clean up changelog by @Lms24 in [#1234](https://github.com/getsentry/sentry-wizard/pull/1234)
|
|
49
|
+
- Add unlabeled trigger to changelog-preview by @BYK in [#1189](https://github.com/getsentry/sentry-wizard/pull/1189)
|
|
50
|
+
- Use pull_request_target for changelog preview by @BYK in [#1196](https://github.com/getsentry/sentry-wizard/pull/1196)
|
|
51
|
+
|
|
3
52
|
## 6.11.0
|
|
4
53
|
|
|
5
54
|
### New Features
|
|
@@ -26,6 +26,9 @@ const clifty_1 = require("clifty");
|
|
|
26
26
|
whenAsked('Do you want to enable Tracing', {
|
|
27
27
|
timeout: 90000, // package installation can take a while in CI
|
|
28
28
|
}).respondWith(clifty_1.KEYS.ENTER);
|
|
29
|
+
whenAsked('Do you want to enable Logs', {
|
|
30
|
+
timeout: 90000, // package installation can take a while in CI
|
|
31
|
+
}).respondWith(clifty_1.KEYS.ENTER);
|
|
29
32
|
})
|
|
30
33
|
.whenAsked('Optionally add a project-scoped MCP server configuration for the Sentry MCP?')
|
|
31
34
|
.respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER)
|
|
@@ -58,6 +61,8 @@ const clifty_1 = require("clifty");
|
|
|
58
61
|
'import * as Sentry from "@sentry/cloudflare";',
|
|
59
62
|
'export default Sentry.withSentry(env => ({',
|
|
60
63
|
'dsn: "https://public@dsn.ingest.sentry.io/1337",',
|
|
64
|
+
'tracesSampleRate: 1',
|
|
65
|
+
'enableLogs: true',
|
|
61
66
|
]);
|
|
62
67
|
});
|
|
63
68
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare-worker.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/cloudflare-worker.test.ts"],"names":[],"mappings":";;AAAA,mCAAmE;AACnE,mDAAkD;AAClD,oCAMkB;AAElB,uCAAuC;AACvC,mCAAuC;AAEvC,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,MAAM,WAAW,GAAG,uBAAW,CAAC,UAAU,CAAC;IAC3C,IAAI,cAAsB,CAAC;IAC3B,IAAI,yBAAiC,CAAC;IAEtC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,IAAA,6BAAqB,EAAC,qBAAqB,CAAC,CAAC;IAE7E,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;QACnB,yEAAyE;QACzE,yBAAyB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAElE,cAAc,GAAG,MAAM,IAAA,gBAAO,EAAC;YAC7B,GAAG,EAAE,UAAU;SAChB,CAAC;aACC,iBAAiB,EAAE;aACnB,YAAY,CACX,+EAA+E,CAChF;aACA,IAAI,CAAC,sBAAsB,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,EAAE;YAC5D,SAAS,CAAC,qCAAqC,CAAC,CAAC,WAAW,CAC1D,aAAI,CAAC,IAAI,EACT,aAAI,CAAC,KAAK,CACX,CAAC;YACF,YAAY,CAAC,+BAA+B,CAAC,CAAC;QAChD,CAAC,CAAC;aACD,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;YACnC,SAAS,CAAC,+BAA+B,EAAE;gBACzC,OAAO,EAAE,KAAM,EAAE,8CAA8C;aAChE,CAAC,CAAC,WAAW,CAAC,aAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC;aACD,SAAS,CACR,8EAA8E,CAC/E;aACA,WAAW,CAAC,aAAI,CAAC,IAAI,EAAE,aAAI,CAAC,KAAK,CAAC;aAClC,YAAY,CACX,sEAAsE,CACvE;aACA,GAAG,CAAC,IAAA,wBAAgB,EAAC,WAAW,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,GAAG,EAAE;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,IAAA,eAAM,EAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,IAAA,wBAAgB,EAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,IAAA,yBAAiB,EAAC,GAAG,UAAU,iBAAiB,EAAE;YAChD,0BAA0B,yBAAyB,GAAG;YACtD,gCAAgC;YAChC,cAAc;YACd,uBAAuB;YACvB,kCAAkC;SACnC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,IAAA,yBAAiB,EAAC,GAAG,UAAU,eAAe,EAAE;YAC9C,+CAA+C;YAC/C,4CAA4C;YAC5C,kDAAkD;
|
|
1
|
+
{"version":3,"file":"cloudflare-worker.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/cloudflare-worker.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterAll, beforeAll, describe, expect, it } from 'vitest';\nimport { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkIfBuilds,\n checkPackageJson,\n createIsolatedTestEnv,\n getWizardCommand,\n} from '../utils';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\ndescribe('cloudflare-worker', () => {\n const integration = Integration.cloudflare;\n let wizardExitCode: number;\n let expectedCompatibilityDate: string;\n\n const { projectDir, cleanup } = createIsolatedTestEnv('cloudflare-test-app');\n\n beforeAll(async () => {\n // Capture the date before running the wizard (wizard runs in subprocess)\n expectedCompatibilityDate = new Date().toISOString().slice(0, 10);\n\n wizardExitCode = await withEnv({\n cwd: projectDir,\n })\n .defineInteraction()\n .expectOutput(\n 'The Sentry Cloudflare 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/cloudflare');\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 Logs', {\n timeout: 90_000, // package installation can take a while in CI\n }).respondWith(KEYS.ENTER);\n })\n .whenAsked(\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n )\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput(\n 'Sentry has been successfully configured for your Cloudflare project.',\n )\n .run(getWizardCommand(integration));\n });\n\n afterAll(() => {\n cleanup();\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, '@sentry/cloudflare');\n });\n\n it('builds correctly', async () => {\n await checkIfBuilds(projectDir);\n });\n\n it('wrangler.jsonc file contains Sentry configuration', () => {\n checkFileContents(`${projectDir}/wrangler.jsonc`, [\n `\"compatibility_date\": \"${expectedCompatibilityDate}\"`,\n '\"global_fetch_strictly_public\"',\n '\"nodejs_als\"',\n '\"version_metadata\": {',\n '\"binding\": \"CF_VERSION_METADATA\"',\n ]);\n });\n\n it('modifies the worker file to include Sentry initialization', () => {\n checkFileContents(`${projectDir}/src/index.ts`, [\n 'import * as Sentry from \"@sentry/cloudflare\";',\n 'export default Sentry.withSentry(env => ({',\n 'dsn: \"https://public@dsn.ingest.sentry.io/1337\",',\n 'tracesSampleRate: 1',\n 'enableLogs: true',\n ]);\n });\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pnpm-workspace.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/pnpm-workspace.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 createIsolatedTestEnv,\n getWizardCommand,\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('pnpm workspace', () => {\n const integration = Integration.sveltekit;\n let wizardExitCode: number;\n\n const { projectDir: workspaceDir, cleanup } = createIsolatedTestEnv(\n 'pnpm-workspace-test-app',\n );\n const projectDir = path.resolve(workspaceDir, 'packages/sveltekit');\n\n beforeAll(async () => {\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.DOWN,\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 cleanup();\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, '@sentry/sveltekit');\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 org: \"${TEST_ARGS.ORG_SLUG}\",\n project: \"${TEST_ARGS.PROJECT_SLUG}\"\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"]}
|
|
1
|
+
{"version":3,"file":"pnpm-workspace.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/pnpm-workspace.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAClC,4CAA8B;AAC9B,mDAAkD;AAClD,oCAUkB;AAClB,mCAAmE;AAEnE,uCAAuC;AACvC,mCAAuC;AAEvC,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,MAAM,WAAW,GAAG,uBAAW,CAAC,SAAS,CAAC;IAC1C,IAAI,cAAsB,CAAC;IAE3B,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,IAAA,6BAAqB,EACjE,yBAAyB,CAC1B,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;IAEpE,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;QACnB,cAAc,GAAG,MAAM,IAAA,gBAAO,EAAC;YAC7B,GAAG,EAAE,UAAU;SAChB,CAAC;aACC,iBAAiB,EAAE;aACnB,YAAY,CACX,8EAA8E,CAC/E;aACA,IAAI,CAAC,sBAAsB,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,EAAE;YAC5D,SAAS,CAAC,qCAAqC,CAAC,CAAC,WAAW,CAC1D,aAAI,CAAC,IAAI,EACT,aAAI,CAAC,IAAI,EACT,aAAI,CAAC,IAAI,EACT,aAAI,CAAC,KAAK,CACX,CAAC;YACF,YAAY,CAAC,8BAA8B,CAAC,CAAC;QAC/C,CAAC,CAAC;aACD,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;YACnC,SAAS,CAAC,+BAA+B,EAAE;gBACzC,OAAO,EAAE,KAAM,EAAE,8CAA8C;aAChE,CAAC,CAAC,WAAW,CAAC,aAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,SAAS,CAAC,sCAAsC,CAAC,CAAC,WAAW,CAC3D,aAAI,CAAC,KAAK,CACX,CAAC;YACF,SAAS,CAAC,4BAA4B,CAAC,CAAC,WAAW,CAAC,aAAI,CAAC,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC;aACD,SAAS,CAAC,uCAAuC,CAAC;aAClD,WAAW,CAAC,aAAI,CAAC,KAAK,CAAC;aACvB,SAAS,CACR,8EAA8E,CAC/E;aACA,WAAW,CAAC,aAAI,CAAC,IAAI,EAAE,aAAI,CAAC,KAAK,CAAC;aAClC,YAAY,CAAC,kDAAkD,CAAC;aAChE,GAAG,CAAC,IAAA,wBAAgB,EAAC,WAAW,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,GAAG,EAAE;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,IAAA,eAAM,EAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,IAAA,wBAAgB,EAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,IAAA,2BAAmB,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,IAAA,uBAAe,EACb,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,6CAA6C,CAAC,CACxE,CAAC;QACF,IAAA,uBAAe,EACb,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,2CAA2C,CAAC,CACtE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAChC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAC3C,CAAC;QACF,IAAA,eAAM,EAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;wBAOhC,iBAAS,CAAC,QAAQ;4BACd,iBAAS,CAAC,YAAY;;;;OAI3C,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CACjC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAChD,CAAC;QACF,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CACjC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAChD,CAAC;QAEF,IAAA,eAAM,EAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;kBAKvC,iBAAS,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BhC,CAAC,CAAC;QAEL,IAAA,eAAM,EAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;OAQlD,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,qBAAqB,GAAG,EAAE,CAAC,YAAY,CAC3C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,+BAA+B,CAAC,CAC1D,CAAC;QAEF,IAAA,eAAM,EAAC,qBAAqB,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;kBAIjD,iBAAS,CAAC,WAAW;;;;;;;;;;OAUhC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAClC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAC7C,CAAC;QACF,IAAA,eAAM,EAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BnD,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,kDAAkD;IAClD,IAAA,WAAE,EAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,IAAA,4BAAoB,EAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,IAAA,6BAAqB,EAAC,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","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 createIsolatedTestEnv,\n getWizardCommand,\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('pnpm workspace', () => {\n const integration = Integration.sveltekit;\n let wizardExitCode: number;\n\n const { projectDir: workspaceDir, cleanup } = createIsolatedTestEnv(\n 'pnpm-workspace-test-app',\n );\n const projectDir = path.resolve(workspaceDir, 'packages/sveltekit');\n\n beforeAll(async () => {\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.DOWN,\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 cleanup();\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, '@sentry/sveltekit');\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 org: \"${TEST_ARGS.ORG_SLUG}\",\n project: \"${TEST_ARGS.PROJECT_SLUG}\"\n }), sveltekit()]\n });\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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const Constants_1 = require("../../lib/Constants");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
//@ts-expect-error - clifty is ESM only
|
|
7
|
+
const clifty_1 = require("clifty");
|
|
8
|
+
// Expects React Router >= 7.9.5
|
|
9
|
+
async function runWizardWithInstrumentationAPI(projectDir) {
|
|
10
|
+
const wizardInteraction = (0, clifty_1.withEnv)({
|
|
11
|
+
cwd: projectDir,
|
|
12
|
+
}).defineInteraction();
|
|
13
|
+
wizardInteraction
|
|
14
|
+
.whenAsked('Please select your package manager.')
|
|
15
|
+
.respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER)
|
|
16
|
+
.expectOutput('Installing @sentry/react-router')
|
|
17
|
+
.expectOutput('Installed @sentry/react-router', {
|
|
18
|
+
timeout: 240000,
|
|
19
|
+
})
|
|
20
|
+
.whenAsked('Do you want to enable Tracing')
|
|
21
|
+
.respondWith(clifty_1.KEYS.ENTER) // Yes
|
|
22
|
+
.whenAsked('Do you want to enable Session Replay')
|
|
23
|
+
.respondWith(clifty_1.KEYS.ENTER) // Yes
|
|
24
|
+
.whenAsked('Do you want to enable Logs')
|
|
25
|
+
.respondWith(clifty_1.KEYS.ENTER) // Yes
|
|
26
|
+
.whenAsked('Do you want to enable Profiling')
|
|
27
|
+
.respondWith(clifty_1.KEYS.ENTER) // Yes
|
|
28
|
+
.whenAsked('Do you want to use the Instrumentation API')
|
|
29
|
+
.respondWith(clifty_1.KEYS.ENTER) // Yes
|
|
30
|
+
.expectOutput('Installing @sentry/profiling-node')
|
|
31
|
+
.expectOutput('Installed @sentry/profiling-node', {
|
|
32
|
+
timeout: 240000,
|
|
33
|
+
})
|
|
34
|
+
.whenAsked('Do you want to create an example page')
|
|
35
|
+
.respondWith(clifty_1.KEYS.ENTER); // Yes
|
|
36
|
+
return wizardInteraction
|
|
37
|
+
.whenAsked('Optionally add a project-scoped MCP server configuration for the Sentry MCP?')
|
|
38
|
+
.respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER) // No
|
|
39
|
+
.expectOutput('Successfully installed the Sentry React Router SDK!')
|
|
40
|
+
.run((0, utils_1.getWizardCommand)(Constants_1.Integration.reactRouter));
|
|
41
|
+
}
|
|
42
|
+
(0, vitest_1.describe)('React Router Instrumentation API', () => {
|
|
43
|
+
(0, vitest_1.describe)('with Instrumentation API enabled', () => {
|
|
44
|
+
let wizardExitCode;
|
|
45
|
+
const { projectDir, cleanup } = (0, utils_1.createIsolatedTestEnv)('react-router-test-app');
|
|
46
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
47
|
+
wizardExitCode = await runWizardWithInstrumentationAPI(projectDir);
|
|
48
|
+
});
|
|
49
|
+
(0, vitest_1.afterAll)(() => {
|
|
50
|
+
cleanup();
|
|
51
|
+
});
|
|
52
|
+
(0, vitest_1.test)('exits with exit code 0', () => {
|
|
53
|
+
(0, vitest_1.expect)(wizardExitCode).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
(0, vitest_1.test)('package.json is updated correctly', () => {
|
|
56
|
+
(0, utils_1.checkPackageJson)(projectDir, '@sentry/react-router');
|
|
57
|
+
});
|
|
58
|
+
(0, vitest_1.test)('.env.sentry-build-plugin is created and contains the auth token', () => {
|
|
59
|
+
(0, utils_1.checkEnvBuildPlugin)(projectDir);
|
|
60
|
+
});
|
|
61
|
+
(0, vitest_1.test)('entry.client file contains Instrumentation API setup', () => {
|
|
62
|
+
(0, utils_1.checkFileContents)(`${projectDir}/app/entry.client.tsx`, [
|
|
63
|
+
'import * as Sentry from',
|
|
64
|
+
'@sentry/react-router',
|
|
65
|
+
'const tracing = Sentry.reactRouterTracingIntegration({ useInstrumentationAPI: true });',
|
|
66
|
+
'integrations: [tracing',
|
|
67
|
+
'unstable_instrumentations={[tracing.clientInstrumentation]}',
|
|
68
|
+
]);
|
|
69
|
+
});
|
|
70
|
+
(0, vitest_1.test)('entry.server file contains Sentry server hooks', () => {
|
|
71
|
+
(0, utils_1.checkFileContents)(`${projectDir}/app/entry.server.tsx`, [
|
|
72
|
+
'import * as Sentry from',
|
|
73
|
+
'@sentry/react-router',
|
|
74
|
+
'Sentry.wrapSentryHandleRequest(',
|
|
75
|
+
'export const handleError = Sentry.createSentryHandleError(',
|
|
76
|
+
'export const unstable_instrumentations = [Sentry.createSentryServerInstrumentation()]',
|
|
77
|
+
]);
|
|
78
|
+
});
|
|
79
|
+
(0, vitest_1.test)('instrument.server file exists', () => {
|
|
80
|
+
(0, utils_1.checkFileExists)(`${projectDir}/instrument.server.mjs`);
|
|
81
|
+
});
|
|
82
|
+
(0, vitest_1.test)('example page exists', () => {
|
|
83
|
+
(0, utils_1.checkFileExists)(`${projectDir}/app/routes/sentry-example-page.tsx`);
|
|
84
|
+
});
|
|
85
|
+
(0, vitest_1.test)('builds successfully', async () => {
|
|
86
|
+
await (0, utils_1.checkIfBuilds)(projectDir);
|
|
87
|
+
}, 60000);
|
|
88
|
+
(0, vitest_1.test)('runs on dev mode correctly', async () => {
|
|
89
|
+
await (0, utils_1.checkIfRunsOnDevMode)(projectDir, 'to expose');
|
|
90
|
+
}, 30000);
|
|
91
|
+
(0, vitest_1.test)('runs on prod mode correctly', async () => {
|
|
92
|
+
await (0, utils_1.checkIfRunsOnProdMode)(projectDir, 'react-router-serve');
|
|
93
|
+
}, 30000);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=react-router-instrumentation-api.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-router-instrumentation-api.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/react-router-instrumentation-api.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterAll, beforeAll, describe, test, expect } from 'vitest';\nimport { Integration } from '../../lib/Constants';\nimport {\n checkEnvBuildPlugin,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n createIsolatedTestEnv,\n getWizardCommand,\n} from '../utils';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\n// Expects React Router >= 7.9.5\nasync function runWizardWithInstrumentationAPI(\n projectDir: string,\n): Promise<number> {\n const wizardInteraction = withEnv({\n cwd: projectDir,\n }).defineInteraction();\n\n wizardInteraction\n .whenAsked('Please select your package manager.')\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput('Installing @sentry/react-router')\n .expectOutput('Installed @sentry/react-router', {\n timeout: 240_000,\n })\n\n .whenAsked('Do you want to enable Tracing')\n .respondWith(KEYS.ENTER) // Yes\n .whenAsked('Do you want to enable Session Replay')\n .respondWith(KEYS.ENTER) // Yes\n .whenAsked('Do you want to enable Logs')\n .respondWith(KEYS.ENTER) // Yes\n .whenAsked('Do you want to enable Profiling')\n .respondWith(KEYS.ENTER) // Yes\n .whenAsked('Do you want to use the Instrumentation API')\n .respondWith(KEYS.ENTER) // Yes\n .expectOutput('Installing @sentry/profiling-node')\n .expectOutput('Installed @sentry/profiling-node', {\n timeout: 240_000,\n })\n .whenAsked('Do you want to create an example page')\n .respondWith(KEYS.ENTER); // Yes\n\n return wizardInteraction\n .whenAsked(\n 'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',\n )\n .respondWith(KEYS.DOWN, KEYS.ENTER) // No\n .expectOutput('Successfully installed the Sentry React Router SDK!')\n .run(getWizardCommand(Integration.reactRouter));\n}\n\ndescribe('React Router Instrumentation API', () => {\n describe('with Instrumentation API enabled', () => {\n let wizardExitCode: number;\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'react-router-test-app',\n );\n\n beforeAll(async () => {\n wizardExitCode = await runWizardWithInstrumentationAPI(projectDir);\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, '@sentry/react-router');\n });\n\n test('.env.sentry-build-plugin is created and contains the auth token', () => {\n checkEnvBuildPlugin(projectDir);\n });\n\n test('entry.client file contains Instrumentation API setup', () => {\n checkFileContents(`${projectDir}/app/entry.client.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n 'const tracing = Sentry.reactRouterTracingIntegration({ useInstrumentationAPI: true });',\n 'integrations: [tracing',\n 'unstable_instrumentations={[tracing.clientInstrumentation]}',\n ]);\n });\n\n test('entry.server file contains Sentry server hooks', () => {\n checkFileContents(`${projectDir}/app/entry.server.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n 'Sentry.wrapSentryHandleRequest(',\n 'export const handleError = Sentry.createSentryHandleError(',\n 'export const unstable_instrumentations = [Sentry.createSentryServerInstrumentation()]',\n ]);\n });\n\n test('instrument.server file exists', () => {\n checkFileExists(`${projectDir}/instrument.server.mjs`);\n });\n\n test('example page exists', () => {\n checkFileExists(`${projectDir}/app/routes/sentry-example-page.tsx`);\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n }, 60_000);\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(projectDir, 'to expose');\n }, 30_000);\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(projectDir, 'react-router-serve');\n }, 30_000);\n });\n});\n"]}
|
|
@@ -55,6 +55,8 @@ async function runWizardOnReactRouterProject(projectDir, opts) {
|
|
|
55
55
|
.respondWith(clifty_1.KEYS.ENTER)
|
|
56
56
|
.whenAsked('Do you want to enable Profiling')
|
|
57
57
|
.respondWith(clifty_1.KEYS.ENTER)
|
|
58
|
+
.whenAsked('Do you want to use the Instrumentation API')
|
|
59
|
+
.respondWith(clifty_1.KEYS.DOWN, clifty_1.KEYS.ENTER) // No
|
|
58
60
|
.expectOutput('Installing @sentry/profiling-node')
|
|
59
61
|
.expectOutput('Installed @sentry/profiling-node', {
|
|
60
62
|
timeout: 240000,
|
|
@@ -121,7 +123,7 @@ async function runWizardOnReactRouterProject(projectDir, opts) {
|
|
|
121
123
|
});
|
|
122
124
|
(0, vitest_1.test)('package.json scripts are updated correctly', () => {
|
|
123
125
|
(0, utils_1.checkFileContents)(`${projectDir}/package.json`, [
|
|
124
|
-
`"start": "NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js"`,
|
|
126
|
+
`"start": "NODE_ENV=production NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js"`,
|
|
125
127
|
`"dev": "NODE_OPTIONS='--import ./instrument.server.mjs' react-router dev"`,
|
|
126
128
|
]);
|
|
127
129
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-router.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/react-router.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 TEST_ARGS,\n checkEnvBuildPlugin,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n createIsolatedTestEnv,\n getWizardCommand,\n} from '../utils';\nimport { afterAll, beforeAll, describe, test, expect } from 'vitest';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\nasync function runWizardOnReactRouterProject(\n projectDir: string,\n opts?: {\n modifiedFiles?: boolean;\n },\n): Promise<number> {\n const { modifiedFiles = false } = opts || {};\n\n const wizardInteraction = withEnv({\n cwd: projectDir,\n }).defineInteraction();\n\n if (modifiedFiles) {\n wizardInteraction\n .whenAsked('Do you want to continue anyway?')\n .respondWith(KEYS.ENTER);\n }\n\n wizardInteraction\n .whenAsked('Please select your package manager.')\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput('Installing @sentry/react-router')\n .expectOutput('Installed @sentry/react-router', {\n timeout: 240_000,\n })\n\n .whenAsked('Do you want to enable Tracing')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to enable Session Replay')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to enable Logs')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to enable Profiling')\n .respondWith(KEYS.ENTER)\n .expectOutput('Installing @sentry/profiling-node')\n .expectOutput('Installed @sentry/profiling-node', {\n timeout: 240_000,\n })\n .whenAsked('Do you want to create an example page')\n .respondWith(KEYS.ENTER);\n\n if (modifiedFiles) {\n wizardInteraction\n .whenAsked('Would you like to try running npx react-router reveal')\n .respondWith(KEYS.ENTER)\n .whenAsked('Did you apply the snippet above?')\n .respondWith(KEYS.ENTER);\n }\n\n return wizardInteraction\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 React Router SDK!')\n .run(getWizardCommand(Integration.reactRouter));\n}\n\ndescribe('React Router', () => {\n describe('with empty project', () => {\n let wizardExitCode: number;\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'react-router-test-app',\n );\n\n beforeAll(async () => {\n wizardExitCode = await runWizardOnReactRouterProject(projectDir);\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, '@sentry/react-router');\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('example API route exists', () => {\n checkFileExists(`${projectDir}/app/routes/api.sentry-example-api.ts`);\n });\n\n test('example page is added to routes configuration', () => {\n checkFileContents(`${projectDir}/app/routes.ts`, [\n 'route(\"/sentry-example-page\", \"routes/sentry-example-page.tsx\")',\n 'route(\"/api/sentry-example-api\", \"routes/api.sentry-example-api.ts\")',\n ]);\n });\n\n test('instrument.server file exists', () => {\n checkFileExists(`${projectDir}/instrument.server.mjs`);\n });\n\n test('entry.client file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/app/entry.client.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",`,\n 'integrations: [Sentry.reactRouterTracingIntegration(), Sentry.replayIntegration()]',\n 'enableLogs: true,',\n 'tracesSampleRate: 1.0,',\n ]);\n });\n\n test('package.json scripts are updated correctly', () => {\n checkFileContents(`${projectDir}/package.json`, [\n `\"start\": \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js\"`,\n `\"dev\": \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router dev\"`,\n ]);\n });\n\n test('entry.server file contains Sentry instrumentation', () => {\n checkFileContents(`${projectDir}/app/entry.server.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n 'export const handleError = Sentry.createSentryHandleError(',\n 'export default Sentry.wrapSentryHandleRequest(handleRequest);',\n ]);\n });\n\n test('instrument.server file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/instrument.server.mjs`, [\n \"import * as Sentry from '@sentry/react-router';\",\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",`,\n 'enableLogs: true,',\n ]);\n });\n\n test('root file contains Sentry ErrorBoundary', () => {\n checkFileContents(`${projectDir}/app/root.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n 'export function ErrorBoundary',\n 'Sentry.captureException(error)',\n ]);\n });\n\n test('vite.config file contains sentryReactRouter plugin', () => {\n checkFileContents(`${projectDir}/vite.config.ts`, [\n 'import { sentryReactRouter } from',\n '@sentry/react-router',\n 'sentryReactRouter(',\n 'authToken: process.env.SENTRY_AUTH_TOKEN',\n ]);\n });\n\n test('react-router.config file contains buildEnd hook with sentryOnBuildEnd', () => {\n checkFileContents(`${projectDir}/react-router.config.ts`, [\n 'import { sentryOnBuildEnd } from',\n '@sentry/react-router',\n 'ssr: true,',\n 'buildEnd: async',\n 'await sentryOnBuildEnd({',\n ]);\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n }, 60_000); // 1 minute timeout\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(projectDir, 'to expose');\n }, 30_000); // 30 second timeout\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(projectDir, 'react-router-serve');\n }, 30_000); // 30 second timeout\n });\n\n describe('edge cases', () => {\n describe('existing Sentry setup', () => {\n let wizardExitCode: number;\n\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'react-router-test-app',\n );\n\n beforeAll(async () => {\n // Add existing Sentry setup to the isolated test app\n const clientEntryPath = path.join(\n projectDir,\n 'app',\n 'entry.client.tsx',\n );\n const existingContent = `import * as Sentry from \"@sentry/react-router\";\nimport { startTransition, StrictMode } from \"react\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { HydratedRouter } from \"react-router/dom\";\n\nSentry.init({\n dsn: \"https://existing@dsn.ingest.sentry.io/1337\",\n tracesSampleRate: 1.0,\n});\n\nstartTransition(() => {\n hydrateRoot(\n document,\n <StrictMode>\n <HydratedRouter />\n </StrictMode>\n );\n});`;\n fs.writeFileSync(clientEntryPath, existingContent);\n\n wizardExitCode = await runWizardOnReactRouterProject(projectDir, {\n modifiedFiles: true,\n });\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('wizard handles existing Sentry without duplication', () => {\n const clientContent = fs.readFileSync(\n `${projectDir}/app/entry.client.tsx`,\n 'utf8',\n );\n const sentryImportCount = (\n clientContent.match(\n /import \\* as Sentry from \"@sentry\\/react-router\"/g,\n ) || []\n ).length;\n const sentryInitCount = (clientContent.match(/Sentry\\.init\\(/g) || [])\n .length;\n\n expect(sentryImportCount).toBe(1);\n expect(sentryInitCount).toBe(1);\n });\n\n // Only test the essential checks for this edge case\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, '@sentry/react-router');\n });\n\n test('essential files exist or wizard completes gracefully', () => {\n // Check if key directories exist\n expect(fs.existsSync(`${projectDir}/app`)).toBe(true);\n\n // When there's existing Sentry setup, the wizard may skip some file creation\n // to avoid conflicts. This is acceptable behavior.\n // Let's check if the wizard at least completed by verifying package.json was updated\n const packageJsonPath = `${projectDir}/package.json`;\n expect(fs.existsSync(packageJsonPath)).toBe(true);\n\n const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');\n const packageJson = JSON.parse(packageJsonContent) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const hasSentryPackage =\n packageJson.dependencies?.['@sentry/react-router'] ||\n packageJson.devDependencies?.['@sentry/react-router'];\n\n // The wizard should have at least installed the Sentry package\n expect(hasSentryPackage).toBeTruthy();\n });\n });\n\n describe('missing entry files', () => {\n let wizardExitCode: number;\n\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'react-router-test-app',\n );\n\n beforeAll(async () => {\n // Copy project and remove entry files\n\n const entryClientPath = path.join(\n projectDir,\n 'app',\n 'entry.client.tsx',\n );\n const entryServerPath = path.join(\n projectDir,\n 'app',\n 'entry.server.tsx',\n );\n\n if (fs.existsSync(entryClientPath)) fs.unlinkSync(entryClientPath);\n if (fs.existsSync(entryServerPath)) fs.unlinkSync(entryServerPath);\n\n wizardExitCode = await runWizardOnReactRouterProject(projectDir);\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('wizard creates missing entry files', () => {\n checkFileExists(`${projectDir}/app/entry.client.tsx`);\n checkFileExists(`${projectDir}/app/entry.server.tsx`);\n });\n\n test('basic configuration still works', () => {\n checkPackageJson(projectDir, '@sentry/react-router');\n checkFileExists(`${projectDir}/instrument.server.mjs`);\n });\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"react-router.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/react-router.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 TEST_ARGS,\n checkEnvBuildPlugin,\n checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n createIsolatedTestEnv,\n getWizardCommand,\n} from '../utils';\nimport { afterAll, beforeAll, describe, test, expect } from 'vitest';\n\n//@ts-expect-error - clifty is ESM only\nimport { KEYS, withEnv } from 'clifty';\n\nasync function runWizardOnReactRouterProject(\n projectDir: string,\n opts?: {\n modifiedFiles?: boolean;\n },\n): Promise<number> {\n const { modifiedFiles = false } = opts || {};\n\n const wizardInteraction = withEnv({\n cwd: projectDir,\n }).defineInteraction();\n\n if (modifiedFiles) {\n wizardInteraction\n .whenAsked('Do you want to continue anyway?')\n .respondWith(KEYS.ENTER);\n }\n\n wizardInteraction\n .whenAsked('Please select your package manager.')\n .respondWith(KEYS.DOWN, KEYS.ENTER)\n .expectOutput('Installing @sentry/react-router')\n .expectOutput('Installed @sentry/react-router', {\n timeout: 240_000,\n })\n\n .whenAsked('Do you want to enable Tracing')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to enable Session Replay')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to enable Logs')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to enable Profiling')\n .respondWith(KEYS.ENTER)\n .whenAsked('Do you want to use the Instrumentation API')\n .respondWith(KEYS.DOWN, KEYS.ENTER) // No\n .expectOutput('Installing @sentry/profiling-node')\n .expectOutput('Installed @sentry/profiling-node', {\n timeout: 240_000,\n })\n .whenAsked('Do you want to create an example page')\n .respondWith(KEYS.ENTER);\n\n if (modifiedFiles) {\n wizardInteraction\n .whenAsked('Would you like to try running npx react-router reveal')\n .respondWith(KEYS.ENTER)\n .whenAsked('Did you apply the snippet above?')\n .respondWith(KEYS.ENTER);\n }\n\n return wizardInteraction\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 React Router SDK!')\n .run(getWizardCommand(Integration.reactRouter));\n}\n\ndescribe('React Router', () => {\n describe('with empty project', () => {\n let wizardExitCode: number;\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'react-router-test-app',\n );\n\n beforeAll(async () => {\n wizardExitCode = await runWizardOnReactRouterProject(projectDir);\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, '@sentry/react-router');\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('example API route exists', () => {\n checkFileExists(`${projectDir}/app/routes/api.sentry-example-api.ts`);\n });\n\n test('example page is added to routes configuration', () => {\n checkFileContents(`${projectDir}/app/routes.ts`, [\n 'route(\"/sentry-example-page\", \"routes/sentry-example-page.tsx\")',\n 'route(\"/api/sentry-example-api\", \"routes/api.sentry-example-api.ts\")',\n ]);\n });\n\n test('instrument.server file exists', () => {\n checkFileExists(`${projectDir}/instrument.server.mjs`);\n });\n\n test('entry.client file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/app/entry.client.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",`,\n 'integrations: [Sentry.reactRouterTracingIntegration(), Sentry.replayIntegration()]',\n 'enableLogs: true,',\n 'tracesSampleRate: 1.0,',\n ]);\n });\n\n test('package.json scripts are updated correctly', () => {\n checkFileContents(`${projectDir}/package.json`, [\n `\"start\": \"NODE_ENV=production NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js\"`,\n `\"dev\": \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router dev\"`,\n ]);\n });\n\n test('entry.server file contains Sentry instrumentation', () => {\n checkFileContents(`${projectDir}/app/entry.server.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n 'export const handleError = Sentry.createSentryHandleError(',\n 'export default Sentry.wrapSentryHandleRequest(handleRequest);',\n ]);\n });\n\n test('instrument.server file contains Sentry initialization', () => {\n checkFileContents(`${projectDir}/instrument.server.mjs`, [\n \"import * as Sentry from '@sentry/react-router';\",\n `Sentry.init({\n dsn: \"${TEST_ARGS.PROJECT_DSN}\",`,\n 'enableLogs: true,',\n ]);\n });\n\n test('root file contains Sentry ErrorBoundary', () => {\n checkFileContents(`${projectDir}/app/root.tsx`, [\n 'import * as Sentry from',\n '@sentry/react-router',\n 'export function ErrorBoundary',\n 'Sentry.captureException(error)',\n ]);\n });\n\n test('vite.config file contains sentryReactRouter plugin', () => {\n checkFileContents(`${projectDir}/vite.config.ts`, [\n 'import { sentryReactRouter } from',\n '@sentry/react-router',\n 'sentryReactRouter(',\n 'authToken: process.env.SENTRY_AUTH_TOKEN',\n ]);\n });\n\n test('react-router.config file contains buildEnd hook with sentryOnBuildEnd', () => {\n checkFileContents(`${projectDir}/react-router.config.ts`, [\n 'import { sentryOnBuildEnd } from',\n '@sentry/react-router',\n 'ssr: true,',\n 'buildEnd: async',\n 'await sentryOnBuildEnd({',\n ]);\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n }, 60_000); // 1 minute timeout\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(projectDir, 'to expose');\n }, 30_000); // 30 second timeout\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(projectDir, 'react-router-serve');\n }, 30_000); // 30 second timeout\n });\n\n describe('edge cases', () => {\n describe('existing Sentry setup', () => {\n let wizardExitCode: number;\n\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'react-router-test-app',\n );\n\n beforeAll(async () => {\n // Add existing Sentry setup to the isolated test app\n const clientEntryPath = path.join(\n projectDir,\n 'app',\n 'entry.client.tsx',\n );\n const existingContent = `import * as Sentry from \"@sentry/react-router\";\nimport { startTransition, StrictMode } from \"react\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { HydratedRouter } from \"react-router/dom\";\n\nSentry.init({\n dsn: \"https://existing@dsn.ingest.sentry.io/1337\",\n tracesSampleRate: 1.0,\n});\n\nstartTransition(() => {\n hydrateRoot(\n document,\n <StrictMode>\n <HydratedRouter />\n </StrictMode>\n );\n});`;\n fs.writeFileSync(clientEntryPath, existingContent);\n\n wizardExitCode = await runWizardOnReactRouterProject(projectDir, {\n modifiedFiles: true,\n });\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('wizard handles existing Sentry without duplication', () => {\n const clientContent = fs.readFileSync(\n `${projectDir}/app/entry.client.tsx`,\n 'utf8',\n );\n const sentryImportCount = (\n clientContent.match(\n /import \\* as Sentry from \"@sentry\\/react-router\"/g,\n ) || []\n ).length;\n const sentryInitCount = (clientContent.match(/Sentry\\.init\\(/g) || [])\n .length;\n\n expect(sentryImportCount).toBe(1);\n expect(sentryInitCount).toBe(1);\n });\n\n // Only test the essential checks for this edge case\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, '@sentry/react-router');\n });\n\n test('essential files exist or wizard completes gracefully', () => {\n // Check if key directories exist\n expect(fs.existsSync(`${projectDir}/app`)).toBe(true);\n\n // When there's existing Sentry setup, the wizard may skip some file creation\n // to avoid conflicts. This is acceptable behavior.\n // Let's check if the wizard at least completed by verifying package.json was updated\n const packageJsonPath = `${projectDir}/package.json`;\n expect(fs.existsSync(packageJsonPath)).toBe(true);\n\n const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');\n const packageJson = JSON.parse(packageJsonContent) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const hasSentryPackage =\n packageJson.dependencies?.['@sentry/react-router'] ||\n packageJson.devDependencies?.['@sentry/react-router'];\n\n // The wizard should have at least installed the Sentry package\n expect(hasSentryPackage).toBeTruthy();\n });\n });\n\n describe('missing entry files', () => {\n let wizardExitCode: number;\n\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'react-router-test-app',\n );\n\n beforeAll(async () => {\n // Copy project and remove entry files\n\n const entryClientPath = path.join(\n projectDir,\n 'app',\n 'entry.client.tsx',\n );\n const entryServerPath = path.join(\n projectDir,\n 'app',\n 'entry.server.tsx',\n );\n\n if (fs.existsSync(entryClientPath)) fs.unlinkSync(entryClientPath);\n if (fs.existsSync(entryServerPath)) fs.unlinkSync(entryServerPath);\n\n wizardExitCode = await runWizardOnReactRouterProject(projectDir);\n });\n\n afterAll(() => {\n cleanup();\n });\n\n test('exits with exit code 0', () => {\n expect(wizardExitCode).toBe(0);\n });\n\n test('wizard creates missing entry files', () => {\n checkFileExists(`${projectDir}/app/entry.client.tsx`);\n checkFileExists(`${projectDir}/app/entry.server.tsx`);\n });\n\n test('basic configuration still works', () => {\n checkPackageJson(projectDir, '@sentry/react-router');\n checkFileExists(`${projectDir}/instrument.server.mjs`);\n });\n });\n });\n});\n"]}
|
|
@@ -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 checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n createIsolatedTestEnv,\n getWizardCommand,\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 integration = Integration.sveltekit;\n let wizardExitCode: number;\n\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'sveltekit-tracing-test-app',\n );\n\n beforeAll(async () => {\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 cleanup();\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, '@sentry/sveltekit');\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 checkFileContents(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+page.svelte'),\n // svelte 5 specific syntax\n ['let hasSentError = $state(false);', 'onclick={getSentryData}'],\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 org: \"${TEST_ARGS.ORG_SLUG}\",\n project: \"${TEST_ARGS.PROJECT_SLUG}\"\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"]}
|
|
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 checkFileContents,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n createIsolatedTestEnv,\n getWizardCommand,\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 integration = Integration.sveltekit;\n let wizardExitCode: number;\n\n const { projectDir, cleanup } = createIsolatedTestEnv(\n 'sveltekit-tracing-test-app',\n );\n\n beforeAll(async () => {\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 cleanup();\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, '@sentry/sveltekit');\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 checkFileContents(\n path.resolve(projectDir, 'src/routes/sentry-example-page/+page.svelte'),\n // svelte 5 specific syntax\n ['let hasSentError = $state(false);', 'onclick={getSentryData}'],\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 org: \"${TEST_ARGS.ORG_SLUG}\",\n project: \"${TEST_ARGS.PROJECT_SLUG}\"\n }), sveltekit()]\n });\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"]}
|
|
@@ -34,6 +34,7 @@ const debug_1 = require("../utils/debug");
|
|
|
34
34
|
const swiftAppLaunchRegex = /(func\s+application\s*\(\s*_\s+application:\s*[^,]+,\s*didFinishLaunchingWithOptions[^,]+:\s*[^)]+\s*\)\s+->\s+Bool\s+{)|func\s+applicationDidFinishLaunching\s*\(\s*_\s+aNotification:\s+Notification\s*\)\s*{/im;
|
|
35
35
|
const objcAppLaunchRegex = /-\s*\(\s*BOOL\s*\)\s*application:\s*\(\s*UIApplication\s*\*\s*\)\s*application\s+didFinishLaunchingWithOptions:\s*\(\s*NSDictionary\s*\*\s*\)\s*launchOptions\s*{/im;
|
|
36
36
|
const swiftUIRegex = /@main\s+struct[^:]+:\s*(SwiftUI\.)?App\s*{/im;
|
|
37
|
+
const swiftUIInitRegex = /\binit\s*\(\s*\)\s*\{/m;
|
|
37
38
|
function isAppDelegateFile(filePath) {
|
|
38
39
|
(0, debug_1.debug)('Checking if ' + filePath + ' is an AppDelegate file');
|
|
39
40
|
const appLaunchRegex = filePath.toLowerCase().endsWith('.swift')
|
|
@@ -107,9 +108,22 @@ function addCodeSnippetToProject(files, dsn, enableLogs) {
|
|
|
107
108
|
// This branch is not reached, because we already checked for SwiftUI in isAppDelegateFile
|
|
108
109
|
return false;
|
|
109
110
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
const afterStructContent = fileContent.slice(swiftUIMatch.index);
|
|
112
|
+
const bodyMatch = /var\s+body\s*:/m.exec(afterStructContent);
|
|
113
|
+
const searchRange = bodyMatch
|
|
114
|
+
? afterStructContent.slice(0, bodyMatch.index)
|
|
115
|
+
: afterStructContent;
|
|
116
|
+
const initMatch = swiftUIInitRegex.exec(searchRange);
|
|
117
|
+
if (initMatch) {
|
|
118
|
+
match = {
|
|
119
|
+
index: swiftUIMatch.index + initMatch.index,
|
|
120
|
+
0: initMatch[0],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
match = swiftUIMatch;
|
|
125
|
+
codeSnippet = ` init() {\n${codeSnippet} }`;
|
|
126
|
+
}
|
|
113
127
|
}
|
|
114
128
|
const insertIndex = match.index + match[0].length;
|
|
115
129
|
let newFileContent = fileContent.slice(0, insertIndex) +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-tools.js","sourceRoot":"","sources":["../../../src/apple/code-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Sentry from '@sentry/node';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as templates from './templates';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport { debug } from '../utils/debug';\n\nconst swiftAppLaunchRegex =\n /(func\\s+application\\s*\\(\\s*_\\s+application:\\s*[^,]+,\\s*didFinishLaunchingWithOptions[^,]+:\\s*[^)]+\\s*\\)\\s+->\\s+Bool\\s+{)|func\\s+applicationDidFinishLaunching\\s*\\(\\s*_\\s+aNotification:\\s+Notification\\s*\\)\\s*{/im;\nconst objcAppLaunchRegex =\n /-\\s*\\(\\s*BOOL\\s*\\)\\s*application:\\s*\\(\\s*UIApplication\\s*\\*\\s*\\)\\s*application\\s+didFinishLaunchingWithOptions:\\s*\\(\\s*NSDictionary\\s*\\*\\s*\\)\\s*launchOptions\\s*{/im;\nconst swiftUIRegex = /@main\\s+struct[^:]+:\\s*(SwiftUI\\.)?App\\s*{/im;\n\nfunction isAppDelegateFile(filePath: string): boolean {\n debug('Checking if ' + filePath + ' is an AppDelegate file');\n const appLaunchRegex = filePath.toLowerCase().endsWith('.swift')\n ? swiftAppLaunchRegex\n : objcAppLaunchRegex;\n\n const fileContent = fs.readFileSync(filePath, 'utf8');\n return appLaunchRegex.test(fileContent) || swiftUIRegex.test(fileContent);\n}\n\nfunction findAppDidFinishLaunchingWithOptionsInDirectory(\n dir: string,\n): string | null {\n debug('Searching for AppDelegate in directory: ' + dir);\n const files = fs.readdirSync(dir);\n const filePaths = files.map((f) => path.join(dir, f));\n return findAppDidFinishLaunchingWithOptions(filePaths);\n}\n\nfunction findAppDidFinishLaunchingWithOptions(files: string[]): string | null {\n debug(`Searching for AppDelegate in ${files.length} files`);\n\n // Iterate over subdirectories after iterating over files,\n // because the AppDelegate is usually in the top level\n const dirs: string[] = [];\n for (const filePath of files) {\n debug('Checking file: ' + filePath);\n if (\n filePath.endsWith('.swift') ||\n filePath.endsWith('.m') ||\n filePath.endsWith('.mm')\n ) {\n if (fs.existsSync(filePath) && isAppDelegateFile(filePath)) {\n debug('Found AppDelegate in ' + filePath);\n return filePath;\n }\n } else if (\n !path.basename(filePath).startsWith('.') &&\n !filePath.endsWith('.xcodeproj') &&\n !filePath.endsWith('.xcassets') &&\n fs.existsSync(filePath) &&\n fs.lstatSync(filePath).isDirectory()\n ) {\n dirs.push(filePath);\n }\n }\n\n for (const dr of dirs) {\n const result = findAppDidFinishLaunchingWithOptionsInDirectory(dr);\n if (result) {\n debug('Found AppDelegate in ' + dr);\n return result;\n }\n }\n return null;\n}\n\nexport function addCodeSnippetToProject(\n files: string[],\n dsn: string,\n enableLogs: boolean,\n): boolean {\n const appDelegate = findAppDidFinishLaunchingWithOptions(files);\n if (!appDelegate) {\n return false;\n }\n\n const fileContent = fs.readFileSync(appDelegate, 'utf8');\n const isSwift = appDelegate.toLowerCase().endsWith('.swift');\n const appLaunchRegex = isSwift ? swiftAppLaunchRegex : objcAppLaunchRegex;\n const importStatement = isSwift ? 'import Sentry\\n' : '@import Sentry;\\n';\n const checkForSentryInit = isSwift ? 'SentrySDK.start' : '[SentrySDK start';\n let codeSnippet = isSwift\n ? templates.getSwiftSnippet(dsn, enableLogs)\n : templates.getObjcSnippet(dsn, enableLogs);\n\n Sentry.setTag('code-language', isSwift ? 'swift' : 'objc');\n Sentry.setTag(\n 'ui-engine',\n swiftUIRegex.test(fileContent) ? 'swiftui' : 'uikit',\n );\n\n if (fileContent.includes(checkForSentryInit)) {\n //already initialized\n clack.log.info(\n 'Sentry is already initialized in your AppDelegate. Skipping adding the code snippet.',\n );\n return true;\n }\n\n let match = appLaunchRegex.exec(fileContent);\n if (!match) {\n const swiftUIMatch = swiftUIRegex.exec(fileContent);\n if (!swiftUIMatch) {\n // This branch is not reached, because we already checked for SwiftUI in isAppDelegateFile\n return false;\n }\n //Is SwiftUI with no init\n match = swiftUIMatch;\n codeSnippet = ` init() {\\n${codeSnippet} }`;\n }\n\n const insertIndex = match.index + match[0].length;\n let newFileContent =\n fileContent.slice(0, insertIndex) +\n '\\n' +\n codeSnippet +\n fileContent.slice(insertIndex);\n\n if (newFileContent.indexOf(importStatement) < 0) {\n const firstImport = /^[ \\t]*import +\\w+.*$/m.exec(newFileContent);\n if (firstImport) {\n const importIndex = firstImport.index + firstImport[0].length;\n newFileContent =\n newFileContent.slice(0, importIndex) +\n '\\n' +\n importStatement +\n newFileContent.slice(importIndex);\n } else {\n newFileContent = importStatement + newFileContent;\n }\n }\n\n fs.writeFileSync(appDelegate, newFileContent, 'utf8');\n\n clack.log.step('Added Sentry initialization code snippet to ' + appDelegate);\n return true;\n}\n\n/**\n * Exported for testing purposes, but should not be used in other modules.\n */\nexport let exportForTesting: {\n isAppDelegateFile: typeof isAppDelegateFile;\n findAppDidFinishLaunchingWithOptionsInDirectory: typeof findAppDidFinishLaunchingWithOptionsInDirectory;\n findAppDidFinishLaunchingWithOptions: typeof findAppDidFinishLaunchingWithOptions;\n};\nif (process.env.NODE_ENV === 'test') {\n exportForTesting = {\n isAppDelegateFile,\n findAppDidFinishLaunchingWithOptionsInDirectory,\n findAppDidFinishLaunchingWithOptions,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"code-tools.js","sourceRoot":"","sources":["../../../src/apple/code-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Sentry from '@sentry/node';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as templates from './templates';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport { debug } from '../utils/debug';\n\nconst swiftAppLaunchRegex =\n /(func\\s+application\\s*\\(\\s*_\\s+application:\\s*[^,]+,\\s*didFinishLaunchingWithOptions[^,]+:\\s*[^)]+\\s*\\)\\s+->\\s+Bool\\s+{)|func\\s+applicationDidFinishLaunching\\s*\\(\\s*_\\s+aNotification:\\s+Notification\\s*\\)\\s*{/im;\nconst objcAppLaunchRegex =\n /-\\s*\\(\\s*BOOL\\s*\\)\\s*application:\\s*\\(\\s*UIApplication\\s*\\*\\s*\\)\\s*application\\s+didFinishLaunchingWithOptions:\\s*\\(\\s*NSDictionary\\s*\\*\\s*\\)\\s*launchOptions\\s*{/im;\nconst swiftUIRegex = /@main\\s+struct[^:]+:\\s*(SwiftUI\\.)?App\\s*{/im;\nconst swiftUIInitRegex = /\\binit\\s*\\(\\s*\\)\\s*\\{/m;\n\nfunction isAppDelegateFile(filePath: string): boolean {\n debug('Checking if ' + filePath + ' is an AppDelegate file');\n const appLaunchRegex = filePath.toLowerCase().endsWith('.swift')\n ? swiftAppLaunchRegex\n : objcAppLaunchRegex;\n\n const fileContent = fs.readFileSync(filePath, 'utf8');\n return appLaunchRegex.test(fileContent) || swiftUIRegex.test(fileContent);\n}\n\nfunction findAppDidFinishLaunchingWithOptionsInDirectory(\n dir: string,\n): string | null {\n debug('Searching for AppDelegate in directory: ' + dir);\n const files = fs.readdirSync(dir);\n const filePaths = files.map((f) => path.join(dir, f));\n return findAppDidFinishLaunchingWithOptions(filePaths);\n}\n\nfunction findAppDidFinishLaunchingWithOptions(files: string[]): string | null {\n debug(`Searching for AppDelegate in ${files.length} files`);\n\n // Iterate over subdirectories after iterating over files,\n // because the AppDelegate is usually in the top level\n const dirs: string[] = [];\n for (const filePath of files) {\n debug('Checking file: ' + filePath);\n if (\n filePath.endsWith('.swift') ||\n filePath.endsWith('.m') ||\n filePath.endsWith('.mm')\n ) {\n if (fs.existsSync(filePath) && isAppDelegateFile(filePath)) {\n debug('Found AppDelegate in ' + filePath);\n return filePath;\n }\n } else if (\n !path.basename(filePath).startsWith('.') &&\n !filePath.endsWith('.xcodeproj') &&\n !filePath.endsWith('.xcassets') &&\n fs.existsSync(filePath) &&\n fs.lstatSync(filePath).isDirectory()\n ) {\n dirs.push(filePath);\n }\n }\n\n for (const dr of dirs) {\n const result = findAppDidFinishLaunchingWithOptionsInDirectory(dr);\n if (result) {\n debug('Found AppDelegate in ' + dr);\n return result;\n }\n }\n return null;\n}\n\nexport function addCodeSnippetToProject(\n files: string[],\n dsn: string,\n enableLogs: boolean,\n): boolean {\n const appDelegate = findAppDidFinishLaunchingWithOptions(files);\n if (!appDelegate) {\n return false;\n }\n\n const fileContent = fs.readFileSync(appDelegate, 'utf8');\n const isSwift = appDelegate.toLowerCase().endsWith('.swift');\n const appLaunchRegex = isSwift ? swiftAppLaunchRegex : objcAppLaunchRegex;\n const importStatement = isSwift ? 'import Sentry\\n' : '@import Sentry;\\n';\n const checkForSentryInit = isSwift ? 'SentrySDK.start' : '[SentrySDK start';\n let codeSnippet = isSwift\n ? templates.getSwiftSnippet(dsn, enableLogs)\n : templates.getObjcSnippet(dsn, enableLogs);\n\n Sentry.setTag('code-language', isSwift ? 'swift' : 'objc');\n Sentry.setTag(\n 'ui-engine',\n swiftUIRegex.test(fileContent) ? 'swiftui' : 'uikit',\n );\n\n if (fileContent.includes(checkForSentryInit)) {\n //already initialized\n clack.log.info(\n 'Sentry is already initialized in your AppDelegate. Skipping adding the code snippet.',\n );\n return true;\n }\n\n let match = appLaunchRegex.exec(fileContent);\n if (!match) {\n const swiftUIMatch = swiftUIRegex.exec(fileContent);\n if (!swiftUIMatch) {\n // This branch is not reached, because we already checked for SwiftUI in isAppDelegateFile\n return false;\n }\n\n const afterStructContent = fileContent.slice(swiftUIMatch.index);\n const bodyMatch = /var\\s+body\\s*:/m.exec(afterStructContent);\n const searchRange = bodyMatch\n ? afterStructContent.slice(0, bodyMatch.index)\n : afterStructContent;\n\n const initMatch = swiftUIInitRegex.exec(searchRange);\n\n if (initMatch) {\n match = {\n index: swiftUIMatch.index + initMatch.index,\n 0: initMatch[0],\n } as RegExpExecArray;\n } else {\n match = swiftUIMatch;\n codeSnippet = ` init() {\\n${codeSnippet} }`;\n }\n }\n\n const insertIndex = match.index + match[0].length;\n let newFileContent =\n fileContent.slice(0, insertIndex) +\n '\\n' +\n codeSnippet +\n fileContent.slice(insertIndex);\n\n if (newFileContent.indexOf(importStatement) < 0) {\n const firstImport = /^[ \\t]*import +\\w+.*$/m.exec(newFileContent);\n if (firstImport) {\n const importIndex = firstImport.index + firstImport[0].length;\n newFileContent =\n newFileContent.slice(0, importIndex) +\n '\\n' +\n importStatement +\n newFileContent.slice(importIndex);\n } else {\n newFileContent = importStatement + newFileContent;\n }\n }\n\n fs.writeFileSync(appDelegate, newFileContent, 'utf8');\n\n clack.log.step('Added Sentry initialization code snippet to ' + appDelegate);\n return true;\n}\n\n/**\n * Exported for testing purposes, but should not be used in other modules.\n */\nexport let exportForTesting: {\n isAppDelegateFile: typeof isAppDelegateFile;\n findAppDidFinishLaunchingWithOptionsInDirectory: typeof findAppDidFinishLaunchingWithOptionsInDirectory;\n findAppDidFinishLaunchingWithOptions: typeof findAppDidFinishLaunchingWithOptions;\n};\nif (process.env.NODE_ENV === 'test') {\n exportForTesting = {\n isAppDelegateFile,\n findAppDidFinishLaunchingWithOptionsInDirectory,\n findAppDidFinishLaunchingWithOptions,\n };\n}\n"]}
|