@sentry/wizard 6.11.0 → 6.13.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 +64 -0
- package/dist/bin.js +16 -1
- package/dist/bin.js.map +1 -1
- package/dist/e2e-tests/tests/angular-17.test.js +3 -4
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +3 -4
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/cloudflare-worker.test.js +5 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.js +60 -0
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/e2e-tests/tests/help-message.test.js +8 -3
- package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-3.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-4.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js +8 -4
- package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +96 -0
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -0
- package/dist/e2e-tests/tests/react-router.test.js +6 -7
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +2 -4
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js +24 -8
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +8 -4
- package/dist/e2e-tests/tests/sveltekit-tracing.test.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/lib/Steps/Integrations/Electron.js +2 -2
- package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
- package/dist/src/android/android-wizard.js +3 -0
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/angular/codemods/main.d.ts +1 -1
- package/dist/src/angular/codemods/main.js +0 -1
- package/dist/src/angular/codemods/main.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +2 -3
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/check-installed-cli.d.ts +1 -1
- package/dist/src/apple/check-installed-cli.js +13 -7
- package/dist/src/apple/check-installed-cli.js.map +1 -1
- package/dist/src/apple/code-tools.js +17 -3
- package/dist/src/apple/code-tools.js.map +1 -1
- package/dist/src/apple/configure-package-manager.js +18 -5
- package/dist/src/apple/configure-package-manager.js.map +1 -1
- package/dist/src/apple/configure-xcode-project.js +8 -1
- package/dist/src/apple/configure-xcode-project.js.map +1 -1
- package/dist/src/apple/lookup-xcode-project.d.ts +8 -5
- package/dist/src/apple/lookup-xcode-project.js +22 -17
- package/dist/src/apple/lookup-xcode-project.js.map +1 -1
- package/dist/src/apple/options.d.ts +5 -0
- package/dist/src/apple/options.js.map +1 -1
- package/dist/src/apple/sentry-swift-package.d.ts +4 -0
- package/dist/src/apple/sentry-swift-package.js +17 -0
- package/dist/src/apple/sentry-swift-package.js.map +1 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.d.ts +2 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js +251 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js.map +1 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.d.ts +13 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js +48 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-test-file.d.ts +18 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js +122 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.d.ts +6 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js +147 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js.map +1 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.d.ts +4 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js +8 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js.map +1 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.d.ts +23 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js +136 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js.map +1 -0
- package/dist/src/apple/xcode-manager.d.ts +59 -1
- package/dist/src/apple/xcode-manager.js +507 -106
- package/dist/src/apple/xcode-manager.js.map +1 -1
- package/dist/src/cloudflare/cloudflare-wizard.js +5 -0
- package/dist/src/cloudflare/cloudflare-wizard.js.map +1 -1
- package/dist/src/cloudflare/sdk-setup.d.ts +1 -0
- package/dist/src/cloudflare/sdk-setup.js.map +1 -1
- package/dist/src/cloudflare/templates.d.ts +1 -0
- package/dist/src/cloudflare/templates.js +7 -1
- package/dist/src/cloudflare/templates.js.map +1 -1
- package/dist/src/cloudflare/wrap-worker.d.ts +1 -0
- package/dist/src/cloudflare/wrap-worker.js +7 -0
- package/dist/src/cloudflare/wrap-worker.js.map +1 -1
- package/dist/src/flutter/flutter-wizard.js +3 -0
- package/dist/src/flutter/flutter-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.js +12 -6
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/nuxt/templates.js +12 -6
- package/dist/src/nuxt/templates.js.map +1 -1
- package/dist/src/react-native/expo.d.ts +6 -0
- package/dist/src/react-native/expo.js +27 -1
- package/dist/src/react-native/expo.js.map +1 -1
- package/dist/src/react-native/git.d.ts +5 -0
- package/dist/src/react-native/git.js +32 -1
- package/dist/src/react-native/git.js.map +1 -1
- package/dist/src/react-native/javascript.js +3 -1
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +12 -6
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
- package/dist/src/react-router/codemods/client.entry.js +124 -26
- package/dist/src/react-router/codemods/client.entry.js.map +1 -1
- package/dist/src/react-router/codemods/react-router-config.js +1 -1
- package/dist/src/react-router/codemods/react-router-config.js.map +1 -1
- package/dist/src/react-router/codemods/server-entry.d.ts +1 -1
- package/dist/src/react-router/codemods/server-entry.js +40 -4
- package/dist/src/react-router/codemods/server-entry.js.map +1 -1
- package/dist/src/react-router/codemods/vite.js +46 -1
- package/dist/src/react-router/codemods/vite.js.map +1 -1
- package/dist/src/react-router/react-router-wizard.js +62 -21
- package/dist/src/react-router/react-router-wizard.js.map +1 -1
- package/dist/src/react-router/sdk-setup.d.ts +5 -3
- package/dist/src/react-router/sdk-setup.js +44 -16
- package/dist/src/react-router/sdk-setup.js.map +1 -1
- package/dist/src/react-router/templates.d.ts +2 -4
- package/dist/src/react-router/templates.js +89 -87
- package/dist/src/react-router/templates.js.map +1 -1
- package/dist/src/remix/sdk-setup.js +1 -2
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/run.d.ts +4 -1
- package/dist/src/run.js +13 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/remix.js +4 -4
- package/dist/src/sourcemaps/tools/remix.js.map +1 -1
- package/dist/src/sourcemaps/tools/vite.js +1 -1
- package/dist/src/sourcemaps/tools/vite.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/setup.js +17 -4
- package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js.map +1 -1
- package/dist/src/sveltekit/templates.js +12 -6
- package/dist/src/sveltekit/templates.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +10 -0
- package/dist/src/utils/ast-utils.js +19 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +2 -1
- package/dist/src/utils/clack/index.js +17 -6
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/utils/files.d.ts +2 -0
- package/dist/src/utils/files.js +58 -0
- package/dist/src/utils/files.js.map +1 -0
- package/dist/src/utils/git.d.ts +3 -1
- package/dist/src/utils/git.js +2 -1
- package/dist/src/utils/git.js.map +1 -1
- package/dist/src/utils/line-endings.d.ts +1 -0
- package/dist/src/utils/line-endings.js +76 -0
- package/dist/src/utils/line-endings.js.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/angular/angular-wizard.test.js +0 -5
- package/dist/test/angular/angular-wizard.test.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +78 -0
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/apple/configure-package-manager.test.d.ts +1 -0
- package/dist/test/apple/configure-package-manager.test.js +161 -0
- package/dist/test/apple/configure-package-manager.test.js.map +1 -0
- package/dist/test/apple/lookup-xcode-project.test.d.ts +1 -0
- package/dist/test/apple/lookup-xcode-project.test.js +167 -0
- package/dist/test/apple/lookup-xcode-project.test.js.map +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.d.ts +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js +487 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js.map +1 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.d.ts +24 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js +191 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js +110 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js +146 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js +186 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js +192 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js.map +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.d.ts +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js +77 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js.map +1 -0
- package/dist/test/apple/xcode-manager.test.js +452 -43
- package/dist/test/apple/xcode-manager.test.js.map +1 -1
- package/dist/test/cloudflare/sdk-setup.test.js +20 -2
- package/dist/test/cloudflare/sdk-setup.test.js.map +1 -1
- package/dist/test/cloudflare/templates.test.js +54 -0
- package/dist/test/cloudflare/templates.test.js.map +1 -1
- package/dist/test/cloudflare/wrap-worker.test.js +74 -11
- package/dist/test/cloudflare/wrap-worker.test.js.map +1 -1
- package/dist/test/constants.test.d.ts +1 -0
- package/dist/test/constants.test.js +12 -0
- package/dist/test/constants.test.js.map +1 -0
- package/dist/test/nextjs/templates.test.js +66 -33
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/dist/test/nuxt/templates.test.js +66 -36
- package/dist/test/nuxt/templates.test.js.map +1 -1
- package/dist/test/react-native/expo.test.js +140 -0
- package/dist/test/react-native/expo.test.js.map +1 -1
- package/dist/test/react-native/git.test.d.ts +1 -0
- package/dist/test/react-native/git.test.js +160 -0
- package/dist/test/react-native/git.test.js.map +1 -0
- package/dist/test/react-router/codemods/client-entry.test.js +38 -5
- package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/server-entry.test.js +83 -0
- package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/vite.test.js +89 -0
- package/dist/test/react-router/codemods/vite.test.js.map +1 -1
- package/dist/test/react-router/sdk-setup.test.js +98 -6
- package/dist/test/react-router/sdk-setup.test.js.map +1 -1
- package/dist/test/react-router/templates.test.js +50 -38
- package/dist/test/react-router/templates.test.js.map +1 -1
- package/dist/test/remix/build-script.test.d.ts +1 -0
- package/dist/test/remix/build-script.test.js +124 -0
- package/dist/test/remix/build-script.test.js.map +1 -0
- package/dist/test/remix/client-entry.test.js +4 -10
- package/dist/test/remix/client-entry.test.js.map +1 -1
- package/dist/test/run.test.d.ts +1 -0
- package/dist/test/run.test.js +137 -0
- package/dist/test/run.test.js.map +1 -0
- package/dist/test/sourcemaps/tools/vite.test.js +12 -8
- package/dist/test/sourcemaps/tools/vite.test.js.map +1 -1
- package/dist/test/sveltekit/templates.test.js +78 -27
- package/dist/test/sveltekit/templates.test.js.map +1 -1
- package/dist/test/utils/ast-utils.test.js +22 -0
- package/dist/test/utils/ast-utils.test.js.map +1 -1
- package/dist/test/utils/clack/index.test.js +101 -0
- package/dist/test/utils/clack/index.test.js.map +1 -1
- package/dist/test/utils/git.test.js +10 -0
- package/dist/test/utils/git.test.js.map +1 -1
- package/dist/test/utils/line-endings.test.d.ts +1 -0
- package/dist/test/utils/line-endings.test.js +103 -0
- package/dist/test/utils/line-endings.test.js.map +1 -0
- package/package.json +2 -2
- package/dist/src/react-router/codemods/root.d.ts +0 -1
- package/dist/src/react-router/codemods/root.js +0 -171
- package/dist/src/react-router/codemods/root.js.map +0 -1
- package/dist/test/react-router/codemods/root.test.js +0 -178
- package/dist/test/react-router/codemods/root.test.js.map +0 -1
- /package/dist/{test/react-router/codemods/root.test.d.ts → e2e-tests/tests/react-router-instrumentation-api.test.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/sveltekit/sdk-setup/setup.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExportNamedDeclaration, Program } from '@babel/types';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport chalk from 'chalk';\n\nimport * as Sentry from '@sentry/node';\n\n//@ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport type { ProxifiedModule } from 'magicast';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { builders, generateCode, loadFile } from 'magicast';\nimport {\n getClientHooksTemplate,\n getInstrumentationServerTemplate,\n getServerHooksTemplate,\n} from '../templates';\nimport {\n featureSelectionPrompt,\n isUsingTypeScript,\n showCopyPasteInstructions,\n} from '../../utils/clack';\nimport { findFile, hasSentryContent } from '../../utils/ast-utils';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\nimport {\n enableTracingAndInstrumentation,\n type PartialBackwardsForwardsCompatibleSvelteConfig,\n} from './svelte-config';\nimport { ProjectInfo } from './types';\nimport { modifyViteConfig } from './vite';\nimport { modifyAndRecordFail } from './utils';\nimport { debug } from '../../utils/debug';\n\nexport async function createOrMergeSvelteKitFiles(\n projectInfo: ProjectInfo,\n svelteConfig: PartialBackwardsForwardsCompatibleSvelteConfig,\n setupForSvelteKitTracing: boolean,\n): Promise<void> {\n const selectedFeatures = await featureSelectionPrompt([\n {\n id: 'performance',\n prompt: `Do you want to enable ${chalk.bold(\n 'Tracing',\n )} to track the performance of your application?`,\n enabledHint: 'recommended',\n },\n {\n id: 'replay',\n prompt: `Do you want to enable ${chalk.bold(\n 'Session Replay',\n )} to get a video-like reproduction of errors during a user session?`,\n enabledHint: 'recommended, but increases bundle size',\n },\n {\n id: 'logs',\n prompt: `Do you want to enable ${chalk.bold(\n 'Logs',\n )} to send your application logs to Sentry?`,\n enabledHint: 'recommended',\n },\n ] as const);\n\n const { clientHooksPath, serverHooksPath } = getHooksConfigDirs(svelteConfig);\n\n // full file paths with correct file ending (or undefined if not found)\n const originalClientHooksFile = findFile(clientHooksPath);\n const originalServerHooksFile = findFile(serverHooksPath);\n const originalInstrumentationServerFile = findFile(\n path.resolve(process.cwd(), 'src', 'instrumentation.server'),\n );\n\n const viteConfig = findFile(path.resolve(process.cwd(), 'vite.config'));\n\n const fileEnding = isUsingTypeScript() ? 'ts' : 'js';\n\n const { dsn } = projectInfo;\n\n if (setupForSvelteKitTracing) {\n await enableTracingAndInstrumentation(\n svelteConfig,\n selectedFeatures.performance,\n );\n\n try {\n if (!originalInstrumentationServerFile) {\n await createNewInstrumentationServerFile(dsn, selectedFeatures);\n } else {\n await mergeInstrumentationServerFile(\n originalInstrumentationServerFile,\n dsn,\n selectedFeatures,\n );\n }\n } catch (e) {\n clack.log.warn(\n `Failed to automatically set up ${chalk.cyan(\n `instrumentation.server.${\n fileEnding ?? isUsingTypeScript() ? 'ts' : 'js'\n }`,\n )}.`,\n );\n debug(e);\n\n await showCopyPasteInstructions({\n codeSnippet: getInstrumentationServerTemplate(dsn, selectedFeatures),\n filename: `instrumentation.server.${\n fileEnding ?? isUsingTypeScript() ? 'ts' : 'js'\n }`,\n });\n\n Sentry.setTag('created-instrumentation-server', 'fail');\n }\n }\n\n Sentry.setTag(\n 'server-hooks-file-strategy',\n originalServerHooksFile ? 'merge' : 'create',\n );\n\n if (!originalServerHooksFile) {\n await createNewHooksFile(\n `${serverHooksPath}.${fileEnding}`,\n 'server',\n dsn,\n selectedFeatures,\n !setupForSvelteKitTracing,\n );\n } else {\n await mergeHooksFile(\n originalServerHooksFile,\n 'server',\n dsn,\n selectedFeatures,\n !setupForSvelteKitTracing,\n );\n }\n\n Sentry.setTag(\n 'client-hooks-file-strategy',\n originalClientHooksFile ? 'merge' : 'create',\n );\n if (!originalClientHooksFile) {\n await createNewHooksFile(\n `${clientHooksPath}.${fileEnding}`,\n 'client',\n dsn,\n selectedFeatures,\n true,\n );\n } else {\n await mergeHooksFile(\n originalClientHooksFile,\n 'client',\n dsn,\n selectedFeatures,\n true,\n );\n }\n\n if (viteConfig) {\n await modifyViteConfig(viteConfig, projectInfo);\n }\n}\n\n/**\n * Attempts to read the svelte.config.js file to find the location of the hooks files.\n * If users specified a custom location, we'll use that. Otherwise, we'll use the default.\n */\nfunction getHooksConfigDirs(\n svelteConfig: PartialBackwardsForwardsCompatibleSvelteConfig,\n): {\n clientHooksPath: string;\n serverHooksPath: string;\n} {\n const relativeUserClientHooksPath = svelteConfig?.kit?.files?.hooks?.client;\n const relativeUserServerHooksPath = svelteConfig?.kit?.files?.hooks?.server;\n const userClientHooksPath =\n relativeUserClientHooksPath &&\n path.resolve(process.cwd(), relativeUserClientHooksPath);\n const userServerHooksPath =\n relativeUserServerHooksPath &&\n path.resolve(process.cwd(), relativeUserServerHooksPath);\n\n const defaulHooksDir = path.resolve(process.cwd(), 'src');\n const defaultClientHooksPath = path.resolve(defaulHooksDir, 'hooks.client'); // file ending missing on purpose\n const defaultServerHooksPath = path.resolve(defaulHooksDir, 'hooks.server'); // same here\n\n return {\n clientHooksPath: userClientHooksPath || defaultClientHooksPath,\n serverHooksPath: userServerHooksPath || defaultServerHooksPath,\n };\n}\n\n/**\n * Reads the template, replaces the dsn placeholder with the actual dsn and writes the file to @param hooksFileDest\n */\nasync function createNewHooksFile(\n hooksFileDest: string,\n hooktype: 'client' | 'server',\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n setupForSvelteKitTracing: boolean,\n): Promise<void> {\n const filledTemplate =\n hooktype === 'client'\n ? getClientHooksTemplate(dsn, selectedFeatures)\n : getServerHooksTemplate(dsn, selectedFeatures, setupForSvelteKitTracing);\n\n await fs.promises.mkdir(path.dirname(hooksFileDest), { recursive: true });\n await fs.promises.writeFile(hooksFileDest, filledTemplate);\n\n clack.log.success(`Created ${hooksFileDest}`);\n Sentry.setTag(`created-${hooktype}-hooks`, 'success');\n}\n\nasync function createNewInstrumentationServerFile(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n): Promise<void> {\n const filledTemplate = getInstrumentationServerTemplate(\n dsn,\n selectedFeatures,\n );\n\n const fileEnding = isUsingTypeScript() ? 'ts' : 'js';\n\n const instrumentationServerFile = path.resolve(\n process.cwd(),\n 'src',\n `instrumentation.server.${fileEnding}`,\n );\n\n await fs.promises.mkdir(path.dirname(instrumentationServerFile), {\n recursive: true,\n });\n\n await fs.promises.writeFile(instrumentationServerFile, filledTemplate);\n\n clack.log.success(\n `Created ${chalk.cyan(path.basename(instrumentationServerFile))}`,\n );\n Sentry.setTag('created-instrumentation-server', 'success');\n}\n\n/**\n * Merges the users' hooks file with Sentry-related code.\n *\n * Both hooks:\n * - add import * as Sentry\n * - add Sentry.init\n * - add handleError hook wrapper\n *\n * Additionally in Server hook:\n * - add handle hook handler\n */\nasync function mergeHooksFile(\n hooksFile: string,\n hookType: 'client' | 'server',\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n includeSentryInit: boolean,\n): Promise<void> {\n const originalHooksMod = await loadFile(hooksFile);\n\n const file: 'server-hooks' | 'client-hooks' = `${hookType}-hooks`;\n\n if (hasSentryContent(originalHooksMod.$ast as t.Program)) {\n // We don't want to mess with files that already have Sentry content.\n // Let's just bail out at this point.\n clack.log.warn(\n `File ${chalk.cyan(\n path.basename(hooksFile),\n )} already contains Sentry code.\nSkipping adding Sentry functionality to.`,\n );\n Sentry.setTag(`modified-${file}`, 'fail');\n Sentry.setTag(`${file}-fail-reason`, 'has-sentry-content');\n return;\n }\n\n await modifyAndRecordFail(\n () =>\n originalHooksMod.imports.$add({\n from: '@sentry/sveltekit',\n imported: '*',\n local: 'Sentry',\n }),\n 'import-injection',\n file,\n );\n\n if (hookType === 'client' || includeSentryInit) {\n await modifyAndRecordFail(\n () => {\n if (hookType === 'client') {\n insertClientInitCall(dsn, originalHooksMod, selectedFeatures);\n } else {\n insertServerInitCall(dsn, originalHooksMod, selectedFeatures);\n }\n },\n 'init-call-injection',\n file,\n );\n }\n\n await modifyAndRecordFail(\n () => wrapHandleError(originalHooksMod),\n 'wrap-handle-error',\n file,\n );\n\n if (hookType === 'server') {\n await modifyAndRecordFail(\n () => wrapHandle(originalHooksMod),\n 'wrap-handle',\n 'server-hooks',\n );\n }\n\n await modifyAndRecordFail(\n async () => {\n const modifiedCode = originalHooksMod.generate().code;\n await fs.promises.writeFile(hooksFile, modifiedCode);\n },\n 'write-file',\n file,\n );\n\n clack.log.success(`Added Sentry code to ${hooksFile}`);\n Sentry.setTag(`modified-${hookType}-hooks`, 'success');\n}\n\n/**\n * Merges the users' instrumentation.server file with Sentry-related code.\n *\n * Both hooks:\n * - add import * as Sentry\n * - add Sentry.init\n * - add handleError hook wrapper\n *\n * Additionally in Server hook:\n * - add handle hook handler\n */\nasync function mergeInstrumentationServerFile(\n instrumentationServerFilePath: string,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): Promise<void> {\n const originalInstrumentationServerMod = await loadFile(\n instrumentationServerFilePath,\n );\n const filename = path.basename(instrumentationServerFilePath);\n\n if (hasSentryContent(originalInstrumentationServerMod.$ast as t.Program)) {\n // We don't want to mess with files that already have Sentry content.\n // Let's just bail out at this point.\n clack.log.warn(\n `File ${chalk.cyan(filename)} already contains Sentry code.\nSkipping adding Sentry functionality to it.`,\n );\n Sentry.setTag(`modified-instrumentation-server`, 'fail');\n Sentry.setTag(`instrumentation-server-fail-reason`, 'has-sentry-content');\n return;\n }\n\n await modifyAndRecordFail(\n () =>\n originalInstrumentationServerMod.imports.$add({\n from: '@sentry/sveltekit',\n imported: '*',\n local: 'Sentry',\n }),\n 'import-injection',\n 'instrumentation-server',\n );\n\n await modifyAndRecordFail(\n () => {\n insertServerInitCall(\n dsn,\n originalInstrumentationServerMod,\n selectedFeatures,\n );\n },\n 'init-call-injection',\n 'instrumentation-server',\n );\n\n await modifyAndRecordFail(\n async () => {\n const modifiedCode = originalInstrumentationServerMod.generate().code;\n await fs.promises.writeFile(instrumentationServerFilePath, modifiedCode);\n },\n 'write-file',\n 'instrumentation-server',\n );\n\n clack.log.success(`Added Sentry.init code to ${chalk.cyan(filename)}`);\n Sentry.setTag(`modified-instrumentation-server`, 'success');\n}\n\nexport function insertClientInitCall(\n dsn: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalHooksMod: ProxifiedModule<any>,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): void {\n const initCallComment = `\n // If you don't want to use Session Replay, remove the \\`Replay\\` integration,\n // \\`replaysSessionSampleRate\\` and \\`replaysOnErrorSampleRate\\` options.`;\n\n const initArgs: {\n dsn: string;\n tracesSampleRate?: number;\n replaysSessionSampleRate?: number;\n replaysOnErrorSampleRate?: number;\n integrations?: string[];\n enableLogs?: boolean;\n sendDefaultPii?: boolean;\n } = {\n dsn,\n };\n\n if (selectedFeatures.performance) {\n initArgs.tracesSampleRate = 1.0;\n }\n\n if (selectedFeatures.replay) {\n initArgs.replaysSessionSampleRate = 0.1;\n initArgs.replaysOnErrorSampleRate = 1.0;\n initArgs.integrations = [builders.functionCall('Sentry.replayIntegration')];\n }\n\n if (selectedFeatures.logs) {\n initArgs.enableLogs = true;\n }\n\n initArgs.sendDefaultPii = true;\n\n // This assignment of any values is fine because we're just creating a function call in magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const initCall = builders.functionCall('Sentry.init', initArgs);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const initCallWithComment = builders.raw(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n `${initCallComment}\\n${generateCode(initCall).code}`,\n );\n\n const originalHooksModAST = originalHooksMod.$ast as Program;\n\n const initCallInsertionIndex = getInitCallInsertionIndex(originalHooksModAST);\n\n originalHooksModAST.body.splice(\n initCallInsertionIndex,\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n generateCode(initCallWithComment).code,\n );\n}\n\nfunction insertServerInitCall(\n dsn: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalMod: ProxifiedModule<any>,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n): void {\n const initArgs: {\n dsn: string;\n tracesSampleRate?: number;\n enableLogs?: boolean;\n sendDefaultPii?: boolean;\n } = {\n dsn,\n };\n\n if (selectedFeatures.performance) {\n initArgs.tracesSampleRate = 1.0;\n }\n\n if (selectedFeatures.logs) {\n initArgs.enableLogs = true;\n }\n\n initArgs.sendDefaultPii = true;\n\n // This assignment of any values is fine because we're just creating a function call in magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const initCall = builders.functionCall('Sentry.init', initArgs);\n\n const originalModAST = originalMod.$ast as Program;\n\n const initCallInsertionIndex = getInitCallInsertionIndex(originalModAST);\n\n originalModAST.body.splice(\n initCallInsertionIndex,\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n generateCode(initCall).code,\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction wrapHandleError(mod: ProxifiedModule<any>): void {\n const modAst = mod.exports.$ast as Program;\n const namedExports = modAst.body.filter(\n (node) => node.type === 'ExportNamedDeclaration',\n ) as ExportNamedDeclaration[];\n\n let foundHandleError = false;\n\n namedExports.forEach((modExport) => {\n const declaration = modExport.declaration;\n if (!declaration) {\n return;\n }\n if (declaration.type === 'FunctionDeclaration') {\n if (!declaration.id || declaration.id.name !== 'handleError') {\n return;\n }\n foundHandleError = true;\n const userCode = generateCode(declaration).code;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handleError = builders.raw(\n `Sentry.handleErrorWithSentry(${userCode.replace(\n 'handleError',\n '_handleError',\n )})`,\n );\n // because magicast doesn't overwrite the original function export, we need to remove it manually\n modAst.body = modAst.body.filter((node) => node !== modExport);\n } else if (declaration.type === 'VariableDeclaration') {\n const declarations = declaration.declarations;\n declarations.forEach((declaration) => {\n // @ts-expect-error - id should always have a name in this case\n if (!declaration.id || declaration.id.name !== 'handleError') {\n return;\n }\n foundHandleError = true;\n const userCode = declaration.init;\n const stringifiedUserCode = userCode ? generateCode(userCode).code : '';\n // @ts-expect-error - we can just place a string here, magicast will convert it to a node\n declaration.init = `Sentry.handleErrorWithSentry(${stringifiedUserCode})`;\n });\n }\n });\n\n if (!foundHandleError) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handleError = builders.functionCall(\n 'Sentry.handleErrorWithSentry',\n );\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction wrapHandle(mod: ProxifiedModule<any>): void {\n const modAst = mod.exports.$ast as Program;\n const namedExports = modAst.body.filter(\n (node) => node.type === 'ExportNamedDeclaration',\n ) as ExportNamedDeclaration[];\n\n let foundHandle = false;\n\n namedExports.forEach((modExport) => {\n const declaration = modExport.declaration;\n if (!declaration) {\n return;\n }\n if (declaration.type === 'FunctionDeclaration') {\n if (!declaration.id || declaration.id.name !== 'handle') {\n return;\n }\n foundHandle = true;\n const userCode = generateCode(declaration).code;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handle = builders.raw(\n `sequence(Sentry.sentryHandle(), ${userCode.replace(\n 'handle',\n '_handle',\n )})`,\n );\n // because of an issue with magicast, we need to remove the original export\n modAst.body = modAst.body.filter((node) => node !== modExport);\n } else if (declaration.type === 'VariableDeclaration') {\n const declarations = declaration.declarations;\n declarations.forEach((declaration) => {\n if (\n !declaration.id ||\n declaration.id.type !== 'Identifier' ||\n (declaration.id.name && declaration.id.name !== 'handle')\n ) {\n return;\n }\n const userCode = declaration.init;\n const stringifiedUserCode = userCode ? generateCode(userCode).code : '';\n // @ts-expect-error - we can just place a string here, magicast will convert it to a node\n declaration.init = `sequence(Sentry.sentryHandle(), ${stringifiedUserCode})`;\n foundHandle = true;\n });\n }\n });\n\n if (!foundHandle) {\n // can't use builders.functionCall here because it doesn't yet\n // support member expressions (Sentry.sentryHandle()) in args\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handle = builders.raw('sequence(Sentry.sentryHandle())');\n }\n\n try {\n mod.imports.$add({\n from: '@sveltejs/kit/hooks',\n imported: 'sequence',\n local: 'sequence',\n });\n } catch (_) {\n // It's possible sequence is already imported. in this case, magicast throws but that's fine.\n }\n}\n\n/**\n * We want to insert the init call on top of the file but after all import statements\n */\nfunction getInitCallInsertionIndex(originalModAST: Program): number {\n // We need to deep-copy here because reverse mutates in place\n const copiedBodyNodes = [...originalModAST.body];\n const lastImportDeclaration = copiedBodyNodes\n .reverse()\n .find((node) => node.type === 'ImportDeclaration');\n\n const initCallInsertionIndex = lastImportDeclaration\n ? originalModAST.body.indexOf(lastImportDeclaration) + 1\n : 0;\n return initCallInsertionIndex;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/sveltekit/sdk-setup/setup.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExportNamedDeclaration, Program } from '@babel/types';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport chalk from 'chalk';\n\nimport * as Sentry from '@sentry/node';\n\n//@ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport type { ProxifiedModule } from 'magicast';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { builders, generateCode, loadFile } from 'magicast';\nimport {\n getClientHooksTemplate,\n getInstrumentationServerTemplate,\n getServerHooksTemplate,\n} from '../templates';\nimport {\n featureSelectionPrompt,\n isUsingTypeScript,\n showCopyPasteInstructions,\n} from '../../utils/clack';\nimport { findFile, hasSentryContent } from '../../utils/ast-utils';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\nimport {\n enableTracingAndInstrumentation,\n type PartialBackwardsForwardsCompatibleSvelteConfig,\n} from './svelte-config';\nimport { ProjectInfo } from './types';\nimport { modifyViteConfig } from './vite';\nimport { modifyAndRecordFail } from './utils';\nimport { debug } from '../../utils/debug';\n\nexport async function createOrMergeSvelteKitFiles(\n projectInfo: ProjectInfo,\n svelteConfig: PartialBackwardsForwardsCompatibleSvelteConfig,\n setupForSvelteKitTracing: boolean,\n): Promise<void> {\n const selectedFeatures = await featureSelectionPrompt([\n {\n id: 'performance',\n prompt: `Do you want to enable ${chalk.bold(\n 'Tracing',\n )} to track the performance of your application?`,\n enabledHint: 'recommended',\n },\n {\n id: 'replay',\n prompt: `Do you want to enable ${chalk.bold(\n 'Session Replay',\n )} to get a video-like reproduction of errors during a user session?`,\n enabledHint: 'recommended, but increases bundle size',\n },\n {\n id: 'logs',\n prompt: `Do you want to enable ${chalk.bold(\n 'Logs',\n )} to send your application logs to Sentry?`,\n enabledHint: 'recommended',\n },\n ] as const);\n\n const { clientHooksPath, serverHooksPath } = getHooksConfigDirs(svelteConfig);\n\n // full file paths with correct file ending (or undefined if not found)\n const originalClientHooksFile = findFile(clientHooksPath);\n const originalServerHooksFile = findFile(serverHooksPath);\n const originalInstrumentationServerFile = findFile(\n path.resolve(process.cwd(), 'src', 'instrumentation.server'),\n );\n\n const viteConfig = findFile(path.resolve(process.cwd(), 'vite.config'));\n\n const fileEnding = isUsingTypeScript() ? 'ts' : 'js';\n\n const { dsn } = projectInfo;\n\n if (setupForSvelteKitTracing) {\n await enableTracingAndInstrumentation(\n svelteConfig,\n selectedFeatures.performance,\n );\n\n try {\n if (!originalInstrumentationServerFile) {\n await createNewInstrumentationServerFile(dsn, selectedFeatures);\n } else {\n await mergeInstrumentationServerFile(\n originalInstrumentationServerFile,\n dsn,\n selectedFeatures,\n );\n }\n } catch (e) {\n clack.log.warn(\n `Failed to automatically set up ${chalk.cyan(\n `instrumentation.server.${\n fileEnding ?? isUsingTypeScript() ? 'ts' : 'js'\n }`,\n )}.`,\n );\n debug(e);\n\n await showCopyPasteInstructions({\n codeSnippet: getInstrumentationServerTemplate(dsn, selectedFeatures),\n filename: `instrumentation.server.${\n fileEnding ?? isUsingTypeScript() ? 'ts' : 'js'\n }`,\n });\n\n Sentry.setTag('created-instrumentation-server', 'fail');\n }\n }\n\n Sentry.setTag(\n 'server-hooks-file-strategy',\n originalServerHooksFile ? 'merge' : 'create',\n );\n\n if (!originalServerHooksFile) {\n await createNewHooksFile(\n `${serverHooksPath}.${fileEnding}`,\n 'server',\n dsn,\n selectedFeatures,\n !setupForSvelteKitTracing,\n );\n } else {\n await mergeHooksFile(\n originalServerHooksFile,\n 'server',\n dsn,\n selectedFeatures,\n !setupForSvelteKitTracing,\n );\n }\n\n Sentry.setTag(\n 'client-hooks-file-strategy',\n originalClientHooksFile ? 'merge' : 'create',\n );\n if (!originalClientHooksFile) {\n await createNewHooksFile(\n `${clientHooksPath}.${fileEnding}`,\n 'client',\n dsn,\n selectedFeatures,\n true,\n );\n } else {\n await mergeHooksFile(\n originalClientHooksFile,\n 'client',\n dsn,\n selectedFeatures,\n true,\n );\n }\n\n if (viteConfig) {\n await modifyViteConfig(viteConfig, projectInfo);\n }\n}\n\n/**\n * Attempts to read the svelte.config.js file to find the location of the hooks files.\n * If users specified a custom location, we'll use that. Otherwise, we'll use the default.\n */\nfunction getHooksConfigDirs(\n svelteConfig: PartialBackwardsForwardsCompatibleSvelteConfig,\n): {\n clientHooksPath: string;\n serverHooksPath: string;\n} {\n const relativeUserClientHooksPath = svelteConfig?.kit?.files?.hooks?.client;\n const relativeUserServerHooksPath = svelteConfig?.kit?.files?.hooks?.server;\n const userClientHooksPath =\n relativeUserClientHooksPath &&\n path.resolve(process.cwd(), relativeUserClientHooksPath);\n const userServerHooksPath =\n relativeUserServerHooksPath &&\n path.resolve(process.cwd(), relativeUserServerHooksPath);\n\n const defaulHooksDir = path.resolve(process.cwd(), 'src');\n const defaultClientHooksPath = path.resolve(defaulHooksDir, 'hooks.client'); // file ending missing on purpose\n const defaultServerHooksPath = path.resolve(defaulHooksDir, 'hooks.server'); // same here\n\n return {\n clientHooksPath: userClientHooksPath || defaultClientHooksPath,\n serverHooksPath: userServerHooksPath || defaultServerHooksPath,\n };\n}\n\n/**\n * Reads the template, replaces the dsn placeholder with the actual dsn and writes the file to @param hooksFileDest\n */\nasync function createNewHooksFile(\n hooksFileDest: string,\n hooktype: 'client' | 'server',\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n setupForSvelteKitTracing: boolean,\n): Promise<void> {\n const filledTemplate =\n hooktype === 'client'\n ? getClientHooksTemplate(dsn, selectedFeatures)\n : getServerHooksTemplate(dsn, selectedFeatures, setupForSvelteKitTracing);\n\n await fs.promises.mkdir(path.dirname(hooksFileDest), { recursive: true });\n await fs.promises.writeFile(hooksFileDest, filledTemplate);\n\n clack.log.success(`Created ${hooksFileDest}`);\n Sentry.setTag(`created-${hooktype}-hooks`, 'success');\n}\n\nasync function createNewInstrumentationServerFile(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n): Promise<void> {\n const filledTemplate = getInstrumentationServerTemplate(\n dsn,\n selectedFeatures,\n );\n\n const fileEnding = isUsingTypeScript() ? 'ts' : 'js';\n\n const instrumentationServerFile = path.resolve(\n process.cwd(),\n 'src',\n `instrumentation.server.${fileEnding}`,\n );\n\n await fs.promises.mkdir(path.dirname(instrumentationServerFile), {\n recursive: true,\n });\n\n await fs.promises.writeFile(instrumentationServerFile, filledTemplate);\n\n clack.log.success(\n `Created ${chalk.cyan(path.basename(instrumentationServerFile))}`,\n );\n Sentry.setTag('created-instrumentation-server', 'success');\n}\n\n/**\n * Merges the users' hooks file with Sentry-related code.\n *\n * Both hooks:\n * - add import * as Sentry\n * - add Sentry.init\n * - add handleError hook wrapper\n *\n * Additionally in Server hook:\n * - add handle hook handler\n */\nasync function mergeHooksFile(\n hooksFile: string,\n hookType: 'client' | 'server',\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n includeSentryInit: boolean,\n): Promise<void> {\n const originalHooksMod = await loadFile(hooksFile);\n\n const file: 'server-hooks' | 'client-hooks' = `${hookType}-hooks`;\n\n if (hasSentryContent(originalHooksMod.$ast as t.Program)) {\n // We don't want to mess with files that already have Sentry content.\n // Let's just bail out at this point.\n clack.log.warn(\n `File ${chalk.cyan(\n path.basename(hooksFile),\n )} already contains Sentry code.\nSkipping adding Sentry functionality to.`,\n );\n Sentry.setTag(`modified-${file}`, 'fail');\n Sentry.setTag(`${file}-fail-reason`, 'has-sentry-content');\n return;\n }\n\n await modifyAndRecordFail(\n () =>\n originalHooksMod.imports.$add({\n from: '@sentry/sveltekit',\n imported: '*',\n local: 'Sentry',\n }),\n 'import-injection',\n file,\n );\n\n if (hookType === 'client' || includeSentryInit) {\n await modifyAndRecordFail(\n () => {\n if (hookType === 'client') {\n insertClientInitCall(dsn, originalHooksMod, selectedFeatures);\n } else {\n insertServerInitCall(dsn, originalHooksMod, selectedFeatures);\n }\n },\n 'init-call-injection',\n file,\n );\n }\n\n await modifyAndRecordFail(\n () => wrapHandleError(originalHooksMod),\n 'wrap-handle-error',\n file,\n );\n\n if (hookType === 'server') {\n await modifyAndRecordFail(\n () => wrapHandle(originalHooksMod),\n 'wrap-handle',\n 'server-hooks',\n );\n }\n\n await modifyAndRecordFail(\n async () => {\n const modifiedCode = originalHooksMod.generate().code;\n await fs.promises.writeFile(hooksFile, modifiedCode);\n },\n 'write-file',\n file,\n );\n\n clack.log.success(`Added Sentry code to ${hooksFile}`);\n Sentry.setTag(`modified-${hookType}-hooks`, 'success');\n}\n\n/**\n * Merges the users' instrumentation.server file with Sentry-related code.\n *\n * Both hooks:\n * - add import * as Sentry\n * - add Sentry.init\n * - add handleError hook wrapper\n *\n * Additionally in Server hook:\n * - add handle hook handler\n */\nasync function mergeInstrumentationServerFile(\n instrumentationServerFilePath: string,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): Promise<void> {\n const originalInstrumentationServerMod = await loadFile(\n instrumentationServerFilePath,\n );\n const filename = path.basename(instrumentationServerFilePath);\n\n if (hasSentryContent(originalInstrumentationServerMod.$ast as t.Program)) {\n // We don't want to mess with files that already have Sentry content.\n // Let's just bail out at this point.\n clack.log.warn(\n `File ${chalk.cyan(filename)} already contains Sentry code.\nSkipping adding Sentry functionality to it.`,\n );\n Sentry.setTag(`modified-instrumentation-server`, 'fail');\n Sentry.setTag(`instrumentation-server-fail-reason`, 'has-sentry-content');\n return;\n }\n\n await modifyAndRecordFail(\n () =>\n originalInstrumentationServerMod.imports.$add({\n from: '@sentry/sveltekit',\n imported: '*',\n local: 'Sentry',\n }),\n 'import-injection',\n 'instrumentation-server',\n );\n\n await modifyAndRecordFail(\n () => {\n insertServerInitCall(\n dsn,\n originalInstrumentationServerMod,\n selectedFeatures,\n );\n },\n 'init-call-injection',\n 'instrumentation-server',\n );\n\n await modifyAndRecordFail(\n async () => {\n const modifiedCode = originalInstrumentationServerMod.generate().code;\n await fs.promises.writeFile(instrumentationServerFilePath, modifiedCode);\n },\n 'write-file',\n 'instrumentation-server',\n );\n\n clack.log.success(`Added Sentry.init code to ${chalk.cyan(filename)}`);\n Sentry.setTag(`modified-instrumentation-server`, 'success');\n}\n\nconst DATA_COLLECTION_HINT = [\n '',\n ' dataCollection: {',\n ' // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:',\n ' // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#dataCollection',\n ' // userInfo: false,',\n ' // httpBodies: [],',\n ' },',\n].join('\\n');\n\nexport function insertClientInitCall(\n dsn: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalHooksMod: ProxifiedModule<any>,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n): void {\n const initCallComment = `\n // If you don't want to use Session Replay, remove the \\`Replay\\` integration,\n // \\`replaysSessionSampleRate\\` and \\`replaysOnErrorSampleRate\\` options.`;\n\n const initArgs: {\n dsn: string;\n tracesSampleRate?: number;\n replaysSessionSampleRate?: number;\n replaysOnErrorSampleRate?: number;\n integrations?: string[];\n enableLogs?: boolean;\n } = {\n dsn,\n };\n\n if (selectedFeatures.performance) {\n initArgs.tracesSampleRate = 1.0;\n }\n\n if (selectedFeatures.replay) {\n initArgs.replaysSessionSampleRate = 0.1;\n initArgs.replaysOnErrorSampleRate = 1.0;\n initArgs.integrations = [builders.functionCall('Sentry.replayIntegration')];\n }\n\n if (selectedFeatures.logs) {\n initArgs.enableLogs = true;\n }\n\n // This assignment of any values is fine because we're just creating a function call in magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const initCall = builders.functionCall('Sentry.init', initArgs);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const generatedInitCode = generateCode(initCall).code;\n const initCodeWithHint = generatedInitCode.replace(\n /\\n\\}\\)$/,\n `,${DATA_COLLECTION_HINT}\\n})`,\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const initCallWithComment = builders.raw(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n `${initCallComment}\\n${initCodeWithHint}`,\n );\n\n const originalHooksModAST = originalHooksMod.$ast as Program;\n\n const initCallInsertionIndex = getInitCallInsertionIndex(originalHooksModAST);\n\n originalHooksModAST.body.splice(\n initCallInsertionIndex,\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n generateCode(initCallWithComment).code,\n );\n}\n\nfunction insertServerInitCall(\n dsn: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalMod: ProxifiedModule<any>,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n): void {\n const initArgs: {\n dsn: string;\n tracesSampleRate?: number;\n enableLogs?: boolean;\n } = {\n dsn,\n };\n\n if (selectedFeatures.performance) {\n initArgs.tracesSampleRate = 1.0;\n }\n\n if (selectedFeatures.logs) {\n initArgs.enableLogs = true;\n }\n\n // This assignment of any values is fine because we're just creating a function call in magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const initCall = builders.functionCall('Sentry.init', initArgs);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const generatedInitCode = generateCode(initCall).code;\n const initCodeWithHint = generatedInitCode.replace(\n /\\n\\}\\)$/,\n `,${DATA_COLLECTION_HINT}\\n})`,\n );\n\n const originalModAST = originalMod.$ast as Program;\n\n const initCallInsertionIndex = getInitCallInsertionIndex(originalModAST);\n\n originalModAST.body.splice(\n initCallInsertionIndex,\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n initCodeWithHint,\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction wrapHandleError(mod: ProxifiedModule<any>): void {\n const modAst = mod.exports.$ast as Program;\n const namedExports = modAst.body.filter(\n (node) => node.type === 'ExportNamedDeclaration',\n ) as ExportNamedDeclaration[];\n\n let foundHandleError = false;\n\n namedExports.forEach((modExport) => {\n const declaration = modExport.declaration;\n if (!declaration) {\n return;\n }\n if (declaration.type === 'FunctionDeclaration') {\n if (!declaration.id || declaration.id.name !== 'handleError') {\n return;\n }\n foundHandleError = true;\n const userCode = generateCode(declaration).code;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handleError = builders.raw(\n `Sentry.handleErrorWithSentry(${userCode.replace(\n 'handleError',\n '_handleError',\n )})`,\n );\n // because magicast doesn't overwrite the original function export, we need to remove it manually\n modAst.body = modAst.body.filter((node) => node !== modExport);\n } else if (declaration.type === 'VariableDeclaration') {\n const declarations = declaration.declarations;\n declarations.forEach((declaration) => {\n // @ts-expect-error - id should always have a name in this case\n if (!declaration.id || declaration.id.name !== 'handleError') {\n return;\n }\n foundHandleError = true;\n const userCode = declaration.init;\n const stringifiedUserCode = userCode ? generateCode(userCode).code : '';\n // @ts-expect-error - we can just place a string here, magicast will convert it to a node\n declaration.init = `Sentry.handleErrorWithSentry(${stringifiedUserCode})`;\n });\n }\n });\n\n if (!foundHandleError) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handleError = builders.functionCall(\n 'Sentry.handleErrorWithSentry',\n );\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction wrapHandle(mod: ProxifiedModule<any>): void {\n const modAst = mod.exports.$ast as Program;\n const namedExports = modAst.body.filter(\n (node) => node.type === 'ExportNamedDeclaration',\n ) as ExportNamedDeclaration[];\n\n let foundHandle = false;\n\n namedExports.forEach((modExport) => {\n const declaration = modExport.declaration;\n if (!declaration) {\n return;\n }\n if (declaration.type === 'FunctionDeclaration') {\n if (!declaration.id || declaration.id.name !== 'handle') {\n return;\n }\n foundHandle = true;\n const userCode = generateCode(declaration).code;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handle = builders.raw(\n `sequence(Sentry.sentryHandle(), ${userCode.replace(\n 'handle',\n '_handle',\n )})`,\n );\n // because of an issue with magicast, we need to remove the original export\n modAst.body = modAst.body.filter((node) => node !== modExport);\n } else if (declaration.type === 'VariableDeclaration') {\n const declarations = declaration.declarations;\n declarations.forEach((declaration) => {\n if (\n !declaration.id ||\n declaration.id.type !== 'Identifier' ||\n (declaration.id.name && declaration.id.name !== 'handle')\n ) {\n return;\n }\n const userCode = declaration.init;\n const stringifiedUserCode = userCode ? generateCode(userCode).code : '';\n // @ts-expect-error - we can just place a string here, magicast will convert it to a node\n declaration.init = `sequence(Sentry.sentryHandle(), ${stringifiedUserCode})`;\n foundHandle = true;\n });\n }\n });\n\n if (!foundHandle) {\n // can't use builders.functionCall here because it doesn't yet\n // support member expressions (Sentry.sentryHandle()) in args\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.handle = builders.raw('sequence(Sentry.sentryHandle())');\n }\n\n try {\n mod.imports.$add({\n from: '@sveltejs/kit/hooks',\n imported: 'sequence',\n local: 'sequence',\n });\n } catch (_) {\n // It's possible sequence is already imported. in this case, magicast throws but that's fine.\n }\n}\n\n/**\n * We want to insert the init call on top of the file but after all import statements\n */\nfunction getInitCallInsertionIndex(originalModAST: Program): number {\n // We need to deep-copy here because reverse mutates in place\n const copiedBodyNodes = [...originalModAST.body];\n const lastImportDeclaration = copiedBodyNodes\n .reverse()\n .find((node) => node.type === 'ImportDeclaration');\n\n const initCallInsertionIndex = lastImportDeclaration\n ? originalModAST.body.indexOf(lastImportDeclaration) + 1\n : 0;\n return initCallInsertionIndex;\n}\n"]}
|
|
@@ -66,7 +66,7 @@ Skipping adding Sentry functionality to.`);
|
|
|
66
66
|
index: 0,
|
|
67
67
|
}), 'add-vite-plugin', 'vite-cfg');
|
|
68
68
|
await (0, utils_1.modifyAndRecordFail)(async () => {
|
|
69
|
-
const code = (0, magicast_1.generateCode)(viteModule.$ast).code;
|
|
69
|
+
const code = (0, ast_utils_1.preserveTrailingNewline)(viteConfigContent, (0, magicast_1.generateCode)(viteModule.$ast).code);
|
|
70
70
|
await fs.promises.writeFile(viteConfigPath, code);
|
|
71
71
|
}, 'write-file', 'vite-cfg');
|
|
72
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../../../../src/sveltekit/sdk-setup/vite.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qDAAuC;AACvC,uCAAyB;AACzB,2CAA6B;AAC7B,kDAA0B;AAE1B,8EAA8E;AAC9E,6DAAmC;AACnC,kFAAkF;AAClF,uCAAqD;AACrD,kFAAkF;AAClF,8CAAiD;AAMjD,
|
|
1
|
+
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../../../../src/sveltekit/sdk-setup/vite.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qDAAuC;AACvC,uCAAyB;AACzB,2CAA6B;AAC7B,kDAA0B;AAE1B,8EAA8E;AAC9E,6DAAmC;AACnC,kFAAkF;AAClF,uCAAqD;AACrD,kFAAkF;AAClF,8CAAiD;AAMjD,qDAG+B;AAC/B,6CAA0C;AAC1C,6CAAqD;AAErD,mCAA8C;AAEvC,KAAK,UAAU,gBAAgB,CACpC,cAAsB,EACtB,WAAwB;IAExB,MAAM,iBAAiB,GAAG,CACxB,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CACpD,CAAC,QAAQ,EAAE,CAAC;IAEb,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;IAEtD,MAAM,wBAAwB,GAAG,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;IAE3E,IAAI;QACF,MAAM,UAAU,GAAG,IAAA,sBAAW,EAAC,iBAAiB,CAAC,CAAC;QAElD,IAAI,IAAA,4BAAgB,EAAC,UAAU,CAAC,IAAiB,CAAC,EAAE;YAClD,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,QAAQ,wBAAwB;yCACC,CAClC,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,sBAAsB,EAAE,oBAAoB,CAAC,CAAC;YAC5D,OAAO;SACR;QAED,MAAM,IAAA,2BAAmB,EACvB,GAAG,EAAE,CACH,IAAA,uBAAa,EAAC,UAAU,EAAE;YACxB,QAAQ,EAAE,iBAAiB;YAC3B,IAAI,EAAE,mBAAmB;YACzB,WAAW,EAAE,iBAAiB;YAC9B,OAAO,EAAE;gBACP,GAAG;gBACH,OAAO;gBACP,GAAG,CAAC,UAAU,IAAI,EAAE,GAAG,EAAE,CAAC;aAC3B;YACD,KAAK,EAAE,CAAC;SACT,CAAC,EACJ,iBAAiB,EACjB,UAAU,CACX,CAAC;QAEF,MAAM,IAAA,2BAAmB,EACvB,KAAK,IAAI,EAAE;YACT,MAAM,IAAI,GAAG,IAAA,mCAAuB,EAClC,iBAAiB,EACjB,IAAA,uBAAY,EAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CACnC,CAAC;YACF,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC,EACD,YAAY,EACZ,UAAU,CACX,CAAC;KACH;IAAC,OAAO,CAAC,EAAE;QACV,IAAA,aAAK,EAAC,CAAC,CAAC,CAAC;QACT,MAAM,gCAAgC,CACpC,cAAc,EACd,wBAAwB,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CACxD,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,yCAAyC,CAAC,CAAC;KACpE;IAED,iBAAK,CAAC,GAAG,CAAC,OAAO,CAAC,wBAAwB,wBAAwB,EAAE,CAAC,CAAC;IACtE,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAhED,4CAgEC;AAED,KAAK,UAAU,gCAAgC,CAC7C,cAAsB,EACtB,WAAmB;IAEnB,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAEzD,iBAAK,CAAC,GAAG,CAAC,OAAO,CACf,sCAAsC,eAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC;EACtE,eAAK,CAAC,GAAG,CAAC;wEAC4D,CAAC,EAAE,CACxE,CAAC;IAEF,iBAAK,CAAC,GAAG,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;IAEzE,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,kCAAkC,eAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CACpE,CAAC;IAEF,gEAAgE;IAChE,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEzB,MAAM,IAAA,wBAAgB,EACpB,iBAAK,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,iCAAiC;QAC1C,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,2BAA2B,EAAE;SAClE;QACD,YAAY,EAAE,IAAI;KACnB,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,wBAAwB,GAAG,CAC/B,GAAW,EACX,OAAe,EACf,UAAmB,EACnB,GAAW,EACX,EAAE,CACF,eAAK,CAAC,IAAI,CAAC;;;EAGX,eAAK,CAAC,WAAW,CAAC,qDAAqD,CAAC;;;;;MAKpE,eAAK,CAAC,WAAW,CAAC;cACV,GAAG;kBACC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE;QAClE,CAAC;;;;CAIR,CAAC,CAAC","sourcesContent":["import * as Sentry from '@sentry/node';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport chalk from 'chalk';\n\n//@ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { addVitePlugin } from 'magicast/helpers';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nimport {\n hasSentryContent,\n preserveTrailingNewline,\n} from '../../utils/ast-utils';\nimport { debug } from '../../utils/debug';\nimport { abortIfCancelled } from '../../utils/clack';\nimport type { ProjectInfo } from './types';\nimport { modifyAndRecordFail } from './utils';\n\nexport async function modifyViteConfig(\n viteConfigPath: string,\n projectInfo: ProjectInfo,\n): Promise<void> {\n const viteConfigContent = (\n await fs.promises.readFile(viteConfigPath, 'utf-8')\n ).toString();\n\n const { org, project, url, selfHosted } = projectInfo;\n\n const prettyViteConfigFilename = chalk.cyan(path.basename(viteConfigPath));\n\n try {\n const viteModule = parseModule(viteConfigContent);\n\n if (hasSentryContent(viteModule.$ast as t.Program)) {\n clack.log.warn(\n `File ${prettyViteConfigFilename} already contains Sentry code.\nSkipping adding Sentry functionality to.`,\n );\n Sentry.setTag(`modified-vite-cfg`, 'fail');\n Sentry.setTag(`vite-cfg-fail-reason`, 'has-sentry-content');\n return;\n }\n\n await modifyAndRecordFail(\n () =>\n addVitePlugin(viteModule, {\n imported: 'sentrySvelteKit',\n from: '@sentry/sveltekit',\n constructor: 'sentrySvelteKit',\n options: {\n org,\n project,\n ...(selfHosted && { url }),\n },\n index: 0,\n }),\n 'add-vite-plugin',\n 'vite-cfg',\n );\n\n await modifyAndRecordFail(\n async () => {\n const code = preserveTrailingNewline(\n viteConfigContent,\n generateCode(viteModule.$ast).code,\n );\n await fs.promises.writeFile(viteConfigPath, code);\n },\n 'write-file',\n 'vite-cfg',\n );\n } catch (e) {\n debug(e);\n await showFallbackViteCopyPasteSnippet(\n viteConfigPath,\n getViteConfigCodeSnippet(org, project, selfHosted, url),\n );\n Sentry.captureException('Sveltekit Vite Config Modification Fail');\n }\n\n clack.log.success(`Added Sentry code to ${prettyViteConfigFilename}`);\n Sentry.setTag(`modified-vite-cfg`, 'success');\n}\n\nasync function showFallbackViteCopyPasteSnippet(\n viteConfigPath: string,\n codeSnippet: string,\n) {\n const viteConfigFilename = path.basename(viteConfigPath);\n\n clack.log.warning(\n `Couldn't automatically modify your ${chalk.cyan(viteConfigFilename)}\n${chalk.dim(`This sometimes happens when we encounter more complex vite configs.\nIt may not seem like it but sometimes our magical powers are limited ;)`)}`,\n );\n\n clack.log.info(\"But don't worry - it's super easy to do this yourself!\");\n\n clack.log.step(\n `Add the following code to your ${chalk.cyan(viteConfigFilename)}:`,\n );\n\n // Intentionally logging to console here for easier copy/pasting\n // eslint-disable-next-line no-console\n console.log(codeSnippet);\n\n await abortIfCancelled(\n clack.select({\n message: 'Did you copy the snippet above?',\n options: [\n { label: 'Yes!', value: true, hint: \"Great, that's already it!\" },\n ],\n initialValue: true,\n }),\n );\n}\n\nconst getViteConfigCodeSnippet = (\n org: string,\n project: string,\n selfHosted: boolean,\n url: string,\n) =>\n chalk.gray(`\nimport { sveltekit } from '@sveltejs/kit/vite';\nimport { defineConfig } from 'vite';\n${chalk.greenBright(\"import { sentrySvelteKit } from '@sentry/sveltekit'\")}\n\nexport default defineConfig({\n plugins: [\n // Make sure \\`sentrySvelteKit\\` is registered before \\`sveltekit\\`\n ${chalk.greenBright(`sentrySvelteKit({\n org: '${org}',\n project: '${project}',${selfHosted ? `\\n url: '${url}',` : ''}\n }),`)}\n sveltekit(),\n ]\n});\n`);\n"]}
|
|
@@ -30,9 +30,12 @@ ${selectedFeatures.replay
|
|
|
30
30
|
integrations: [replayIntegration()],`
|
|
31
31
|
: ''}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
dataCollection: {
|
|
34
|
+
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
|
35
|
+
// https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#dataCollection
|
|
36
|
+
// userInfo: false,
|
|
37
|
+
// httpBodies: [],
|
|
38
|
+
},
|
|
36
39
|
});
|
|
37
40
|
|
|
38
41
|
// If you have a custom error handler, pass it to \`handleErrorWithSentry\`
|
|
@@ -57,9 +60,12 @@ ${selectedFeatures.logs
|
|
|
57
60
|
`
|
|
58
61
|
: ''}
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
dataCollection: {
|
|
64
|
+
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
|
65
|
+
// https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#dataCollection
|
|
66
|
+
// userInfo: false,
|
|
67
|
+
// httpBodies: [],
|
|
68
|
+
},
|
|
63
69
|
|
|
64
70
|
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
65
71
|
// spotlight: import.meta.env.DEV,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/sveltekit/templates.ts"],"names":[],"mappings":";;;AAAA,SAAgB,sBAAsB,CACpC,GAAW,EACX,gBAIC;IAED,OAAO;;;;UAIC,GAAG;EAEX,gBAAgB,CAAC,WAAW;QAC1B,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,IAAI;QACnB,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,MAAM;QACrB,CAAC,CAAC;;;;;;;;;uCASiC;QACnC,CAAC,CAAC,EACN;;;;;;;;;CASC,CAAC;AACF,CAAC;AAlDD,wDAkDC;AAED,SAAgB,sBAAsB,CACpC,GAAW,EACX,gBAIC,EACD,iBAA0B;IAE1B,MAAM,UAAU,GAAG,iBAAiB;QAClC,CAAC,CAAC;;;UAGI,GAAG;EAEX,gBAAgB,CAAC,WAAW;YAC1B,CAAC,CAAC;;CAEL;YACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,IAAI;YACnB,CAAC,CAAC;;CAEL;YACG,CAAC,CAAC,EACN;;;;;;;;IAQI;QACA,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;EAEP,UAAU;;;;;;;CAOX,CAAC;AACF,CAAC;AAhDD,wDAgDC;AAED,SAAgB,gCAAgC,CAC9C,GAAW,EACX,gBAGC;IAED,OAAO;;;UAGC,GAAG;EAEX,gBAAgB,CAAC,WAAW;QAC1B,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,IAAI;QACnB,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;;;IAGI,CAAC;AACL,CAAC;AA5BD,4EA4BC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CAAC,OAM1C;IACC,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU;QACvC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,iBAAiB,OAAO,CAAC,OAAO,oBAAoB,OAAO,CAAC,SAAS,EAAE;QACvF,CAAC,CAAC,WAAW,OAAO,CAAC,OAAO,8BAA8B,OAAO,CAAC,SAAS,EAAE,CAAC;IAEhF,OAAO;;;;;;;;;uBASc,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iGAsCwB,cAAc;;;;;;UAMrG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4J1C,CAAC;AACF,CAAC;AA7ND,gEA6NC;AAED,SAAgB,wBAAwB;IACtC,OAAO;;;;;;CAMR,CAAC;AACF,CAAC;AARD,4DAQC","sourcesContent":["export function getClientHooksTemplate(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n) {\n return `import { handleErrorWithSentry, replayIntegration } from \"@sentry/sveltekit\";\nimport * as Sentry from '@sentry/sveltekit';\n\nSentry.init({\n dsn: '${dsn}',\n${\n selectedFeatures.performance\n ? `\n tracesSampleRate: 1.0,\n`\n : ''\n}\n${\n selectedFeatures.logs\n ? ` // Enable logs to be sent to Sentry\n enableLogs: true,\n`\n : ''\n}\n${\n selectedFeatures.replay\n ? ` // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // If the entire session is not sampled, use the below sample rate to sample\n // sessions when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // If you don't want to use Session Replay, just remove the line below:\n integrations: [replayIntegration()],`\n : ''\n}\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n});\n\n// If you have a custom error handler, pass it to \\`handleErrorWithSentry\\`\nexport const handleError = handleErrorWithSentry();\n`;\n}\n\nexport function getServerHooksTemplate(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n includeSentryInit: boolean,\n) {\n const sentryInit = includeSentryInit\n ? `import * as Sentry from '@sentry/sveltekit';\n\nSentry.init({\n dsn: '${dsn}',\n${\n selectedFeatures.performance\n ? `\n tracesSampleRate: 1.0,\n`\n : ''\n}\n${\n selectedFeatures.logs\n ? ` // Enable logs to be sent to Sentry\n enableLogs: true,\n`\n : ''\n}\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n});`\n : ``;\n\n return `import { sequence } from \"@sveltejs/kit/hooks\";\nimport { handleErrorWithSentry, sentryHandle } from \"@sentry/sveltekit\";\n${sentryInit}\n\n// If you have custom handlers, make sure to place them after \\`sentryHandle()\\` in the \\`sequence\\` function.\nexport const handle = sequence(sentryHandle());\n\n// If you have a custom error handler, pass it to \\`handleErrorWithSentry\\`\nexport const handleError = handleErrorWithSentry();\n`;\n}\n\nexport function getInstrumentationServerTemplate(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n) {\n return `import * as Sentry from '@sentry/sveltekit';\n\nSentry.init({\n dsn: '${dsn}',\n${\n selectedFeatures.performance\n ? `\n tracesSampleRate: 1.0,\n`\n : ''\n}\n${\n selectedFeatures.logs\n ? ` // Enable logs to be sent to Sentry\n enableLogs: true,\n`\n : ''\n}\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n});`;\n}\n\n/**\n * +page.svelte with Sentry example\n */\nexport function getSentryExampleSveltePage(options: {\n selfHosted: boolean;\n url: string;\n orgSlug: string;\n projectId: string;\n isUsingSvelte5: boolean;\n}) {\n const issuesPageLink = options.selfHosted\n ? `${options.url}organizations/${options.orgSlug}/issues/?project=${options.projectId}`\n : `https://${options.orgSlug}.sentry.io/issues/?project=${options.projectId}`;\n\n return `<!--\nThis is just a very simple page with a button to throw an example error.\nFeel free to delete this file and the entire sentry route.\n-->\n\n<script>\n import * as Sentry from '@sentry/sveltekit';\n import { onMount } from 'svelte';\n \n let hasSentError = ${options.isUsingSvelte5 ? '$state(false)' : 'false'};\n let isConnected = true;\n\n onMount(async () => {\n const result = await Sentry.diagnoseSdkConnectivity();\n isConnected = result !== 'sentry-unreachable';\n });\n\n function getSentryData() {\n Sentry.startSpan(\n {\n name: 'Example Frontend Span',\n op: 'test'\n },\n async () => {\n const res = await fetch('/sentry-example-page');\n if (!res.ok) {\n hasSentError = true;\n throw new Error('Sentry Example Frontend Error');\n }\n }\n );\n }\n</script>\n\n<title>sentry-example-page</title>\n\n<div>\n <main>\n <div class=\"flex-spacer\"></div>\n <svg height=\"40\" width=\"40\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.85 2.995a3.698 3.698 0 0 1 1.353 1.354l16.303 28.278a3.703 3.703 0 0 1-1.354 5.053 3.694 3.694 0 0 1-1.848.496h-3.828a31.149 31.149 0 0 0 0-3.09h3.815a.61.61 0 0 0 .537-.917L20.523 5.893a.61.61 0 0 0-1.057 0l-3.739 6.494a28.948 28.948 0 0 1 9.63 10.453 28.988 28.988 0 0 1 3.499 13.78v1.542h-9.852v-1.544a19.106 19.106 0 0 0-2.182-8.85 19.08 19.08 0 0 0-6.032-6.829l-1.85 3.208a15.377 15.377 0 0 1 6.382 12.484v1.542H3.696A3.694 3.694 0 0 1 0 34.473c0-.648.17-1.286.494-1.849l2.33-4.074a8.562 8.562 0 0 1 2.689 1.536L3.158 34.17a.611.611 0 0 0 .538.917h8.448a12.481 12.481 0 0 0-6.037-9.09l-1.344-.772 4.908-8.545 1.344.77a22.16 22.16 0 0 1 7.705 7.444 22.193 22.193 0 0 1 3.316 10.193h3.699a25.892 25.892 0 0 0-3.811-12.033 25.856 25.856 0 0 0-9.046-8.796l-1.344-.772 5.269-9.136a3.698 3.698 0 0 1 3.2-1.849c.648 0 1.285.17 1.847.495Z\" fill=\"currentcolor\"/>\n </svg>\n <h1>\n sentry-example-page\n </h1>\n\n <p class=\"description\">\n Click the button below, and view the sample error on the Sentry <a target=\"_blank\" href=\"${issuesPageLink}\">Issues Page</a>. \n For more details about setting up Sentry, <a target=\"_blank\" href=\"https://docs.sentry.io/platforms/javascript/guides/sveltekit/\">read our docs</a>.\n </p>\n\n <button\n type=\"button\"\n on${options.isUsingSvelte5 ? '' : ':'}click={getSentryData}\n disabled={!isConnected}\n >\n <span>\n Throw Sample Error\n </span>\n </button>\n\n {#if hasSentError}\n <p class=\"success\">\n Sample error was sent to Sentry.\n </p>\n {:else if !isConnected}\n <div class=\"connectivity-error\">\n <p>It looks like network requests to Sentry are being blocked, which will prevent errors from being captured. Try disabling your ad-blocker to complete the test.</p>\n </div>\n {:else}\n <div class=\"success_placeholder\"></div>\n {/if}\n <div class=\"flex-spacer\"></div>\n </main>\n</div>\n\n<style>\n :global(body) {\n margin: 0;\n\n @media (prefers-color-scheme: dark) {\n color: #ededed;\n background-color: #0a0a0a;\n }\n }\n\n main {\n display: flex;\n min-height: 100vh;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n box-sizing: border-box;\n gap: 16px;\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n\n h1 {\n padding: 0px 4px;\n border-radius: 4px;\n background-color: rgba(24, 20, 35, 0.03);\n font-family: monospace;\n font-size: 20px;\n line-height: 1.2;\n }\n\n p {\n margin: 0;\n font-size: 20px;\n }\n\n a {\n color: #6341F0;\n text-decoration: underline;\n cursor: pointer;\n\n @media (prefers-color-scheme: dark) {\n color: #B3A1FF;\n }\n }\n\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n\n & > span {\n transform: translateY(0);\n border: none;\n }\n }\n }\n\n .description {\n text-align: center;\n color: #6E6C75;\n max-width: 500px;\n line-height: 1.5;\n font-size: 20px;\n\n @media (prefers-color-scheme: dark) {\n color: #A49FB5;\n }\n }\n\n .flex-spacer {\n flex: 1;\n }\n\n .success {\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n }\n\n .success_placeholder {\n height: 46px;\n }\n\n .connectivity-error {\n padding: 12px 16px;\n background-color: #E50045;\n border-radius: 8px;\n width: 500px;\n color: #FFFFFF;\n border: 1px solid #A80033;\n text-align: center;\n margin: 0;\n }\n \n .connectivity-error a {\n color: #FFFFFF;\n text-decoration: underline;\n }\n</style>\n`;\n}\n\nexport function getSentryExampleApiRoute() {\n return `// This is just a very simple API route that throws an example error.\n// Feel free to delete this file and the entire sentry route.\n\nexport const GET = async () => {\n throw new Error(\"Sentry Example API Route Error\");\n};\n`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/sveltekit/templates.ts"],"names":[],"mappings":";;;AAAA,SAAgB,sBAAsB,CACpC,GAAW,EACX,gBAIC;IAED,OAAO;;;;UAIC,GAAG;EAEX,gBAAgB,CAAC,WAAW;QAC1B,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,IAAI;QACnB,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,MAAM;QACrB,CAAC,CAAC;;;;;;;;;uCASiC;QACnC,CAAC,CAAC,EACN;;;;;;;;;;;;CAYC,CAAC;AACF,CAAC;AArDD,wDAqDC;AAED,SAAgB,sBAAsB,CACpC,GAAW,EACX,gBAIC,EACD,iBAA0B;IAE1B,MAAM,UAAU,GAAG,iBAAiB;QAClC,CAAC,CAAC;;;UAGI,GAAG;EAEX,gBAAgB,CAAC,WAAW;YAC1B,CAAC,CAAC;;CAEL;YACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,IAAI;YACnB,CAAC,CAAC;;CAEL;YACG,CAAC,CAAC,EACN;;;;;;;;;;;IAWI;QACA,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;EAEP,UAAU;;;;;;;CAOX,CAAC;AACF,CAAC;AAnDD,wDAmDC;AAED,SAAgB,gCAAgC,CAC9C,GAAW,EACX,gBAGC;IAED,OAAO;;;UAGC,GAAG;EAEX,gBAAgB,CAAC,WAAW;QAC1B,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;EAEE,gBAAgB,CAAC,IAAI;QACnB,CAAC,CAAC;;CAEL;QACG,CAAC,CAAC,EACN;;;IAGI,CAAC;AACL,CAAC;AA5BD,4EA4BC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CAAC,OAM1C;IACC,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU;QACvC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,iBAAiB,OAAO,CAAC,OAAO,oBAAoB,OAAO,CAAC,SAAS,EAAE;QACvF,CAAC,CAAC,WAAW,OAAO,CAAC,OAAO,8BAA8B,OAAO,CAAC,SAAS,EAAE,CAAC;IAEhF,OAAO;;;;;;;;;uBASc,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iGAsCwB,cAAc;;;;;;UAMrG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4J1C,CAAC;AACF,CAAC;AA7ND,gEA6NC;AAED,SAAgB,wBAAwB;IACtC,OAAO;;;;;;CAMR,CAAC;AACF,CAAC;AARD,4DAQC","sourcesContent":["export function getClientHooksTemplate(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n) {\n return `import { handleErrorWithSentry, replayIntegration } from \"@sentry/sveltekit\";\nimport * as Sentry from '@sentry/sveltekit';\n\nSentry.init({\n dsn: '${dsn}',\n${\n selectedFeatures.performance\n ? `\n tracesSampleRate: 1.0,\n`\n : ''\n}\n${\n selectedFeatures.logs\n ? ` // Enable logs to be sent to Sentry\n enableLogs: true,\n`\n : ''\n}\n${\n selectedFeatures.replay\n ? ` // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // If the entire session is not sampled, use the below sample rate to sample\n // sessions when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // If you don't want to use Session Replay, just remove the line below:\n integrations: [replayIntegration()],`\n : ''\n}\n\n dataCollection: {\n // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:\n // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#dataCollection\n // userInfo: false,\n // httpBodies: [],\n },\n});\n\n// If you have a custom error handler, pass it to \\`handleErrorWithSentry\\`\nexport const handleError = handleErrorWithSentry();\n`;\n}\n\nexport function getServerHooksTemplate(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n },\n includeSentryInit: boolean,\n) {\n const sentryInit = includeSentryInit\n ? `import * as Sentry from '@sentry/sveltekit';\n\nSentry.init({\n dsn: '${dsn}',\n${\n selectedFeatures.performance\n ? `\n tracesSampleRate: 1.0,\n`\n : ''\n}\n${\n selectedFeatures.logs\n ? ` // Enable logs to be sent to Sentry\n enableLogs: true,\n`\n : ''\n}\n\n dataCollection: {\n // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:\n // https://docs.sentry.io/platforms/javascript/guides/sveltekit/configuration/options/#dataCollection\n // userInfo: false,\n // httpBodies: [],\n },\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n});`\n : ``;\n\n return `import { sequence } from \"@sveltejs/kit/hooks\";\nimport { handleErrorWithSentry, sentryHandle } from \"@sentry/sveltekit\";\n${sentryInit}\n\n// If you have custom handlers, make sure to place them after \\`sentryHandle()\\` in the \\`sequence\\` function.\nexport const handle = sequence(sentryHandle());\n\n// If you have a custom error handler, pass it to \\`handleErrorWithSentry\\`\nexport const handleError = handleErrorWithSentry();\n`;\n}\n\nexport function getInstrumentationServerTemplate(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n) {\n return `import * as Sentry from '@sentry/sveltekit';\n\nSentry.init({\n dsn: '${dsn}',\n${\n selectedFeatures.performance\n ? `\n tracesSampleRate: 1.0,\n`\n : ''\n}\n${\n selectedFeatures.logs\n ? ` // Enable logs to be sent to Sentry\n enableLogs: true,\n`\n : ''\n}\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: import.meta.env.DEV,\n});`;\n}\n\n/**\n * +page.svelte with Sentry example\n */\nexport function getSentryExampleSveltePage(options: {\n selfHosted: boolean;\n url: string;\n orgSlug: string;\n projectId: string;\n isUsingSvelte5: boolean;\n}) {\n const issuesPageLink = options.selfHosted\n ? `${options.url}organizations/${options.orgSlug}/issues/?project=${options.projectId}`\n : `https://${options.orgSlug}.sentry.io/issues/?project=${options.projectId}`;\n\n return `<!--\nThis is just a very simple page with a button to throw an example error.\nFeel free to delete this file and the entire sentry route.\n-->\n\n<script>\n import * as Sentry from '@sentry/sveltekit';\n import { onMount } from 'svelte';\n \n let hasSentError = ${options.isUsingSvelte5 ? '$state(false)' : 'false'};\n let isConnected = true;\n\n onMount(async () => {\n const result = await Sentry.diagnoseSdkConnectivity();\n isConnected = result !== 'sentry-unreachable';\n });\n\n function getSentryData() {\n Sentry.startSpan(\n {\n name: 'Example Frontend Span',\n op: 'test'\n },\n async () => {\n const res = await fetch('/sentry-example-page');\n if (!res.ok) {\n hasSentError = true;\n throw new Error('Sentry Example Frontend Error');\n }\n }\n );\n }\n</script>\n\n<title>sentry-example-page</title>\n\n<div>\n <main>\n <div class=\"flex-spacer\"></div>\n <svg height=\"40\" width=\"40\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.85 2.995a3.698 3.698 0 0 1 1.353 1.354l16.303 28.278a3.703 3.703 0 0 1-1.354 5.053 3.694 3.694 0 0 1-1.848.496h-3.828a31.149 31.149 0 0 0 0-3.09h3.815a.61.61 0 0 0 .537-.917L20.523 5.893a.61.61 0 0 0-1.057 0l-3.739 6.494a28.948 28.948 0 0 1 9.63 10.453 28.988 28.988 0 0 1 3.499 13.78v1.542h-9.852v-1.544a19.106 19.106 0 0 0-2.182-8.85 19.08 19.08 0 0 0-6.032-6.829l-1.85 3.208a15.377 15.377 0 0 1 6.382 12.484v1.542H3.696A3.694 3.694 0 0 1 0 34.473c0-.648.17-1.286.494-1.849l2.33-4.074a8.562 8.562 0 0 1 2.689 1.536L3.158 34.17a.611.611 0 0 0 .538.917h8.448a12.481 12.481 0 0 0-6.037-9.09l-1.344-.772 4.908-8.545 1.344.77a22.16 22.16 0 0 1 7.705 7.444 22.193 22.193 0 0 1 3.316 10.193h3.699a25.892 25.892 0 0 0-3.811-12.033 25.856 25.856 0 0 0-9.046-8.796l-1.344-.772 5.269-9.136a3.698 3.698 0 0 1 3.2-1.849c.648 0 1.285.17 1.847.495Z\" fill=\"currentcolor\"/>\n </svg>\n <h1>\n sentry-example-page\n </h1>\n\n <p class=\"description\">\n Click the button below, and view the sample error on the Sentry <a target=\"_blank\" href=\"${issuesPageLink}\">Issues Page</a>. \n For more details about setting up Sentry, <a target=\"_blank\" href=\"https://docs.sentry.io/platforms/javascript/guides/sveltekit/\">read our docs</a>.\n </p>\n\n <button\n type=\"button\"\n on${options.isUsingSvelte5 ? '' : ':'}click={getSentryData}\n disabled={!isConnected}\n >\n <span>\n Throw Sample Error\n </span>\n </button>\n\n {#if hasSentError}\n <p class=\"success\">\n Sample error was sent to Sentry.\n </p>\n {:else if !isConnected}\n <div class=\"connectivity-error\">\n <p>It looks like network requests to Sentry are being blocked, which will prevent errors from being captured. Try disabling your ad-blocker to complete the test.</p>\n </div>\n {:else}\n <div class=\"success_placeholder\"></div>\n {/if}\n <div class=\"flex-spacer\"></div>\n </main>\n</div>\n\n<style>\n :global(body) {\n margin: 0;\n\n @media (prefers-color-scheme: dark) {\n color: #ededed;\n background-color: #0a0a0a;\n }\n }\n\n main {\n display: flex;\n min-height: 100vh;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n box-sizing: border-box;\n gap: 16px;\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n\n h1 {\n padding: 0px 4px;\n border-radius: 4px;\n background-color: rgba(24, 20, 35, 0.03);\n font-family: monospace;\n font-size: 20px;\n line-height: 1.2;\n }\n\n p {\n margin: 0;\n font-size: 20px;\n }\n\n a {\n color: #6341F0;\n text-decoration: underline;\n cursor: pointer;\n\n @media (prefers-color-scheme: dark) {\n color: #B3A1FF;\n }\n }\n\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n\n & > span {\n transform: translateY(0);\n border: none;\n }\n }\n }\n\n .description {\n text-align: center;\n color: #6E6C75;\n max-width: 500px;\n line-height: 1.5;\n font-size: 20px;\n\n @media (prefers-color-scheme: dark) {\n color: #A49FB5;\n }\n }\n\n .flex-spacer {\n flex: 1;\n }\n\n .success {\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n }\n\n .success_placeholder {\n height: 46px;\n }\n\n .connectivity-error {\n padding: 12px 16px;\n background-color: #E50045;\n border-radius: 8px;\n width: 500px;\n color: #FFFFFF;\n border: 1px solid #A80033;\n text-align: center;\n margin: 0;\n }\n \n .connectivity-error a {\n color: #FFFFFF;\n text-decoration: underline;\n }\n</style>\n`;\n}\n\nexport function getSentryExampleApiRoute() {\n return `// This is just a very simple API route that throws an example error.\n// Feel free to delete this file and the entire sentry route.\n\nexport const GET = async () => {\n throw new Error(\"Sentry Example API Route Error\");\n};\n`;\n}\n"]}
|
|
@@ -116,4 +116,14 @@ export declare function safeInsertBeforeReturn(body: t.Statement[], statement: t
|
|
|
116
116
|
* @returns The matching ObjectProperty, or undefined if not found
|
|
117
117
|
*/
|
|
118
118
|
export declare function findProperty(configObj: t.ObjectExpression, name: string): t.ObjectProperty | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* Preserves trailing newline from original content if present.
|
|
121
|
+
* Code generators like magicast/recast don't preserve trailing newlines,
|
|
122
|
+
* so this ensures we don't unnecessarily modify user files.
|
|
123
|
+
*
|
|
124
|
+
* @param originalContent - The original file content
|
|
125
|
+
* @param generatedCode - The code generated by AST transformation
|
|
126
|
+
* @returns The generated code with trailing newline preserved if original had one
|
|
127
|
+
*/
|
|
128
|
+
export declare function preserveTrailingNewline(originalContent: string, generatedCode: string): string;
|
|
119
129
|
export {};
|
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.findProperty = exports.safeInsertBeforeReturn = exports.safeGetFunctionBody = exports.safeGetIdentifierName = exports.safeCalleeIdentifierMatch = exports.getLastRequireIndex = exports.printJsonC = exports.parseJsonC = exports.setOrUpdateObjectProperty = exports.getOrSetObjectProperty = exports.getObjectProperty = exports.hasSentryContent = exports.findFile = void 0;
|
|
26
|
+
exports.preserveTrailingNewline = exports.findProperty = exports.safeInsertBeforeReturn = exports.safeGetFunctionBody = exports.safeGetIdentifierName = exports.safeCalleeIdentifierMatch = exports.getLastRequireIndex = exports.printJsonC = exports.parseJsonC = exports.setOrUpdateObjectProperty = exports.getOrSetObjectProperty = exports.getObjectProperty = exports.hasSentryContent = exports.findFile = void 0;
|
|
27
27
|
const fs = __importStar(require("fs"));
|
|
28
28
|
const recast = __importStar(require("recast"));
|
|
29
29
|
const b = recast.types.builders;
|
|
@@ -285,4 +285,22 @@ function findProperty(configObj, name) {
|
|
|
285
285
|
p.key.name === name); // Safe: predicate guarantees type
|
|
286
286
|
}
|
|
287
287
|
exports.findProperty = findProperty;
|
|
288
|
+
/**
|
|
289
|
+
* Preserves trailing newline from original content if present.
|
|
290
|
+
* Code generators like magicast/recast don't preserve trailing newlines,
|
|
291
|
+
* so this ensures we don't unnecessarily modify user files.
|
|
292
|
+
*
|
|
293
|
+
* @param originalContent - The original file content
|
|
294
|
+
* @param generatedCode - The code generated by AST transformation
|
|
295
|
+
* @returns The generated code with trailing newline preserved if original had one
|
|
296
|
+
*/
|
|
297
|
+
function preserveTrailingNewline(originalContent, generatedCode) {
|
|
298
|
+
const hadTrailingNewline = originalContent.endsWith('\n');
|
|
299
|
+
const hasTrailingNewline = generatedCode.endsWith('\n');
|
|
300
|
+
if (hadTrailingNewline && !hasTrailingNewline) {
|
|
301
|
+
return generatedCode + '\n';
|
|
302
|
+
}
|
|
303
|
+
return generatedCode;
|
|
304
|
+
}
|
|
305
|
+
exports.preserveTrailingNewline = preserveTrailingNewline;
|
|
288
306
|
//# sourceMappingURL=ast-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../../src/utils/ast-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nconst b = recast.types.builders;\n\n/**\n * Checks if a file where we don't know its concrete file type yet exists\n * and returns the full path to the file with the correct file type.\n */\nexport function findFile(\n filePath: string,\n fileTypes: string[] = ['.js', '.ts', '.mjs', '.cjs'],\n): string | undefined {\n return fileTypes\n .map((type) => `${filePath}${type}`)\n .find((file) => fs.existsSync(file));\n}\n\n/**\n * checks for require('@sentry/*') syntax\n */\nexport function hasSentryContent(program: t.Program): boolean {\n let foundSentry: boolean | undefined = false;\n recast.visit(program, {\n visitStringLiteral(path) {\n foundSentry = foundSentry || path.node.value.startsWith('@sentry/');\n this.traverse(path);\n },\n visitLiteral(path) {\n foundSentry =\n foundSentry || path.node.value?.toString().startsWith('@sentry/');\n this.traverse(path);\n },\n });\n\n return !!foundSentry;\n}\n\n/**\n * Searches for a property of an ObjectExpression by name\n *\n * @param object the ObjectExpression to search in\n * @param name the name of the property to search for\n *\n * @returns the property if it exists\n */\nexport function getObjectProperty(\n object: t.ObjectExpression,\n name: string,\n): t.Property | undefined {\n return object.properties.find((p): p is t.Property => {\n const isObjectProp = p.type === 'Property' || p.type === 'ObjectProperty';\n\n if (!isObjectProp) {\n return false;\n }\n\n const hasMatchingLiteralKey =\n isObjectProp &&\n (p.key.type === 'Literal' || p.key.type === 'StringLiteral') &&\n p.key.value === name;\n\n if (hasMatchingLiteralKey) {\n return true;\n }\n\n // has matching identifier key\n return isObjectProp && p.key.type === 'Identifier' && p.key.name === name;\n });\n}\n\n/**\n * Attempts to find a property of an ObjectExpression by name. If it doesn't exist,\n * the property will be added to the ObjectExpression with the provided default value.\n *\n * @param object the parent object expression to search in\n * @param name the name of the property to search for\n * @param defaultValue the default value to set if the property doesn't exist\n *\n * @returns the\n */\nexport function getOrSetObjectProperty(\n object: t.ObjectExpression,\n name: string,\n defaultValue:\n | t.Literal\n | t.BooleanLiteral\n | t.StringLiteral\n | t.ObjectExpression,\n): t.Property {\n const existingProperty = getObjectProperty(object, name);\n\n if (existingProperty) {\n return existingProperty;\n }\n\n const newProperty = b.property.from({\n kind: 'init',\n key: b.stringLiteral(name),\n value: defaultValue,\n });\n\n object.properties.push(newProperty);\n\n return newProperty;\n}\n\n/**\n * Sets a property of an ObjectExpression if it exists, otherwise adds it\n * to the ObjectExpression. Optionally, a comment can be added to the\n * property.\n *\n * @param object the ObjectExpression to set the property on\n * @param name the name of the property to set\n * @param value the value of the property to set\n * @param comment (optional) a comment to add to the property\n */\nexport function setOrUpdateObjectProperty(\n object: t.ObjectExpression,\n name: string,\n value:\n | t.Literal\n | t.BooleanLiteral\n | t.StringLiteral\n | t.ObjectExpression\n | t.ArrayExpression,\n comment?: string,\n): void {\n const newComments =\n comment &&\n comment.split('\\n').map((c) => b.commentLine(` ${c}`, true, false));\n\n const existingProperty = getObjectProperty(object, name);\n\n if (existingProperty) {\n existingProperty.value = value;\n if (newComments) {\n existingProperty.comments = [\n ...(existingProperty?.comments || []),\n ...newComments,\n ];\n }\n } else {\n object.properties.push(\n b.objectProperty.from({\n key: b.stringLiteral(name),\n value,\n ...(newComments && {\n comments: newComments,\n }),\n }),\n );\n }\n}\n\ntype JsonCParseResult =\n | {\n jsonObject: t.ObjectExpression;\n ast: t.Program;\n }\n | {\n jsonObject: undefined;\n ast: undefined;\n };\n\n/**\n * Parses a JSON string with (potential) comments (JSON-C) and returns the JS AST\n * that can be walked and modified with recast like a normal JS AST.\n *\n * This is done by wrapping the JSON-C string in parentheses, thereby making it\n * a JS `Program` with an `ExpressionStatement` as its body. The expression is then\n * extracted from the AST and returned alongside the AST.\n *\n * To preserve as much original formatting as possible, the returned `ast`\n * property should be passed to {@link `printJsonC`} to get the JSON-C string back.\n *\n * If the input is not valid JSON-C, the result will be undefined.\n *\n * @see {@link JsonCParseResult}\n *\n * @param jsonString a JSON-C string\n *\n * @returns a {@link JsonCParseResult}, containing either the JSON-C object and the AST or undefined in both cases\n */\nexport function parseJsonC(jsonString: string): JsonCParseResult {\n try {\n const jsTsConfig = `(${jsonString})`;\n // no idea why recast returns any here, this is dumb :/\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const ast = recast.parse(jsTsConfig.toString()).program as t.Program;\n\n const jsonObject =\n (ast.body[0].type === 'ExpressionStatement' &&\n ast.body[0].expression.type === 'ObjectExpression' &&\n ast.body[0].expression) ||\n undefined;\n\n if (jsonObject) {\n return { jsonObject, ast };\n }\n } catch {\n /* empty */\n }\n return { jsonObject: undefined, ast: undefined };\n}\n\n/**\n * Takes the AST of a parsed JSON-C \"program\" and returns the JSON-C string without\n * any of the temporary JS wrapper code that was previously applied.\n *\n * Only use this in conjunction with {@link `parseJsonC`}\n *\n * @param ast the `ast` returned from {@link `parseJsonC`}\n *\n * @returns the JSON-C string\n */\nexport function printJsonC(ast: t.Program): string {\n const js = recast.print(ast).code;\n return js.substring(1, js.length - 1);\n}\n\n/**\n * Walks the program body and returns index of the last variable assignment initialized by require statement.\n * Only counts top level require statements.\n *\n * @returns index of the last `const foo = require('bar');` statement or -1 if none was found.\n */\nexport function getLastRequireIndex(program: t.Program): number {\n let lastRequireIdex = -1;\n program.body.forEach((s, i) => {\n if (\n s.type === 'VariableDeclaration' &&\n s.declarations[0].type === 'VariableDeclarator' &&\n s.declarations[0].init !== null &&\n typeof s.declarations[0].init !== 'undefined' &&\n s.declarations[0].init.type === 'CallExpression' &&\n s.declarations[0].init.callee.type === 'Identifier' &&\n s.declarations[0].init.callee.name === 'require'\n ) {\n lastRequireIdex = i;\n }\n });\n return lastRequireIdex;\n}\n\n/**\n * Safely checks if a callee is an identifier with the given name\n * Prevents crashes when accessing callee.name on non-identifier nodes\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function safeCalleeIdentifierMatch(callee: any, name: string): boolean {\n return Boolean(\n callee &&\n typeof callee === 'object' &&\n 'type' in callee &&\n (callee as { type: string }).type === 'Identifier' &&\n 'name' in callee &&\n (callee as { name: string }).name === name,\n );\n}\n\n/**\n * Safely gets the name of an identifier node\n * Returns null if the node is not an identifier or is undefined\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function safeGetIdentifierName(node: any): string | null {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return node && node.type === 'Identifier' ? String(node.name) : null;\n}\n\n/**\n * Safely access function body array with proper validation\n * Prevents crashes when accessing body.body on nodes that don't have a body\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function safeGetFunctionBody(node: any): t.Statement[] | null {\n if (!node || typeof node !== 'object' || !('body' in node)) {\n return null;\n }\n\n const nodeBody = (node as { body: unknown }).body;\n if (!nodeBody || typeof nodeBody !== 'object' || !('body' in nodeBody)) {\n return null;\n }\n\n const bodyArray = (nodeBody as { body: unknown }).body;\n return Array.isArray(bodyArray) ? (bodyArray as t.Statement[]) : null;\n}\n\n/**\n * Safely insert statement before last statement in function body\n * Typically used to insert code before a return statement\n * Returns true if insertion was successful, false otherwise\n */\nexport function safeInsertBeforeReturn(\n body: t.Statement[],\n statement: t.Statement,\n): boolean {\n if (!body || !Array.isArray(body) || body.length === 0) {\n return false;\n }\n\n // Insert before the last statement (typically a return statement)\n const insertIndex = Math.max(0, body.length - 1);\n body.splice(insertIndex, 0, statement);\n return true;\n}\n\n/**\n * Finds a property in an ObjectExpression by name.\n * Commonly used for traversing Vite/React Router config objects.\n *\n * @param configObj - The ObjectExpression to search\n * @param name - The property name to find\n * @returns The matching ObjectProperty, or undefined if not found\n */\nexport function findProperty(\n configObj: t.ObjectExpression,\n name: string,\n): t.ObjectProperty | undefined {\n return configObj.properties.find(\n (p) =>\n p.type === 'ObjectProperty' &&\n p.key.type === 'Identifier' &&\n p.key.name === name,\n ) as t.ObjectProperty | undefined; // Safe: predicate guarantees type\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../../src/utils/ast-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nconst b = recast.types.builders;\n\n/**\n * Checks if a file where we don't know its concrete file type yet exists\n * and returns the full path to the file with the correct file type.\n */\nexport function findFile(\n filePath: string,\n fileTypes: string[] = ['.js', '.ts', '.mjs', '.cjs'],\n): string | undefined {\n return fileTypes\n .map((type) => `${filePath}${type}`)\n .find((file) => fs.existsSync(file));\n}\n\n/**\n * checks for require('@sentry/*') syntax\n */\nexport function hasSentryContent(program: t.Program): boolean {\n let foundSentry: boolean | undefined = false;\n recast.visit(program, {\n visitStringLiteral(path) {\n foundSentry = foundSentry || path.node.value.startsWith('@sentry/');\n this.traverse(path);\n },\n visitLiteral(path) {\n foundSentry =\n foundSentry || path.node.value?.toString().startsWith('@sentry/');\n this.traverse(path);\n },\n });\n\n return !!foundSentry;\n}\n\n/**\n * Searches for a property of an ObjectExpression by name\n *\n * @param object the ObjectExpression to search in\n * @param name the name of the property to search for\n *\n * @returns the property if it exists\n */\nexport function getObjectProperty(\n object: t.ObjectExpression,\n name: string,\n): t.Property | undefined {\n return object.properties.find((p): p is t.Property => {\n const isObjectProp = p.type === 'Property' || p.type === 'ObjectProperty';\n\n if (!isObjectProp) {\n return false;\n }\n\n const hasMatchingLiteralKey =\n isObjectProp &&\n (p.key.type === 'Literal' || p.key.type === 'StringLiteral') &&\n p.key.value === name;\n\n if (hasMatchingLiteralKey) {\n return true;\n }\n\n // has matching identifier key\n return isObjectProp && p.key.type === 'Identifier' && p.key.name === name;\n });\n}\n\n/**\n * Attempts to find a property of an ObjectExpression by name. If it doesn't exist,\n * the property will be added to the ObjectExpression with the provided default value.\n *\n * @param object the parent object expression to search in\n * @param name the name of the property to search for\n * @param defaultValue the default value to set if the property doesn't exist\n *\n * @returns the\n */\nexport function getOrSetObjectProperty(\n object: t.ObjectExpression,\n name: string,\n defaultValue:\n | t.Literal\n | t.BooleanLiteral\n | t.StringLiteral\n | t.ObjectExpression,\n): t.Property {\n const existingProperty = getObjectProperty(object, name);\n\n if (existingProperty) {\n return existingProperty;\n }\n\n const newProperty = b.property.from({\n kind: 'init',\n key: b.stringLiteral(name),\n value: defaultValue,\n });\n\n object.properties.push(newProperty);\n\n return newProperty;\n}\n\n/**\n * Sets a property of an ObjectExpression if it exists, otherwise adds it\n * to the ObjectExpression. Optionally, a comment can be added to the\n * property.\n *\n * @param object the ObjectExpression to set the property on\n * @param name the name of the property to set\n * @param value the value of the property to set\n * @param comment (optional) a comment to add to the property\n */\nexport function setOrUpdateObjectProperty(\n object: t.ObjectExpression,\n name: string,\n value:\n | t.Literal\n | t.BooleanLiteral\n | t.StringLiteral\n | t.ObjectExpression\n | t.ArrayExpression,\n comment?: string,\n): void {\n const newComments =\n comment &&\n comment.split('\\n').map((c) => b.commentLine(` ${c}`, true, false));\n\n const existingProperty = getObjectProperty(object, name);\n\n if (existingProperty) {\n existingProperty.value = value;\n if (newComments) {\n existingProperty.comments = [\n ...(existingProperty?.comments || []),\n ...newComments,\n ];\n }\n } else {\n object.properties.push(\n b.objectProperty.from({\n key: b.stringLiteral(name),\n value,\n ...(newComments && {\n comments: newComments,\n }),\n }),\n );\n }\n}\n\ntype JsonCParseResult =\n | {\n jsonObject: t.ObjectExpression;\n ast: t.Program;\n }\n | {\n jsonObject: undefined;\n ast: undefined;\n };\n\n/**\n * Parses a JSON string with (potential) comments (JSON-C) and returns the JS AST\n * that can be walked and modified with recast like a normal JS AST.\n *\n * This is done by wrapping the JSON-C string in parentheses, thereby making it\n * a JS `Program` with an `ExpressionStatement` as its body. The expression is then\n * extracted from the AST and returned alongside the AST.\n *\n * To preserve as much original formatting as possible, the returned `ast`\n * property should be passed to {@link `printJsonC`} to get the JSON-C string back.\n *\n * If the input is not valid JSON-C, the result will be undefined.\n *\n * @see {@link JsonCParseResult}\n *\n * @param jsonString a JSON-C string\n *\n * @returns a {@link JsonCParseResult}, containing either the JSON-C object and the AST or undefined in both cases\n */\nexport function parseJsonC(jsonString: string): JsonCParseResult {\n try {\n const jsTsConfig = `(${jsonString})`;\n // no idea why recast returns any here, this is dumb :/\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const ast = recast.parse(jsTsConfig.toString()).program as t.Program;\n\n const jsonObject =\n (ast.body[0].type === 'ExpressionStatement' &&\n ast.body[0].expression.type === 'ObjectExpression' &&\n ast.body[0].expression) ||\n undefined;\n\n if (jsonObject) {\n return { jsonObject, ast };\n }\n } catch {\n /* empty */\n }\n return { jsonObject: undefined, ast: undefined };\n}\n\n/**\n * Takes the AST of a parsed JSON-C \"program\" and returns the JSON-C string without\n * any of the temporary JS wrapper code that was previously applied.\n *\n * Only use this in conjunction with {@link `parseJsonC`}\n *\n * @param ast the `ast` returned from {@link `parseJsonC`}\n *\n * @returns the JSON-C string\n */\nexport function printJsonC(ast: t.Program): string {\n const js = recast.print(ast).code;\n return js.substring(1, js.length - 1);\n}\n\n/**\n * Walks the program body and returns index of the last variable assignment initialized by require statement.\n * Only counts top level require statements.\n *\n * @returns index of the last `const foo = require('bar');` statement or -1 if none was found.\n */\nexport function getLastRequireIndex(program: t.Program): number {\n let lastRequireIdex = -1;\n program.body.forEach((s, i) => {\n if (\n s.type === 'VariableDeclaration' &&\n s.declarations[0].type === 'VariableDeclarator' &&\n s.declarations[0].init !== null &&\n typeof s.declarations[0].init !== 'undefined' &&\n s.declarations[0].init.type === 'CallExpression' &&\n s.declarations[0].init.callee.type === 'Identifier' &&\n s.declarations[0].init.callee.name === 'require'\n ) {\n lastRequireIdex = i;\n }\n });\n return lastRequireIdex;\n}\n\n/**\n * Safely checks if a callee is an identifier with the given name\n * Prevents crashes when accessing callee.name on non-identifier nodes\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function safeCalleeIdentifierMatch(callee: any, name: string): boolean {\n return Boolean(\n callee &&\n typeof callee === 'object' &&\n 'type' in callee &&\n (callee as { type: string }).type === 'Identifier' &&\n 'name' in callee &&\n (callee as { name: string }).name === name,\n );\n}\n\n/**\n * Safely gets the name of an identifier node\n * Returns null if the node is not an identifier or is undefined\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function safeGetIdentifierName(node: any): string | null {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return node && node.type === 'Identifier' ? String(node.name) : null;\n}\n\n/**\n * Safely access function body array with proper validation\n * Prevents crashes when accessing body.body on nodes that don't have a body\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function safeGetFunctionBody(node: any): t.Statement[] | null {\n if (!node || typeof node !== 'object' || !('body' in node)) {\n return null;\n }\n\n const nodeBody = (node as { body: unknown }).body;\n if (!nodeBody || typeof nodeBody !== 'object' || !('body' in nodeBody)) {\n return null;\n }\n\n const bodyArray = (nodeBody as { body: unknown }).body;\n return Array.isArray(bodyArray) ? (bodyArray as t.Statement[]) : null;\n}\n\n/**\n * Safely insert statement before last statement in function body\n * Typically used to insert code before a return statement\n * Returns true if insertion was successful, false otherwise\n */\nexport function safeInsertBeforeReturn(\n body: t.Statement[],\n statement: t.Statement,\n): boolean {\n if (!body || !Array.isArray(body) || body.length === 0) {\n return false;\n }\n\n // Insert before the last statement (typically a return statement)\n const insertIndex = Math.max(0, body.length - 1);\n body.splice(insertIndex, 0, statement);\n return true;\n}\n\n/**\n * Finds a property in an ObjectExpression by name.\n * Commonly used for traversing Vite/React Router config objects.\n *\n * @param configObj - The ObjectExpression to search\n * @param name - The property name to find\n * @returns The matching ObjectProperty, or undefined if not found\n */\nexport function findProperty(\n configObj: t.ObjectExpression,\n name: string,\n): t.ObjectProperty | undefined {\n return configObj.properties.find(\n (p) =>\n p.type === 'ObjectProperty' &&\n p.key.type === 'Identifier' &&\n p.key.name === name,\n ) as t.ObjectProperty | undefined; // Safe: predicate guarantees type\n}\n\n/**\n * Preserves trailing newline from original content if present.\n * Code generators like magicast/recast don't preserve trailing newlines,\n * so this ensures we don't unnecessarily modify user files.\n *\n * @param originalContent - The original file content\n * @param generatedCode - The code generated by AST transformation\n * @returns The generated code with trailing newline preserved if original had one\n */\nexport function preserveTrailingNewline(\n originalContent: string,\n generatedCode: string,\n): string {\n const hadTrailingNewline = originalContent.endsWith('\\n');\n const hasTrailingNewline = generatedCode.endsWith('\\n');\n\n if (hadTrailingNewline && !hasTrailingNewline) {\n return generatedCode + '\\n';\n }\n\n return generatedCode;\n}\n"]}
|
|
@@ -49,9 +49,10 @@ export declare function printWelcome(options: {
|
|
|
49
49
|
* @param options.ignoreGitChanges If true, the wizard will not check if the project is a git repository.
|
|
50
50
|
* @param options.cwd The directory of the project. If undefined, the current process working directory will be used.
|
|
51
51
|
*/
|
|
52
|
-
export declare function confirmContinueIfNoOrDirtyGitRepo(
|
|
52
|
+
export declare function confirmContinueIfNoOrDirtyGitRepo({ ignoreGitChanges, cwd, nonInteractive, }: {
|
|
53
53
|
ignoreGitChanges: boolean | undefined;
|
|
54
54
|
cwd: string | undefined;
|
|
55
|
+
nonInteractive?: boolean;
|
|
55
56
|
}): Promise<void>;
|
|
56
57
|
export declare function askToInstallSentryCLI(): Promise<boolean>;
|
|
57
58
|
export declare function askForItemSelection(items: string[], message: string): Promise<{
|
|
@@ -172,12 +172,17 @@ exports.printWelcome = printWelcome;
|
|
|
172
172
|
* @param options.ignoreGitChanges If true, the wizard will not check if the project is a git repository.
|
|
173
173
|
* @param options.cwd The directory of the project. If undefined, the current process working directory will be used.
|
|
174
174
|
*/
|
|
175
|
-
async function confirmContinueIfNoOrDirtyGitRepo(
|
|
175
|
+
async function confirmContinueIfNoOrDirtyGitRepo({ ignoreGitChanges, cwd, nonInteractive = false, }) {
|
|
176
176
|
return (0, telemetry_1.traceStep)('check-git-status', async () => {
|
|
177
177
|
if (!(0, git_1.isInGitRepo)({
|
|
178
|
-
cwd:
|
|
178
|
+
cwd: cwd,
|
|
179
179
|
}) &&
|
|
180
|
-
|
|
180
|
+
ignoreGitChanges !== true) {
|
|
181
|
+
if (nonInteractive) {
|
|
182
|
+
clack.log.error('Project is not inside a git repository in non-interactive mode. Run from a git repository or pass --ignore-git-changes to skip this safety check.');
|
|
183
|
+
Sentry.setTag('continue-without-git', false);
|
|
184
|
+
await abort();
|
|
185
|
+
}
|
|
181
186
|
const continueWithoutGit = await abortIfCancelled(clack.confirm({
|
|
182
187
|
message: 'You are not inside a git repository. The wizard will create and update files. Do you want to continue anyway?',
|
|
183
188
|
}));
|
|
@@ -188,14 +193,20 @@ async function confirmContinueIfNoOrDirtyGitRepo(options) {
|
|
|
188
193
|
// return early to avoid checking for uncommitted files
|
|
189
194
|
return;
|
|
190
195
|
}
|
|
191
|
-
const uncommittedOrUntrackedFiles = (0, git_1.getUncommittedOrUntrackedFiles)(
|
|
192
|
-
|
|
193
|
-
|
|
196
|
+
const uncommittedOrUntrackedFiles = (0, git_1.getUncommittedOrUntrackedFiles)({
|
|
197
|
+
cwd: cwd,
|
|
198
|
+
});
|
|
199
|
+
if (uncommittedOrUntrackedFiles.length && ignoreGitChanges !== true) {
|
|
194
200
|
clack.log.warn(`You have uncommitted or untracked files in your repo:
|
|
195
201
|
|
|
196
202
|
${uncommittedOrUntrackedFiles.join('\n')}
|
|
197
203
|
|
|
198
204
|
The wizard will create and update files.`);
|
|
205
|
+
if (nonInteractive) {
|
|
206
|
+
clack.log.error('Project has uncommitted or untracked files in non-interactive mode. Commit or stash your changes, or pass --ignore-git-changes to skip this safety check.');
|
|
207
|
+
Sentry.setTag('continue-with-dirty-repo', false);
|
|
208
|
+
await abort();
|
|
209
|
+
}
|
|
199
210
|
const continueWithDirtyRepo = await abortIfCancelled(clack.confirm({
|
|
200
211
|
message: 'Do you want to continue anyway?',
|
|
201
212
|
}));
|