@sentry/wizard 6.6.1 → 6.7.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 +22 -0
- package/LICENSE +97 -8
- package/dist/bin.js +5 -0
- package/dist/bin.js.map +1 -1
- package/dist/e2e-tests/tests/help-message.test.js +5 -1
- package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs-15.test.js +79 -0
- package/dist/e2e-tests/tests/nextjs-15.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router.test.d.ts +1 -0
- package/dist/e2e-tests/tests/react-router.test.js +255 -0
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -0
- package/dist/e2e-tests/utils/index.d.ts +8 -2
- package/dist/e2e-tests/utils/index.js +72 -21
- package/dist/e2e-tests/utils/index.js.map +1 -1
- 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 +8 -1
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/angular/angular-wizard.js +8 -1
- package/dist/src/angular/angular-wizard.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +8 -1
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/flutter/flutter-wizard.js +8 -1
- package/dist/src/flutter/flutter-wizard.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +35 -9
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.d.ts +3 -3
- package/dist/src/nextjs/templates.js +18 -7
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/nuxt/nuxt-wizard.js +8 -1
- package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +8 -1
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.d.ts +1 -0
- package/dist/src/react-router/codemods/client.entry.js +73 -0
- package/dist/src/react-router/codemods/client.entry.js.map +1 -0
- package/dist/src/react-router/codemods/react-router-config.d.ts +9 -0
- package/dist/src/react-router/codemods/react-router-config.js +178 -0
- package/dist/src/react-router/codemods/react-router-config.js.map +1 -0
- package/dist/src/react-router/codemods/root.d.ts +1 -0
- package/dist/src/react-router/codemods/root.js +171 -0
- package/dist/src/react-router/codemods/root.js.map +1 -0
- package/dist/src/react-router/codemods/routes-config.d.ts +1 -0
- package/dist/src/react-router/codemods/routes-config.js +106 -0
- package/dist/src/react-router/codemods/routes-config.js.map +1 -0
- package/dist/src/react-router/codemods/server-entry.d.ts +4 -0
- package/dist/src/react-router/codemods/server-entry.js +275 -0
- package/dist/src/react-router/codemods/server-entry.js.map +1 -0
- package/dist/src/react-router/codemods/utils.d.ts +2 -0
- package/dist/src/react-router/codemods/utils.js +13 -0
- package/dist/src/react-router/codemods/utils.js.map +1 -0
- package/dist/src/react-router/codemods/vite.d.ts +8 -0
- package/dist/src/react-router/codemods/vite.js +169 -0
- package/dist/src/react-router/codemods/vite.js.map +1 -0
- package/dist/src/react-router/react-router-wizard.d.ts +2 -0
- package/dist/src/react-router/react-router-wizard.js +254 -0
- package/dist/src/react-router/react-router-wizard.js.map +1 -0
- package/dist/src/react-router/sdk-example.d.ts +18 -0
- package/dist/src/react-router/sdk-example.js +306 -0
- package/dist/src/react-router/sdk-example.js.map +1 -0
- package/dist/src/react-router/sdk-setup.d.ts +17 -0
- package/dist/src/react-router/sdk-setup.js +250 -0
- package/dist/src/react-router/sdk-setup.js.map +1 -0
- package/dist/src/react-router/templates.d.ts +11 -0
- package/dist/src/react-router/templates.js +273 -0
- package/dist/src/react-router/templates.js.map +1 -0
- package/dist/src/remix/remix-wizard.js +8 -1
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/run.d.ts +2 -1
- package/dist/src/run.js +6 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js +8 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +8 -1
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +30 -0
- package/dist/src/utils/ast-utils.js +71 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +5 -2
- package/dist/src/utils/clack/index.js +8 -0
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/utils/types.d.ts +9 -0
- package/dist/src/utils/types.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/nextjs/templates.test.js +20 -0
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/dist/test/react-router/codemods/client-entry.test.d.ts +1 -0
- package/dist/test/react-router/codemods/client-entry.test.js +168 -0
- package/dist/test/react-router/codemods/client-entry.test.js.map +1 -0
- package/dist/test/react-router/codemods/react-router-config.test.d.ts +1 -0
- package/dist/test/react-router/codemods/react-router-config.test.js +168 -0
- package/dist/test/react-router/codemods/react-router-config.test.js.map +1 -0
- package/dist/test/react-router/codemods/root.test.d.ts +1 -0
- package/dist/test/react-router/codemods/root.test.js +178 -0
- package/dist/test/react-router/codemods/root.test.js.map +1 -0
- package/dist/test/react-router/codemods/server-entry.test.d.ts +1 -0
- package/dist/test/react-router/codemods/server-entry.test.js +415 -0
- package/dist/test/react-router/codemods/server-entry.test.js.map +1 -0
- package/dist/test/react-router/codemods/vite.test.d.ts +1 -0
- package/dist/test/react-router/codemods/vite.test.js +158 -0
- package/dist/test/react-router/codemods/vite.test.js.map +1 -0
- package/dist/test/react-router/routes-config.test.d.ts +1 -0
- package/dist/test/react-router/routes-config.test.js +156 -0
- package/dist/test/react-router/routes-config.test.js.map +1 -0
- package/dist/test/react-router/sdk-setup.test.d.ts +1 -0
- package/dist/test/react-router/sdk-setup.test.js +411 -0
- package/dist/test/react-router/sdk-setup.test.js.map +1 -0
- package/dist/test/react-router/templates.test.d.ts +1 -0
- package/dist/test/react-router/templates.test.js +220 -0
- package/dist/test/react-router/templates.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -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 });\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\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":";;AAAA,mCAA8C;AAC9C,0DAUoC;AAEpC,IAAA,iBAAQ,EAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAA,iBAAQ,EAAC,sCAAsC,EAAE,GAAG,EAAE;QACpD,IAAA,WAAE,EAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,MAAM,QAAQ,GAAG,IAAA,gDAAoC,EAAC,QAAQ,EAAE;gBAC9D,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,0EAA0E,EAAE,GAAG,EAAE;YAClF,MAAM,QAAQ,GAAG,IAAA,gDAAoC,EAAC,QAAQ,EAAE;gBAC9D,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,kEAAkE,EAAE,GAAG,EAAE;YAC1E,MAAM,QAAQ,GAAG,IAAA,gDAAoC,EAAC,QAAQ,EAAE;gBAC9D,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;OAqBtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,QAAQ,GAAG,IAAA,gDAAoC,EAAC,QAAQ,EAAE;gBAC9D,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAA,WAAE,EAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,QAAQ,GAAG,IAAA,gDAAoC,EACnD,EAAE,EACF;gBACE,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,KAAK;aACZ,EACD,IAAI,CACL,CAAC;YAEF,oCAAoC;YACpC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACtC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,mCAAmC,EAAE,GAAG,EAAE;QACjD,IAAA,iBAAQ,EAAC,aAAa,EAAE,GAAG,EAAE;YAC3B,IAAA,WAAE,EAAC,+DAA+D,EAAE,GAAG,EAAE;gBACvE,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,QAAQ,EAAE,QAAQ,EAAE;oBACrE,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,IAAI;iBACX,CAAC,CAAC;gBAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;SAqBtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAA,WAAE,EAAC,0EAA0E,EAAE,GAAG,EAAE;gBAClF,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,QAAQ,EAAE,QAAQ,EAAE;oBACrE,WAAW,EAAE,KAAK;oBAClB,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,IAAI;iBACX,CAAC,CAAC;gBAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;SAkBtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAA,WAAE,EAAC,6DAA6D,EAAE,GAAG,EAAE;gBACrE,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,QAAQ,EAAE,QAAQ,EAAE;oBACrE,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,IAAI;iBACX,CAAC,CAAC;gBAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;SAqBtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAA,WAAE,EAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,QAAQ,EAAE,QAAQ,EAAE;oBACrE,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,KAAK;iBACZ,CAAC,CAAC;gBAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;SAkBtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAA,WAAE,EAAC,kCAAkC,EAAE,GAAG,EAAE;gBAC1C,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAChD,EAAE,EACF,QAAQ,EACR;oBACE,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,KAAK;oBACb,IAAI,EAAE,KAAK;iBACZ,EACD,IAAI,CACL,CAAC;gBAEF,oCAAoC;gBACpC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBACtC,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,iBAAQ,EAAC,MAAM,EAAE,GAAG,EAAE;YACpB,IAAA,WAAE,EAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,QAAQ,EAAE,MAAM,EAAE;oBACnE,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,IAAI;iBACX,CAAC,CAAC;gBAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;SAsBtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAA,WAAE,EAAC,mEAAmE,EAAE,GAAG,EAAE;gBAC3E,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,QAAQ,EAAE,MAAM,EAAE;oBACnE,WAAW,EAAE,KAAK;oBAClB,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,IAAI;iBACX,CAAC,CAAC;gBAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;SAmBtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAA,WAAE,EAAC,iDAAiD,EAAE,GAAG,EAAE;gBACzD,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,QAAQ,EAAE,MAAM,EAAE;oBACnE,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,KAAK;iBACZ,CAAC,CAAC;gBAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;SAmBtC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,oCAAoC,EAAE,GAAG,EAAE;QAClD,IAAA,WAAE,EAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,MAAM,QAAQ,GAAG,IAAA,8CAAkC,EAAC;gBAClD,OAAO,EAAE,QAAQ;gBACjB,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,+BAA+B;gBAC1C,WAAW,EAAE,IAAI;aAClB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,QAAQ,GAAG,IAAA,8CAAkC,EAAC;gBAClD,OAAO,EAAE,QAAQ;gBACjB,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,IAAI;gBAChB,SAAS,EAAE,uBAAuB;gBAClC,WAAW,EAAE,IAAI;aAClB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,8DAA8D,EAAE,GAAG,EAAE;YACtE,MAAM,QAAQ,GAAG,IAAA,8CAAkC,EAAC;gBAClD,OAAO,EAAE,QAAQ;gBACjB,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,+BAA+B;gBAC1C,WAAW,EAAE,KAAK;aACnB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,IAAA,WAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,IAAA,eAAM,EAAC,IAAA,yBAAa,EAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;OAqBjD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAA,WAAE,EAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,IAAA,eAAM,EAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;OAmBlD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,IAAA,WAAE,EAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,QAAQ,GAAG,IAAA,sCAA0B,EAAC,IAAI,CAAC,CAAC;YAElD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;CAe5C,CAAC,CAAC;QACC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,QAAQ,GAAG,IAAA,sCAA0B,EAAC,KAAK,CAAC,CAAC;YAEnD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;KAexC,CAAC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,mCAAmC,EAAE,GAAG,EAAE;QACjD,IAAA,WAAE,EAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,IAAI,CAAC,CAAC;YAEzD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,QAAQ,GAAG,IAAA,6CAAiC,EAAC,KAAK,CAAC,CAAC;YAE1D,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;OAuBtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,8BAA8B,EAAE,GAAG,EAAE;QAC5C,IAAA,WAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,QAAQ,GAAG,IAAA,wCAA4B,EAAC;gBAC5C,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,mBAAmB;gBAC9B,OAAO,EAAE,QAAQ;gBACjB,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAC5C,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,0CAA0C,CAAC,CAAC;YACvE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CACxB,gDAAgD,CACjD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAG,IAAA,wCAA4B,EAAC;gBAC5C,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,mBAAmB;gBAC9B,OAAO,EAAE,QAAQ;gBACjB,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,KAAK;aACpB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAC5C,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YACnD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CACxB,gDAAgD,CACjD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,QAAQ,GAAG,IAAA,wCAA4B,EAAC;gBAC5C,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,mBAAmB;gBAC9B,OAAO,EAAE,QAAQ;gBACjB,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,KAAK;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAChD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CACxB,8CAA8C,CAC/C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,IAAA,WAAE,EAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,QAAQ,GAAG,IAAA,4CAAgC,EAAC;gBAChD,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,0CAA0C,CAAC,CAAC;YACvE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,2CAA2C,CAAC,CAAC;YACxE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,4CAA4C,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,QAAQ,GAAG,IAAA,4CAAgC,EAAC;gBAChD,YAAY,EAAE,KAAK;aACpB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YACnD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,2CAA2C,CAAC,CAAC;YACxE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,4CAA4C,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,gCAAgC,EAAE,GAAG,EAAE;QAC9C,IAAA,WAAE,EAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,QAAQ,GAAG,IAAA,0CAA8B,EAAC;gBAC9C,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,0CAA0C,CAAC,CAAC;YACvE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,2CAA2C,CAAC,CAAC;YACxE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACpD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,yDAAyD,EAAE,GAAG,EAAE;YACjE,MAAM,QAAQ,GAAG,IAAA,0CAA8B,EAAC;gBAC9C,YAAY,EAAE,KAAK;aACpB,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YACnD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,2CAA2C,CAAC,CAAC;YACxE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACpD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const vitest_1 = require("vitest");
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const path = __importStar(require("path"));
|
|
29
|
+
const client_entry_1 = require("../../../src/react-router/codemods/client.entry");
|
|
30
|
+
vitest_1.vi.mock('@clack/prompts', () => {
|
|
31
|
+
const mock = {
|
|
32
|
+
log: {
|
|
33
|
+
warn: vitest_1.vi.fn(),
|
|
34
|
+
info: vitest_1.vi.fn(),
|
|
35
|
+
success: vitest_1.vi.fn(),
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
default: mock,
|
|
40
|
+
...mock,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
(0, vitest_1.describe)('instrumentClientEntry', () => {
|
|
44
|
+
const fixturesDir = path.join(__dirname, 'fixtures', 'client-entry');
|
|
45
|
+
let tmpDir;
|
|
46
|
+
let tmpFile;
|
|
47
|
+
(0, vitest_1.beforeEach)(() => {
|
|
48
|
+
vitest_1.vi.clearAllMocks();
|
|
49
|
+
// Create unique tmp directory for each test
|
|
50
|
+
tmpDir = path.join(fixturesDir, 'tmp', `test-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);
|
|
51
|
+
tmpFile = path.join(tmpDir, 'entry.client.tsx');
|
|
52
|
+
// Ensure tmp directory exists
|
|
53
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
54
|
+
});
|
|
55
|
+
(0, vitest_1.afterEach)(() => {
|
|
56
|
+
// Clean up tmp directory
|
|
57
|
+
if (fs.existsSync(tmpDir)) {
|
|
58
|
+
fs.rmSync(tmpDir, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
(0, vitest_1.it)('should add Sentry import and initialization with all features enabled', async () => {
|
|
62
|
+
const basicContent = fs.readFileSync(path.join(fixturesDir, 'basic.tsx'), 'utf8');
|
|
63
|
+
fs.writeFileSync(tmpFile, basicContent);
|
|
64
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', true, true, true);
|
|
65
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
66
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
67
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
68
|
+
(0, vitest_1.expect)(modifiedContent).toContain('dsn: "test-dsn"');
|
|
69
|
+
(0, vitest_1.expect)(modifiedContent).toContain('integrations: [');
|
|
70
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.reactRouterTracingIntegration()');
|
|
71
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.replayIntegration(');
|
|
72
|
+
(0, vitest_1.expect)(modifiedContent).toContain('enableLogs: true');
|
|
73
|
+
});
|
|
74
|
+
(0, vitest_1.it)('should add Sentry initialization with only tracing enabled', async () => {
|
|
75
|
+
const basicContent = fs.readFileSync(path.join(fixturesDir, 'basic.tsx'), 'utf8');
|
|
76
|
+
fs.writeFileSync(tmpFile, basicContent);
|
|
77
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', true, false, false);
|
|
78
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
79
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
80
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
81
|
+
(0, vitest_1.expect)(modifiedContent).toContain('dsn: "test-dsn"');
|
|
82
|
+
(0, vitest_1.expect)(modifiedContent).toContain('integrations: [');
|
|
83
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.reactRouterTracingIntegration()');
|
|
84
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('Sentry.replayIntegration()');
|
|
85
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('enableLogs: true');
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.it)('should add Sentry initialization with only replay enabled', async () => {
|
|
88
|
+
const basicContent = fs.readFileSync(path.join(fixturesDir, 'basic.tsx'), 'utf8');
|
|
89
|
+
fs.writeFileSync(tmpFile, basicContent);
|
|
90
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', false, true, false);
|
|
91
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
92
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
93
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
94
|
+
(0, vitest_1.expect)(modifiedContent).toContain('dsn: "test-dsn"');
|
|
95
|
+
(0, vitest_1.expect)(modifiedContent).toContain('integrations: [');
|
|
96
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('Sentry.reactRouterTracingIntegration()');
|
|
97
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.replayIntegration(');
|
|
98
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('enableLogs: true');
|
|
99
|
+
});
|
|
100
|
+
(0, vitest_1.it)('should add Sentry initialization with only logs enabled', async () => {
|
|
101
|
+
const basicContent = fs.readFileSync(path.join(fixturesDir, 'basic.tsx'), 'utf8');
|
|
102
|
+
fs.writeFileSync(tmpFile, basicContent);
|
|
103
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', false, false, true);
|
|
104
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
105
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
106
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
107
|
+
(0, vitest_1.expect)(modifiedContent).toContain('dsn: "test-dsn"');
|
|
108
|
+
(0, vitest_1.expect)(modifiedContent).toContain('integrations: [');
|
|
109
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('Sentry.reactRouterTracingIntegration()');
|
|
110
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('Sentry.replayIntegration()');
|
|
111
|
+
(0, vitest_1.expect)(modifiedContent).toContain('enableLogs: true');
|
|
112
|
+
});
|
|
113
|
+
(0, vitest_1.it)('should add minimal Sentry initialization when all features are disabled', async () => {
|
|
114
|
+
const basicContent = fs.readFileSync(path.join(fixturesDir, 'basic.tsx'), 'utf8');
|
|
115
|
+
fs.writeFileSync(tmpFile, basicContent);
|
|
116
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', false, false, false);
|
|
117
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
118
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
119
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
120
|
+
(0, vitest_1.expect)(modifiedContent).toContain('dsn: "test-dsn"');
|
|
121
|
+
(0, vitest_1.expect)(modifiedContent).toContain('integrations: []');
|
|
122
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('Sentry.reactRouterTracingIntegration()');
|
|
123
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('Sentry.replayIntegration()');
|
|
124
|
+
(0, vitest_1.expect)(modifiedContent).not.toContain('enableLogs: true');
|
|
125
|
+
});
|
|
126
|
+
(0, vitest_1.it)('should not modify file when Sentry content already exists', async () => {
|
|
127
|
+
const withSentryContent = fs.readFileSync(path.join(fixturesDir, 'with-sentry.tsx'), 'utf8');
|
|
128
|
+
fs.writeFileSync(tmpFile, withSentryContent);
|
|
129
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', true, true, true);
|
|
130
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
131
|
+
// Content should remain unchanged
|
|
132
|
+
(0, vitest_1.expect)(modifiedContent).toBe(withSentryContent);
|
|
133
|
+
});
|
|
134
|
+
(0, vitest_1.it)('should insert Sentry initialization after imports', async () => {
|
|
135
|
+
const withImportsContent = fs.readFileSync(path.join(fixturesDir, 'with-imports.tsx'), 'utf8');
|
|
136
|
+
fs.writeFileSync(tmpFile, withImportsContent);
|
|
137
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', true, false, false);
|
|
138
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
139
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
140
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
141
|
+
// Check that the Sentry import is before the init call
|
|
142
|
+
const sentryImportIndex = modifiedContent.indexOf('import * as Sentry from "@sentry/react-router";');
|
|
143
|
+
const sentryInitIndex = modifiedContent.indexOf('Sentry.init({');
|
|
144
|
+
(0, vitest_1.expect)(sentryImportIndex).toBeLessThan(sentryInitIndex);
|
|
145
|
+
});
|
|
146
|
+
(0, vitest_1.it)('should handle files with no imports', async () => {
|
|
147
|
+
const noImportsContent = fs.readFileSync(path.join(fixturesDir, 'no-imports.tsx'), 'utf8');
|
|
148
|
+
fs.writeFileSync(tmpFile, noImportsContent);
|
|
149
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', false, true, false);
|
|
150
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
151
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
152
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
153
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.replayIntegration(');
|
|
154
|
+
});
|
|
155
|
+
(0, vitest_1.it)('should preserve existing code structure', async () => {
|
|
156
|
+
const complexContent = fs.readFileSync(path.join(fixturesDir, 'complex.tsx'), 'utf8');
|
|
157
|
+
fs.writeFileSync(tmpFile, complexContent);
|
|
158
|
+
await (0, client_entry_1.instrumentClientEntry)(tmpFile, 'test-dsn', true, true, false);
|
|
159
|
+
const modifiedContent = fs.readFileSync(tmpFile, 'utf8');
|
|
160
|
+
(0, vitest_1.expect)(modifiedContent).toContain('import * as Sentry from "@sentry/react-router";');
|
|
161
|
+
(0, vitest_1.expect)(modifiedContent).toContain('Sentry.init({');
|
|
162
|
+
// Original content should still be there
|
|
163
|
+
(0, vitest_1.expect)(modifiedContent).toContain('startTransition');
|
|
164
|
+
(0, vitest_1.expect)(modifiedContent).toContain('hydrateRoot');
|
|
165
|
+
(0, vitest_1.expect)(modifiedContent).toContain('<StrictMode>');
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
//# sourceMappingURL=client-entry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-entry.test.js","sourceRoot":"","sources":["../../../../test/react-router/codemods/client-entry.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { instrumentClientEntry } from '../../../src/react-router/codemods/client.entry';\n\nvi.mock('@clack/prompts', () => {\n const mock = {\n log: {\n warn: vi.fn(),\n info: vi.fn(),\n success: vi.fn(),\n },\n };\n return {\n default: mock,\n ...mock,\n };\n});\n\ndescribe('instrumentClientEntry', () => {\n const fixturesDir = path.join(__dirname, 'fixtures', 'client-entry');\n let tmpDir: string;\n let tmpFile: string;\n\n beforeEach(() => {\n vi.clearAllMocks();\n\n // Create unique tmp directory for each test\n tmpDir = path.join(\n fixturesDir,\n 'tmp',\n `test-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n );\n tmpFile = path.join(tmpDir, 'entry.client.tsx');\n\n // Ensure tmp directory exists\n fs.mkdirSync(tmpDir, { recursive: true });\n });\n\n afterEach(() => {\n // Clean up tmp directory\n if (fs.existsSync(tmpDir)) {\n fs.rmSync(tmpDir, { recursive: true });\n }\n });\n\n it('should add Sentry import and initialization with all features enabled', async () => {\n const basicContent = fs.readFileSync(\n path.join(fixturesDir, 'basic.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, basicContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', true, true, true);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n expect(modifiedContent).toContain('dsn: \"test-dsn\"');\n expect(modifiedContent).toContain('integrations: [');\n expect(modifiedContent).toContain('Sentry.reactRouterTracingIntegration()');\n expect(modifiedContent).toContain('Sentry.replayIntegration(');\n expect(modifiedContent).toContain('enableLogs: true');\n });\n\n it('should add Sentry initialization with only tracing enabled', async () => {\n const basicContent = fs.readFileSync(\n path.join(fixturesDir, 'basic.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, basicContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', true, false, false);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n expect(modifiedContent).toContain('dsn: \"test-dsn\"');\n expect(modifiedContent).toContain('integrations: [');\n expect(modifiedContent).toContain('Sentry.reactRouterTracingIntegration()');\n expect(modifiedContent).not.toContain('Sentry.replayIntegration()');\n expect(modifiedContent).not.toContain('enableLogs: true');\n });\n\n it('should add Sentry initialization with only replay enabled', async () => {\n const basicContent = fs.readFileSync(\n path.join(fixturesDir, 'basic.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, basicContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', false, true, false);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n expect(modifiedContent).toContain('dsn: \"test-dsn\"');\n expect(modifiedContent).toContain('integrations: [');\n expect(modifiedContent).not.toContain(\n 'Sentry.reactRouterTracingIntegration()',\n );\n expect(modifiedContent).toContain('Sentry.replayIntegration(');\n expect(modifiedContent).not.toContain('enableLogs: true');\n });\n\n it('should add Sentry initialization with only logs enabled', async () => {\n const basicContent = fs.readFileSync(\n path.join(fixturesDir, 'basic.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, basicContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', false, false, true);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n expect(modifiedContent).toContain('dsn: \"test-dsn\"');\n expect(modifiedContent).toContain('integrations: [');\n expect(modifiedContent).not.toContain(\n 'Sentry.reactRouterTracingIntegration()',\n );\n expect(modifiedContent).not.toContain('Sentry.replayIntegration()');\n expect(modifiedContent).toContain('enableLogs: true');\n });\n\n it('should add minimal Sentry initialization when all features are disabled', async () => {\n const basicContent = fs.readFileSync(\n path.join(fixturesDir, 'basic.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, basicContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', false, false, false);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n expect(modifiedContent).toContain('dsn: \"test-dsn\"');\n expect(modifiedContent).toContain('integrations: []');\n expect(modifiedContent).not.toContain(\n 'Sentry.reactRouterTracingIntegration()',\n );\n expect(modifiedContent).not.toContain('Sentry.replayIntegration()');\n expect(modifiedContent).not.toContain('enableLogs: true');\n });\n\n it('should not modify file when Sentry content already exists', async () => {\n const withSentryContent = fs.readFileSync(\n path.join(fixturesDir, 'with-sentry.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, withSentryContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', true, true, true);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n // Content should remain unchanged\n expect(modifiedContent).toBe(withSentryContent);\n });\n\n it('should insert Sentry initialization after imports', async () => {\n const withImportsContent = fs.readFileSync(\n path.join(fixturesDir, 'with-imports.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, withImportsContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', true, false, false);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n\n // Check that the Sentry import is before the init call\n const sentryImportIndex = modifiedContent.indexOf(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n const sentryInitIndex = modifiedContent.indexOf('Sentry.init({');\n expect(sentryImportIndex).toBeLessThan(sentryInitIndex);\n });\n\n it('should handle files with no imports', async () => {\n const noImportsContent = fs.readFileSync(\n path.join(fixturesDir, 'no-imports.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, noImportsContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', false, true, false);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n expect(modifiedContent).toContain('Sentry.replayIntegration(');\n });\n\n it('should preserve existing code structure', async () => {\n const complexContent = fs.readFileSync(\n path.join(fixturesDir, 'complex.tsx'),\n 'utf8',\n );\n\n fs.writeFileSync(tmpFile, complexContent);\n\n await instrumentClientEntry(tmpFile, 'test-dsn', true, true, false);\n\n const modifiedContent = fs.readFileSync(tmpFile, 'utf8');\n\n expect(modifiedContent).toContain(\n 'import * as Sentry from \"@sentry/react-router\";',\n );\n expect(modifiedContent).toContain('Sentry.init({');\n\n // Original content should still be there\n expect(modifiedContent).toContain('startTransition');\n expect(modifiedContent).toContain('hydrateRoot');\n expect(modifiedContent).toContain('<StrictMode>');\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const fs = __importStar(require("fs"));
|
|
27
|
+
const path = __importStar(require("path"));
|
|
28
|
+
const vitest_1 = require("vitest");
|
|
29
|
+
const react_router_config_1 = require("../../../src/react-router/codemods/react-router-config");
|
|
30
|
+
vitest_1.vi.mock('@clack/prompts', () => ({
|
|
31
|
+
default: {
|
|
32
|
+
log: {
|
|
33
|
+
info: vitest_1.vi.fn(),
|
|
34
|
+
warn: vitest_1.vi.fn(),
|
|
35
|
+
success: vitest_1.vi.fn(),
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
}));
|
|
39
|
+
vitest_1.vi.mock('fs', async () => {
|
|
40
|
+
const actual = await vitest_1.vi.importActual('fs');
|
|
41
|
+
return {
|
|
42
|
+
...actual,
|
|
43
|
+
existsSync: vitest_1.vi.fn(),
|
|
44
|
+
promises: {
|
|
45
|
+
...actual.promises,
|
|
46
|
+
readFile: vitest_1.vi.fn(),
|
|
47
|
+
writeFile: vitest_1.vi.fn(),
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
(0, vitest_1.describe)('React Router Config File Instrumentation', () => {
|
|
52
|
+
const mockCwd = '/mock/project';
|
|
53
|
+
(0, vitest_1.beforeEach)(() => {
|
|
54
|
+
vitest_1.vi.clearAllMocks();
|
|
55
|
+
vitest_1.vi.spyOn(process, 'cwd').mockReturnValue(mockCwd);
|
|
56
|
+
});
|
|
57
|
+
(0, vitest_1.afterEach)(() => {
|
|
58
|
+
vitest_1.vi.restoreAllMocks();
|
|
59
|
+
});
|
|
60
|
+
(0, vitest_1.describe)('instrumentReactRouterConfig', () => {
|
|
61
|
+
(0, vitest_1.it)('should create new config file if it does not exist', async () => {
|
|
62
|
+
const writtenFiles = {};
|
|
63
|
+
vitest_1.vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
64
|
+
vitest_1.vi.mocked(fs.promises.writeFile).mockImplementation((filePath, content) => {
|
|
65
|
+
writtenFiles[filePath] = content;
|
|
66
|
+
return Promise.resolve();
|
|
67
|
+
});
|
|
68
|
+
const result = await (0, react_router_config_1.instrumentReactRouterConfig)(true);
|
|
69
|
+
(0, vitest_1.expect)(result.ssrWasChanged).toBe(false);
|
|
70
|
+
const configPath = path.join(mockCwd, 'react-router.config.ts');
|
|
71
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).toContain('ssr: true');
|
|
72
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).toContain('sentryOnBuildEnd');
|
|
73
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).toContain('buildEnd:');
|
|
74
|
+
});
|
|
75
|
+
(0, vitest_1.it)('should create .js config when TypeScript is not used', async () => {
|
|
76
|
+
const writtenFiles = {};
|
|
77
|
+
vitest_1.vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
78
|
+
vitest_1.vi.mocked(fs.promises.writeFile).mockImplementation((filePath, content) => {
|
|
79
|
+
writtenFiles[filePath] = content;
|
|
80
|
+
return Promise.resolve();
|
|
81
|
+
});
|
|
82
|
+
await (0, react_router_config_1.instrumentReactRouterConfig)(false);
|
|
83
|
+
const configPath = path.join(mockCwd, 'react-router.config.js');
|
|
84
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).toBeDefined();
|
|
85
|
+
// Verify JS config doesn't have TypeScript-only syntax
|
|
86
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).not.toContain('import type');
|
|
87
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).not.toContain('satisfies Config');
|
|
88
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).toContain('sentryOnBuildEnd');
|
|
89
|
+
(0, vitest_1.expect)(writtenFiles[configPath]).toContain('buildEnd:');
|
|
90
|
+
});
|
|
91
|
+
(0, vitest_1.it)('should detect and skip if Sentry content already exists', async () => {
|
|
92
|
+
const existingConfig = `import { sentryOnBuildEnd } from '@sentry/react-router';
|
|
93
|
+
|
|
94
|
+
export default {
|
|
95
|
+
ssr: true,
|
|
96
|
+
buildEnd: async ({ viteConfig, reactRouterConfig, buildManifest }) => {
|
|
97
|
+
await sentryOnBuildEnd({ viteConfig, reactRouterConfig, buildManifest });
|
|
98
|
+
}
|
|
99
|
+
};`;
|
|
100
|
+
vitest_1.vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
101
|
+
vitest_1.vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);
|
|
102
|
+
const result = await (0, react_router_config_1.instrumentReactRouterConfig)(true);
|
|
103
|
+
(0, vitest_1.expect)(result.ssrWasChanged).toBe(false);
|
|
104
|
+
});
|
|
105
|
+
(0, vitest_1.it)('should add buildEnd hook to existing config', async () => {
|
|
106
|
+
const existingConfig = `export default {
|
|
107
|
+
ssr: true,
|
|
108
|
+
async: false
|
|
109
|
+
};`;
|
|
110
|
+
const writtenFiles = {};
|
|
111
|
+
vitest_1.vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
112
|
+
vitest_1.vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);
|
|
113
|
+
vitest_1.vi.mocked(fs.promises.writeFile).mockImplementation((filePath, content) => {
|
|
114
|
+
writtenFiles[filePath] = content;
|
|
115
|
+
return Promise.resolve();
|
|
116
|
+
});
|
|
117
|
+
const result = await (0, react_router_config_1.instrumentReactRouterConfig)(true);
|
|
118
|
+
(0, vitest_1.expect)(result.ssrWasChanged).toBe(false);
|
|
119
|
+
const writtenConfig = Object.values(writtenFiles)[0];
|
|
120
|
+
(0, vitest_1.expect)(writtenConfig).toContain('sentryOnBuildEnd');
|
|
121
|
+
(0, vitest_1.expect)(writtenConfig).toContain('buildEnd:');
|
|
122
|
+
});
|
|
123
|
+
(0, vitest_1.it)('should set ssr: true if missing', async () => {
|
|
124
|
+
const existingConfig = `export default {
|
|
125
|
+
async: false
|
|
126
|
+
};`;
|
|
127
|
+
const writtenFiles = {};
|
|
128
|
+
vitest_1.vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
129
|
+
vitest_1.vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);
|
|
130
|
+
vitest_1.vi.mocked(fs.promises.writeFile).mockImplementation((filePath, content) => {
|
|
131
|
+
writtenFiles[filePath] = content;
|
|
132
|
+
return Promise.resolve();
|
|
133
|
+
});
|
|
134
|
+
const result = await (0, react_router_config_1.instrumentReactRouterConfig)(true);
|
|
135
|
+
(0, vitest_1.expect)(result.ssrWasChanged).toBe(true);
|
|
136
|
+
const writtenConfig = Object.values(writtenFiles)[0];
|
|
137
|
+
(0, vitest_1.expect)(writtenConfig).toContain('ssr: true');
|
|
138
|
+
});
|
|
139
|
+
(0, vitest_1.it)('should report ssrWasChanged when changing ssr from false to true', async () => {
|
|
140
|
+
const existingConfig = `export default {
|
|
141
|
+
ssr: false
|
|
142
|
+
};`;
|
|
143
|
+
const writtenFiles = {};
|
|
144
|
+
vitest_1.vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
145
|
+
vitest_1.vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);
|
|
146
|
+
vitest_1.vi.mocked(fs.promises.writeFile).mockImplementation((filePath, content) => {
|
|
147
|
+
writtenFiles[filePath] = content;
|
|
148
|
+
return Promise.resolve();
|
|
149
|
+
});
|
|
150
|
+
const result = await (0, react_router_config_1.instrumentReactRouterConfig)(true);
|
|
151
|
+
(0, vitest_1.expect)(result.ssrWasChanged).toBe(true);
|
|
152
|
+
const writtenConfig = Object.values(writtenFiles)[0];
|
|
153
|
+
(0, vitest_1.expect)(writtenConfig).toContain('ssr: true');
|
|
154
|
+
});
|
|
155
|
+
(0, vitest_1.it)('should throw error if buildEnd already exists', async () => {
|
|
156
|
+
const existingConfig = `export default {
|
|
157
|
+
ssr: true,
|
|
158
|
+
buildEnd: async () => {
|
|
159
|
+
console.log('existing hook');
|
|
160
|
+
}
|
|
161
|
+
};`;
|
|
162
|
+
vitest_1.vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
163
|
+
vitest_1.vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);
|
|
164
|
+
await (0, vitest_1.expect)((0, react_router_config_1.instrumentReactRouterConfig)(true)).rejects.toThrow('A buildEnd hook already exists');
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
//# sourceMappingURL=react-router-config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-router-config.test.js","sourceRoot":"","sources":["../../../../test/react-router/codemods/react-router-config.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\nimport { instrumentReactRouterConfig } from '../../../src/react-router/codemods/react-router-config';\n\nvi.mock('@clack/prompts', () => ({\n default: {\n log: {\n info: vi.fn(),\n warn: vi.fn(),\n success: vi.fn(),\n },\n },\n}));\nvi.mock('fs', async () => {\n const actual = await vi.importActual<typeof fs>('fs');\n return {\n ...actual,\n existsSync: vi.fn(),\n promises: {\n ...actual.promises,\n readFile: vi.fn(),\n writeFile: vi.fn(),\n },\n };\n});\n\ndescribe('React Router Config File Instrumentation', () => {\n const mockCwd = '/mock/project';\n\n beforeEach(() => {\n vi.clearAllMocks();\n vi.spyOn(process, 'cwd').mockReturnValue(mockCwd);\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n describe('instrumentReactRouterConfig', () => {\n it('should create new config file if it does not exist', async () => {\n const writtenFiles: Record<string, string> = {};\n\n vi.mocked(fs.existsSync).mockReturnValue(false);\n vi.mocked(fs.promises.writeFile).mockImplementation(\n (filePath, content) => {\n writtenFiles[filePath as string] = content as string;\n return Promise.resolve();\n },\n );\n\n const result = await instrumentReactRouterConfig(true);\n\n expect(result.ssrWasChanged).toBe(false);\n\n const configPath = path.join(mockCwd, 'react-router.config.ts');\n expect(writtenFiles[configPath]).toContain('ssr: true');\n expect(writtenFiles[configPath]).toContain('sentryOnBuildEnd');\n expect(writtenFiles[configPath]).toContain('buildEnd:');\n });\n\n it('should create .js config when TypeScript is not used', async () => {\n const writtenFiles: Record<string, string> = {};\n\n vi.mocked(fs.existsSync).mockReturnValue(false);\n vi.mocked(fs.promises.writeFile).mockImplementation(\n (filePath, content) => {\n writtenFiles[filePath as string] = content as string;\n return Promise.resolve();\n },\n );\n\n await instrumentReactRouterConfig(false);\n\n const configPath = path.join(mockCwd, 'react-router.config.js');\n expect(writtenFiles[configPath]).toBeDefined();\n // Verify JS config doesn't have TypeScript-only syntax\n expect(writtenFiles[configPath]).not.toContain('import type');\n expect(writtenFiles[configPath]).not.toContain('satisfies Config');\n expect(writtenFiles[configPath]).toContain('sentryOnBuildEnd');\n expect(writtenFiles[configPath]).toContain('buildEnd:');\n });\n\n it('should detect and skip if Sentry content already exists', async () => {\n const existingConfig = `import { sentryOnBuildEnd } from '@sentry/react-router';\n\nexport default {\n ssr: true,\n buildEnd: async ({ viteConfig, reactRouterConfig, buildManifest }) => {\n await sentryOnBuildEnd({ viteConfig, reactRouterConfig, buildManifest });\n }\n};`;\n\n vi.mocked(fs.existsSync).mockReturnValue(true);\n vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);\n\n const result = await instrumentReactRouterConfig(true);\n\n expect(result.ssrWasChanged).toBe(false);\n });\n\n it('should add buildEnd hook to existing config', async () => {\n const existingConfig = `export default {\n ssr: true,\n async: false\n};`;\n\n const writtenFiles: Record<string, string> = {};\n\n vi.mocked(fs.existsSync).mockReturnValue(true);\n vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);\n vi.mocked(fs.promises.writeFile).mockImplementation(\n (filePath, content) => {\n writtenFiles[filePath as string] = content as string;\n return Promise.resolve();\n },\n );\n\n const result = await instrumentReactRouterConfig(true);\n\n expect(result.ssrWasChanged).toBe(false);\n\n const writtenConfig = Object.values(writtenFiles)[0];\n expect(writtenConfig).toContain('sentryOnBuildEnd');\n expect(writtenConfig).toContain('buildEnd:');\n });\n\n it('should set ssr: true if missing', async () => {\n const existingConfig = `export default {\n async: false\n};`;\n\n const writtenFiles: Record<string, string> = {};\n\n vi.mocked(fs.existsSync).mockReturnValue(true);\n vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);\n vi.mocked(fs.promises.writeFile).mockImplementation(\n (filePath, content) => {\n writtenFiles[filePath as string] = content as string;\n return Promise.resolve();\n },\n );\n\n const result = await instrumentReactRouterConfig(true);\n\n expect(result.ssrWasChanged).toBe(true);\n\n const writtenConfig = Object.values(writtenFiles)[0];\n expect(writtenConfig).toContain('ssr: true');\n });\n\n it('should report ssrWasChanged when changing ssr from false to true', async () => {\n const existingConfig = `export default {\n ssr: false\n};`;\n\n const writtenFiles: Record<string, string> = {};\n\n vi.mocked(fs.existsSync).mockReturnValue(true);\n vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);\n vi.mocked(fs.promises.writeFile).mockImplementation(\n (filePath, content) => {\n writtenFiles[filePath as string] = content as string;\n return Promise.resolve();\n },\n );\n\n const result = await instrumentReactRouterConfig(true);\n\n expect(result.ssrWasChanged).toBe(true);\n\n const writtenConfig = Object.values(writtenFiles)[0];\n expect(writtenConfig).toContain('ssr: true');\n });\n\n it('should throw error if buildEnd already exists', async () => {\n const existingConfig = `export default {\n ssr: true,\n buildEnd: async () => {\n console.log('existing hook');\n }\n};`;\n\n vi.mocked(fs.existsSync).mockReturnValue(true);\n vi.mocked(fs.promises.readFile).mockResolvedValue(existingConfig);\n\n await expect(instrumentReactRouterConfig(true)).rejects.toThrow(\n 'A buildEnd hook already exists',\n );\n });\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|