@sentry/wizard 3.23.3 → 3.24.1
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 +14 -2
- package/dist/package.json +2 -2
- package/dist/src/nextjs/templates.js +1 -1
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/react-native/glob.js +24 -4
- package/dist/src/react-native/glob.js.map +1 -1
- package/dist/src/remix/codemods/express-server.d.ts +0 -4
- package/dist/src/remix/codemods/express-server.js +1 -80
- package/dist/src/remix/codemods/express-server.js.map +1 -1
- package/dist/src/remix/codemods/handle-error.js +2 -2
- package/dist/src/remix/codemods/handle-error.js.map +1 -1
- package/dist/src/remix/remix-wizard.js +62 -19
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/remix/sdk-example.js +1 -1
- package/dist/src/remix/sdk-example.js.map +1 -1
- package/dist/src/remix/sdk-setup.d.ts +5 -3
- package/dist/src/remix/sdk-setup.js +98 -38
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/remix/templates.d.ts +1 -1
- package/dist/src/remix/templates.js +1 -1
- package/dist/src/remix/templates.js.map +1 -1
- package/dist/src/remix/utils.d.ts +9 -3
- package/dist/src/remix/utils.js +39 -10
- package/dist/src/remix/utils.js.map +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
- package/dist/test/nextjs/templates.test.js +1 -1
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/package.json +2 -2
- package/src/nextjs/templates.ts +1 -1
- package/src/react-native/glob.ts +1 -1
- package/src/remix/codemods/express-server.ts +0 -121
- package/src/remix/codemods/handle-error.ts +3 -2
- package/src/remix/remix-wizard.ts +45 -17
- package/src/remix/sdk-example.ts +0 -2
- package/src/remix/sdk-setup.ts +125 -33
- package/src/remix/templates.ts +1 -1
- package/src/remix/utils.ts +57 -7
- package/src/sourcemaps/sourcemaps-wizard.ts +1 -1
- package/test/nextjs/templates.test.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.24.1
|
|
4
|
+
|
|
5
|
+
- fix(nextjs): Add trailing comma to `sentryUrl` option in `withSentryConfig` template (#601)
|
|
6
|
+
|
|
7
|
+
## 3.24.0
|
|
8
|
+
|
|
9
|
+
- feat(remix): Switch to OTEL setup (#593)
|
|
10
|
+
- feat(remix): Update `start` script for built-in Remix servers (#604)
|
|
11
|
+
- deps: Bump glob to `10.4.2` (#599)
|
|
12
|
+
|
|
3
13
|
## 3.23.3
|
|
4
14
|
|
|
5
15
|
- fix(nextjs): Fix Types of GlobalError (#592)
|
|
@@ -12,12 +22,14 @@
|
|
|
12
22
|
|
|
13
23
|
## 3.23.1
|
|
14
24
|
|
|
15
|
-
- fix(nextjs): Replace `url` with `sentryUrl` in `withSentryConfig` options
|
|
25
|
+
- fix(nextjs): Replace `url` with `sentryUrl` in `withSentryConfig` options
|
|
26
|
+
(#579)
|
|
16
27
|
|
|
17
28
|
## 3.23.0
|
|
18
29
|
|
|
19
30
|
- feat(apple): Disable build script sandboxing (#574)
|
|
20
|
-
- feat(reactnative): Added comment to add spotlight in Sentry.init for React
|
|
31
|
+
- feat(reactnative): Added comment to add spotlight in Sentry.init for React
|
|
32
|
+
Native config (#548)
|
|
21
33
|
- feat(reactnative): Added `withSentryConfig` Metro patch (#575)
|
|
22
34
|
|
|
23
35
|
## 3.22.3
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.24.1",
|
|
4
4
|
"homepage": "https://github.com/getsentry/sentry-wizard",
|
|
5
5
|
"repository": "https://github.com/getsentry/sentry-wizard",
|
|
6
6
|
"description": "Sentry wizard helping you to configure your project",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@sentry/node": "^7.69.0",
|
|
30
30
|
"axios": "1.6.0",
|
|
31
31
|
"chalk": "^2.4.1",
|
|
32
|
-
"glob": "^
|
|
32
|
+
"glob": "^8.1.0",
|
|
33
33
|
"inquirer": "^6.2.0",
|
|
34
34
|
"lodash": "^4.17.15",
|
|
35
35
|
"magicast": "^0.2.10",
|
|
@@ -8,7 +8,7 @@ var chalk_1 = __importDefault(require("chalk"));
|
|
|
8
8
|
var clack_utils_1 = require("../utils/clack-utils");
|
|
9
9
|
function getWithSentryConfigOptionsTemplate(_a) {
|
|
10
10
|
var orgSlug = _a.orgSlug, projectSlug = _a.projectSlug, selfHosted = _a.selfHosted, tunnelRoute = _a.tunnelRoute, sentryUrl = _a.sentryUrl;
|
|
11
|
-
return "{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"".concat(orgSlug, "\",\n project: \"").concat(projectSlug, "\",").concat(selfHosted ? "\n sentryUrl: \"".concat(sentryUrl, "\"") : '', "\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 // ").concat(tunnelRoute ? 'Route' : '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 ").concat(tunnelRoute ? '' : '// ', "tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\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 }");
|
|
11
|
+
return "{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"".concat(orgSlug, "\",\n project: \"").concat(projectSlug, "\",").concat(selfHosted ? "\n sentryUrl: \"".concat(sentryUrl, "\",") : '', "\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 // ").concat(tunnelRoute ? 'Route' : '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 ").concat(tunnelRoute ? '' : '// ', "tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\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 }");
|
|
12
12
|
}
|
|
13
13
|
exports.getWithSentryConfigOptionsTemplate = getWithSentryConfigOptionsTemplate;
|
|
14
14
|
function getNextjsConfigCjsTemplate(withSentryConfigOptionsTemplate) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/nextjs/templates.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { makeCodeSnippet } from '../utils/clack-utils';\n\ntype WithSentryConfigOptions = {\n orgSlug: string;\n projectSlug: string;\n selfHosted: boolean;\n sentryUrl: string;\n tunnelRoute: boolean;\n};\n\nexport function getWithSentryConfigOptionsTemplate({\n orgSlug,\n projectSlug,\n selfHosted,\n tunnelRoute,\n sentryUrl,\n}: WithSentryConfigOptions): string {\n return `{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"${orgSlug}\",\n project: \"${projectSlug}\",${\n selfHosted ? `\\n sentryUrl: \"${sentryUrl}\"` : ''\n }\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 // ${\n tunnelRoute ? 'Route' : 'Uncomment to route'\n } 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 ? '' : '// '}tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\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\nexport function getNextjsConfigCjsTemplate(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `const { withSentryConfig } = require(\"@sentry/nextjs\");\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nmodule.exports = withSentryConfig(\n nextConfig,\n ${withSentryConfigOptionsTemplate}\n);\n`;\n}\n\nexport function getNextjsConfigCjsAppendix(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// Injected content via Sentry wizard below\n\nconst { withSentryConfig } = require(\"@sentry/nextjs\");\n\nmodule.exports = withSentryConfig(\n module.exports,\n ${withSentryConfigOptionsTemplate}\n);\n`;\n}\n\nexport function getNextjsConfigEsmCopyPasteSnippet(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// next.config.mjs\nimport { withSentryConfig } from \"@sentry/nextjs\";\n\nexport default withSentryConfig(\n yourNextConfig,\n ${withSentryConfigOptionsTemplate}\n);\n`;\n}\n\nexport function getSentryConfigContents(\n dsn: string,\n config: 'server' | 'client' | 'edge',\n): string {\n let primer;\n if (config === 'server') {\n primer = `// 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 } else if (config === 'client') {\n primer = `// This file configures the initialization of Sentry on the client.\n// The config you add here will be used whenever a users loads a page in their browser.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n } else if (config === 'edge') {\n primer = `// 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\n let additionalOptions = '';\n if (config === 'client') {\n additionalOptions = `\n\n replaysOnErrorSampleRate: 1.0,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // You can remove this option if you're not planning to use the Sentry Session Replay feature:\n integrations: [\n Sentry.replayIntegration({\n // Additional Replay configuration goes in here, for example:\n maskAllText: true,\n blockAllMedia: true,\n }),\n ],`;\n }\n\n let spotlightOption = '';\n if (config === 'server') {\n spotlightOption = `\n\n // Uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: process.env.NODE_ENV === 'development',\n `;\n }\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `${primer}\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"${dsn}\",\n\n // Adjust this value in production, or use tracesSampler for greater control\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,${additionalOptions}${spotlightOption}\n});\n`;\n}\n\nexport function getSentryExamplePageContents(options: {\n selfHosted: boolean;\n sentryUrl: string;\n orgSlug: string;\n projectId: string;\n useClient: boolean;\n}): string {\n const issuesPageLink = options.selfHosted\n ? `${options.sentryUrl}organizations/${options.orgSlug}/issues/?project=${options.projectId}`\n : `https://${options.orgSlug}.sentry.io/issues/?project=${options.projectId}`;\n\n return `${\n options.useClient ? '\"use client\";\\n\\n' : ''\n }import Head from \"next/head\";\nimport * as Sentry from \"@sentry/nextjs\";\n\nexport default function Page() {\n return (\n <div>\n <Head>\n <title>Sentry Onboarding</title>\n <meta name=\"description\" content=\"Test Sentry for your Next.js app!\" />\n </Head>\n\n <main\n style={{\n minHeight: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <h1 style={{ fontSize: \"4rem\", margin: \"14px 0\" }}>\n <svg\n style={{\n height: \"1em\",\n }}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 200 44\"\n >\n <path\n fill=\"currentColor\"\n d=\"M124.32,28.28,109.56,9.22h-3.68V34.77h3.73V15.19l15.18,19.58h3.26V9.22h-3.73ZM87.15,23.54h13.23V20.22H87.14V12.53h14.93V9.21H83.34V34.77h18.92V31.45H87.14ZM71.59,20.3h0C66.44,19.06,65,18.08,65,15.7c0-2.14,1.89-3.59,4.71-3.59a12.06,12.06,0,0,1,7.07,2.55l2-2.83a14.1,14.1,0,0,0-9-3c-5.06,0-8.59,3-8.59,7.27,0,4.6,3,6.19,8.46,7.52C74.51,24.74,76,25.78,76,28.11s-2,3.77-5.09,3.77a12.34,12.34,0,0,1-8.3-3.26l-2.25,2.69a15.94,15.94,0,0,0,10.42,3.85c5.48,0,9-2.95,9-7.51C79.75,23.79,77.47,21.72,71.59,20.3ZM195.7,9.22l-7.69,12-7.64-12h-4.46L186,24.67V34.78h3.84V24.55L200,9.22Zm-64.63,3.46h8.37v22.1h3.84V12.68h8.37V9.22H131.08ZM169.41,24.8c3.86-1.07,6-3.77,6-7.63,0-4.91-3.59-8-9.38-8H154.67V34.76h3.8V25.58h6.45l6.48,9.2h4.44l-7-9.82Zm-10.95-2.5V12.6h7.17c3.74,0,5.88,1.77,5.88,4.84s-2.29,4.86-5.84,4.86Z M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z\"\n ></path>\n </svg>\n </h1>\n\n <p>Get started by sending us a sample error:</p>\n <button\n type=\"button\"\n style={{\n padding: \"12px\",\n cursor: \"pointer\",\n backgroundColor: \"#AD6CAA\",\n borderRadius: \"4px\",\n border: \"none\",\n color: \"white\",\n fontSize: \"14px\",\n margin: \"18px\",\n }}\n onClick={async () => {\n await Sentry.startSpan({\n name: 'Example Frontend Span',\n op: 'test'\n }, async () => {\n const res = await fetch(\"/api/sentry-example-api\");\n if (!res.ok) {\n throw new Error(\"Sentry Example Frontend Error\");\n }\n });\n }}\n >\n Throw error!\n </button>\n\n <p>\n Next, look for the error on the{\" \"}\n <a href=\"${issuesPageLink}\">Issues Page</a>.\n </p>\n <p style={{ marginTop: \"24px\" }}>\n For more information, see{\" \"}\n <a href=\"https://docs.sentry.io/platforms/javascript/guides/nextjs/\">\n https://docs.sentry.io/platforms/javascript/guides/nextjs/\n </a>\n </p>\n </main>\n </div>\n );\n}\n`;\n}\n\nexport function getSentryExampleApiRoute() {\n return `// A faulty API route to test Sentry's error monitoring\nexport default function handler(_req, res) {\n throw new Error(\"Sentry Example API Route Error\");\n res.status(200).json({ name: \"John Doe\" });\n}\n`;\n}\n\nexport function getSentryExampleAppDirApiRoute() {\n return `import { NextResponse } from \"next/server\";\n\nexport const dynamic = \"force-dynamic\";\n\n// A faulty API route to test Sentry's error monitoring\nexport function GET() {\n throw new Error(\"Sentry Example API Route Error\");\n return NextResponse.json({ data: \"Testing Sentry Error...\" });\n}\n`;\n}\n\nexport function getSentryDefaultUnderscoreErrorPage() {\n return `import * as Sentry from \"@sentry/nextjs\";\nimport Error from \"next/error\";\n\nconst CustomErrorComponent = (props) => {\n return <Error statusCode={props.statusCode} />;\n};\n\nCustomErrorComponent.getInitialProps = async (contextData) => {\n // In case this is running in a serverless function, await this in order to give Sentry\n // time to send the error before the lambda exits\n await Sentry.captureUnderscoreErrorException(contextData);\n\n // This will contain the status code of the response\n return Error.getInitialProps(contextData);\n};\n\nexport default CustomErrorComponent;\n`;\n}\n\nexport function getSimpleUnderscoreErrorCopyPasteSnippet() {\n return `\n${chalk.green(`import * as Sentry from '@sentry/nextjs';`)}\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (${chalk.green(\n `contextData`,\n )}) => {\n ${chalk.green('await Sentry.captureUnderscoreErrorException(contextData);')}\n\n ${chalk.dim('// ...other getInitialProps code')}\n};\n`;\n}\n\nexport function getFullUnderscoreErrorCopyPasteSnippet(isTs: boolean) {\n return `\nimport * as Sentry from '@sentry/nextjs';${\n isTs ? '\\nimport type { NextPageContext } from \"next\";' : ''\n }\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (contextData${\n isTs ? ': NextPageContext' : ''\n }) => {\n await Sentry.captureUnderscoreErrorException(contextData);\n};\n`;\n}\n\nexport function getInstrumentationHookContent(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return `export async function register() {\n if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config');\n }\n\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config');\n }\n}\n`;\n}\n\nexport function getInstrumentationHookCopyPasteSnippet(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return makeCodeSnippet(true, (unchanged, plus) => {\n return unchanged(`export ${plus('async')} function register() {\n ${plus(`if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config');\n }\n\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config');\n }`)}\n}`);\n });\n}\n\nexport function getSentryDefaultGlobalErrorPage(isTs: boolean) {\n return isTs\n ? `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({ error }: { error: Error & { digest?: string } }) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html>\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}`\n : `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({ error }) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html>\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}\n`;\n}\n\nexport function getGlobalErrorCopyPasteSnippet(isTs: boolean) {\n if (isTs) {\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green(\n '{ error }: { error: Error }',\n )}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n } else {\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green('{ error }')}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/nextjs/templates.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { makeCodeSnippet } from '../utils/clack-utils';\n\ntype WithSentryConfigOptions = {\n orgSlug: string;\n projectSlug: string;\n selfHosted: boolean;\n sentryUrl: string;\n tunnelRoute: boolean;\n};\n\nexport function getWithSentryConfigOptionsTemplate({\n orgSlug,\n projectSlug,\n selfHosted,\n tunnelRoute,\n sentryUrl,\n}: WithSentryConfigOptions): string {\n return `{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"${orgSlug}\",\n project: \"${projectSlug}\",${\n selfHosted ? `\\n sentryUrl: \"${sentryUrl}\",` : ''\n }\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 // ${\n tunnelRoute ? 'Route' : 'Uncomment to route'\n } 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 ? '' : '// '}tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\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\nexport function getNextjsConfigCjsTemplate(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `const { withSentryConfig } = require(\"@sentry/nextjs\");\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nmodule.exports = withSentryConfig(\n nextConfig,\n ${withSentryConfigOptionsTemplate}\n);\n`;\n}\n\nexport function getNextjsConfigCjsAppendix(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// Injected content via Sentry wizard below\n\nconst { withSentryConfig } = require(\"@sentry/nextjs\");\n\nmodule.exports = withSentryConfig(\n module.exports,\n ${withSentryConfigOptionsTemplate}\n);\n`;\n}\n\nexport function getNextjsConfigEsmCopyPasteSnippet(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// next.config.mjs\nimport { withSentryConfig } from \"@sentry/nextjs\";\n\nexport default withSentryConfig(\n yourNextConfig,\n ${withSentryConfigOptionsTemplate}\n);\n`;\n}\n\nexport function getSentryConfigContents(\n dsn: string,\n config: 'server' | 'client' | 'edge',\n): string {\n let primer;\n if (config === 'server') {\n primer = `// 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 } else if (config === 'client') {\n primer = `// This file configures the initialization of Sentry on the client.\n// The config you add here will be used whenever a users loads a page in their browser.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n } else if (config === 'edge') {\n primer = `// 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\n let additionalOptions = '';\n if (config === 'client') {\n additionalOptions = `\n\n replaysOnErrorSampleRate: 1.0,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // You can remove this option if you're not planning to use the Sentry Session Replay feature:\n integrations: [\n Sentry.replayIntegration({\n // Additional Replay configuration goes in here, for example:\n maskAllText: true,\n blockAllMedia: true,\n }),\n ],`;\n }\n\n let spotlightOption = '';\n if (config === 'server') {\n spotlightOption = `\n\n // Uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: process.env.NODE_ENV === 'development',\n `;\n }\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `${primer}\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"${dsn}\",\n\n // Adjust this value in production, or use tracesSampler for greater control\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,${additionalOptions}${spotlightOption}\n});\n`;\n}\n\nexport function getSentryExamplePageContents(options: {\n selfHosted: boolean;\n sentryUrl: string;\n orgSlug: string;\n projectId: string;\n useClient: boolean;\n}): string {\n const issuesPageLink = options.selfHosted\n ? `${options.sentryUrl}organizations/${options.orgSlug}/issues/?project=${options.projectId}`\n : `https://${options.orgSlug}.sentry.io/issues/?project=${options.projectId}`;\n\n return `${\n options.useClient ? '\"use client\";\\n\\n' : ''\n }import Head from \"next/head\";\nimport * as Sentry from \"@sentry/nextjs\";\n\nexport default function Page() {\n return (\n <div>\n <Head>\n <title>Sentry Onboarding</title>\n <meta name=\"description\" content=\"Test Sentry for your Next.js app!\" />\n </Head>\n\n <main\n style={{\n minHeight: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <h1 style={{ fontSize: \"4rem\", margin: \"14px 0\" }}>\n <svg\n style={{\n height: \"1em\",\n }}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 200 44\"\n >\n <path\n fill=\"currentColor\"\n d=\"M124.32,28.28,109.56,9.22h-3.68V34.77h3.73V15.19l15.18,19.58h3.26V9.22h-3.73ZM87.15,23.54h13.23V20.22H87.14V12.53h14.93V9.21H83.34V34.77h18.92V31.45H87.14ZM71.59,20.3h0C66.44,19.06,65,18.08,65,15.7c0-2.14,1.89-3.59,4.71-3.59a12.06,12.06,0,0,1,7.07,2.55l2-2.83a14.1,14.1,0,0,0-9-3c-5.06,0-8.59,3-8.59,7.27,0,4.6,3,6.19,8.46,7.52C74.51,24.74,76,25.78,76,28.11s-2,3.77-5.09,3.77a12.34,12.34,0,0,1-8.3-3.26l-2.25,2.69a15.94,15.94,0,0,0,10.42,3.85c5.48,0,9-2.95,9-7.51C79.75,23.79,77.47,21.72,71.59,20.3ZM195.7,9.22l-7.69,12-7.64-12h-4.46L186,24.67V34.78h3.84V24.55L200,9.22Zm-64.63,3.46h8.37v22.1h3.84V12.68h8.37V9.22H131.08ZM169.41,24.8c3.86-1.07,6-3.77,6-7.63,0-4.91-3.59-8-9.38-8H154.67V34.76h3.8V25.58h6.45l6.48,9.2h4.44l-7-9.82Zm-10.95-2.5V12.6h7.17c3.74,0,5.88,1.77,5.88,4.84s-2.29,4.86-5.84,4.86Z M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z\"\n ></path>\n </svg>\n </h1>\n\n <p>Get started by sending us a sample error:</p>\n <button\n type=\"button\"\n style={{\n padding: \"12px\",\n cursor: \"pointer\",\n backgroundColor: \"#AD6CAA\",\n borderRadius: \"4px\",\n border: \"none\",\n color: \"white\",\n fontSize: \"14px\",\n margin: \"18px\",\n }}\n onClick={async () => {\n await Sentry.startSpan({\n name: 'Example Frontend Span',\n op: 'test'\n }, async () => {\n const res = await fetch(\"/api/sentry-example-api\");\n if (!res.ok) {\n throw new Error(\"Sentry Example Frontend Error\");\n }\n });\n }}\n >\n Throw error!\n </button>\n\n <p>\n Next, look for the error on the{\" \"}\n <a href=\"${issuesPageLink}\">Issues Page</a>.\n </p>\n <p style={{ marginTop: \"24px\" }}>\n For more information, see{\" \"}\n <a href=\"https://docs.sentry.io/platforms/javascript/guides/nextjs/\">\n https://docs.sentry.io/platforms/javascript/guides/nextjs/\n </a>\n </p>\n </main>\n </div>\n );\n}\n`;\n}\n\nexport function getSentryExampleApiRoute() {\n return `// A faulty API route to test Sentry's error monitoring\nexport default function handler(_req, res) {\n throw new Error(\"Sentry Example API Route Error\");\n res.status(200).json({ name: \"John Doe\" });\n}\n`;\n}\n\nexport function getSentryExampleAppDirApiRoute() {\n return `import { NextResponse } from \"next/server\";\n\nexport const dynamic = \"force-dynamic\";\n\n// A faulty API route to test Sentry's error monitoring\nexport function GET() {\n throw new Error(\"Sentry Example API Route Error\");\n return NextResponse.json({ data: \"Testing Sentry Error...\" });\n}\n`;\n}\n\nexport function getSentryDefaultUnderscoreErrorPage() {\n return `import * as Sentry from \"@sentry/nextjs\";\nimport Error from \"next/error\";\n\nconst CustomErrorComponent = (props) => {\n return <Error statusCode={props.statusCode} />;\n};\n\nCustomErrorComponent.getInitialProps = async (contextData) => {\n // In case this is running in a serverless function, await this in order to give Sentry\n // time to send the error before the lambda exits\n await Sentry.captureUnderscoreErrorException(contextData);\n\n // This will contain the status code of the response\n return Error.getInitialProps(contextData);\n};\n\nexport default CustomErrorComponent;\n`;\n}\n\nexport function getSimpleUnderscoreErrorCopyPasteSnippet() {\n return `\n${chalk.green(`import * as Sentry from '@sentry/nextjs';`)}\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (${chalk.green(\n `contextData`,\n )}) => {\n ${chalk.green('await Sentry.captureUnderscoreErrorException(contextData);')}\n\n ${chalk.dim('// ...other getInitialProps code')}\n};\n`;\n}\n\nexport function getFullUnderscoreErrorCopyPasteSnippet(isTs: boolean) {\n return `\nimport * as Sentry from '@sentry/nextjs';${\n isTs ? '\\nimport type { NextPageContext } from \"next\";' : ''\n }\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (contextData${\n isTs ? ': NextPageContext' : ''\n }) => {\n await Sentry.captureUnderscoreErrorException(contextData);\n};\n`;\n}\n\nexport function getInstrumentationHookContent(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return `export async function register() {\n if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config');\n }\n\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config');\n }\n}\n`;\n}\n\nexport function getInstrumentationHookCopyPasteSnippet(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return makeCodeSnippet(true, (unchanged, plus) => {\n return unchanged(`export ${plus('async')} function register() {\n ${plus(`if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config');\n }\n\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config');\n }`)}\n}`);\n });\n}\n\nexport function getSentryDefaultGlobalErrorPage(isTs: boolean) {\n return isTs\n ? `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({ error }: { error: Error & { digest?: string } }) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html>\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}`\n : `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({ error }) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html>\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}\n`;\n}\n\nexport function getGlobalErrorCopyPasteSnippet(isTs: boolean) {\n if (isTs) {\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green(\n '{ error }: { error: Error }',\n )}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n } else {\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green('{ error }')}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n }\n}\n"]}
|
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
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;
|
|
4
24
|
};
|
|
5
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
26
|
exports.getFirstMatchedPath = exports.APP_BUILD_GRADLE = exports.XCODE_PROJECT = void 0;
|
|
7
|
-
var
|
|
27
|
+
var glob = __importStar(require("glob"));
|
|
8
28
|
exports.XCODE_PROJECT = 'ios/*.xcodeproj/project.pbxproj';
|
|
9
29
|
exports.APP_BUILD_GRADLE = '**/app/build.gradle';
|
|
10
30
|
var IGNORE_PATTERNS = ['node_modules/**', 'ios/Pods/**', '**/Pods/**'];
|
|
11
31
|
function getFirstMatchedPath(pattern) {
|
|
12
|
-
var matches =
|
|
32
|
+
var matches = glob.sync(pattern, {
|
|
13
33
|
ignore: IGNORE_PATTERNS,
|
|
14
34
|
});
|
|
15
35
|
return matches[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glob.js","sourceRoot":"","sources":["../../../src/react-native/glob.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"glob.js","sourceRoot":"","sources":["../../../src/react-native/glob.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAA6B;AAEhB,QAAA,aAAa,GAAG,iCAAiC,CAAC;AAClD,QAAA,gBAAgB,GAAG,qBAAqB,CAAC;AAEtD,IAAM,eAAe,GAAG,CAAC,iBAAiB,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;AACzE,SAAgB,mBAAmB,CAAC,OAAe;IACjD,IAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QACjC,MAAM,EAAE,eAAe;KACxB,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAND,kDAMC","sourcesContent":["import * as glob from 'glob';\n\nexport const XCODE_PROJECT = 'ios/*.xcodeproj/project.pbxproj';\nexport const APP_BUILD_GRADLE = '**/app/build.gradle';\n\nconst IGNORE_PATTERNS = ['node_modules/**', 'ios/Pods/**', '**/Pods/**'];\nexport function getFirstMatchedPath(pattern: string): string | undefined {\n const matches = glob.sync(pattern, {\n ignore: IGNORE_PATTERNS,\n });\n\n return matches[0];\n}\n"]}
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
import * as recast from 'recast';
|
|
2
|
-
import { ProxifiedImportItem } from 'magicast';
|
|
3
1
|
export declare function findCustomExpressServerImplementation(): Promise<string | null>;
|
|
4
|
-
export declare function instrumentExpressCreateRequestHandler(expressServerPath: string): Promise<boolean>;
|
|
5
|
-
export declare function wrapCreateRequestHandlerWithSentry(createRequestHandlerImport: ProxifiedImportItem | undefined): recast.types.namedTypes.VariableDeclaration | undefined;
|
|
@@ -58,19 +58,10 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
58
58
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
62
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
63
|
-
};
|
|
64
61
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
-
exports.
|
|
66
|
-
// @ts-expect-error - clack is ESM and TS complains about that. It works though
|
|
67
|
-
var prompts_1 = __importDefault(require("@clack/prompts"));
|
|
68
|
-
var chalk_1 = __importDefault(require("chalk"));
|
|
69
|
-
var recast = __importStar(require("recast"));
|
|
70
|
-
var ast_types_1 = require("ast-types");
|
|
62
|
+
exports.findCustomExpressServerImplementation = void 0;
|
|
71
63
|
var magicast_1 = require("magicast");
|
|
72
64
|
var fs = __importStar(require("fs"));
|
|
73
|
-
var utils_1 = require("../utils");
|
|
74
65
|
var ast_utils_1 = require("../../utils/ast-utils");
|
|
75
66
|
// Try to find the Express server implementation that contains `createRequestHandler` from `@remix-run/express`
|
|
76
67
|
function findCustomExpressServerImplementation() {
|
|
@@ -118,74 +109,4 @@ function findCustomExpressServerImplementation() {
|
|
|
118
109
|
});
|
|
119
110
|
}
|
|
120
111
|
exports.findCustomExpressServerImplementation = findCustomExpressServerImplementation;
|
|
121
|
-
// Wrap createRequestHandler with `wrapExpressCreateRequestHandler` from `@sentry/remix`
|
|
122
|
-
function instrumentExpressCreateRequestHandler(expressServerPath) {
|
|
123
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
124
|
-
var originalExpressServerMod, createRequestHandlerImport, insertionIndex, createRequestHandlerConst, e_1;
|
|
125
|
-
return __generator(this, function (_a) {
|
|
126
|
-
switch (_a.label) {
|
|
127
|
-
case 0: return [4 /*yield*/, (0, magicast_1.loadFile)(expressServerPath)];
|
|
128
|
-
case 1:
|
|
129
|
-
originalExpressServerMod = _a.sent();
|
|
130
|
-
if ((0, utils_1.hasSentryContent)((0, magicast_1.generateCode)(originalExpressServerMod.$ast).code, originalExpressServerMod.$code)) {
|
|
131
|
-
prompts_1.default.log.warn("Express server in ".concat(chalk_1.default.cyan(expressServerPath), " already has Sentry instrumentation. Skipping."));
|
|
132
|
-
return [2 /*return*/, false];
|
|
133
|
-
}
|
|
134
|
-
originalExpressServerMod.imports.$add({
|
|
135
|
-
from: '@sentry/remix',
|
|
136
|
-
imported: 'wrapExpressCreateRequestHandler',
|
|
137
|
-
local: 'wrapExpressCreateRequestHandler',
|
|
138
|
-
});
|
|
139
|
-
createRequestHandlerImport = originalExpressServerMod.imports.$items.find(function (imp) {
|
|
140
|
-
return imp.from === '@remix-run/express' &&
|
|
141
|
-
imp.imported === 'createRequestHandler';
|
|
142
|
-
});
|
|
143
|
-
(0, ast_types_1.visit)(originalExpressServerMod.$ast, {
|
|
144
|
-
visitIdentifier: function (path) {
|
|
145
|
-
if (path.value.name === 'createRequestHandler' &&
|
|
146
|
-
path.parentPath.value.type === 'CallExpression') {
|
|
147
|
-
path.value.name = 'sentryCreateRequestHandler';
|
|
148
|
-
}
|
|
149
|
-
this.traverse(path);
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
insertionIndex = (0, utils_1.getInitCallInsertionIndex)(originalExpressServerMod.$ast);
|
|
153
|
-
createRequestHandlerConst = wrapCreateRequestHandlerWithSentry(createRequestHandlerImport);
|
|
154
|
-
if (!createRequestHandlerConst) {
|
|
155
|
-
// Todo: throw error
|
|
156
|
-
}
|
|
157
|
-
originalExpressServerMod.$ast.body.splice(insertionIndex, 0,
|
|
158
|
-
// @ts-expect-error - string works here because the AST is proxified by magicast
|
|
159
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
160
|
-
createRequestHandlerConst);
|
|
161
|
-
_a.label = 2;
|
|
162
|
-
case 2:
|
|
163
|
-
_a.trys.push([2, 4, , 5]);
|
|
164
|
-
return [4 /*yield*/, (0, magicast_1.writeFile)(originalExpressServerMod.$ast, expressServerPath)];
|
|
165
|
-
case 3:
|
|
166
|
-
_a.sent();
|
|
167
|
-
prompts_1.default.log.info("Successfully instrumented Express server in ".concat(chalk_1.default.cyan(expressServerPath), "."));
|
|
168
|
-
return [3 /*break*/, 5];
|
|
169
|
-
case 4:
|
|
170
|
-
e_1 = _a.sent();
|
|
171
|
-
prompts_1.default.log.warn("Could not write to Express server in ".concat(chalk_1.default.cyan(expressServerPath), "."));
|
|
172
|
-
throw e_1;
|
|
173
|
-
case 5: return [2 /*return*/, true];
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
exports.instrumentExpressCreateRequestHandler = instrumentExpressCreateRequestHandler;
|
|
179
|
-
// Wrap `createRequestHandler` with `wrapExpressCreateRequestHandler` and set const name to `sentryCreateRequestHandler`
|
|
180
|
-
function wrapCreateRequestHandlerWithSentry(createRequestHandlerImport) {
|
|
181
|
-
if (!createRequestHandlerImport) {
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
var createRequestHandler = createRequestHandlerImport.local;
|
|
185
|
-
var wrapCreateRequestHandler = recast.types.builders.callExpression(recast.types.builders.identifier('wrapExpressCreateRequestHandler'), [recast.types.builders.identifier(createRequestHandler)]);
|
|
186
|
-
return recast.types.builders.variableDeclaration('const', [
|
|
187
|
-
recast.types.builders.variableDeclarator(recast.types.builders.identifier('sentryCreateRequestHandler'), wrapCreateRequestHandler),
|
|
188
|
-
]);
|
|
189
|
-
}
|
|
190
|
-
exports.wrapCreateRequestHandlerWithSentry = wrapCreateRequestHandlerWithSentry;
|
|
191
112
|
//# sourceMappingURL=express-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express-server.js","sourceRoot":"","sources":["../../../../src/remix/codemods/express-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"express-server.js","sourceRoot":"","sources":["../../../../src/remix/codemods/express-server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAGkB;AAClB,qCAAyB;AAEzB,mDAAiD;AAEjD,+GAA+G;AAC/G,SAAsB,qCAAqC;;;;;;oBACnD,aAAa,GAAG;wBACpB,QAAQ;wBACR,cAAc;wBACd,YAAY;wBACZ,kBAAkB;qBACnB,CAAC;0BAEkC,EAAb,+BAAa;;;yBAAb,CAAA,2BAAa,CAAA;oBAAzB,QAAQ;oBACX,QAAQ,GAAG,IAAA,oBAAQ,EAAC,QAAQ,CAAC,CAAC;oBAEpC,IAAI,CAAC,QAAQ,EAAE;wBACb,wBAAS;qBACV;oBAEK,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBAEvC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;wBACtB,wBAAS;qBACV;oBAEe,qBAAM,IAAA,mBAAQ,EAAC,QAAQ,CAAC,EAAA;;oBAAlC,OAAO,GAAG,SAAwB;oBAClC,0BAA0B,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAC5D,UAAC,GAAG;wBACF,OAAA,GAAG,CAAC,IAAI,KAAK,oBAAoB;4BACjC,GAAG,CAAC,QAAQ,KAAK,sBAAsB;oBADvC,CACuC,CAC1C,CAAC;oBAEF,IAAI,0BAA0B,EAAE;wBAC9B,sBAAO,QAAQ,EAAC;qBACjB;;;oBAtBoB,IAAa,CAAA;;wBAyBpC,sBAAO,IAAI,EAAC;;;;CACb;AAlCD,sFAkCC","sourcesContent":["import {\n loadFile,\n // @ts-expect-error - magicast is ESM and TS complains about that. It works though\n} from 'magicast';\nimport * as fs from 'fs';\n\nimport { findFile } from '../../utils/ast-utils';\n\n// Try to find the Express server implementation that contains `createRequestHandler` from `@remix-run/express`\nexport async function findCustomExpressServerImplementation() {\n const possiblePaths = [\n 'server',\n 'server/index',\n 'app/server',\n 'app/server/index',\n ];\n\n for (const filePath of possiblePaths) {\n const filename = findFile(filePath);\n\n if (!filename) {\n continue;\n }\n\n const fileStat = fs.statSync(filename);\n\n if (!fileStat.isFile()) {\n continue;\n }\n\n const fileMod = await loadFile(filename);\n const createRequestHandlerImport = fileMod.imports.$items.find(\n (imp) =>\n imp.from === '@remix-run/express' &&\n imp.imported === 'createRequestHandler',\n );\n\n if (createRequestHandlerImport) {\n return filename;\n }\n }\n\n return null;\n}\n"]}
|
|
@@ -50,12 +50,12 @@ function instrumentHandleError(originalEntryServerMod, serverEntryFilename) {
|
|
|
50
50
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
51
51
|
var implementation = recast.parse(templates_1.HANDLE_ERROR_TEMPLATE_V2).program
|
|
52
52
|
.body[0];
|
|
53
|
-
originalEntryServerModAST.body.splice((0, utils_1.
|
|
53
|
+
originalEntryServerModAST.body.splice((0, utils_1.getAfterImportsInsertionIndex)(originalEntryServerModAST), 0,
|
|
54
54
|
// @ts-expect-error - string works here because the AST is proxified by magicast
|
|
55
55
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
56
56
|
recast.types.builders.exportNamedDeclaration(implementation));
|
|
57
57
|
}
|
|
58
|
-
else if ((0, utils_1.hasSentryContent)((0, magicast_1.generateCode)(handleErrorFunction).code, originalEntryServerMod.$code)) {
|
|
58
|
+
else if ((0, utils_1.hasSentryContent)((0, magicast_1.generateCode)(handleErrorFunction).code, originalEntryServerMod.$code, 'captureRemixServerException')) {
|
|
59
59
|
return false;
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-error.js","sourceRoot":"","sources":["../../../../src/remix/codemods/handle-error.ts"],"names":[],"mappings":";AAAA,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAM5D,6CAAiC;AAEjC,0CAAwD;AACxD,
|
|
1
|
+
{"version":3,"file":"handle-error.js","sourceRoot":"","sources":["../../../../src/remix/codemods/handle-error.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport type { ProxifiedModule } from 'magicast';\nimport type { Program } from '@babel/types';\n\nimport * as recast from 'recast';\n\nimport { HANDLE_ERROR_TEMPLATE_V2 } from '../templates';\nimport { getAfterImportsInsertionIndex, hasSentryContent } from '../utils';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode } from 'magicast';\n\nexport function instrumentHandleError(\n originalEntryServerMod: ProxifiedModule<any>,\n serverEntryFilename: string,\n): boolean {\n const originalEntryServerModAST = originalEntryServerMod.$ast as Program;\n\n const handleErrorFunction = originalEntryServerModAST.body.find(\n (node) =>\n node.type === 'ExportNamedDeclaration' &&\n node.declaration?.type === 'FunctionDeclaration' &&\n node.declaration.id?.name === 'handleError',\n );\n\n if (!handleErrorFunction) {\n clack.log.warn(\n `Could not find function ${chalk.cyan('handleError')} in ${chalk.cyan(\n serverEntryFilename,\n )}. Creating one for you.`,\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const implementation = recast.parse(HANDLE_ERROR_TEMPLATE_V2).program\n .body[0];\n\n originalEntryServerModAST.body.splice(\n getAfterImportsInsertionIndex(originalEntryServerModAST),\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n recast.types.builders.exportNamedDeclaration(implementation),\n );\n } else if (\n hasSentryContent(\n generateCode(handleErrorFunction).code,\n originalEntryServerMod.$code,\n 'captureRemixServerException',\n )\n ) {\n return false;\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const implementation = recast.parse(HANDLE_ERROR_TEMPLATE_V2).program\n .body[0];\n\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n handleErrorFunction.declaration.body.body.unshift(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n recast.parse(HANDLE_ERROR_TEMPLATE_V2).program.body[0].body.body[0],\n );\n\n // First parameter is the error\n //\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n handleErrorFunction.declaration.params[0] = implementation.params[0];\n\n // Second parameter is the request inside an object\n // Merging the object properties to make sure it includes request\n //\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (handleErrorFunction.declaration.params?.[1]?.properties) {\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n handleErrorFunction.declaration.params[1].properties.push(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n implementation.params[1].properties[0],\n );\n } else {\n // Create second parameter if it doesn't exist\n //\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n handleErrorFunction.declaration.params[1] = implementation.params[1];\n }\n }\n\n return true;\n}\n"]}
|
|
@@ -66,7 +66,7 @@ function runRemixWizard(options) {
|
|
|
66
66
|
exports.runRemixWizard = runRemixWizard;
|
|
67
67
|
function runRemixWizardWithTelemetry(options) {
|
|
68
68
|
return __awaiter(this, void 0, void 0, function () {
|
|
69
|
-
var remixConfig, packageJson, _a, selectedProject, authToken, sentryUrl, selfHosted, dsn, isTS, isV2, viteConfig, shouldCreateExamplePage;
|
|
69
|
+
var remixConfig, packageJson, _a, selectedProject, authToken, sentryUrl, selfHosted, dsn, isTS, isV2, viteConfig, instrumentationFile, serverFileInstrumented, shouldCreateExamplePage;
|
|
70
70
|
var _this = this;
|
|
71
71
|
return __generator(this, function (_b) {
|
|
72
72
|
switch (_b.label) {
|
|
@@ -215,19 +215,20 @@ function runRemixWizardWithTelemetry(options) {
|
|
|
215
215
|
}); })];
|
|
216
216
|
case 13:
|
|
217
217
|
_b.sent();
|
|
218
|
-
|
|
218
|
+
instrumentationFile = '';
|
|
219
|
+
return [4 /*yield*/, (0, telemetry_1.traceStep)('Create server instrumentation file', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
219
220
|
var e_5;
|
|
220
221
|
return __generator(this, function (_a) {
|
|
221
222
|
switch (_a.label) {
|
|
222
223
|
case 0:
|
|
223
224
|
_a.trys.push([0, 2, , 3]);
|
|
224
|
-
return [4 /*yield*/, (0, sdk_setup_1.
|
|
225
|
+
return [4 /*yield*/, (0, sdk_setup_1.createServerInstrumentationFile)(dsn)];
|
|
225
226
|
case 1:
|
|
226
|
-
_a.sent();
|
|
227
|
+
instrumentationFile = _a.sent();
|
|
227
228
|
return [3 /*break*/, 3];
|
|
228
229
|
case 2:
|
|
229
230
|
e_5 = _a.sent();
|
|
230
|
-
prompts_1.default.log.warn(
|
|
231
|
+
prompts_1.default.log.warn('Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/');
|
|
231
232
|
(0, debug_1.debug)(e_5);
|
|
232
233
|
return [3 /*break*/, 3];
|
|
233
234
|
case 3: return [2 /*return*/];
|
|
@@ -236,23 +237,20 @@ function runRemixWizardWithTelemetry(options) {
|
|
|
236
237
|
}); })];
|
|
237
238
|
case 14:
|
|
238
239
|
_b.sent();
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
serverFileInstrumented = false;
|
|
241
|
+
return [4 /*yield*/, (0, telemetry_1.traceStep)('Create server instrumentation file and import it', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
242
|
+
var e_6;
|
|
241
243
|
return __generator(this, function (_a) {
|
|
242
244
|
switch (_a.label) {
|
|
243
245
|
case 0:
|
|
244
246
|
_a.trys.push([0, 2, , 3]);
|
|
245
|
-
|
|
246
|
-
if (!hasExpressAdapter) {
|
|
247
|
-
return [2 /*return*/];
|
|
248
|
-
}
|
|
249
|
-
return [4 /*yield*/, (0, sdk_setup_1.instrumentExpressServer)()];
|
|
247
|
+
return [4 /*yield*/, (0, sdk_setup_1.insertServerInstrumentationFile)(dsn)];
|
|
250
248
|
case 1:
|
|
251
|
-
_a.sent();
|
|
249
|
+
serverFileInstrumented = _a.sent();
|
|
252
250
|
return [3 /*break*/, 3];
|
|
253
251
|
case 2:
|
|
254
252
|
e_6 = _a.sent();
|
|
255
|
-
prompts_1.default.log.warn(
|
|
253
|
+
prompts_1.default.log.warn('Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/');
|
|
256
254
|
(0, debug_1.debug)(e_6);
|
|
257
255
|
return [3 /*break*/, 3];
|
|
258
256
|
case 3: return [2 /*return*/];
|
|
@@ -261,10 +259,55 @@ function runRemixWizardWithTelemetry(options) {
|
|
|
261
259
|
}); })];
|
|
262
260
|
case 15:
|
|
263
261
|
_b.sent();
|
|
264
|
-
return [
|
|
262
|
+
if (!(!serverFileInstrumented && instrumentationFile)) return [3 /*break*/, 17];
|
|
263
|
+
return [4 /*yield*/, (0, telemetry_1.traceStep)('Update `start` script to import instrumentation file.', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
264
|
+
var e_7;
|
|
265
|
+
return __generator(this, function (_a) {
|
|
266
|
+
switch (_a.label) {
|
|
267
|
+
case 0:
|
|
268
|
+
_a.trys.push([0, 2, , 3]);
|
|
269
|
+
return [4 /*yield*/, (0, sdk_setup_1.updateStartScript)(instrumentationFile)];
|
|
270
|
+
case 1:
|
|
271
|
+
_a.sent();
|
|
272
|
+
return [3 /*break*/, 3];
|
|
273
|
+
case 2:
|
|
274
|
+
e_7 = _a.sent();
|
|
275
|
+
prompts_1.default.log
|
|
276
|
+
.warn("Could not automatically add Sentry initialization to server entry.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/");
|
|
277
|
+
(0, debug_1.debug)(e_7);
|
|
278
|
+
return [3 /*break*/, 3];
|
|
279
|
+
case 3: return [2 /*return*/];
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}); })];
|
|
265
283
|
case 16:
|
|
284
|
+
_b.sent();
|
|
285
|
+
_b.label = 17;
|
|
286
|
+
case 17: return [4 /*yield*/, (0, telemetry_1.traceStep)('Instrument server `handleError`', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
287
|
+
var e_8;
|
|
288
|
+
return __generator(this, function (_a) {
|
|
289
|
+
switch (_a.label) {
|
|
290
|
+
case 0:
|
|
291
|
+
_a.trys.push([0, 2, , 3]);
|
|
292
|
+
return [4 /*yield*/, (0, sdk_setup_1.instrumentSentryOnEntryServer)(isV2, isTS)];
|
|
293
|
+
case 1:
|
|
294
|
+
_a.sent();
|
|
295
|
+
return [3 /*break*/, 3];
|
|
296
|
+
case 2:
|
|
297
|
+
e_8 = _a.sent();
|
|
298
|
+
prompts_1.default.log.warn("Could not initialize Sentry on server entry.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/");
|
|
299
|
+
(0, debug_1.debug)(e_8);
|
|
300
|
+
return [3 /*break*/, 3];
|
|
301
|
+
case 3: return [2 /*return*/];
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}); })];
|
|
305
|
+
case 18:
|
|
306
|
+
_b.sent();
|
|
307
|
+
return [4 /*yield*/, (0, clack_utils_1.askShouldCreateExamplePage)()];
|
|
308
|
+
case 19:
|
|
266
309
|
shouldCreateExamplePage = _b.sent();
|
|
267
|
-
if (!shouldCreateExamplePage) return [3 /*break*/,
|
|
310
|
+
if (!shouldCreateExamplePage) return [3 /*break*/, 21];
|
|
268
311
|
return [4 /*yield*/, (0, telemetry_1.traceStep)('Create example page', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
269
312
|
return __generator(this, function (_a) {
|
|
270
313
|
switch (_a.label) {
|
|
@@ -281,10 +324,10 @@ function runRemixWizardWithTelemetry(options) {
|
|
|
281
324
|
}
|
|
282
325
|
});
|
|
283
326
|
}); })];
|
|
284
|
-
case
|
|
327
|
+
case 20:
|
|
285
328
|
_b.sent();
|
|
286
|
-
_b.label =
|
|
287
|
-
case
|
|
329
|
+
_b.label = 21;
|
|
330
|
+
case 21:
|
|
288
331
|
prompts_1.default.outro("\n".concat(chalk_1.default.green('Sentry has been successfully configured for your Remix project.'), "\n\n").concat(chalk_1.default.cyan('You can now deploy your project to see Sentry in action.'), "\n\n").concat(chalk_1.default.cyan("To learn more about how to use Sentry with Remix, visit our documentation:\nhttps://docs.sentry.io/platforms/javascript/guides/remix/")));
|
|
289
332
|
return [2 /*return*/];
|
|
290
333
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remix-wizard.js","sourceRoot":"","sources":["../../../src/remix/remix-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nimport {\n addSentryCliConfig,\n askShouldCreateExamplePage,\n confirmContinueIfNoOrDirtyGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n isUsingTypeScript,\n printWelcome,\n rcCliSetupConfig,\n} from '../utils/clack-utils';\nimport { hasPackageInstalled } from '../utils/package-json';\nimport { WizardOptions } from '../utils/types';\nimport {\n initializeSentryOnEntryClient,\n initializeSentryOnEntryServer,\n updateBuildScript,\n instrumentRootRoute,\n isRemixV2,\n loadRemixConfig,\n runRemixReveal,\n instrumentExpressServer,\n} from './sdk-setup';\nimport { debug } from '../utils/debug';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport { isHydrogenApp } from './utils';\nimport { DEFAULT_URL } from '../../lib/Constants';\nimport { findFile } from '../utils/ast-utils';\nimport { configureVitePlugin } from '../sourcemaps/tools/vite';\nimport { createExamplePage } from './sdk-example';\n\nexport async function runRemixWizard(options: WizardOptions): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'remix',\n },\n () => runRemixWizardWithTelemetry(options),\n );\n}\n\nasync function runRemixWizardWithTelemetry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Remix Wizard',\n promoCode: options.promoCode,\n telemetryEnabled: options.telemetryEnabled,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo();\n\n const remixConfig = await loadRemixConfig();\n const packageJson = await getPackageDotJson();\n\n // We expect `@remix-run/dev` to be installed for every Remix project\n await ensurePackageIsInstalled(packageJson, '@remix-run/dev', 'Remix');\n\n const { selectedProject, authToken, sentryUrl, selfHosted } =\n await getOrAskForProjectData(options, 'javascript-remix');\n\n await installPackage({\n packageName: '@sentry/remix',\n alreadyInstalled: hasPackageInstalled('@sentry/remix', packageJson),\n });\n\n const dsn = selectedProject.keys[0].dsn.public;\n\n const isTS = isUsingTypeScript();\n const isV2 = isRemixV2(remixConfig, packageJson);\n const viteConfig = findFile('vite.config');\n\n await addSentryCliConfig({ authToken }, rcCliSetupConfig);\n\n if (viteConfig) {\n await traceStep(\n 'Update vite configuration for sourcemap uploads',\n async () => {\n try {\n await configureVitePlugin({\n orgSlug: selectedProject.organization.slug,\n projectSlug: selectedProject.slug,\n url: sentryUrl,\n selfHosted,\n authToken,\n });\n } catch (e) {\n clack.log\n .warn(`Could not update vite configuration to generate and upload sourcemaps.\n Please update your vite configuration manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/sourcemaps/`);\n debug(e);\n }\n },\n );\n } else {\n await traceStep('Update build script for sourcemap uploads', async () => {\n try {\n await updateBuildScript({\n org: selectedProject.organization.slug,\n project: selectedProject.slug,\n url: sentryUrl === DEFAULT_URL ? undefined : sentryUrl,\n isHydrogen: isHydrogenApp(packageJson),\n });\n } catch (e) {\n clack.log\n .warn(`Could not update build script to generate and upload sourcemaps.\n Please update your build script manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/sourcemaps/`);\n debug(e);\n }\n });\n }\n\n await traceStep('Instrument root route', async () => {\n try {\n await instrumentRootRoute(isV2, isTS);\n } catch (e) {\n clack.log.warn(`Could not instrument root route.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);\n debug(e);\n }\n });\n\n traceStep('Reveal missing entry files', () => {\n try {\n runRemixReveal(isTS);\n } catch (e) {\n clack.log.warn(`Could not run 'npx remix reveal'.\n Please create your entry files manually`);\n debug(e);\n }\n });\n\n await traceStep('Initialize Sentry on client entry', async () => {\n try {\n await initializeSentryOnEntryClient(dsn, isTS);\n } catch (e) {\n clack.log.warn(`Could not initialize Sentry on client entry.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);\n debug(e);\n }\n });\n\n await traceStep('Initialize Sentry on server entry', async () => {\n try {\n await initializeSentryOnEntryServer(dsn, isV2, isTS);\n } catch (e) {\n clack.log.warn(`Could not initialize Sentry on server entry.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);\n debug(e);\n }\n });\n\n await traceStep('Instrument custom Express server', async () => {\n try {\n const hasExpressAdapter = hasPackageInstalled(\n '@remix-run/express',\n packageJson,\n );\n\n if (!hasExpressAdapter) {\n return;\n }\n\n await instrumentExpressServer();\n } catch (e) {\n clack.log.warn(`Could not instrument custom Express server.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/#custom-express-server`);\n debug(e);\n }\n });\n\n const shouldCreateExamplePage = await askShouldCreateExamplePage();\n\n if (shouldCreateExamplePage) {\n await traceStep('Create example page', async () => {\n await createExamplePage({\n isTS,\n selfHosted,\n orgSlug: selectedProject.organization.slug,\n projectId: selectedProject.id,\n url: sentryUrl,\n });\n });\n }\n\n clack.outro(`\n${chalk.green(\n 'Sentry has been successfully configured for your Remix project.',\n)}\n\n${chalk.cyan('You can now deploy your project to see Sentry in action.')}\n\n${chalk.cyan(\n `To learn more about how to use Sentry with Remix, visit our documentation:\nhttps://docs.sentry.io/platforms/javascript/guides/remix/`,\n)}`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remix-wizard.js","sourceRoot":"","sources":["../../../src/remix/remix-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nimport {\n addSentryCliConfig,\n askShouldCreateExamplePage,\n confirmContinueIfNoOrDirtyGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n isUsingTypeScript,\n printWelcome,\n rcCliSetupConfig,\n} from '../utils/clack-utils';\nimport { hasPackageInstalled } from '../utils/package-json';\nimport { WizardOptions } from '../utils/types';\nimport {\n initializeSentryOnEntryClient,\n instrumentSentryOnEntryServer,\n updateBuildScript,\n instrumentRootRoute,\n isRemixV2,\n loadRemixConfig,\n runRemixReveal,\n insertServerInstrumentationFile,\n createServerInstrumentationFile,\n updateStartScript,\n} from './sdk-setup';\nimport { debug } from '../utils/debug';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport { isHydrogenApp } from './utils';\nimport { DEFAULT_URL } from '../../lib/Constants';\nimport { findFile } from '../utils/ast-utils';\nimport { configureVitePlugin } from '../sourcemaps/tools/vite';\nimport { createExamplePage } from './sdk-example';\n\nexport async function runRemixWizard(options: WizardOptions): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'remix',\n },\n () => runRemixWizardWithTelemetry(options),\n );\n}\n\nasync function runRemixWizardWithTelemetry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Remix Wizard',\n promoCode: options.promoCode,\n telemetryEnabled: options.telemetryEnabled,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo();\n\n const remixConfig = await loadRemixConfig();\n const packageJson = await getPackageDotJson();\n\n // We expect `@remix-run/dev` to be installed for every Remix project\n await ensurePackageIsInstalled(packageJson, '@remix-run/dev', 'Remix');\n\n const { selectedProject, authToken, sentryUrl, selfHosted } =\n await getOrAskForProjectData(options, 'javascript-remix');\n\n await installPackage({\n packageName: '@sentry/remix',\n alreadyInstalled: hasPackageInstalled('@sentry/remix', packageJson),\n });\n\n const dsn = selectedProject.keys[0].dsn.public;\n\n const isTS = isUsingTypeScript();\n const isV2 = isRemixV2(remixConfig, packageJson);\n const viteConfig = findFile('vite.config');\n\n await addSentryCliConfig({ authToken }, rcCliSetupConfig);\n\n if (viteConfig) {\n await traceStep(\n 'Update vite configuration for sourcemap uploads',\n async () => {\n try {\n await configureVitePlugin({\n orgSlug: selectedProject.organization.slug,\n projectSlug: selectedProject.slug,\n url: sentryUrl,\n selfHosted,\n authToken,\n });\n } catch (e) {\n clack.log\n .warn(`Could not update vite configuration to generate and upload sourcemaps.\n Please update your vite configuration manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/sourcemaps/`);\n debug(e);\n }\n },\n );\n } else {\n await traceStep('Update build script for sourcemap uploads', async () => {\n try {\n await updateBuildScript({\n org: selectedProject.organization.slug,\n project: selectedProject.slug,\n url: sentryUrl === DEFAULT_URL ? undefined : sentryUrl,\n isHydrogen: isHydrogenApp(packageJson),\n });\n } catch (e) {\n clack.log\n .warn(`Could not update build script to generate and upload sourcemaps.\n Please update your build script manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/sourcemaps/`);\n debug(e);\n }\n });\n }\n\n await traceStep('Instrument root route', async () => {\n try {\n await instrumentRootRoute(isV2, isTS);\n } catch (e) {\n clack.log.warn(`Could not instrument root route.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);\n debug(e);\n }\n });\n\n traceStep('Reveal missing entry files', () => {\n try {\n runRemixReveal(isTS);\n } catch (e) {\n clack.log.warn(`Could not run 'npx remix reveal'.\n Please create your entry files manually`);\n debug(e);\n }\n });\n\n await traceStep('Initialize Sentry on client entry', async () => {\n try {\n await initializeSentryOnEntryClient(dsn, isTS);\n } catch (e) {\n clack.log.warn(`Could not initialize Sentry on client entry.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);\n debug(e);\n }\n });\n\n let instrumentationFile = '';\n\n await traceStep('Create server instrumentation file', async () => {\n try {\n instrumentationFile = await createServerInstrumentationFile(dsn);\n } catch (e) {\n clack.log.warn(\n 'Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/',\n );\n debug(e);\n }\n });\n\n let serverFileInstrumented = false;\n\n await traceStep(\n 'Create server instrumentation file and import it',\n async () => {\n try {\n serverFileInstrumented = await insertServerInstrumentationFile(dsn);\n } catch (e) {\n clack.log.warn(\n 'Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/',\n );\n debug(e);\n }\n },\n );\n\n if (!serverFileInstrumented && instrumentationFile) {\n await traceStep(\n 'Update `start` script to import instrumentation file.',\n async () => {\n try {\n await updateStartScript(instrumentationFile);\n } catch (e) {\n clack.log\n .warn(`Could not automatically add Sentry initialization to server entry.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);\n debug(e);\n }\n },\n );\n }\n\n await traceStep('Instrument server `handleError`', async () => {\n try {\n await instrumentSentryOnEntryServer(isV2, isTS);\n } catch (e) {\n clack.log.warn(`Could not initialize Sentry on server entry.\n Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);\n debug(e);\n }\n });\n\n const shouldCreateExamplePage = await askShouldCreateExamplePage();\n\n if (shouldCreateExamplePage) {\n await traceStep('Create example page', async () => {\n await createExamplePage({\n isTS,\n selfHosted,\n orgSlug: selectedProject.organization.slug,\n projectId: selectedProject.id,\n url: sentryUrl,\n });\n });\n }\n\n clack.outro(`\n${chalk.green(\n 'Sentry has been successfully configured for your Remix project.',\n)}\n\n${chalk.cyan('You can now deploy your project to see Sentry in action.')}\n\n${chalk.cyan(\n `To learn more about how to use Sentry with Remix, visit our documentation:\nhttps://docs.sentry.io/platforms/javascript/guides/remix/`,\n)}`);\n}\n"]}
|