@sentry/wizard 6.9.0 → 6.11.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 +56 -1
- package/dist/ci-ensure-runtime-loaded.sh +82 -0
- package/dist/e2e-tests/tests/angular-17.test.js +72 -82
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +71 -80
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/cloudflare-worker.test.d.ts +1 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js +64 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js.map +1 -0
- package/dist/e2e-tests/tests/cloudflare-wrangler-sourcemaps.test.js +2 -5
- package/dist/e2e-tests/tests/cloudflare-wrangler-sourcemaps.test.js.map +1 -1
- package/dist/e2e-tests/tests/expo.test.js +36 -61
- package/dist/e2e-tests/tests/expo.test.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.js +63 -70
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/e2e-tests/tests/help-message.test.js +2 -2
- package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs-14.test.js +54 -82
- package/dist/e2e-tests/tests/nextjs-14.test.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs-15.test.js +95 -105
- package/dist/e2e-tests/tests/nextjs-15.test.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs-16.test.d.ts +1 -0
- package/dist/e2e-tests/tests/nextjs-16.test.js +123 -0
- package/dist/e2e-tests/tests/nextjs-16.test.js.map +1 -0
- package/dist/e2e-tests/tests/nuxt-3.test.js +45 -58
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-4.test.js +59 -73
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js +4 -7
- package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-native.test.js +44 -80
- package/dist/e2e-tests/tests/react-native.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router.test.js +163 -145
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +162 -132
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js +48 -36
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +3 -6
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
- package/dist/e2e-tests/utils/index.d.ts +21 -43
- package/dist/e2e-tests/utils/index.js +108 -183
- package/dist/e2e-tests/utils/index.js.map +1 -1
- package/dist/get-e2e-test-matrix.mjs +11 -0
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +5 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/src/android/android-wizard.js +2 -4
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/angular/angular-wizard.js +4 -6
- package/dist/src/angular/angular-wizard.js.map +1 -1
- package/dist/src/angular/sdk-setup.js +1 -1
- package/dist/src/angular/sdk-setup.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +2 -4
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/cloudflare/cloudflare-wizard.d.ts +3 -0
- package/dist/src/cloudflare/cloudflare-wizard.js +99 -0
- package/dist/src/cloudflare/cloudflare-wizard.js.map +1 -0
- package/dist/src/cloudflare/sdk-setup.d.ts +7 -0
- package/dist/src/cloudflare/sdk-setup.js +47 -0
- package/dist/src/cloudflare/sdk-setup.js.map +1 -0
- package/dist/src/cloudflare/templates.d.ts +4 -0
- package/dist/src/cloudflare/templates.js +44 -0
- package/dist/src/cloudflare/templates.js.map +1 -0
- package/dist/src/cloudflare/wrangler/create-wrangler-config.d.ts +4 -0
- package/dist/src/cloudflare/wrangler/create-wrangler-config.js +27 -0
- package/dist/src/cloudflare/wrangler/create-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/ensure-wrangler-config.d.ts +4 -0
- package/dist/src/cloudflare/wrangler/ensure-wrangler-config.js +25 -0
- package/dist/src/cloudflare/wrangler/ensure-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/find-wrangler-config.d.ts +4 -0
- package/dist/src/cloudflare/wrangler/find-wrangler-config.js +23 -0
- package/dist/src/cloudflare/wrangler/find-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.d.ts +6 -0
- package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.js +52 -0
- package/dist/src/cloudflare/wrangler/get-entry-point-from-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrangler/update-wrangler-config.d.ts +17 -0
- package/dist/src/cloudflare/wrangler/update-wrangler-config.js +173 -0
- package/dist/src/cloudflare/wrangler/update-wrangler-config.js.map +1 -0
- package/dist/src/cloudflare/wrap-worker.d.ts +32 -0
- package/dist/src/cloudflare/wrap-worker.js +109 -0
- package/dist/src/cloudflare/wrap-worker.js.map +1 -0
- package/dist/src/flutter/flutter-wizard.js +3 -6
- package/dist/src/flutter/flutter-wizard.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +46 -10
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.d.ts +6 -3
- package/dist/src/nextjs/templates.js +144 -93
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/nuxt/nuxt-wizard.js +3 -5
- package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +2 -4
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.js +4 -1
- package/dist/src/react-router/codemods/client.entry.js.map +1 -1
- package/dist/src/react-router/react-router-wizard.js +3 -5
- package/dist/src/react-router/react-router-wizard.js.map +1 -1
- package/dist/src/react-router/sdk-example.js +5 -2
- package/dist/src/react-router/sdk-example.js.map +1 -1
- package/dist/src/react-router/sdk-setup.d.ts +1 -1
- package/dist/src/react-router/sdk-setup.js +3 -4
- package/dist/src/react-router/sdk-setup.js.map +1 -1
- package/dist/src/remix/remix-wizard.js +2 -4
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/run.d.ts +1 -1
- package/dist/src/run.js +5 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/sentry-cli.js +1 -1
- package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
- package/dist/src/sourcemaps/tools/wrangler.js +1 -1
- package/dist/src/sourcemaps/tools/wrangler.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +4 -6
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/telemetry.d.ts +1 -1
- package/dist/src/telemetry.js +52 -31
- package/dist/src/telemetry.js.map +1 -1
- package/dist/src/utils/abort-if-sportlight-not-supported.d.ts +5 -0
- package/dist/src/utils/abort-if-sportlight-not-supported.js +40 -0
- package/dist/src/utils/abort-if-sportlight-not-supported.js.map +1 -0
- package/dist/src/utils/ast-utils.d.ts +1 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +19 -2
- package/dist/src/utils/clack/index.js +174 -12
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/utils/clack/mcp-config.js +117 -59
- package/dist/src/utils/clack/mcp-config.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/angular/angular-wizard.test.js +2 -4
- package/dist/test/angular/angular-wizard.test.js.map +1 -1
- package/dist/test/apple/cocoapod.test.js +7 -3
- package/dist/test/apple/cocoapod.test.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +8 -2
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/cloudflare/create-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/create-wrangler-config.test.js +48 -0
- package/dist/test/cloudflare/create-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/ensure-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/ensure-wrangler-config.test.js +61 -0
- package/dist/test/cloudflare/ensure-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/find-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/find-wrangler-config.test.js +77 -0
- package/dist/test/cloudflare/find-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.js +81 -0
- package/dist/test/cloudflare/get-entry-point-from-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/sdk-setup.test.d.ts +1 -0
- package/dist/test/cloudflare/sdk-setup.test.js +152 -0
- package/dist/test/cloudflare/sdk-setup.test.js.map +1 -0
- package/dist/test/cloudflare/templates.test.d.ts +1 -0
- package/dist/test/cloudflare/templates.test.js +68 -0
- package/dist/test/cloudflare/templates.test.js.map +1 -0
- package/dist/test/cloudflare/update-wrangler-config.test.d.ts +1 -0
- package/dist/test/cloudflare/update-wrangler-config.test.js +216 -0
- package/dist/test/cloudflare/update-wrangler-config.test.js.map +1 -0
- package/dist/test/cloudflare/wrap-worker.test.d.ts +1 -0
- package/dist/test/cloudflare/wrap-worker.test.js +143 -0
- package/dist/test/cloudflare/wrap-worker.test.js.map +1 -0
- package/dist/test/nextjs/templates.test.js +156 -87
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/dist/test/nextjs/wizard-double-wrap-prevention.test.js +12 -7
- package/dist/test/nextjs/wizard-double-wrap-prevention.test.js.map +1 -1
- package/dist/test/react-router/sdk-setup.test.js +2 -2
- package/dist/test/react-router/sdk-setup.test.js.map +1 -1
- package/dist/test/utils/clack/index.test.js +37 -29
- package/dist/test/utils/clack/index.test.js.map +1 -1
- package/dist/test/utils/clack/mcp-config.test.js +176 -51
- package/dist/test/utils/clack/mcp-config.test.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/nextjs/templates.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport {\n getRootLayout,\n getSentryServersideConfigContents,\n getInstrumentationClientFileContents,\n getWithSentryConfigOptionsTemplate,\n getGenerateMetadataSnippet,\n getRootLayoutWithGenerateMetadata,\n getSentryExamplePageContents,\n getSentryExamplePagesDirApiRoute,\n getSentryExampleAppDirApiRoute,\n} from '../../src/nextjs/templates';\n\ndescribe('Next.js code templates', () => {\n describe('getInstrumentationClientFileContents', () => {\n it('generates client-side Sentry config with all features enabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [\n Sentry.replayIntegration(),\n ],\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Define how likely Replay events are sampled.\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 // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\"\n `);\n });\n\n it('generates client-side Sentry config with performance monitoring disabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [\n Sentry.replayIntegration(),\n ],\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Define how likely Replay events are sampled.\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 // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\"\n `);\n });\n\n it('generates client-side Sentry config with session replay disabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: true,\n replay: false,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\"\n `);\n });\n\n it('generates client-side Sentry config with logs disabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [\n Sentry.replayIntegration(),\n ],\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Define how likely Replay events are sampled.\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 // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\"\n `);\n });\n it('uses empty DSN in spotlight mode', () => {\n const template = getInstrumentationClientFileContents(\n '',\n {\n performance: true,\n replay: false,\n logs: false,\n },\n true, // spotlight\n );\n\n // Verify DSN is empty for spotlight\n expect(template).toContain('dsn: \"\"');\n expect(template).toContain('spotlight: true');\n });\n });\n\n describe('getSentryServersideConfigContents', () => {\n describe('server-side', () => {\n it('generates server-side Sentry config with all features enabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with performance monitoring disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with spotlight disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with logs disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('uses empty DSN in spotlight mode', () => {\n const template = getSentryServersideConfigContents(\n '',\n 'server',\n {\n performance: true,\n replay: false,\n logs: false,\n },\n true, // spotlight\n );\n\n // Verify DSN is empty for spotlight\n expect(template).toContain('dsn: \"\"');\n expect(template).toContain('spotlight: true');\n });\n });\n\n describe('edge', () => {\n it('generates edge Sentry config with all features enabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'edge', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates edge Sentry config with performance monitoring disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'edge', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates edge Sentry config with logs disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'edge', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n });\n });\n\n describe('getWithSentryConfigOptionsTemplate', () => {\n it('generates options for SaaS', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('generates options for self-hosted', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: true,\n sentryUrl: 'https://my-sentry.com',\n tunnelRoute: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n sentryUrl: \"https://my-sentry.com\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('comments out tunnelRoute if `tunnelRoute` option is disabled', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n // tunnelRoute: \"/monitoring\",\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n });\n\n describe('getRootLayout', () => {\n it('generates a root layout component with types', () => {\n expect(getRootLayout(true)).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n // You can delete this file at any time.\n\n export const metadata = {\n title: 'Sentry NextJS Example',\n description: 'Generated by Sentry',\n }\n\n export default function RootLayout({\n children,\n }: {\n children: React.ReactNode\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n it('generates a root layout component without types', () => {\n expect(getRootLayout(false)).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n // You can delete this file at any time.\n\n export const metadata = {\n title: 'Sentry NextJS Example',\n description: 'Generated by Sentry',\n }\n\n export default function RootLayout({\n children,\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n });\n\n describe('getGenerateMetadataSnippet', () => {\n it('generates metadata snippet with TypeScript types', () => {\n const template = getGenerateMetadataSnippet(true);\n\n expect(template).toMatchInlineSnapshot(`\n\"\n import * as Sentry from '@sentry/nextjs';\n import type { Metadata } from 'next';\n\n // Add or edit your \"generateMetadata\" to include the Sentry trace data:\n export function generateMetadata(): Metadata {\n return {\n // ... your existing metadata\n other: {\n ...Sentry.getTraceData()\n }\n };\n }\n\"\n`);\n });\n\n it('generates metadata snippet without TypeScript types', () => {\n const template = getGenerateMetadataSnippet(false);\n\n expect(template).toMatchInlineSnapshot(`\n\"\n import * as Sentry from '@sentry/nextjs';\n \n\n // Add or edit your \"generateMetadata\" to include the Sentry trace data:\n export function generateMetadata() {\n return {\n // ... your existing metadata\n other: {\n ...Sentry.getTraceData()\n }\n };\n }\n\"\n `);\n });\n });\n\n describe('getRootLayoutWithGenerateMetadata', () => {\n it('generates root layout with TypeScript types', () => {\n const template = getRootLayoutWithGenerateMetadata(true);\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n import * as Sentry from '@sentry/nextjs';\n import type { Metadata } from 'next';\n\n export function generateMetadata(): Metadata {\n return {\n other: {\n ...Sentry.getTraceData(),\n }\n }\n };\n\n export default function RootLayout({\n children,\n }: {\n children: React.ReactNode\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n\n it('generates root layout without TypeScript types', () => {\n const template = getRootLayoutWithGenerateMetadata(false);\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n import * as Sentry from '@sentry/nextjs';\n\n \n export function generateMetadata() {\n return {\n other: {\n ...Sentry.getTraceData(),\n }\n }\n };\n\n export default function RootLayout({\n children,\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n });\n\n describe('getSentryExamplePageContents', () => {\n it('generates example page with TypeScript types', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: true,\n isTypeScript: true,\n });\n\n expect(template).toContain('\"use client\";');\n expect(template).toContain('constructor(message: string | undefined)');\n expect(template).toContain(\n 'class SentryExampleFrontendError extends Error',\n );\n });\n\n it('generates example page without TypeScript types', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: true,\n isTypeScript: false,\n });\n\n expect(template).toContain('\"use client\";');\n expect(template).toContain('constructor(message)');\n expect(template).toContain(\n 'class SentryExampleFrontendError extends Error',\n );\n });\n\n it('generates example page without useClient directive', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: false,\n isTypeScript: true,\n });\n\n expect(template).not.toContain('\"use client\";');\n expect(template).toContain(\n 'https://my-org.sentry.io/issues/?project=123',\n );\n });\n });\n\n describe('getSentryExamplePagesDirApiRoute', () => {\n it('generates Pages Router API route with TypeScript types', () => {\n const template = getSentryExamplePagesDirApiRoute({\n isTypeScript: true,\n });\n\n expect(template).toContain('constructor(message: string | undefined)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export default function handler(_req, res)');\n });\n\n it('generates Pages Router API route without TypeScript types', () => {\n const template = getSentryExamplePagesDirApiRoute({\n isTypeScript: false,\n });\n\n expect(template).toContain('constructor(message)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export default function handler(_req, res)');\n });\n });\n\n describe('getSentryExampleAppDirApiRoute', () => {\n it('generates App Router API route with TypeScript types', () => {\n const template = getSentryExampleAppDirApiRoute({\n isTypeScript: true,\n });\n\n expect(template).toContain('constructor(message: string | undefined)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export function GET()');\n expect(template).toContain('export const dynamic = \"force-dynamic\";');\n });\n\n it('generates App Router API route without TypeScript types', () => {\n const template = getSentryExampleAppDirApiRoute({\n isTypeScript: false,\n });\n\n expect(template).toContain('constructor(message)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export function GET()');\n expect(template).toContain('export const dynamic = \"force-dynamic\";');\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/nextjs/templates.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport {\n getRootLayout,\n getSentryServersideConfigContents,\n getInstrumentationClientFileContents,\n getWithSentryConfigOptionsTemplate,\n getGenerateMetadataSnippet,\n getRootLayoutWithGenerateMetadata,\n getSentryExamplePageContents,\n getSentryExamplePagesDirApiRoute,\n getSentryExampleAppDirApiRoute,\n} from '../../src/nextjs/templates';\n\ndescribe('Next.js code templates', () => {\n describe('getInstrumentationClientFileContents', () => {\n it('generates client-side Sentry config with all features enabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [Sentry.replayIntegration()],\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Define how likely Replay events are sampled.\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 // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\n \"\n `);\n });\n\n it('generates client-side Sentry config with performance monitoring disabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [Sentry.replayIntegration()],\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Define how likely Replay events are sampled.\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 // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\n \"\n `);\n });\n\n it('generates client-side Sentry config with session replay disabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: true,\n replay: false,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\n \"\n `);\n });\n\n it('generates client-side Sentry config with logs disabled', () => {\n const template = getInstrumentationClientFileContents('my-dsn', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The added config here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [Sentry.replayIntegration()],\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Define how likely Replay events are sampled.\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 // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n\n export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\n \"\n `);\n });\n it('uses empty DSN in spotlight mode', () => {\n const template = getInstrumentationClientFileContents(\n '',\n {\n performance: true,\n replay: false,\n logs: false,\n },\n true, // spotlight\n );\n\n // Verify DSN is empty for spotlight\n expect(template).toContain('dsn: \"\"');\n expect(template).toContain('spotlight: true');\n });\n });\n\n describe('getSentryServersideConfigContents', () => {\n describe('server-side', () => {\n it('generates server-side Sentry config with all features enabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with performance monitoring disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with spotlight disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with logs disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('uses empty DSN in spotlight mode', () => {\n const template = getSentryServersideConfigContents(\n '',\n 'server',\n {\n performance: true,\n replay: false,\n logs: false,\n },\n true, // spotlight\n );\n\n // Verify DSN is empty for spotlight\n expect(template).toContain('dsn: \"\"');\n expect(template).toContain('spotlight: true');\n });\n });\n\n describe('edge', () => {\n it('generates edge Sentry config with all features enabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'edge', {\n performance: true,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates edge Sentry config with performance monitoring disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'edge', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Enable logs to be sent to Sentry\n enableLogs: true,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n\n it('generates edge Sentry config with logs disabled', () => {\n const template = getSentryServersideConfigContents('my-dsn', 'edge', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n });\n \"\n `);\n });\n });\n });\n\n describe('getWithSentryConfigOptionsTemplate', () => {\n it('generates options for SaaS', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n webpack: {\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n\n // Tree-shaking options for reducing bundle size\n treeshake: {\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n removeDebugLogging: true,\n },\n },\n }\"\n `);\n });\n\n it('generates options for self-hosted', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: true,\n sentryUrl: 'https://my-sentry.com',\n tunnelRoute: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n sentryUrl: \"https://my-sentry.com\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n webpack: {\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n\n // Tree-shaking options for reducing bundle size\n treeshake: {\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n removeDebugLogging: true,\n },\n },\n }\"\n `);\n });\n\n it('comments out tunnelRoute if `tunnelRoute` option is disabled', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n // tunnelRoute: \"/monitoring\",\n\n webpack: {\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n\n // Tree-shaking options for reducing bundle size\n treeshake: {\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n removeDebugLogging: true,\n },\n },\n }\"\n `);\n });\n });\n\n describe('getRootLayout', () => {\n it('generates a root layout component with types', () => {\n expect(getRootLayout(true)).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n // You can delete this file at any time.\n\n export const metadata = {\n title: 'Sentry NextJS Example',\n description: 'Generated by Sentry',\n }\n\n export default function RootLayout({\n children,\n }: {\n children: React.ReactNode\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n it('generates a root layout component without types', () => {\n expect(getRootLayout(false)).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n // You can delete this file at any time.\n\n export const metadata = {\n title: 'Sentry NextJS Example',\n description: 'Generated by Sentry',\n }\n\n export default function RootLayout({\n children,\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n });\n\n describe('getGenerateMetadataSnippet', () => {\n it('generates metadata snippet with TypeScript types', () => {\n const template = getGenerateMetadataSnippet(true);\n\n expect(template).toMatchInlineSnapshot(`\n\"\n import * as Sentry from '@sentry/nextjs';\n import type { Metadata } from 'next';\n\n // Add or edit your \"generateMetadata\" to include the Sentry trace data:\n export function generateMetadata(): Metadata {\n return {\n // ... your existing metadata\n other: {\n ...Sentry.getTraceData()\n }\n };\n }\n\"\n`);\n });\n\n it('generates metadata snippet without TypeScript types', () => {\n const template = getGenerateMetadataSnippet(false);\n\n expect(template).toMatchInlineSnapshot(`\n \"\n import * as Sentry from '@sentry/nextjs';\n \n\n // Add or edit your \"generateMetadata\" to include the Sentry trace data:\n export function generateMetadata() {\n return {\n // ... your existing metadata\n other: {\n ...Sentry.getTraceData()\n }\n };\n }\n \"\n `);\n });\n });\n\n describe('getRootLayoutWithGenerateMetadata', () => {\n it('generates root layout with TypeScript types', () => {\n const template = getRootLayoutWithGenerateMetadata(true);\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n import * as Sentry from '@sentry/nextjs';\n import type { Metadata } from 'next';\n\n export function generateMetadata(): Metadata {\n return {\n other: {\n ...Sentry.getTraceData(),\n }\n }\n };\n\n export default function RootLayout({\n children,\n }: {\n children: React.ReactNode\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n\n it('generates root layout without TypeScript types', () => {\n const template = getRootLayoutWithGenerateMetadata(false);\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n import * as Sentry from '@sentry/nextjs';\n\n\n export function generateMetadata() {\n return {\n other: {\n ...Sentry.getTraceData(),\n }\n }\n };\n\n export default function RootLayout({\n children,\n }) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n }\n \"\n `);\n });\n });\n\n describe('getSentryExamplePageContents', () => {\n it('generates example page with TypeScript types', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: true,\n isTypeScript: true,\n });\n\n expect(template).toContain('\"use client\";');\n expect(template).toContain('constructor(message: string | undefined)');\n expect(template).toContain(\n 'class SentryExampleFrontendError extends Error',\n );\n });\n\n it('generates example page without TypeScript types', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: true,\n isTypeScript: false,\n });\n\n expect(template).toContain('\"use client\";');\n expect(template).toContain('constructor(message)');\n expect(template).toContain(\n 'class SentryExampleFrontendError extends Error',\n );\n });\n\n it('generates example page without useClient directive', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: false,\n isTypeScript: true,\n });\n\n expect(template).not.toContain('\"use client\";');\n expect(template).toContain(\n 'https://my-org.sentry.io/issues/?project=123',\n );\n });\n\n it('generates example page with logger calls when logsEnabled is true', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: true,\n isTypeScript: true,\n logsEnabled: true,\n });\n\n expect(template).toContain(\n 'Sentry.logger.info(\"Sentry example page loaded\")',\n );\n expect(template).toContain(\n 'Sentry.logger.info(\"User clicked the button, throwing a sample error\")',\n );\n });\n\n it('generates example page without logger calls when logsEnabled is false', () => {\n const template = getSentryExamplePageContents({\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n orgSlug: 'my-org',\n projectId: '123',\n useClient: true,\n isTypeScript: true,\n logsEnabled: false,\n });\n\n expect(template).not.toContain('Sentry.logger.info');\n });\n });\n\n describe('getSentryExamplePagesDirApiRoute', () => {\n it('generates Pages Router API route with TypeScript types', () => {\n const template = getSentryExamplePagesDirApiRoute({\n isTypeScript: true,\n });\n\n expect(template).toContain('constructor(message: string | undefined)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export default function handler(_req, res)');\n });\n\n it('generates Pages Router API route without TypeScript types', () => {\n const template = getSentryExamplePagesDirApiRoute({\n isTypeScript: false,\n });\n\n expect(template).toContain('constructor(message)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export default function handler(_req, res)');\n });\n\n it('generates Pages Router API route with logger calls when logsEnabled is true', () => {\n const template = getSentryExamplePagesDirApiRoute({\n isTypeScript: true,\n logsEnabled: true,\n });\n\n expect(template).toContain('import * as Sentry from \"@sentry/nextjs\";');\n expect(template).toContain(\n 'Sentry.logger.info(\"Sentry example API called\")',\n );\n });\n\n it('generates Pages Router API route without logger calls when logsEnabled is false', () => {\n const template = getSentryExamplePagesDirApiRoute({\n isTypeScript: true,\n logsEnabled: false,\n });\n\n expect(template).not.toContain(\n 'import * as Sentry from \"@sentry/nextjs\"',\n );\n expect(template).not.toContain('Sentry.logger.info');\n });\n });\n\n describe('getSentryExampleAppDirApiRoute', () => {\n it('generates App Router API route with TypeScript types', () => {\n const template = getSentryExampleAppDirApiRoute({\n isTypeScript: true,\n });\n\n expect(template).toContain('constructor(message: string | undefined)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export function GET()');\n expect(template).toContain('export const dynamic = \"force-dynamic\";');\n });\n\n it('generates App Router API route without TypeScript types', () => {\n const template = getSentryExampleAppDirApiRoute({\n isTypeScript: false,\n });\n\n expect(template).toContain('constructor(message)');\n expect(template).toContain('class SentryExampleAPIError extends Error');\n expect(template).toContain('export function GET()');\n expect(template).toContain('export const dynamic = \"force-dynamic\";');\n });\n\n it('generates App Router API route with logger calls when logsEnabled is true', () => {\n const template = getSentryExampleAppDirApiRoute({\n isTypeScript: true,\n logsEnabled: true,\n });\n\n expect(template).toContain('import * as Sentry from \"@sentry/nextjs\";');\n expect(template).toContain(\n 'Sentry.logger.info(\"Sentry example API called\")',\n );\n });\n\n it('generates App Router API route without logger calls when logsEnabled is false', () => {\n const template = getSentryExampleAppDirApiRoute({\n isTypeScript: true,\n logsEnabled: false,\n });\n\n expect(template).not.toContain('Sentry.logger.info');\n });\n });\n});\n"]}
|
|
@@ -257,13 +257,18 @@ const sentryOptionsSnapshot = `{
|
|
|
257
257
|
// side errors will fail.
|
|
258
258
|
// tunnelRoute: "/monitoring",
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
webpack: {
|
|
261
|
+
// Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
|
|
262
|
+
// See the following for more information:
|
|
263
|
+
// https://docs.sentry.io/product/crons/
|
|
264
|
+
// https://vercel.com/docs/cron-jobs
|
|
265
|
+
automaticVercelMonitors: true,
|
|
262
266
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
// Tree-shaking options for reducing bundle size
|
|
268
|
+
treeshake: {
|
|
269
|
+
// Automatically tree-shake Sentry logger statements to reduce bundle size
|
|
270
|
+
removeDebugLogging: true,
|
|
271
|
+
},
|
|
272
|
+
}
|
|
268
273
|
}`;
|
|
269
274
|
//# sourceMappingURL=wizard-double-wrap-prevention.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard-double-wrap-prevention.test.js","sourceRoot":"","sources":["../../../test/nextjs/wizard-double-wrap-prevention.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, vi } from 'vitest';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport { getWithSentryConfigOptionsTemplate } from '../../src/nextjs/templates';\nimport {\n unwrapSentryConfigAst,\n wrapWithSentryConfig,\n} from '../../src/nextjs/utils';\n\nvi.mock('../../src/utils/clack/mcp-config', () => ({\n offerProjectScopedMcpConfig: vi.fn().mockResolvedValue(undefined),\n}));\n\ndescribe('Next.js wizard double wrap prevention', () => {\n const mockWithSentryConfigOptionsTemplate =\n getWithSentryConfigOptionsTemplate({\n orgSlug: 'test-org',\n projectSlug: 'test-project',\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n tunnelRoute: false,\n });\n\n describe('unwrapSentryConfigAst utility function', () => {\n describe('AST-based expression unwrapping', () => {\n it('keeps code without withSentryConfig', () => {\n const mod = parseModule('export default nextConfig');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n expect(resultAST).toBe(originalAST);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle plain object literal exports', () => {\n const mod = parseModule(\n `export default { nextConfig: { randomValue: true } }`,\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n\n expect(resultAST).toBe(originalAST);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.type).toBe('ObjectExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.properties).toHaveLength(1);\n });\n\n it('should unwrap withSentryConfig with options', () => {\n const mod = parseModule(\n 'export default withSentryConfig(nextConfig, { org: \"test\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should unwrap withSentryConfig without options', () => {\n const mod = parseModule('export default withSentryConfig(nextConfig)');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle nested withSentryConfig calls', () => {\n const mod = parseModule(\n 'export default withSentryConfig(withSentryConfig(nextConfig, { org: \"inner\" }), { org: \"outer\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // Should unwrap one level and return the inner withSentryConfig call\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.type).toBe('CallExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.callee.name).toBe('withSentryConfig');\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"withSentryConfig(nextConfig, { org: \"inner\" })\"`,\n );\n });\n\n it('should handle complex expressions', () => {\n const mod = parseModule(\n 'export default withSentryConfig(someComplexExpression.withMethods())',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"someComplexExpression.withMethods()\"`,\n );\n });\n\n it('should handle object literals', () => {\n const mod = parseModule(\n 'export default withSentryConfig({ next: \"config\", obj: { next: \"nested\" } }, { org: \"test\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"{ next: \"config\", obj: { next: \"nested\" } }\"`,\n );\n });\n\n it('should return unchanged if not a withSentryConfig call', () => {\n const mod = parseModule('export default someOtherFunction(nextConfig)');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n\n expect(resultAST).toBe(originalAST);\n });\n });\n });\n\n describe('MJS/TS files', () => {\n it('should unwrap existing withSentryConfig and re-wrap with new config using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig, {\n org: \"old-org\",\n project: \"old-project\",\n});`;\n\n const mod = parseModule(existingMjsContent);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n // Verify it returns the first argument (nextConfig identifier)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.name).toBe('nextConfig');\n\n // Create a fresh module to simulate the re-wrapping process\n const freshMod =\n parseModule(`import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default nextConfig;`);\n\n // Apply wrapping\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n freshMod.exports.default = wrapWithSentryConfig(\n freshMod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = freshMod.generate().code;\n\n // Verify only one withSentryConfig call exists\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).toContain('test-org');\n expect(newCode).toContain('test-project');\n expect(newCode).not.toContain('old-org');\n expect(newCode).not.toContain('old-project');\n });\n\n it('should handle complex nested configurations using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = { experimental: { appDir: true } };\n\nexport default withSentryConfig(\n withSentryConfig(nextConfig, { org: \"nested-org\" }),\n { org: \"outer-org\" }\n);`;\n\n const mod = parseModule(existingMjsContent);\n\n // First unwrap ----\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const firstUnwrapAST = unwrapSentryConfigAst(mod.exports.default.$ast);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(firstUnwrapAST.type).toBe('CallExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(firstUnwrapAST.callee.name).toBe('withSentryConfig');\n\n const { code: exportDefaultCode1 } = generateCode({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n $ast: firstUnwrapAST,\n });\n expect(exportDefaultCode1).toMatchInlineSnapshot(\n `\"withSentryConfig(nextConfig, { org: \"nested-org\" })\"`,\n );\n\n // Second unwrap ----\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const secondUnwrapAST = unwrapSentryConfigAst(firstUnwrapAST);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(secondUnwrapAST.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(secondUnwrapAST.name).toBe('nextConfig');\n\n const { code: exportDefaultCode2 } = generateCode({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n $ast: secondUnwrapAST,\n });\n\n expect(exportDefaultCode2).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle simple export without existing withSentryConfig using AST', () => {\n const simpleMjsContent = `const nextConfig = {};\n\nexport default nextConfig;`;\n\n const mod = parseModule(simpleMjsContent);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n expect(unwrappedAst).toBe(originalAST);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.default = wrapWithSentryConfig(\n mod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = mod.generate().code;\n\n // Should have exactly one withSentryConfig call\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).toMatchInlineSnapshot(`\n \"const nextConfig = {};\n\n export default withSentryConfig(nextConfig, ${sentryOptionsSnapshot});\"\n `);\n });\n\n it('should handle withSentryConfig(nextConfig) without options using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig);`;\n\n const mod = parseModule(existingMjsContent);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n // Verify it returns the first argument (nextConfig identifier)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.name).toBe('nextConfig');\n\n // Simulate the re-wrapping process\n const freshMod =\n parseModule(`import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default nextConfig;`);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n freshMod.exports.default = wrapWithSentryConfig(\n freshMod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = freshMod.generate().code;\n\n // Should have exactly one withSentryConfig call\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).not.toContain('withSentryConfig(withSentryConfig(');\n expect(newCode).toMatch(/withSentryConfig\\s*\\(\\s*nextConfig\\s*,/);\n });\n });\n});\n\nconst sentryOptionsSnapshot = `{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"test-org\",\n\n project: \"test-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n // tunnelRoute: \"/monitoring\",\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true\n}`;\n"]}
|
|
1
|
+
{"version":3,"file":"wizard-double-wrap-prevention.test.js","sourceRoot":"","sources":["../../../test/nextjs/wizard-double-wrap-prevention.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, vi } from 'vitest';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport { getWithSentryConfigOptionsTemplate } from '../../src/nextjs/templates';\nimport {\n unwrapSentryConfigAst,\n wrapWithSentryConfig,\n} from '../../src/nextjs/utils';\n\nvi.mock('../../src/utils/clack/mcp-config', () => ({\n offerProjectScopedMcpConfig: vi.fn().mockResolvedValue(undefined),\n}));\n\ndescribe('Next.js wizard double wrap prevention', () => {\n const mockWithSentryConfigOptionsTemplate =\n getWithSentryConfigOptionsTemplate({\n orgSlug: 'test-org',\n projectSlug: 'test-project',\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n tunnelRoute: false,\n });\n\n describe('unwrapSentryConfigAst utility function', () => {\n describe('AST-based expression unwrapping', () => {\n it('keeps code without withSentryConfig', () => {\n const mod = parseModule('export default nextConfig');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n expect(resultAST).toBe(originalAST);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle plain object literal exports', () => {\n const mod = parseModule(\n `export default { nextConfig: { randomValue: true } }`,\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n\n expect(resultAST).toBe(originalAST);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.type).toBe('ObjectExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.properties).toHaveLength(1);\n });\n\n it('should unwrap withSentryConfig with options', () => {\n const mod = parseModule(\n 'export default withSentryConfig(nextConfig, { org: \"test\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should unwrap withSentryConfig without options', () => {\n const mod = parseModule('export default withSentryConfig(nextConfig)');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle nested withSentryConfig calls', () => {\n const mod = parseModule(\n 'export default withSentryConfig(withSentryConfig(nextConfig, { org: \"inner\" }), { org: \"outer\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // Should unwrap one level and return the inner withSentryConfig call\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.type).toBe('CallExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.callee.name).toBe('withSentryConfig');\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"withSentryConfig(nextConfig, { org: \"inner\" })\"`,\n );\n });\n\n it('should handle complex expressions', () => {\n const mod = parseModule(\n 'export default withSentryConfig(someComplexExpression.withMethods())',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"someComplexExpression.withMethods()\"`,\n );\n });\n\n it('should handle object literals', () => {\n const mod = parseModule(\n 'export default withSentryConfig({ next: \"config\", obj: { next: \"nested\" } }, { org: \"test\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"{ next: \"config\", obj: { next: \"nested\" } }\"`,\n );\n });\n\n it('should return unchanged if not a withSentryConfig call', () => {\n const mod = parseModule('export default someOtherFunction(nextConfig)');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n\n expect(resultAST).toBe(originalAST);\n });\n });\n });\n\n describe('MJS/TS files', () => {\n it('should unwrap existing withSentryConfig and re-wrap with new config using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig, {\n org: \"old-org\",\n project: \"old-project\",\n});`;\n\n const mod = parseModule(existingMjsContent);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n // Verify it returns the first argument (nextConfig identifier)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.name).toBe('nextConfig');\n\n // Create a fresh module to simulate the re-wrapping process\n const freshMod =\n parseModule(`import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default nextConfig;`);\n\n // Apply wrapping\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n freshMod.exports.default = wrapWithSentryConfig(\n freshMod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = freshMod.generate().code;\n\n // Verify only one withSentryConfig call exists\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).toContain('test-org');\n expect(newCode).toContain('test-project');\n expect(newCode).not.toContain('old-org');\n expect(newCode).not.toContain('old-project');\n });\n\n it('should handle complex nested configurations using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = { experimental: { appDir: true } };\n\nexport default withSentryConfig(\n withSentryConfig(nextConfig, { org: \"nested-org\" }),\n { org: \"outer-org\" }\n);`;\n\n const mod = parseModule(existingMjsContent);\n\n // First unwrap ----\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const firstUnwrapAST = unwrapSentryConfigAst(mod.exports.default.$ast);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(firstUnwrapAST.type).toBe('CallExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(firstUnwrapAST.callee.name).toBe('withSentryConfig');\n\n const { code: exportDefaultCode1 } = generateCode({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n $ast: firstUnwrapAST,\n });\n expect(exportDefaultCode1).toMatchInlineSnapshot(\n `\"withSentryConfig(nextConfig, { org: \"nested-org\" })\"`,\n );\n\n // Second unwrap ----\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const secondUnwrapAST = unwrapSentryConfigAst(firstUnwrapAST);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(secondUnwrapAST.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(secondUnwrapAST.name).toBe('nextConfig');\n\n const { code: exportDefaultCode2 } = generateCode({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n $ast: secondUnwrapAST,\n });\n\n expect(exportDefaultCode2).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle simple export without existing withSentryConfig using AST', () => {\n const simpleMjsContent = `const nextConfig = {};\n\nexport default nextConfig;`;\n\n const mod = parseModule(simpleMjsContent);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n expect(unwrappedAst).toBe(originalAST);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.default = wrapWithSentryConfig(\n mod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = mod.generate().code;\n\n // Should have exactly one withSentryConfig call\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).toMatchInlineSnapshot(`\n \"const nextConfig = {};\n\n export default withSentryConfig(nextConfig, ${sentryOptionsSnapshot});\"\n `);\n });\n\n it('should handle withSentryConfig(nextConfig) without options using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig);`;\n\n const mod = parseModule(existingMjsContent);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n // Verify it returns the first argument (nextConfig identifier)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.name).toBe('nextConfig');\n\n // Simulate the re-wrapping process\n const freshMod =\n parseModule(`import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default nextConfig;`);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n freshMod.exports.default = wrapWithSentryConfig(\n freshMod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = freshMod.generate().code;\n\n // Should have exactly one withSentryConfig call\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).not.toContain('withSentryConfig(withSentryConfig(');\n expect(newCode).toMatch(/withSentryConfig\\s*\\(\\s*nextConfig\\s*,/);\n });\n });\n});\n\nconst sentryOptionsSnapshot = `{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"test-org\",\n\n project: \"test-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n // tunnelRoute: \"/monitoring\",\n\n webpack: {\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n\n // Tree-shaking options for reducing bundle size\n treeshake: {\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n removeDebugLogging: true,\n },\n }\n}`;\n"]}
|
|
@@ -165,7 +165,7 @@ const templates_1 = require("../../src/react-router/templates");
|
|
|
165
165
|
(0, vitest_1.it)('runs the reveal CLI when entry files are missing', () => {
|
|
166
166
|
existsSyncMock.mockReturnValue(false);
|
|
167
167
|
childProcess.execSync.mockImplementation(() => 'ok');
|
|
168
|
-
(0, sdk_setup_1.runReactRouterReveal)(
|
|
168
|
+
(0, sdk_setup_1.runReactRouterReveal)();
|
|
169
169
|
(0, vitest_1.expect)(childProcess.execSync).toHaveBeenCalledWith('npx react-router reveal', {
|
|
170
170
|
encoding: 'utf8',
|
|
171
171
|
stdio: 'pipe',
|
|
@@ -174,7 +174,7 @@ const templates_1 = require("../../src/react-router/templates");
|
|
|
174
174
|
(0, vitest_1.it)('does not run the reveal CLI when entry files already exist', () => {
|
|
175
175
|
existsSyncMock.mockReturnValue(true);
|
|
176
176
|
childProcess.execSync.mockReset();
|
|
177
|
-
(0, sdk_setup_1.runReactRouterReveal)(
|
|
177
|
+
(0, sdk_setup_1.runReactRouterReveal)();
|
|
178
178
|
(0, vitest_1.expect)(childProcess.execSync).not.toHaveBeenCalled();
|
|
179
179
|
});
|
|
180
180
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-setup.test.js","sourceRoot":"","sources":["../../../test/react-router/sdk-setup.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi, beforeEach } from 'vitest';\n\nconst { clackMocks } = vi.hoisted(() => {\n const info = vi.fn();\n const warn = vi.fn();\n const error = vi.fn();\n const success = vi.fn();\n const outro = vi.fn();\n const confirm = vi.fn(() => Promise.resolve(false)); // default to false for tests\n\n return {\n clackMocks: {\n info,\n warn,\n error,\n success,\n outro,\n confirm,\n },\n };\n});\n\nvi.mock('@clack/prompts', () => {\n return {\n __esModule: true,\n default: {\n log: {\n info: clackMocks.info,\n warn: clackMocks.warn,\n error: clackMocks.error,\n success: clackMocks.success,\n },\n outro: clackMocks.outro,\n confirm: clackMocks.confirm,\n },\n };\n});\n\nconst { existsSyncMock, readFileSyncMock, writeFileSyncMock } = vi.hoisted(\n () => {\n return {\n existsSyncMock: vi.fn(),\n readFileSyncMock: vi.fn(),\n writeFileSyncMock: vi.fn(),\n };\n },\n);\n\nconst { getPackageDotJsonMock, getPackageVersionMock } = vi.hoisted(() => ({\n getPackageDotJsonMock: vi.fn(),\n getPackageVersionMock: vi.fn(),\n}));\n\nvi.mock('../../src/utils/package-json', () => ({\n getPackageDotJson: getPackageDotJsonMock,\n getPackageVersion: getPackageVersionMock,\n}));\n\nvi.mock('fs', async () => {\n return {\n ...(await vi.importActual('fs')),\n existsSync: existsSyncMock,\n readFileSync: readFileSyncMock,\n writeFileSync: writeFileSyncMock,\n promises: {\n writeFile: vi.fn(),\n },\n };\n});\n\n// module-level mock for child_process.execSync\nvi.mock('child_process', () => ({\n __esModule: true,\n execSync: vi.fn(),\n}));\n\n// mock showCopyPasteInstructions and makeCodeSnippet used by templates\nvi.mock('../../src/utils/clack', () => {\n return {\n __esModule: true,\n showCopyPasteInstructions: vi.fn(() => Promise.resolve()),\n makeCodeSnippet: vi.fn(\n (\n colors: boolean,\n callback: (\n unchanged: (str: string) => string,\n plus: (str: string) => string,\n minus: (str: string) => string,\n ) => string,\n ) => {\n // Mock implementation that just calls the callback with simple string functions\n const unchanged = (str: string) => str;\n const plus = (str: string) => `+ ${str}`;\n const minus = (str: string) => `- ${str}`;\n return callback(unchanged, plus, minus);\n },\n ),\n getPackageDotJson: getPackageDotJsonMock,\n };\n});\n\nimport {\n isReactRouterV7,\n runReactRouterReveal,\n createServerInstrumentationFile,\n tryRevealAndGetManualInstructions,\n updatePackageJsonScripts,\n} from '../../src/react-router/sdk-setup';\nimport * as childProcess from 'child_process';\nimport type { Mock } from 'vitest';\nimport { getSentryInstrumentationServerContent } from '../../src/react-router/templates';\n\ndescribe('React Router SDK Setup', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n\n getPackageVersionMock.mockImplementation(\n (\n packageName: string,\n packageJson: {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n },\n ) => {\n if (packageJson.dependencies?.[packageName]) {\n return packageJson.dependencies[packageName];\n }\n if (packageJson.devDependencies?.[packageName]) {\n return packageJson.devDependencies[packageName];\n }\n return null;\n },\n );\n });\n\n describe('isReactRouterV7', () => {\n it('should return true for React Router v7+ in dependencies or devDependencies', () => {\n expect(\n isReactRouterV7({ dependencies: { '@react-router/dev': '7.0.0' } }),\n ).toBe(true);\n expect(\n isReactRouterV7({ dependencies: { '@react-router/dev': '^7.1.0' } }),\n ).toBe(true);\n expect(\n isReactRouterV7({\n devDependencies: { '@react-router/dev': '7.1.0' },\n }),\n ).toBe(true);\n });\n\n it('should return false for React Router v6 or missing dependency', () => {\n expect(\n isReactRouterV7({ dependencies: { '@react-router/dev': '6.28.0' } }),\n ).toBe(false);\n expect(isReactRouterV7({ dependencies: { react: '^18.0.0' } })).toBe(\n false,\n );\n expect(isReactRouterV7({})).toBe(false);\n });\n });\n\n describe('generateServerInstrumentation', () => {\n it('should generate server instrumentation file with all features enabled', () => {\n const dsn = 'https://sentry.io/123';\n const enableTracing = true;\n const enableProfiling = false;\n const enableLogs = true;\n\n const result = getSentryInstrumentationServerContent(\n dsn,\n enableTracing,\n enableProfiling,\n enableLogs,\n );\n\n expect(result).toContain('dsn: \"https://sentry.io/123\"');\n expect(result).toContain('tracesSampleRate: 1');\n expect(result).toContain('enableLogs: true');\n });\n\n it('should generate server instrumentation file when performance is disabled', () => {\n const dsn = 'https://sentry.io/123';\n const enableTracing = false;\n const enableProfiling = false;\n const enableLogs = false;\n\n const result = getSentryInstrumentationServerContent(\n dsn,\n enableTracing,\n enableProfiling,\n enableLogs,\n );\n\n expect(result).toContain('dsn: \"https://sentry.io/123\"');\n expect(result).toContain('tracesSampleRate: 0');\n expect(result).not.toContain('enableLogs: true');\n });\n });\n});\n\ndescribe('runReactRouterReveal', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('runs the reveal CLI when entry files are missing', () => {\n existsSyncMock.mockReturnValue(false);\n\n (childProcess.execSync as unknown as Mock).mockImplementation(() => 'ok');\n\n runReactRouterReveal(false);\n\n expect(childProcess.execSync).toHaveBeenCalledWith(\n 'npx react-router reveal',\n {\n encoding: 'utf8',\n stdio: 'pipe',\n },\n );\n });\n\n it('does not run the reveal CLI when entry files already exist', () => {\n existsSyncMock.mockReturnValue(true);\n\n (childProcess.execSync as unknown as Mock).mockReset();\n\n runReactRouterReveal(false);\n\n expect(childProcess.execSync).not.toHaveBeenCalled();\n });\n});\n\ndescribe('server instrumentation helpers', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('createServerInstrumentationFile writes instrumentation file and returns path', () => {\n writeFileSyncMock.mockImplementation(() => undefined);\n\n const path = createServerInstrumentationFile('https://sentry.io/123', {\n performance: true,\n replay: false,\n logs: true,\n profiling: false,\n });\n\n expect(path).toContain('instrument.server.mjs');\n expect(writeFileSyncMock).toHaveBeenCalled();\n const writtenCall = writeFileSyncMock.mock.calls[0] as unknown as [\n string,\n string,\n ];\n expect(writtenCall[0]).toEqual(\n expect.stringContaining('instrument.server.mjs'),\n );\n expect(writtenCall[1]).toEqual(\n expect.stringContaining('dsn: \"https://sentry.io/123\"'),\n );\n expect(writtenCall[1]).toEqual(\n expect.stringContaining('tracesSampleRate: 1'),\n );\n });\n});\n\ndescribe('tryRevealAndGetManualInstructions', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('should return true when user confirms and reveal command succeeds', async () => {\n const missingFilename = 'entry.client.tsx';\n const filePath = '/app/entry.client.tsx';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce(\n 'Successfully generated entry files',\n );\n\n // Mock file existing after reveal\n existsSyncMock.mockReturnValueOnce(true);\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(true);\n expect(clackMocks.confirm).toHaveBeenCalledWith({\n message: expect.stringContaining(\n 'Would you like to try running',\n ) as string,\n initialValue: true,\n });\n expect(clackMocks.info).toHaveBeenCalledWith(\n expect.stringContaining('Running'),\n );\n expect(childProcess.execSync).toHaveBeenCalledWith(\n 'npx react-router reveal',\n {\n encoding: 'utf8',\n stdio: 'pipe',\n },\n );\n expect(clackMocks.success).toHaveBeenCalledWith(\n expect.stringContaining('Found entry.client.tsx after running reveal'),\n );\n });\n\n it('should return false when user declines reveal operation', async () => {\n const missingFilename = 'entry.server.tsx';\n const filePath = '/app/entry.server.tsx';\n\n // Mock user declining the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(false);\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(false);\n expect(clackMocks.confirm).toHaveBeenCalled();\n expect(childProcess.execSync).not.toHaveBeenCalled();\n expect(clackMocks.info).not.toHaveBeenCalled();\n });\n\n it('should return false when reveal command succeeds but file still does not exist', async () => {\n const missingFilename = 'entry.client.jsx';\n const filePath = '/app/entry.client.jsx';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce(\n 'Command output',\n );\n\n // Mock file NOT existing after reveal\n existsSyncMock.mockReturnValueOnce(false);\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(false);\n expect(childProcess.execSync).toHaveBeenCalled();\n expect(clackMocks.warn).toHaveBeenCalledWith(\n expect.stringContaining(\n 'entry.client.jsx still not found after running reveal',\n ),\n );\n });\n\n it('should return false when reveal command throws an error', async () => {\n const missingFilename = 'entry.server.jsx';\n const filePath = '/app/entry.server.jsx';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync throwing an error\n const mockError = new Error('Command failed');\n (childProcess.execSync as unknown as Mock).mockImplementationOnce(() => {\n throw mockError;\n });\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(false);\n expect(childProcess.execSync).toHaveBeenCalled();\n expect(clackMocks.warn).toHaveBeenCalledWith(\n expect.stringContaining('Failed to run npx react-router reveal'),\n );\n });\n\n it('should log command output when reveal succeeds', async () => {\n const missingFilename = 'entry.client.tsx';\n const filePath = '/app/entry.client.tsx';\n const commandOutput = 'Generated entry files successfully';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding with output\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce(\n commandOutput,\n );\n\n // Mock file existing after reveal\n existsSyncMock.mockReturnValueOnce(true);\n\n await tryRevealAndGetManualInstructions(missingFilename, filePath);\n\n expect(clackMocks.info).toHaveBeenCalledWith(commandOutput);\n });\n\n it('should handle reveal command with proper parameters', async () => {\n const missingFilename = 'entry.client.tsx';\n const filePath = '/app/entry.client.tsx';\n\n // Mock user confirming\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce('ok');\n\n // Mock file existing\n existsSyncMock.mockReturnValueOnce(true);\n\n await tryRevealAndGetManualInstructions(missingFilename, filePath);\n\n expect(childProcess.execSync).toHaveBeenCalledWith(\n 'npx react-router reveal',\n {\n encoding: 'utf8',\n stdio: 'pipe',\n },\n );\n });\n});\n\ndescribe('updatePackageJsonScripts', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('should set NODE_ENV=production for both dev and start scripts (workaround for React Router v7 + React 19 issue)', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n dev: 'react-router dev',\n start: 'react-router serve',\n build: 'react-router build',\n },\n };\n\n // Mock getPackageDotJson to return our test package.json\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n // Mock fs.promises.writeFile\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n // Verify writeFile was called\n expect(writeFileMock).toHaveBeenCalled();\n\n // Check the written package.json content\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Both dev and start scripts should use the correct filenames and commands according to documentation\n expect(writtenContent.scripts.dev).toBe(\n \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router dev\",\n );\n\n // The start script should use react-router-serve with build path according to documentation\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js\",\n );\n\n // The build script should remain unchanged\n expect(writtenContent.scripts.build).toBe('react-router build');\n });\n\n it('should handle package.json with only start script', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n start: 'react-router serve',\n },\n };\n\n // Mock getPackageDotJson to return our test package.json\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n // Mock fs.promises.writeFile\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n // Verify only start script is modified when dev doesn't exist\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js\",\n );\n expect(writtenContent.scripts.dev).toBeUndefined();\n });\n\n it('should throw error when no start script exists', async () => {\n const mockPackageJson = {\n scripts: {\n build: 'react-router build',\n },\n };\n\n // Mock getPackageDotJson to return package.json without start script\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n await expect(updatePackageJsonScripts()).rejects.toThrow(\n 'Could not find a `start` script in your package.json. Please add: \"start\": \"react-router-serve ./build/server/index.js\" and re-run the wizard.',\n );\n });\n\n it('should handle unquoted NODE_OPTIONS in dev script', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n dev: 'NODE_OPTIONS=--loader ts-node/register react-router dev',\n start: 'react-router serve',\n },\n };\n\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Should merge unquoted NODE_OPTIONS and wrap result in single quotes\n expect(writtenContent.scripts.dev).toBe(\n \"NODE_OPTIONS='--loader ts-node/register --import ./instrument.server.mjs' react-router dev\",\n );\n });\n\n it('should handle unquoted NODE_OPTIONS in start script', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n start:\n 'NODE_OPTIONS=--require ./dotenv-config.js react-router-serve ./build/server/index.js',\n },\n };\n\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Should merge unquoted NODE_OPTIONS and wrap result in single quotes\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--require ./dotenv-config.js --import ./instrument.server.mjs' react-router-serve ./build/server/index.js\",\n );\n });\n\n it('should handle quoted NODE_OPTIONS and standardize to single quotes', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n dev: 'NODE_OPTIONS=\"--max-old-space-size=4096\" react-router dev',\n start: \"NODE_OPTIONS='--enable-source-maps' react-router serve\",\n },\n };\n\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Should standardize to single quotes\n expect(writtenContent.scripts.dev).toBe(\n \"NODE_OPTIONS='--max-old-space-size=4096 --import ./instrument.server.mjs' react-router dev\",\n );\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--enable-source-maps --import ./instrument.server.mjs' react-router serve\",\n );\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"sdk-setup.test.js","sourceRoot":"","sources":["../../../test/react-router/sdk-setup.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi, beforeEach } from 'vitest';\n\nconst { clackMocks } = vi.hoisted(() => {\n const info = vi.fn();\n const warn = vi.fn();\n const error = vi.fn();\n const success = vi.fn();\n const outro = vi.fn();\n const confirm = vi.fn(() => Promise.resolve(false)); // default to false for tests\n\n return {\n clackMocks: {\n info,\n warn,\n error,\n success,\n outro,\n confirm,\n },\n };\n});\n\nvi.mock('@clack/prompts', () => {\n return {\n __esModule: true,\n default: {\n log: {\n info: clackMocks.info,\n warn: clackMocks.warn,\n error: clackMocks.error,\n success: clackMocks.success,\n },\n outro: clackMocks.outro,\n confirm: clackMocks.confirm,\n },\n };\n});\n\nconst { existsSyncMock, readFileSyncMock, writeFileSyncMock } = vi.hoisted(\n () => {\n return {\n existsSyncMock: vi.fn(),\n readFileSyncMock: vi.fn(),\n writeFileSyncMock: vi.fn(),\n };\n },\n);\n\nconst { getPackageDotJsonMock, getPackageVersionMock } = vi.hoisted(() => ({\n getPackageDotJsonMock: vi.fn(),\n getPackageVersionMock: vi.fn(),\n}));\n\nvi.mock('../../src/utils/package-json', () => ({\n getPackageDotJson: getPackageDotJsonMock,\n getPackageVersion: getPackageVersionMock,\n}));\n\nvi.mock('fs', async () => {\n return {\n ...(await vi.importActual('fs')),\n existsSync: existsSyncMock,\n readFileSync: readFileSyncMock,\n writeFileSync: writeFileSyncMock,\n promises: {\n writeFile: vi.fn(),\n },\n };\n});\n\n// module-level mock for child_process.execSync\nvi.mock('child_process', () => ({\n __esModule: true,\n execSync: vi.fn(),\n}));\n\n// mock showCopyPasteInstructions and makeCodeSnippet used by templates\nvi.mock('../../src/utils/clack', () => {\n return {\n __esModule: true,\n showCopyPasteInstructions: vi.fn(() => Promise.resolve()),\n makeCodeSnippet: vi.fn(\n (\n colors: boolean,\n callback: (\n unchanged: (str: string) => string,\n plus: (str: string) => string,\n minus: (str: string) => string,\n ) => string,\n ) => {\n // Mock implementation that just calls the callback with simple string functions\n const unchanged = (str: string) => str;\n const plus = (str: string) => `+ ${str}`;\n const minus = (str: string) => `- ${str}`;\n return callback(unchanged, plus, minus);\n },\n ),\n getPackageDotJson: getPackageDotJsonMock,\n };\n});\n\nimport {\n isReactRouterV7,\n runReactRouterReveal,\n createServerInstrumentationFile,\n tryRevealAndGetManualInstructions,\n updatePackageJsonScripts,\n} from '../../src/react-router/sdk-setup';\nimport * as childProcess from 'child_process';\nimport type { Mock } from 'vitest';\nimport { getSentryInstrumentationServerContent } from '../../src/react-router/templates';\n\ndescribe('React Router SDK Setup', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n\n getPackageVersionMock.mockImplementation(\n (\n packageName: string,\n packageJson: {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n },\n ) => {\n if (packageJson.dependencies?.[packageName]) {\n return packageJson.dependencies[packageName];\n }\n if (packageJson.devDependencies?.[packageName]) {\n return packageJson.devDependencies[packageName];\n }\n return null;\n },\n );\n });\n\n describe('isReactRouterV7', () => {\n it('should return true for React Router v7+ in dependencies or devDependencies', () => {\n expect(\n isReactRouterV7({ dependencies: { '@react-router/dev': '7.0.0' } }),\n ).toBe(true);\n expect(\n isReactRouterV7({ dependencies: { '@react-router/dev': '^7.1.0' } }),\n ).toBe(true);\n expect(\n isReactRouterV7({\n devDependencies: { '@react-router/dev': '7.1.0' },\n }),\n ).toBe(true);\n });\n\n it('should return false for React Router v6 or missing dependency', () => {\n expect(\n isReactRouterV7({ dependencies: { '@react-router/dev': '6.28.0' } }),\n ).toBe(false);\n expect(isReactRouterV7({ dependencies: { react: '^18.0.0' } })).toBe(\n false,\n );\n expect(isReactRouterV7({})).toBe(false);\n });\n });\n\n describe('generateServerInstrumentation', () => {\n it('should generate server instrumentation file with all features enabled', () => {\n const dsn = 'https://sentry.io/123';\n const enableTracing = true;\n const enableProfiling = false;\n const enableLogs = true;\n\n const result = getSentryInstrumentationServerContent(\n dsn,\n enableTracing,\n enableProfiling,\n enableLogs,\n );\n\n expect(result).toContain('dsn: \"https://sentry.io/123\"');\n expect(result).toContain('tracesSampleRate: 1');\n expect(result).toContain('enableLogs: true');\n });\n\n it('should generate server instrumentation file when performance is disabled', () => {\n const dsn = 'https://sentry.io/123';\n const enableTracing = false;\n const enableProfiling = false;\n const enableLogs = false;\n\n const result = getSentryInstrumentationServerContent(\n dsn,\n enableTracing,\n enableProfiling,\n enableLogs,\n );\n\n expect(result).toContain('dsn: \"https://sentry.io/123\"');\n expect(result).toContain('tracesSampleRate: 0');\n expect(result).not.toContain('enableLogs: true');\n });\n });\n});\n\ndescribe('runReactRouterReveal', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('runs the reveal CLI when entry files are missing', () => {\n existsSyncMock.mockReturnValue(false);\n\n (childProcess.execSync as unknown as Mock).mockImplementation(() => 'ok');\n\n runReactRouterReveal();\n\n expect(childProcess.execSync).toHaveBeenCalledWith(\n 'npx react-router reveal',\n {\n encoding: 'utf8',\n stdio: 'pipe',\n },\n );\n });\n\n it('does not run the reveal CLI when entry files already exist', () => {\n existsSyncMock.mockReturnValue(true);\n\n (childProcess.execSync as unknown as Mock).mockReset();\n\n runReactRouterReveal();\n\n expect(childProcess.execSync).not.toHaveBeenCalled();\n });\n});\n\ndescribe('server instrumentation helpers', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('createServerInstrumentationFile writes instrumentation file and returns path', () => {\n writeFileSyncMock.mockImplementation(() => undefined);\n\n const path = createServerInstrumentationFile('https://sentry.io/123', {\n performance: true,\n replay: false,\n logs: true,\n profiling: false,\n });\n\n expect(path).toContain('instrument.server.mjs');\n expect(writeFileSyncMock).toHaveBeenCalled();\n const writtenCall = writeFileSyncMock.mock.calls[0] as unknown as [\n string,\n string,\n ];\n expect(writtenCall[0]).toEqual(\n expect.stringContaining('instrument.server.mjs'),\n );\n expect(writtenCall[1]).toEqual(\n expect.stringContaining('dsn: \"https://sentry.io/123\"'),\n );\n expect(writtenCall[1]).toEqual(\n expect.stringContaining('tracesSampleRate: 1'),\n );\n });\n});\n\ndescribe('tryRevealAndGetManualInstructions', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('should return true when user confirms and reveal command succeeds', async () => {\n const missingFilename = 'entry.client.tsx';\n const filePath = '/app/entry.client.tsx';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce(\n 'Successfully generated entry files',\n );\n\n // Mock file existing after reveal\n existsSyncMock.mockReturnValueOnce(true);\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(true);\n expect(clackMocks.confirm).toHaveBeenCalledWith({\n message: expect.stringContaining(\n 'Would you like to try running',\n ) as string,\n initialValue: true,\n });\n expect(clackMocks.info).toHaveBeenCalledWith(\n expect.stringContaining('Running'),\n );\n expect(childProcess.execSync).toHaveBeenCalledWith(\n 'npx react-router reveal',\n {\n encoding: 'utf8',\n stdio: 'pipe',\n },\n );\n expect(clackMocks.success).toHaveBeenCalledWith(\n expect.stringContaining('Found entry.client.tsx after running reveal'),\n );\n });\n\n it('should return false when user declines reveal operation', async () => {\n const missingFilename = 'entry.server.tsx';\n const filePath = '/app/entry.server.tsx';\n\n // Mock user declining the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(false);\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(false);\n expect(clackMocks.confirm).toHaveBeenCalled();\n expect(childProcess.execSync).not.toHaveBeenCalled();\n expect(clackMocks.info).not.toHaveBeenCalled();\n });\n\n it('should return false when reveal command succeeds but file still does not exist', async () => {\n const missingFilename = 'entry.client.jsx';\n const filePath = '/app/entry.client.jsx';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce(\n 'Command output',\n );\n\n // Mock file NOT existing after reveal\n existsSyncMock.mockReturnValueOnce(false);\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(false);\n expect(childProcess.execSync).toHaveBeenCalled();\n expect(clackMocks.warn).toHaveBeenCalledWith(\n expect.stringContaining(\n 'entry.client.jsx still not found after running reveal',\n ),\n );\n });\n\n it('should return false when reveal command throws an error', async () => {\n const missingFilename = 'entry.server.jsx';\n const filePath = '/app/entry.server.jsx';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync throwing an error\n const mockError = new Error('Command failed');\n (childProcess.execSync as unknown as Mock).mockImplementationOnce(() => {\n throw mockError;\n });\n\n const result = await tryRevealAndGetManualInstructions(\n missingFilename,\n filePath,\n );\n\n expect(result).toBe(false);\n expect(childProcess.execSync).toHaveBeenCalled();\n expect(clackMocks.warn).toHaveBeenCalledWith(\n expect.stringContaining('Failed to run npx react-router reveal'),\n );\n });\n\n it('should log command output when reveal succeeds', async () => {\n const missingFilename = 'entry.client.tsx';\n const filePath = '/app/entry.client.tsx';\n const commandOutput = 'Generated entry files successfully';\n\n // Mock user confirming the reveal operation\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding with output\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce(\n commandOutput,\n );\n\n // Mock file existing after reveal\n existsSyncMock.mockReturnValueOnce(true);\n\n await tryRevealAndGetManualInstructions(missingFilename, filePath);\n\n expect(clackMocks.info).toHaveBeenCalledWith(commandOutput);\n });\n\n it('should handle reveal command with proper parameters', async () => {\n const missingFilename = 'entry.client.tsx';\n const filePath = '/app/entry.client.tsx';\n\n // Mock user confirming\n clackMocks.confirm.mockResolvedValueOnce(true);\n\n // Mock execSync succeeding\n (childProcess.execSync as unknown as Mock).mockReturnValueOnce('ok');\n\n // Mock file existing\n existsSyncMock.mockReturnValueOnce(true);\n\n await tryRevealAndGetManualInstructions(missingFilename, filePath);\n\n expect(childProcess.execSync).toHaveBeenCalledWith(\n 'npx react-router reveal',\n {\n encoding: 'utf8',\n stdio: 'pipe',\n },\n );\n });\n});\n\ndescribe('updatePackageJsonScripts', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.resetAllMocks();\n });\n\n it('should set NODE_ENV=production for both dev and start scripts (workaround for React Router v7 + React 19 issue)', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n dev: 'react-router dev',\n start: 'react-router serve',\n build: 'react-router build',\n },\n };\n\n // Mock getPackageDotJson to return our test package.json\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n // Mock fs.promises.writeFile\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n // Verify writeFile was called\n expect(writeFileMock).toHaveBeenCalled();\n\n // Check the written package.json content\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Both dev and start scripts should use the correct filenames and commands according to documentation\n expect(writtenContent.scripts.dev).toBe(\n \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router dev\",\n );\n\n // The start script should use react-router-serve with build path according to documentation\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js\",\n );\n\n // The build script should remain unchanged\n expect(writtenContent.scripts.build).toBe('react-router build');\n });\n\n it('should handle package.json with only start script', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n start: 'react-router serve',\n },\n };\n\n // Mock getPackageDotJson to return our test package.json\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n // Mock fs.promises.writeFile\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n // Verify only start script is modified when dev doesn't exist\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js\",\n );\n expect(writtenContent.scripts.dev).toBeUndefined();\n });\n\n it('should throw error when no start script exists', async () => {\n const mockPackageJson = {\n scripts: {\n build: 'react-router build',\n },\n };\n\n // Mock getPackageDotJson to return package.json without start script\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n await expect(updatePackageJsonScripts()).rejects.toThrow(\n 'Could not find a `start` script in your package.json. Please add: \"start\": \"react-router-serve ./build/server/index.js\" and re-run the wizard.',\n );\n });\n\n it('should handle unquoted NODE_OPTIONS in dev script', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n dev: 'NODE_OPTIONS=--loader ts-node/register react-router dev',\n start: 'react-router serve',\n },\n };\n\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Should merge unquoted NODE_OPTIONS and wrap result in single quotes\n expect(writtenContent.scripts.dev).toBe(\n \"NODE_OPTIONS='--loader ts-node/register --import ./instrument.server.mjs' react-router dev\",\n );\n });\n\n it('should handle unquoted NODE_OPTIONS in start script', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n start:\n 'NODE_OPTIONS=--require ./dotenv-config.js react-router-serve ./build/server/index.js',\n },\n };\n\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Should merge unquoted NODE_OPTIONS and wrap result in single quotes\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--require ./dotenv-config.js --import ./instrument.server.mjs' react-router-serve ./build/server/index.js\",\n );\n });\n\n it('should handle quoted NODE_OPTIONS and standardize to single quotes', async () => {\n const mockPackageJson: { scripts: Record<string, string> } = {\n scripts: {\n dev: 'NODE_OPTIONS=\"--max-old-space-size=4096\" react-router dev',\n start: \"NODE_OPTIONS='--enable-source-maps' react-router serve\",\n },\n };\n\n getPackageDotJsonMock.mockResolvedValue(mockPackageJson);\n\n const fsPromises = await import('fs');\n const writeFileMock = vi\n .spyOn(fsPromises.promises, 'writeFile')\n .mockResolvedValue();\n\n await updatePackageJsonScripts();\n\n const writtenContent = JSON.parse(\n writeFileMock.mock.calls[0]?.[1] as string,\n ) as { scripts: Record<string, string> };\n\n // Should standardize to single quotes\n expect(writtenContent.scripts.dev).toBe(\n \"NODE_OPTIONS='--max-old-space-size=4096 --import ./instrument.server.mjs' react-router dev\",\n );\n expect(writtenContent.scripts.start).toBe(\n \"NODE_OPTIONS='--enable-source-maps --import ./instrument.server.mjs' react-router serve\",\n );\n });\n});\n"]}
|