@sentry/nuxt 10.21.0-alpha.1 → 10.21.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/build/cjs/module.js +9 -3
- package/build/cjs/module.js.map +1 -1
- package/build/cjs/server/sdk.js +8 -2
- package/build/cjs/server/sdk.js.map +1 -1
- package/build/cjs/vendor/server-template.js +21 -0
- package/build/cjs/vendor/server-template.js.map +1 -0
- package/build/cjs/vite/databaseConfig.js +43 -0
- package/build/cjs/vite/databaseConfig.js.map +1 -0
- package/build/cjs/vite/storageConfig.js +26 -0
- package/build/cjs/vite/storageConfig.js.map +1 -0
- package/build/esm/module.js +9 -3
- package/build/esm/module.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/server/sdk.js +8 -2
- package/build/esm/server/sdk.js.map +1 -1
- package/build/esm/vendor/server-template.js +19 -0
- package/build/esm/vendor/server-template.js.map +1 -0
- package/build/esm/vite/databaseConfig.js +40 -0
- package/build/esm/vite/databaseConfig.js.map +1 -0
- package/build/esm/vite/storageConfig.js +23 -0
- package/build/esm/vite/storageConfig.js.map +1 -0
- package/build/module/module.json +1 -1
- package/build/module/module.mjs +47 -4
- package/build/module/runtime/plugins/database.server.d.ts +5 -0
- package/build/module/runtime/plugins/database.server.js +150 -0
- package/build/module/runtime/plugins/sentry-cloudflare.server.js +1 -0
- package/build/module/runtime/plugins/sentry.server.d.ts +1 -1
- package/build/module/runtime/plugins/storage.server.d.ts +5 -0
- package/build/module/runtime/plugins/storage.server.js +171 -0
- package/build/module/runtime/utils/database-span-data.d.ts +8 -0
- package/build/module/runtime/utils/database-span-data.js +29 -0
- package/build/types/module.d.ts.map +1 -1
- package/build/types/runtime/plugins/database.server.d.ts +6 -0
- package/build/types/runtime/plugins/database.server.d.ts.map +1 -0
- package/build/types/runtime/plugins/sentry-cloudflare.server.d.ts.map +1 -1
- package/build/types/runtime/plugins/sentry.server.d.ts +1 -1
- package/build/types/runtime/plugins/storage.server.d.ts +6 -0
- package/build/types/runtime/plugins/storage.server.d.ts.map +1 -0
- package/build/types/runtime/utils/database-span-data.d.ts +9 -0
- package/build/types/runtime/utils/database-span-data.d.ts.map +1 -0
- package/build/types/server/sdk.d.ts.map +1 -1
- package/build/types/vendor/server-template.d.ts +8 -0
- package/build/types/vendor/server-template.d.ts.map +1 -0
- package/build/types/vite/databaseConfig.d.ts +6 -0
- package/build/types/vite/databaseConfig.d.ts.map +1 -0
- package/build/types/vite/storageConfig.d.ts +6 -0
- package/build/types/vite/storageConfig.d.ts.map +1 -0
- package/package.json +6 -6
package/build/cjs/module.js
CHANGED
|
@@ -2,8 +2,10 @@ const kit = require('@nuxt/kit');
|
|
|
2
2
|
const core = require('@sentry/core');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const addServerConfig = require('./vite/addServerConfig.js');
|
|
5
|
+
const databaseConfig = require('./vite/databaseConfig.js');
|
|
5
6
|
const middlewareConfig = require('./vite/middlewareConfig.js');
|
|
6
7
|
const sourceMaps = require('./vite/sourceMaps.js');
|
|
8
|
+
const storageConfig = require('./vite/storageConfig.js');
|
|
7
9
|
const utils = require('./vite/utils.js');
|
|
8
10
|
|
|
9
11
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -66,14 +68,16 @@ const module$1 = kit.defineNuxtModule({
|
|
|
66
68
|
|
|
67
69
|
// Add the sentry config file to the include array
|
|
68
70
|
nuxt.hook('prepare:types', options => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
const tsConfig = options.tsConfig ;
|
|
72
|
+
|
|
73
|
+
if (!tsConfig.include) {
|
|
74
|
+
tsConfig.include = [];
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
// Add type references for useRuntimeConfig in root files for nuxt v4
|
|
74
78
|
// Should be relative to `root/.nuxt`
|
|
75
79
|
const relativePath = path.relative(nuxt.options.buildDir, clientConfigFile);
|
|
76
|
-
|
|
80
|
+
tsConfig.include.push(relativePath);
|
|
77
81
|
});
|
|
78
82
|
}
|
|
79
83
|
|
|
@@ -117,6 +121,8 @@ const module$1 = kit.defineNuxtModule({
|
|
|
117
121
|
// Preps the the middleware instrumentation module.
|
|
118
122
|
if (serverConfigFile) {
|
|
119
123
|
middlewareConfig.addMiddlewareImports();
|
|
124
|
+
storageConfig.addStorageInstrumentation(nuxt);
|
|
125
|
+
databaseConfig.addDatabaseInstrumentation(nuxt.options.nitro);
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
nuxt.hooks.hook('nitro:init', nitro => {
|
package/build/cjs/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sources":["../../src/module.ts"],"sourcesContent":["import {\n addPlugin,\n addPluginTemplate,\n addServerPlugin,\n addTemplate,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit';\nimport { consoleSandbox } from '@sentry/core';\nimport * as path from 'path';\nimport type { SentryNuxtModuleOptions } from './common/types';\nimport { addDynamicImportEntryFileWrapper, addSentryTopImport, addServerConfigToBuild } from './vite/addServerConfig';\nimport { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig';\nimport { setupSourceMaps } from './vite/sourceMaps';\nimport { addOTelCommonJSImportAlias, findDefaultSdkInitFile } from './vite/utils';\n\nexport type ModuleOptions = SentryNuxtModuleOptions;\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: '@sentry/nuxt/module',\n configKey: 'sentry',\n compatibility: {\n nuxt: '>=3.7.0',\n },\n },\n defaults: {},\n setup(moduleOptionsParam, nuxt) {\n if (moduleOptionsParam?.enabled === false) {\n return;\n }\n\n const moduleOptions = {\n ...moduleOptionsParam,\n autoInjectServerSentry: moduleOptionsParam.autoInjectServerSentry,\n experimental_entrypointWrappedFunctions: moduleOptionsParam.experimental_entrypointWrappedFunctions || [\n 'default',\n 'handler',\n 'server',\n ],\n };\n\n const moduleDirResolver = createResolver(import.meta.url);\n const buildDirResolver = createResolver(nuxt.options.buildDir);\n\n const clientConfigFile = findDefaultSdkInitFile('client', nuxt);\n\n if (clientConfigFile) {\n // Inject the client-side Sentry config file with a side effect import\n addPluginTemplate({\n mode: 'client',\n filename: 'sentry-client-config.mjs',\n order: 0,\n\n // Dynamic import of config file to wrap it within a Nuxt context (here: defineNuxtPlugin)\n // Makes it possible to call useRuntimeConfig() in the user-defined sentry config file\n getContents: () => `\n import { defineNuxtPlugin } from \"#imports\";\n\n export default defineNuxtPlugin({\n name: 'sentry-client-config',\n async setup() {\n await import(\"${buildDirResolver.resolve(`/${clientConfigFile}`)}\")\n }\n });`,\n });\n\n // Add the plugin which loads client integrations etc. -\n // this must run after the sentry-client-config plugin has run, and the client is initialized!\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/sentry.client'),\n mode: 'client',\n order: 1,\n });\n\n // Add the sentry config file to the include array\n nuxt.hook('prepare:types', options => {\n if (!options.tsConfig.include) {\n options.tsConfig.include = [];\n }\n\n // Add type references for useRuntimeConfig in root files for nuxt v4\n // Should be relative to `root/.nuxt`\n const relativePath = path.relative(nuxt.options.buildDir, clientConfigFile);\n options.tsConfig.include.push(relativePath);\n });\n }\n\n const serverConfigFile = findDefaultSdkInitFile('server', nuxt);\n\n if (serverConfigFile) {\n addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/sentry.server'));\n\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/route-detector.server'),\n mode: 'server',\n });\n }\n\n if (clientConfigFile || serverConfigFile) {\n setupSourceMaps(moduleOptions, nuxt);\n }\n\n addOTelCommonJSImportAlias(nuxt);\n\n const pagesDataTemplate = addTemplate({\n filename: 'sentry--nuxt-pages-data.mjs',\n // Initial empty array (later filled in pages:extend hook)\n // Template needs to be created in the root-level of the module to work\n getContents: () => 'export default [];',\n });\n\n nuxt.hooks.hook('pages:extend', pages => {\n pagesDataTemplate.getContents = () => {\n const pagesSubset = pages\n .map(page => ({ file: page.file, path: page.path }))\n .filter(page => {\n // Check for dynamic parameter (e.g., :userId or [userId])\n return page.path.includes(':') || page?.file?.includes('[');\n });\n\n return `export default ${JSON.stringify(pagesSubset, null, 2)};`;\n };\n });\n\n // Preps the the middleware instrumentation module.\n if (serverConfigFile) {\n addMiddlewareImports();\n }\n\n nuxt.hooks.hook('nitro:init', nitro => {\n if (serverConfigFile) {\n addMiddlewareInstrumentation(nitro);\n }\n\n if (serverConfigFile?.includes('.server.config')) {\n consoleSandbox(() => {\n const serverDir = nitro.options.output.serverDir;\n\n // Netlify env: https://docs.netlify.com/configure-builds/environment-variables/#build-metadata\n if (serverDir.includes('.netlify') || !!process.env.NETLIFY) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Netlify build. Server-side support for the Sentry Nuxt SDK on Netlify is currently unreliable due to technical limitations of serverless functions. Traces are not collected, and errors may occasionally not be reported. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n\n // Vercel env: https://vercel.com/docs/projects/environment-variables/system-environment-variables#VERCEL\n if (serverDir.includes('.vercel') || !!process.env.VERCEL) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Vercel build. The Sentry Nuxt SDK currently does not support tracing on Vercel. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n });\n\n if (moduleOptions.autoInjectServerSentry !== 'experimental_dynamic-import') {\n addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);\n\n if (moduleOptions.debug) {\n const serverDirResolver = createResolver(nitro.options.output.serverDir);\n const serverConfigPath = serverDirResolver.resolve('sentry.server.config.mjs');\n\n // For the default nitro node-preset build output this relative path would be: ./.output/server/sentry.server.config.mjs\n const serverConfigRelativePath = `.${path.sep}${path.relative(nitro.options.rootDir, serverConfigPath)}`;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Using \\`${serverConfigFile}\\` for server-side Sentry configuration. To activate Sentry on the Nuxt server-side, this file must be preloaded when starting your application. Make sure to add this where you deploy and/or run your application. Read more here: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/.`,\n );\n\n if (nitro.options.dev) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] During development, preload Sentry with the NODE_OPTIONS environment variable: \\`NODE_OPTIONS='--import ${serverConfigRelativePath}' nuxt dev\\`. The file is generated in the build directory (usually '.nuxt'). If you delete the build directory, run \\`nuxt dev\\` to regenerate it.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] When running your built application, preload Sentry via a command-line flag (\\`node --import ${serverConfigRelativePath} [...]\\`) or via an environment variable (\\`NODE_OPTIONS='--import ${serverConfigRelativePath}' node [...]\\`).`,\n );\n }\n });\n }\n }\n\n if (moduleOptions.autoInjectServerSentry === 'top-level-import') {\n addSentryTopImport(moduleOptions, nitro);\n }\n\n if (moduleOptions.autoInjectServerSentry === 'experimental_dynamic-import') {\n addDynamicImportEntryFileWrapper(nitro, serverConfigFile, moduleOptions);\n\n if (moduleOptions.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Wrapping the server entry file with a dynamic `import()`, so Sentry can be preloaded before the server initializes.',\n );\n });\n }\n }\n }\n });\n },\n});\n"],"names":["defineNuxtModule","createResolver","findDefaultSdkInitFile","addPluginTemplate","addPlugin","addServerPlugin","setupSourceMaps","addOTelCommonJSImportAlias","addTemplate","addMiddlewareImports","addMiddlewareInstrumentation","consoleSandbox","addServerConfigToBuild","addSentryTopImport","addDynamicImportEntryFileWrapper"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"module.js","sources":["../../src/module.ts"],"sourcesContent":["import {\n addPlugin,\n addPluginTemplate,\n addServerPlugin,\n addTemplate,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit';\nimport { consoleSandbox } from '@sentry/core';\nimport * as path from 'path';\nimport type { SentryNuxtModuleOptions } from './common/types';\nimport { addDynamicImportEntryFileWrapper, addSentryTopImport, addServerConfigToBuild } from './vite/addServerConfig';\nimport { addDatabaseInstrumentation } from './vite/databaseConfig';\nimport { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig';\nimport { setupSourceMaps } from './vite/sourceMaps';\nimport { addStorageInstrumentation } from './vite/storageConfig';\nimport { addOTelCommonJSImportAlias, findDefaultSdkInitFile } from './vite/utils';\n\nexport type ModuleOptions = SentryNuxtModuleOptions;\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: '@sentry/nuxt/module',\n configKey: 'sentry',\n compatibility: {\n nuxt: '>=3.7.0',\n },\n },\n defaults: {},\n setup(moduleOptionsParam, nuxt) {\n if (moduleOptionsParam?.enabled === false) {\n return;\n }\n\n const moduleOptions = {\n ...moduleOptionsParam,\n autoInjectServerSentry: moduleOptionsParam.autoInjectServerSentry,\n experimental_entrypointWrappedFunctions: moduleOptionsParam.experimental_entrypointWrappedFunctions || [\n 'default',\n 'handler',\n 'server',\n ],\n };\n\n const moduleDirResolver = createResolver(import.meta.url);\n const buildDirResolver = createResolver(nuxt.options.buildDir);\n\n const clientConfigFile = findDefaultSdkInitFile('client', nuxt);\n\n if (clientConfigFile) {\n // Inject the client-side Sentry config file with a side effect import\n addPluginTemplate({\n mode: 'client',\n filename: 'sentry-client-config.mjs',\n order: 0,\n\n // Dynamic import of config file to wrap it within a Nuxt context (here: defineNuxtPlugin)\n // Makes it possible to call useRuntimeConfig() in the user-defined sentry config file\n getContents: () => `\n import { defineNuxtPlugin } from \"#imports\";\n\n export default defineNuxtPlugin({\n name: 'sentry-client-config',\n async setup() {\n await import(\"${buildDirResolver.resolve(`/${clientConfigFile}`)}\")\n }\n });`,\n });\n\n // Add the plugin which loads client integrations etc. -\n // this must run after the sentry-client-config plugin has run, and the client is initialized!\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/sentry.client'),\n mode: 'client',\n order: 1,\n });\n\n // Add the sentry config file to the include array\n nuxt.hook('prepare:types', options => {\n const tsConfig = options.tsConfig as { include?: string[] };\n\n if (!tsConfig.include) {\n tsConfig.include = [];\n }\n\n // Add type references for useRuntimeConfig in root files for nuxt v4\n // Should be relative to `root/.nuxt`\n const relativePath = path.relative(nuxt.options.buildDir, clientConfigFile);\n tsConfig.include.push(relativePath);\n });\n }\n\n const serverConfigFile = findDefaultSdkInitFile('server', nuxt);\n\n if (serverConfigFile) {\n addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/sentry.server'));\n\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/route-detector.server'),\n mode: 'server',\n });\n }\n\n if (clientConfigFile || serverConfigFile) {\n setupSourceMaps(moduleOptions, nuxt);\n }\n\n addOTelCommonJSImportAlias(nuxt);\n\n const pagesDataTemplate = addTemplate({\n filename: 'sentry--nuxt-pages-data.mjs',\n // Initial empty array (later filled in pages:extend hook)\n // Template needs to be created in the root-level of the module to work\n getContents: () => 'export default [];',\n });\n\n nuxt.hooks.hook('pages:extend', pages => {\n pagesDataTemplate.getContents = () => {\n const pagesSubset = pages\n .map(page => ({ file: page.file, path: page.path }))\n .filter(page => {\n // Check for dynamic parameter (e.g., :userId or [userId])\n return page.path.includes(':') || page?.file?.includes('[');\n });\n\n return `export default ${JSON.stringify(pagesSubset, null, 2)};`;\n };\n });\n\n // Preps the the middleware instrumentation module.\n if (serverConfigFile) {\n addMiddlewareImports();\n addStorageInstrumentation(nuxt);\n addDatabaseInstrumentation(nuxt.options.nitro);\n }\n\n nuxt.hooks.hook('nitro:init', nitro => {\n if (serverConfigFile) {\n addMiddlewareInstrumentation(nitro);\n }\n\n if (serverConfigFile?.includes('.server.config')) {\n consoleSandbox(() => {\n const serverDir = nitro.options.output.serverDir;\n\n // Netlify env: https://docs.netlify.com/configure-builds/environment-variables/#build-metadata\n if (serverDir.includes('.netlify') || !!process.env.NETLIFY) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Netlify build. Server-side support for the Sentry Nuxt SDK on Netlify is currently unreliable due to technical limitations of serverless functions. Traces are not collected, and errors may occasionally not be reported. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n\n // Vercel env: https://vercel.com/docs/projects/environment-variables/system-environment-variables#VERCEL\n if (serverDir.includes('.vercel') || !!process.env.VERCEL) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Vercel build. The Sentry Nuxt SDK currently does not support tracing on Vercel. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n });\n\n if (moduleOptions.autoInjectServerSentry !== 'experimental_dynamic-import') {\n addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);\n\n if (moduleOptions.debug) {\n const serverDirResolver = createResolver(nitro.options.output.serverDir);\n const serverConfigPath = serverDirResolver.resolve('sentry.server.config.mjs');\n\n // For the default nitro node-preset build output this relative path would be: ./.output/server/sentry.server.config.mjs\n const serverConfigRelativePath = `.${path.sep}${path.relative(nitro.options.rootDir, serverConfigPath)}`;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Using \\`${serverConfigFile}\\` for server-side Sentry configuration. To activate Sentry on the Nuxt server-side, this file must be preloaded when starting your application. Make sure to add this where you deploy and/or run your application. Read more here: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/.`,\n );\n\n if (nitro.options.dev) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] During development, preload Sentry with the NODE_OPTIONS environment variable: \\`NODE_OPTIONS='--import ${serverConfigRelativePath}' nuxt dev\\`. The file is generated in the build directory (usually '.nuxt'). If you delete the build directory, run \\`nuxt dev\\` to regenerate it.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] When running your built application, preload Sentry via a command-line flag (\\`node --import ${serverConfigRelativePath} [...]\\`) or via an environment variable (\\`NODE_OPTIONS='--import ${serverConfigRelativePath}' node [...]\\`).`,\n );\n }\n });\n }\n }\n\n if (moduleOptions.autoInjectServerSentry === 'top-level-import') {\n addSentryTopImport(moduleOptions, nitro);\n }\n\n if (moduleOptions.autoInjectServerSentry === 'experimental_dynamic-import') {\n addDynamicImportEntryFileWrapper(nitro, serverConfigFile, moduleOptions);\n\n if (moduleOptions.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Wrapping the server entry file with a dynamic `import()`, so Sentry can be preloaded before the server initializes.',\n );\n });\n }\n }\n }\n });\n },\n});\n"],"names":["defineNuxtModule","createResolver","findDefaultSdkInitFile","addPluginTemplate","addPlugin","addServerPlugin","setupSourceMaps","addOTelCommonJSImportAlias","addTemplate","addMiddlewareImports","addStorageInstrumentation","addDatabaseInstrumentation","addMiddlewareInstrumentation","consoleSandbox","addServerConfigToBuild","addSentryTopImport","addDynamicImportEntryFileWrapper"],"mappings":"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"}
|
package/build/cjs/server/sdk.js
CHANGED
|
@@ -32,11 +32,10 @@ function init(options) {
|
|
|
32
32
|
*
|
|
33
33
|
* Only exported for testing
|
|
34
34
|
*/
|
|
35
|
-
// TODO (span-streaming): replace with ignoreSpans default
|
|
36
35
|
function lowQualityTransactionsFilter(options) {
|
|
37
36
|
return Object.assign(
|
|
38
37
|
(event => {
|
|
39
|
-
if (event.type !== 'transaction' || !event.transaction) {
|
|
38
|
+
if (event.type !== 'transaction' || !event.transaction || isCacheEvent(event)) {
|
|
40
39
|
return event;
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -108,6 +107,13 @@ async function flushSafelyWithTimeout() {
|
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Checks if the event is a cache event.
|
|
112
|
+
*/
|
|
113
|
+
function isCacheEvent(e) {
|
|
114
|
+
return e.contexts?.trace?.origin === 'auto.cache.nuxt';
|
|
115
|
+
}
|
|
116
|
+
|
|
111
117
|
exports.clientSourceMapErrorFilter = clientSourceMapErrorFilter;
|
|
112
118
|
exports.init = init;
|
|
113
119
|
exports.lowQualityTransactionsFilter = lowQualityTransactionsFilter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import * as path from 'node:path';\nimport type { Client, EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, debug, flush, getGlobalScope, vercelWaitUntil } from '@sentry/core';\nimport {\n type NodeOptions,\n getDefaultIntegrations as getDefaultNodeIntegrations,\n httpIntegration,\n init as initNode,\n} from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport type { SentryNuxtServerOptions } from '../common/types';\n\n/**\n * Initializes the server-side of the Nuxt SDK\n *\n * @param options Configuration options for the SDK.\n */\nexport function init(options: SentryNuxtServerOptions): Client | undefined {\n const sentryOptions = {\n ...options,\n defaultIntegrations: getNuxtDefaultIntegrations(options),\n };\n\n applySdkMetadata(sentryOptions, 'nuxt', ['nuxt', 'node']);\n\n const client = initNode(sentryOptions);\n\n getGlobalScope().addEventProcessor(lowQualityTransactionsFilter(options));\n getGlobalScope().addEventProcessor(clientSourceMapErrorFilter(options));\n\n return client;\n}\n\n/**\n * Filter out transactions for resource requests which we don't want to send to Sentry\n * for quota reasons.\n *\n * Only exported for testing\n */\
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import * as path from 'node:path';\nimport type { Client, Event, EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, debug, flush, getGlobalScope, vercelWaitUntil } from '@sentry/core';\nimport {\n type NodeOptions,\n getDefaultIntegrations as getDefaultNodeIntegrations,\n httpIntegration,\n init as initNode,\n} from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport type { SentryNuxtServerOptions } from '../common/types';\n\n/**\n * Initializes the server-side of the Nuxt SDK\n *\n * @param options Configuration options for the SDK.\n */\nexport function init(options: SentryNuxtServerOptions): Client | undefined {\n const sentryOptions = {\n ...options,\n defaultIntegrations: getNuxtDefaultIntegrations(options),\n };\n\n applySdkMetadata(sentryOptions, 'nuxt', ['nuxt', 'node']);\n\n const client = initNode(sentryOptions);\n\n getGlobalScope().addEventProcessor(lowQualityTransactionsFilter(options));\n getGlobalScope().addEventProcessor(clientSourceMapErrorFilter(options));\n\n return client;\n}\n\n/**\n * Filter out transactions for resource requests which we don't want to send to Sentry\n * for quota reasons.\n *\n * Only exported for testing\n */\nexport function lowQualityTransactionsFilter(options: SentryNuxtServerOptions): EventProcessor {\n return Object.assign(\n (event => {\n if (event.type !== 'transaction' || !event.transaction || isCacheEvent(event)) {\n return event;\n }\n\n // Check if this looks like a parametrized route (contains :param or :param() patterns)\n const hasRouteParameters = /\\/:[^(/\\s]*(\\([^)]*\\))?[^/\\s]*/.test(event.transaction);\n\n if (hasRouteParameters) {\n return event;\n }\n\n // We don't want to send transaction for file requests, so everything ending with a *.someExtension should be filtered out\n // path.extname will return an empty string for normal page requests\n if (path.extname(event.transaction)) {\n options.debug &&\n DEBUG_BUILD &&\n debug.log('NuxtLowQualityTransactionsFilter filtered transaction: ', event.transaction);\n return null;\n }\n return event;\n }) satisfies EventProcessor,\n { id: 'NuxtLowQualityTransactionsFilter' },\n );\n}\n\n/**\n * The browser devtools try to get the source maps, but as client source maps may not be available there is going to be an error (no problem for the application though).\n *\n * Only exported for testing\n */\nexport function clientSourceMapErrorFilter(options: SentryNuxtServerOptions): EventProcessor {\n return Object.assign(\n (event => {\n const errorMsg = event.exception?.values?.[0]?.value;\n if (errorMsg?.match(/^ENOENT: no such file or directory, open '.*\\/_nuxt\\/.*\\.js\\.map'/)) {\n options.debug && DEBUG_BUILD && debug.log('NuxtClientSourceMapErrorFilter filtered error: ', errorMsg);\n return null;\n }\n return event;\n }) satisfies EventProcessor,\n { id: 'NuxtClientSourceMapErrorFilter' },\n );\n}\n\nfunction getNuxtDefaultIntegrations(options: NodeOptions): Integration[] {\n return [\n ...getDefaultNodeIntegrations(options).filter(integration => integration.name !== 'Http'),\n // The httpIntegration is added as defaultIntegration, so users can still overwrite it\n httpIntegration({\n instrumentation: {\n responseHook: () => {\n // Makes it possible to end the tracing span before closing the Vercel lambda (https://vercel.com/docs/functions/functions-api-reference#waituntil)\n vercelWaitUntil(flushSafelyWithTimeout());\n },\n },\n }),\n ];\n}\n\n/**\n * Flushes pending Sentry events with a 2-second timeout and in a way that cannot create unhandled promise rejections.\n */\nasync function flushSafelyWithTimeout(): Promise<void> {\n try {\n DEBUG_BUILD && debug.log('Flushing events...');\n await flush(2000);\n DEBUG_BUILD && debug.log('Done flushing events');\n } catch (e) {\n DEBUG_BUILD && debug.log('Error while flushing events:\\n', e);\n }\n}\n\n/**\n * Checks if the event is a cache event.\n */\nfunction isCacheEvent(e: Event): boolean {\n return e.contexts?.trace?.origin === 'auto.cache.nuxt';\n}\n"],"names":["applySdkMetadata","initNode","getGlobalScope","DEBUG_BUILD","debug","getDefaultNodeIntegrations","httpIntegration","vercelWaitUntil","flush"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const kit = require('@nuxt/kit');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Adds a virtual file that can be used within the Nuxt Nitro server build.
|
|
7
|
+
* Available in NuxtKit v4, so we are porting it here.
|
|
8
|
+
* https://github.com/nuxt/nuxt/blob/d6df732eec1a3bd442bdb325b0335beb7e10cd64/packages/kit/src/template.ts#L55-L62
|
|
9
|
+
*/
|
|
10
|
+
function addServerTemplate(template) {
|
|
11
|
+
const nuxt = kit.useNuxt();
|
|
12
|
+
if (template.filename) {
|
|
13
|
+
nuxt.options.nitro.virtual = nuxt.options.nitro.virtual || {};
|
|
14
|
+
nuxt.options.nitro.virtual[template.filename] = template.getContents;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return template;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.addServerTemplate = addServerTemplate;
|
|
21
|
+
//# sourceMappingURL=server-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-template.js","sources":["../../../src/vendor/server-template.ts"],"sourcesContent":["import { useNuxt } from '@nuxt/kit';\nimport type { NuxtTemplate } from 'nuxt/schema';\n\n/**\n * Adds a virtual file that can be used within the Nuxt Nitro server build.\n * Available in NuxtKit v4, so we are porting it here.\n * https://github.com/nuxt/nuxt/blob/d6df732eec1a3bd442bdb325b0335beb7e10cd64/packages/kit/src/template.ts#L55-L62\n */\nexport function addServerTemplate(template: NuxtTemplate): NuxtTemplate {\n const nuxt = useNuxt();\n if (template.filename) {\n nuxt.options.nitro.virtual = nuxt.options.nitro.virtual || {};\n nuxt.options.nitro.virtual[template.filename] = template.getContents;\n }\n\n return template;\n}\n"],"names":["useNuxt"],"mappings":";;;;AAGA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,QAAQ,EAA8B;AACxE,EAAE,MAAM,IAAA,GAAOA,WAAO,EAAE;AACxB,EAAE,IAAI,QAAQ,CAAC,QAAQ,EAAE;AACzB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAA,GAAU,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAA,IAAW,EAAE;AACjE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAA,GAAI,QAAQ,CAAC,WAAW;AACxE;;AAEA,EAAE,OAAO,QAAQ;AACjB;;;;"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const kit = require('@nuxt/kit');
|
|
4
|
+
const core = require('@sentry/core');
|
|
5
|
+
const serverTemplate = require('../vendor/server-template.js');
|
|
6
|
+
|
|
7
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
8
|
+
/**
|
|
9
|
+
* Sets up the database instrumentation.
|
|
10
|
+
*/
|
|
11
|
+
function addDatabaseInstrumentation(nitro) {
|
|
12
|
+
if (!nitro.experimental?.database) {
|
|
13
|
+
core.consoleSandbox(() => {
|
|
14
|
+
// eslint-disable-next-line no-console
|
|
15
|
+
console.log(
|
|
16
|
+
'[Sentry] [Nitro Database Plugin]: No database configuration found. Skipping database instrumentation.',
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* This is a different option than the one in `experimental.database`, this configures multiple database instances.
|
|
25
|
+
* keys represent database names to be passed to `useDatabase(name?)`.
|
|
26
|
+
* We also use the config to populate database span attributes.
|
|
27
|
+
* https://nitro.build/guide/database#configuration
|
|
28
|
+
*/
|
|
29
|
+
const databaseConfig = nitro.database || { default: {} };
|
|
30
|
+
|
|
31
|
+
// Create a virtual module to pass this data to runtime
|
|
32
|
+
serverTemplate.addServerTemplate({
|
|
33
|
+
filename: '#sentry/database-config.mjs',
|
|
34
|
+
getContents: () => {
|
|
35
|
+
return `export const databaseConfig = ${JSON.stringify(databaseConfig)};`;
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
kit.addServerPlugin(kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vite/databaseConfig.js', document.baseURI).href))).resolve('./runtime/plugins/database.server'));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
exports.addDatabaseInstrumentation = addDatabaseInstrumentation;
|
|
43
|
+
//# sourceMappingURL=databaseConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databaseConfig.js","sources":["../../../src/vite/databaseConfig.ts"],"sourcesContent":["import { addServerPlugin, createResolver } from '@nuxt/kit';\nimport { consoleSandbox } from '@sentry/core';\nimport type { NitroConfig } from 'nitropack/types';\nimport { addServerTemplate } from '../vendor/server-template';\n\n/**\n * Sets up the database instrumentation.\n */\nexport function addDatabaseInstrumentation(nitro: NitroConfig): void {\n if (!nitro.experimental?.database) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] [Nitro Database Plugin]: No database configuration found. Skipping database instrumentation.',\n );\n });\n\n return;\n }\n\n /**\n * This is a different option than the one in `experimental.database`, this configures multiple database instances.\n * keys represent database names to be passed to `useDatabase(name?)`.\n * We also use the config to populate database span attributes.\n * https://nitro.build/guide/database#configuration\n */\n const databaseConfig = nitro.database || { default: {} };\n\n // Create a virtual module to pass this data to runtime\n addServerTemplate({\n filename: '#sentry/database-config.mjs',\n getContents: () => {\n return `export const databaseConfig = ${JSON.stringify(databaseConfig)};`;\n },\n });\n\n addServerPlugin(createResolver(import.meta.url).resolve('./runtime/plugins/database.server'));\n}\n"],"names":["consoleSandbox","addServerTemplate","addServerPlugin","createResolver"],"mappings":";;;;;;;AAKA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,KAAK,EAAqB;AACrE,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE;AACrC,IAAIA,mBAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,uGAAuG;AAC/G,OAAO;AACP,KAAK,CAAC;;AAEN,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,cAAA,GAAiB,KAAK,CAAC,QAAA,IAAY,EAAE,OAAO,EAAE,EAAC,EAAG;;AAE1D;AACA,EAAEC,gCAAiB,CAAC;AACpB,IAAI,QAAQ,EAAE,6BAA6B;AAC3C,IAAI,WAAW,EAAE,MAAM;AACvB,MAAM,OAAO,CAAC,8BAA8B,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAC/E,KAAK;AACL,GAAG,CAAC;;AAEJ,EAAEC,mBAAe,CAACC,kBAAc,CAAC,wQAAe,CAAC,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;AAC/F;;;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const kit = require('@nuxt/kit');
|
|
4
|
+
const serverTemplate = require('../vendor/server-template.js');
|
|
5
|
+
|
|
6
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
7
|
+
/**
|
|
8
|
+
* Prepares the storage config export to be used in the runtime storage instrumentation.
|
|
9
|
+
*/
|
|
10
|
+
function addStorageInstrumentation(nuxt) {
|
|
11
|
+
const moduleDirResolver = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vite/storageConfig.js', document.baseURI).href)));
|
|
12
|
+
const userStorageMounts = Object.keys(nuxt.options.nitro.storage || {});
|
|
13
|
+
|
|
14
|
+
// Create a virtual module to pass this data to runtime
|
|
15
|
+
serverTemplate.addServerTemplate({
|
|
16
|
+
filename: '#sentry/storage-config.mjs',
|
|
17
|
+
getContents: () => {
|
|
18
|
+
return `export const userStorageMounts = ${JSON.stringify(userStorageMounts)};`;
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
kit.addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/storage.server'));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.addStorageInstrumentation = addStorageInstrumentation;
|
|
26
|
+
//# sourceMappingURL=storageConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageConfig.js","sources":["../../../src/vite/storageConfig.ts"],"sourcesContent":["import { addServerPlugin, createResolver } from '@nuxt/kit';\nimport type { Nuxt } from 'nuxt/schema';\nimport { addServerTemplate } from '../vendor/server-template';\n\n/**\n * Prepares the storage config export to be used in the runtime storage instrumentation.\n */\nexport function addStorageInstrumentation(nuxt: Nuxt): void {\n const moduleDirResolver = createResolver(import.meta.url);\n const userStorageMounts = Object.keys(nuxt.options.nitro.storage || {});\n\n // Create a virtual module to pass this data to runtime\n addServerTemplate({\n filename: '#sentry/storage-config.mjs',\n getContents: () => {\n return `export const userStorageMounts = ${JSON.stringify(userStorageMounts)};`;\n },\n });\n\n addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/storage.server'));\n}\n"],"names":["createResolver","addServerTemplate","addServerPlugin"],"mappings":";;;;;;AAIA;AACA;AACA;AACO,SAAS,yBAAyB,CAAC,IAAI,EAAc;AAC5D,EAAE,MAAM,iBAAA,GAAoBA,kBAAc,CAAC,uQAAe,CAAC;AAC3D,EAAE,MAAM,iBAAA,GAAoB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;;AAEzE;AACA,EAAEC,gCAAiB,CAAC;AACpB,IAAI,QAAQ,EAAE,4BAA4B;AAC1C,IAAI,WAAW,EAAE,MAAM;AACvB,MAAM,OAAO,CAAC,iCAAiC,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACrF,KAAK;AACL,GAAG,CAAC;;AAEJ,EAAEC,mBAAe,CAAC,iBAAiB,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;AAChF;;;;"}
|
package/build/esm/module.js
CHANGED
|
@@ -2,8 +2,10 @@ import { defineNuxtModule, createResolver, addPluginTemplate, addPlugin, addServ
|
|
|
2
2
|
import { consoleSandbox } from '@sentry/core';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { addServerConfigToBuild, addSentryTopImport, addDynamicImportEntryFileWrapper } from './vite/addServerConfig.js';
|
|
5
|
+
import { addDatabaseInstrumentation } from './vite/databaseConfig.js';
|
|
5
6
|
import { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig.js';
|
|
6
7
|
import { setupSourceMaps } from './vite/sourceMaps.js';
|
|
8
|
+
import { addStorageInstrumentation } from './vite/storageConfig.js';
|
|
7
9
|
import { findDefaultSdkInitFile, addOTelCommonJSImportAlias } from './vite/utils.js';
|
|
8
10
|
|
|
9
11
|
const module = defineNuxtModule({
|
|
@@ -65,14 +67,16 @@ const module = defineNuxtModule({
|
|
|
65
67
|
|
|
66
68
|
// Add the sentry config file to the include array
|
|
67
69
|
nuxt.hook('prepare:types', options => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
const tsConfig = options.tsConfig ;
|
|
71
|
+
|
|
72
|
+
if (!tsConfig.include) {
|
|
73
|
+
tsConfig.include = [];
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
// Add type references for useRuntimeConfig in root files for nuxt v4
|
|
73
77
|
// Should be relative to `root/.nuxt`
|
|
74
78
|
const relativePath = path.relative(nuxt.options.buildDir, clientConfigFile);
|
|
75
|
-
|
|
79
|
+
tsConfig.include.push(relativePath);
|
|
76
80
|
});
|
|
77
81
|
}
|
|
78
82
|
|
|
@@ -116,6 +120,8 @@ const module = defineNuxtModule({
|
|
|
116
120
|
// Preps the the middleware instrumentation module.
|
|
117
121
|
if (serverConfigFile) {
|
|
118
122
|
addMiddlewareImports();
|
|
123
|
+
addStorageInstrumentation(nuxt);
|
|
124
|
+
addDatabaseInstrumentation(nuxt.options.nitro);
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
nuxt.hooks.hook('nitro:init', nitro => {
|
package/build/esm/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sources":["../../src/module.ts"],"sourcesContent":["import {\n addPlugin,\n addPluginTemplate,\n addServerPlugin,\n addTemplate,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit';\nimport { consoleSandbox } from '@sentry/core';\nimport * as path from 'path';\nimport type { SentryNuxtModuleOptions } from './common/types';\nimport { addDynamicImportEntryFileWrapper, addSentryTopImport, addServerConfigToBuild } from './vite/addServerConfig';\nimport { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig';\nimport { setupSourceMaps } from './vite/sourceMaps';\nimport { addOTelCommonJSImportAlias, findDefaultSdkInitFile } from './vite/utils';\n\nexport type ModuleOptions = SentryNuxtModuleOptions;\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: '@sentry/nuxt/module',\n configKey: 'sentry',\n compatibility: {\n nuxt: '>=3.7.0',\n },\n },\n defaults: {},\n setup(moduleOptionsParam, nuxt) {\n if (moduleOptionsParam?.enabled === false) {\n return;\n }\n\n const moduleOptions = {\n ...moduleOptionsParam,\n autoInjectServerSentry: moduleOptionsParam.autoInjectServerSentry,\n experimental_entrypointWrappedFunctions: moduleOptionsParam.experimental_entrypointWrappedFunctions || [\n 'default',\n 'handler',\n 'server',\n ],\n };\n\n const moduleDirResolver = createResolver(import.meta.url);\n const buildDirResolver = createResolver(nuxt.options.buildDir);\n\n const clientConfigFile = findDefaultSdkInitFile('client', nuxt);\n\n if (clientConfigFile) {\n // Inject the client-side Sentry config file with a side effect import\n addPluginTemplate({\n mode: 'client',\n filename: 'sentry-client-config.mjs',\n order: 0,\n\n // Dynamic import of config file to wrap it within a Nuxt context (here: defineNuxtPlugin)\n // Makes it possible to call useRuntimeConfig() in the user-defined sentry config file\n getContents: () => `\n import { defineNuxtPlugin } from \"#imports\";\n\n export default defineNuxtPlugin({\n name: 'sentry-client-config',\n async setup() {\n await import(\"${buildDirResolver.resolve(`/${clientConfigFile}`)}\")\n }\n });`,\n });\n\n // Add the plugin which loads client integrations etc. -\n // this must run after the sentry-client-config plugin has run, and the client is initialized!\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/sentry.client'),\n mode: 'client',\n order: 1,\n });\n\n // Add the sentry config file to the include array\n nuxt.hook('prepare:types', options => {\n if (!options.tsConfig.include) {\n options.tsConfig.include = [];\n }\n\n // Add type references for useRuntimeConfig in root files for nuxt v4\n // Should be relative to `root/.nuxt`\n const relativePath = path.relative(nuxt.options.buildDir, clientConfigFile);\n options.tsConfig.include.push(relativePath);\n });\n }\n\n const serverConfigFile = findDefaultSdkInitFile('server', nuxt);\n\n if (serverConfigFile) {\n addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/sentry.server'));\n\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/route-detector.server'),\n mode: 'server',\n });\n }\n\n if (clientConfigFile || serverConfigFile) {\n setupSourceMaps(moduleOptions, nuxt);\n }\n\n addOTelCommonJSImportAlias(nuxt);\n\n const pagesDataTemplate = addTemplate({\n filename: 'sentry--nuxt-pages-data.mjs',\n // Initial empty array (later filled in pages:extend hook)\n // Template needs to be created in the root-level of the module to work\n getContents: () => 'export default [];',\n });\n\n nuxt.hooks.hook('pages:extend', pages => {\n pagesDataTemplate.getContents = () => {\n const pagesSubset = pages\n .map(page => ({ file: page.file, path: page.path }))\n .filter(page => {\n // Check for dynamic parameter (e.g., :userId or [userId])\n return page.path.includes(':') || page?.file?.includes('[');\n });\n\n return `export default ${JSON.stringify(pagesSubset, null, 2)};`;\n };\n });\n\n // Preps the the middleware instrumentation module.\n if (serverConfigFile) {\n addMiddlewareImports();\n }\n\n nuxt.hooks.hook('nitro:init', nitro => {\n if (serverConfigFile) {\n addMiddlewareInstrumentation(nitro);\n }\n\n if (serverConfigFile?.includes('.server.config')) {\n consoleSandbox(() => {\n const serverDir = nitro.options.output.serverDir;\n\n // Netlify env: https://docs.netlify.com/configure-builds/environment-variables/#build-metadata\n if (serverDir.includes('.netlify') || !!process.env.NETLIFY) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Netlify build. Server-side support for the Sentry Nuxt SDK on Netlify is currently unreliable due to technical limitations of serverless functions. Traces are not collected, and errors may occasionally not be reported. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n\n // Vercel env: https://vercel.com/docs/projects/environment-variables/system-environment-variables#VERCEL\n if (serverDir.includes('.vercel') || !!process.env.VERCEL) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Vercel build. The Sentry Nuxt SDK currently does not support tracing on Vercel. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n });\n\n if (moduleOptions.autoInjectServerSentry !== 'experimental_dynamic-import') {\n addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);\n\n if (moduleOptions.debug) {\n const serverDirResolver = createResolver(nitro.options.output.serverDir);\n const serverConfigPath = serverDirResolver.resolve('sentry.server.config.mjs');\n\n // For the default nitro node-preset build output this relative path would be: ./.output/server/sentry.server.config.mjs\n const serverConfigRelativePath = `.${path.sep}${path.relative(nitro.options.rootDir, serverConfigPath)}`;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Using \\`${serverConfigFile}\\` for server-side Sentry configuration. To activate Sentry on the Nuxt server-side, this file must be preloaded when starting your application. Make sure to add this where you deploy and/or run your application. Read more here: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/.`,\n );\n\n if (nitro.options.dev) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] During development, preload Sentry with the NODE_OPTIONS environment variable: \\`NODE_OPTIONS='--import ${serverConfigRelativePath}' nuxt dev\\`. The file is generated in the build directory (usually '.nuxt'). If you delete the build directory, run \\`nuxt dev\\` to regenerate it.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] When running your built application, preload Sentry via a command-line flag (\\`node --import ${serverConfigRelativePath} [...]\\`) or via an environment variable (\\`NODE_OPTIONS='--import ${serverConfigRelativePath}' node [...]\\`).`,\n );\n }\n });\n }\n }\n\n if (moduleOptions.autoInjectServerSentry === 'top-level-import') {\n addSentryTopImport(moduleOptions, nitro);\n }\n\n if (moduleOptions.autoInjectServerSentry === 'experimental_dynamic-import') {\n addDynamicImportEntryFileWrapper(nitro, serverConfigFile, moduleOptions);\n\n if (moduleOptions.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Wrapping the server entry file with a dynamic `import()`, so Sentry can be preloaded before the server initializes.',\n );\n });\n }\n }\n }\n });\n },\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"module.js","sources":["../../src/module.ts"],"sourcesContent":["import {\n addPlugin,\n addPluginTemplate,\n addServerPlugin,\n addTemplate,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit';\nimport { consoleSandbox } from '@sentry/core';\nimport * as path from 'path';\nimport type { SentryNuxtModuleOptions } from './common/types';\nimport { addDynamicImportEntryFileWrapper, addSentryTopImport, addServerConfigToBuild } from './vite/addServerConfig';\nimport { addDatabaseInstrumentation } from './vite/databaseConfig';\nimport { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig';\nimport { setupSourceMaps } from './vite/sourceMaps';\nimport { addStorageInstrumentation } from './vite/storageConfig';\nimport { addOTelCommonJSImportAlias, findDefaultSdkInitFile } from './vite/utils';\n\nexport type ModuleOptions = SentryNuxtModuleOptions;\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: '@sentry/nuxt/module',\n configKey: 'sentry',\n compatibility: {\n nuxt: '>=3.7.0',\n },\n },\n defaults: {},\n setup(moduleOptionsParam, nuxt) {\n if (moduleOptionsParam?.enabled === false) {\n return;\n }\n\n const moduleOptions = {\n ...moduleOptionsParam,\n autoInjectServerSentry: moduleOptionsParam.autoInjectServerSentry,\n experimental_entrypointWrappedFunctions: moduleOptionsParam.experimental_entrypointWrappedFunctions || [\n 'default',\n 'handler',\n 'server',\n ],\n };\n\n const moduleDirResolver = createResolver(import.meta.url);\n const buildDirResolver = createResolver(nuxt.options.buildDir);\n\n const clientConfigFile = findDefaultSdkInitFile('client', nuxt);\n\n if (clientConfigFile) {\n // Inject the client-side Sentry config file with a side effect import\n addPluginTemplate({\n mode: 'client',\n filename: 'sentry-client-config.mjs',\n order: 0,\n\n // Dynamic import of config file to wrap it within a Nuxt context (here: defineNuxtPlugin)\n // Makes it possible to call useRuntimeConfig() in the user-defined sentry config file\n getContents: () => `\n import { defineNuxtPlugin } from \"#imports\";\n\n export default defineNuxtPlugin({\n name: 'sentry-client-config',\n async setup() {\n await import(\"${buildDirResolver.resolve(`/${clientConfigFile}`)}\")\n }\n });`,\n });\n\n // Add the plugin which loads client integrations etc. -\n // this must run after the sentry-client-config plugin has run, and the client is initialized!\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/sentry.client'),\n mode: 'client',\n order: 1,\n });\n\n // Add the sentry config file to the include array\n nuxt.hook('prepare:types', options => {\n const tsConfig = options.tsConfig as { include?: string[] };\n\n if (!tsConfig.include) {\n tsConfig.include = [];\n }\n\n // Add type references for useRuntimeConfig in root files for nuxt v4\n // Should be relative to `root/.nuxt`\n const relativePath = path.relative(nuxt.options.buildDir, clientConfigFile);\n tsConfig.include.push(relativePath);\n });\n }\n\n const serverConfigFile = findDefaultSdkInitFile('server', nuxt);\n\n if (serverConfigFile) {\n addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/sentry.server'));\n\n addPlugin({\n src: moduleDirResolver.resolve('./runtime/plugins/route-detector.server'),\n mode: 'server',\n });\n }\n\n if (clientConfigFile || serverConfigFile) {\n setupSourceMaps(moduleOptions, nuxt);\n }\n\n addOTelCommonJSImportAlias(nuxt);\n\n const pagesDataTemplate = addTemplate({\n filename: 'sentry--nuxt-pages-data.mjs',\n // Initial empty array (later filled in pages:extend hook)\n // Template needs to be created in the root-level of the module to work\n getContents: () => 'export default [];',\n });\n\n nuxt.hooks.hook('pages:extend', pages => {\n pagesDataTemplate.getContents = () => {\n const pagesSubset = pages\n .map(page => ({ file: page.file, path: page.path }))\n .filter(page => {\n // Check for dynamic parameter (e.g., :userId or [userId])\n return page.path.includes(':') || page?.file?.includes('[');\n });\n\n return `export default ${JSON.stringify(pagesSubset, null, 2)};`;\n };\n });\n\n // Preps the the middleware instrumentation module.\n if (serverConfigFile) {\n addMiddlewareImports();\n addStorageInstrumentation(nuxt);\n addDatabaseInstrumentation(nuxt.options.nitro);\n }\n\n nuxt.hooks.hook('nitro:init', nitro => {\n if (serverConfigFile) {\n addMiddlewareInstrumentation(nitro);\n }\n\n if (serverConfigFile?.includes('.server.config')) {\n consoleSandbox(() => {\n const serverDir = nitro.options.output.serverDir;\n\n // Netlify env: https://docs.netlify.com/configure-builds/environment-variables/#build-metadata\n if (serverDir.includes('.netlify') || !!process.env.NETLIFY) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Netlify build. Server-side support for the Sentry Nuxt SDK on Netlify is currently unreliable due to technical limitations of serverless functions. Traces are not collected, and errors may occasionally not be reported. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n\n // Vercel env: https://vercel.com/docs/projects/environment-variables/system-environment-variables#VERCEL\n if (serverDir.includes('.vercel') || !!process.env.VERCEL) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Warning: The Sentry SDK detected a Vercel build. The Sentry Nuxt SDK currently does not support tracing on Vercel. For more information on setting up Sentry on the Nuxt server-side, please refer to the documentation: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/',\n );\n }\n });\n\n if (moduleOptions.autoInjectServerSentry !== 'experimental_dynamic-import') {\n addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);\n\n if (moduleOptions.debug) {\n const serverDirResolver = createResolver(nitro.options.output.serverDir);\n const serverConfigPath = serverDirResolver.resolve('sentry.server.config.mjs');\n\n // For the default nitro node-preset build output this relative path would be: ./.output/server/sentry.server.config.mjs\n const serverConfigRelativePath = `.${path.sep}${path.relative(nitro.options.rootDir, serverConfigPath)}`;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Using \\`${serverConfigFile}\\` for server-side Sentry configuration. To activate Sentry on the Nuxt server-side, this file must be preloaded when starting your application. Make sure to add this where you deploy and/or run your application. Read more here: https://docs.sentry.io/platforms/javascript/guides/nuxt/install/.`,\n );\n\n if (nitro.options.dev) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] During development, preload Sentry with the NODE_OPTIONS environment variable: \\`NODE_OPTIONS='--import ${serverConfigRelativePath}' nuxt dev\\`. The file is generated in the build directory (usually '.nuxt'). If you delete the build directory, run \\`nuxt dev\\` to regenerate it.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] When running your built application, preload Sentry via a command-line flag (\\`node --import ${serverConfigRelativePath} [...]\\`) or via an environment variable (\\`NODE_OPTIONS='--import ${serverConfigRelativePath}' node [...]\\`).`,\n );\n }\n });\n }\n }\n\n if (moduleOptions.autoInjectServerSentry === 'top-level-import') {\n addSentryTopImport(moduleOptions, nitro);\n }\n\n if (moduleOptions.autoInjectServerSentry === 'experimental_dynamic-import') {\n addDynamicImportEntryFileWrapper(nitro, serverConfigFile, moduleOptions);\n\n if (moduleOptions.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Wrapping the server entry file with a dynamic `import()`, so Sentry can be preloaded before the server initializes.',\n );\n });\n }\n }\n }\n });\n },\n});\n"],"names":[],"mappings":"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"}
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"10.21.0
|
|
1
|
+
{"type":"module","version":"10.21.0"}
|
package/build/esm/server/sdk.js
CHANGED
|
@@ -30,11 +30,10 @@ function init(options) {
|
|
|
30
30
|
*
|
|
31
31
|
* Only exported for testing
|
|
32
32
|
*/
|
|
33
|
-
// TODO (span-streaming): replace with ignoreSpans default
|
|
34
33
|
function lowQualityTransactionsFilter(options) {
|
|
35
34
|
return Object.assign(
|
|
36
35
|
(event => {
|
|
37
|
-
if (event.type !== 'transaction' || !event.transaction) {
|
|
36
|
+
if (event.type !== 'transaction' || !event.transaction || isCacheEvent(event)) {
|
|
38
37
|
return event;
|
|
39
38
|
}
|
|
40
39
|
|
|
@@ -106,5 +105,12 @@ async function flushSafelyWithTimeout() {
|
|
|
106
105
|
}
|
|
107
106
|
}
|
|
108
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Checks if the event is a cache event.
|
|
110
|
+
*/
|
|
111
|
+
function isCacheEvent(e) {
|
|
112
|
+
return e.contexts?.trace?.origin === 'auto.cache.nuxt';
|
|
113
|
+
}
|
|
114
|
+
|
|
109
115
|
export { clientSourceMapErrorFilter, init, lowQualityTransactionsFilter };
|
|
110
116
|
//# sourceMappingURL=sdk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import * as path from 'node:path';\nimport type { Client, EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, debug, flush, getGlobalScope, vercelWaitUntil } from '@sentry/core';\nimport {\n type NodeOptions,\n getDefaultIntegrations as getDefaultNodeIntegrations,\n httpIntegration,\n init as initNode,\n} from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport type { SentryNuxtServerOptions } from '../common/types';\n\n/**\n * Initializes the server-side of the Nuxt SDK\n *\n * @param options Configuration options for the SDK.\n */\nexport function init(options: SentryNuxtServerOptions): Client | undefined {\n const sentryOptions = {\n ...options,\n defaultIntegrations: getNuxtDefaultIntegrations(options),\n };\n\n applySdkMetadata(sentryOptions, 'nuxt', ['nuxt', 'node']);\n\n const client = initNode(sentryOptions);\n\n getGlobalScope().addEventProcessor(lowQualityTransactionsFilter(options));\n getGlobalScope().addEventProcessor(clientSourceMapErrorFilter(options));\n\n return client;\n}\n\n/**\n * Filter out transactions for resource requests which we don't want to send to Sentry\n * for quota reasons.\n *\n * Only exported for testing\n */\
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import * as path from 'node:path';\nimport type { Client, Event, EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, debug, flush, getGlobalScope, vercelWaitUntil } from '@sentry/core';\nimport {\n type NodeOptions,\n getDefaultIntegrations as getDefaultNodeIntegrations,\n httpIntegration,\n init as initNode,\n} from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport type { SentryNuxtServerOptions } from '../common/types';\n\n/**\n * Initializes the server-side of the Nuxt SDK\n *\n * @param options Configuration options for the SDK.\n */\nexport function init(options: SentryNuxtServerOptions): Client | undefined {\n const sentryOptions = {\n ...options,\n defaultIntegrations: getNuxtDefaultIntegrations(options),\n };\n\n applySdkMetadata(sentryOptions, 'nuxt', ['nuxt', 'node']);\n\n const client = initNode(sentryOptions);\n\n getGlobalScope().addEventProcessor(lowQualityTransactionsFilter(options));\n getGlobalScope().addEventProcessor(clientSourceMapErrorFilter(options));\n\n return client;\n}\n\n/**\n * Filter out transactions for resource requests which we don't want to send to Sentry\n * for quota reasons.\n *\n * Only exported for testing\n */\nexport function lowQualityTransactionsFilter(options: SentryNuxtServerOptions): EventProcessor {\n return Object.assign(\n (event => {\n if (event.type !== 'transaction' || !event.transaction || isCacheEvent(event)) {\n return event;\n }\n\n // Check if this looks like a parametrized route (contains :param or :param() patterns)\n const hasRouteParameters = /\\/:[^(/\\s]*(\\([^)]*\\))?[^/\\s]*/.test(event.transaction);\n\n if (hasRouteParameters) {\n return event;\n }\n\n // We don't want to send transaction for file requests, so everything ending with a *.someExtension should be filtered out\n // path.extname will return an empty string for normal page requests\n if (path.extname(event.transaction)) {\n options.debug &&\n DEBUG_BUILD &&\n debug.log('NuxtLowQualityTransactionsFilter filtered transaction: ', event.transaction);\n return null;\n }\n return event;\n }) satisfies EventProcessor,\n { id: 'NuxtLowQualityTransactionsFilter' },\n );\n}\n\n/**\n * The browser devtools try to get the source maps, but as client source maps may not be available there is going to be an error (no problem for the application though).\n *\n * Only exported for testing\n */\nexport function clientSourceMapErrorFilter(options: SentryNuxtServerOptions): EventProcessor {\n return Object.assign(\n (event => {\n const errorMsg = event.exception?.values?.[0]?.value;\n if (errorMsg?.match(/^ENOENT: no such file or directory, open '.*\\/_nuxt\\/.*\\.js\\.map'/)) {\n options.debug && DEBUG_BUILD && debug.log('NuxtClientSourceMapErrorFilter filtered error: ', errorMsg);\n return null;\n }\n return event;\n }) satisfies EventProcessor,\n { id: 'NuxtClientSourceMapErrorFilter' },\n );\n}\n\nfunction getNuxtDefaultIntegrations(options: NodeOptions): Integration[] {\n return [\n ...getDefaultNodeIntegrations(options).filter(integration => integration.name !== 'Http'),\n // The httpIntegration is added as defaultIntegration, so users can still overwrite it\n httpIntegration({\n instrumentation: {\n responseHook: () => {\n // Makes it possible to end the tracing span before closing the Vercel lambda (https://vercel.com/docs/functions/functions-api-reference#waituntil)\n vercelWaitUntil(flushSafelyWithTimeout());\n },\n },\n }),\n ];\n}\n\n/**\n * Flushes pending Sentry events with a 2-second timeout and in a way that cannot create unhandled promise rejections.\n */\nasync function flushSafelyWithTimeout(): Promise<void> {\n try {\n DEBUG_BUILD && debug.log('Flushing events...');\n await flush(2000);\n DEBUG_BUILD && debug.log('Done flushing events');\n } catch (e) {\n DEBUG_BUILD && debug.log('Error while flushing events:\\n', e);\n }\n}\n\n/**\n * Checks if the event is a cache event.\n */\nfunction isCacheEvent(e: Event): boolean {\n return e.contexts?.trace?.origin === 'auto.cache.nuxt';\n}\n"],"names":["initNode","getDefaultNodeIntegrations"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useNuxt } from '@nuxt/kit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Adds a virtual file that can be used within the Nuxt Nitro server build.
|
|
5
|
+
* Available in NuxtKit v4, so we are porting it here.
|
|
6
|
+
* https://github.com/nuxt/nuxt/blob/d6df732eec1a3bd442bdb325b0335beb7e10cd64/packages/kit/src/template.ts#L55-L62
|
|
7
|
+
*/
|
|
8
|
+
function addServerTemplate(template) {
|
|
9
|
+
const nuxt = useNuxt();
|
|
10
|
+
if (template.filename) {
|
|
11
|
+
nuxt.options.nitro.virtual = nuxt.options.nitro.virtual || {};
|
|
12
|
+
nuxt.options.nitro.virtual[template.filename] = template.getContents;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return template;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { addServerTemplate };
|
|
19
|
+
//# sourceMappingURL=server-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-template.js","sources":["../../../src/vendor/server-template.ts"],"sourcesContent":["import { useNuxt } from '@nuxt/kit';\nimport type { NuxtTemplate } from 'nuxt/schema';\n\n/**\n * Adds a virtual file that can be used within the Nuxt Nitro server build.\n * Available in NuxtKit v4, so we are porting it here.\n * https://github.com/nuxt/nuxt/blob/d6df732eec1a3bd442bdb325b0335beb7e10cd64/packages/kit/src/template.ts#L55-L62\n */\nexport function addServerTemplate(template: NuxtTemplate): NuxtTemplate {\n const nuxt = useNuxt();\n if (template.filename) {\n nuxt.options.nitro.virtual = nuxt.options.nitro.virtual || {};\n nuxt.options.nitro.virtual[template.filename] = template.getContents;\n }\n\n return template;\n}\n"],"names":[],"mappings":";;AAGA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,QAAQ,EAA8B;AACxE,EAAE,MAAM,IAAA,GAAO,OAAO,EAAE;AACxB,EAAE,IAAI,QAAQ,CAAC,QAAQ,EAAE;AACzB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAA,GAAU,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAA,IAAW,EAAE;AACjE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAA,GAAI,QAAQ,CAAC,WAAW;AACxE;;AAEA,EAAE,OAAO,QAAQ;AACjB;;;;"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { addServerPlugin, createResolver } from '@nuxt/kit';
|
|
2
|
+
import { consoleSandbox } from '@sentry/core';
|
|
3
|
+
import { addServerTemplate } from '../vendor/server-template.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sets up the database instrumentation.
|
|
7
|
+
*/
|
|
8
|
+
function addDatabaseInstrumentation(nitro) {
|
|
9
|
+
if (!nitro.experimental?.database) {
|
|
10
|
+
consoleSandbox(() => {
|
|
11
|
+
// eslint-disable-next-line no-console
|
|
12
|
+
console.log(
|
|
13
|
+
'[Sentry] [Nitro Database Plugin]: No database configuration found. Skipping database instrumentation.',
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This is a different option than the one in `experimental.database`, this configures multiple database instances.
|
|
22
|
+
* keys represent database names to be passed to `useDatabase(name?)`.
|
|
23
|
+
* We also use the config to populate database span attributes.
|
|
24
|
+
* https://nitro.build/guide/database#configuration
|
|
25
|
+
*/
|
|
26
|
+
const databaseConfig = nitro.database || { default: {} };
|
|
27
|
+
|
|
28
|
+
// Create a virtual module to pass this data to runtime
|
|
29
|
+
addServerTemplate({
|
|
30
|
+
filename: '#sentry/database-config.mjs',
|
|
31
|
+
getContents: () => {
|
|
32
|
+
return `export const databaseConfig = ${JSON.stringify(databaseConfig)};`;
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
addServerPlugin(createResolver(import.meta.url).resolve('./runtime/plugins/database.server'));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { addDatabaseInstrumentation };
|
|
40
|
+
//# sourceMappingURL=databaseConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databaseConfig.js","sources":["../../../src/vite/databaseConfig.ts"],"sourcesContent":["import { addServerPlugin, createResolver } from '@nuxt/kit';\nimport { consoleSandbox } from '@sentry/core';\nimport type { NitroConfig } from 'nitropack/types';\nimport { addServerTemplate } from '../vendor/server-template';\n\n/**\n * Sets up the database instrumentation.\n */\nexport function addDatabaseInstrumentation(nitro: NitroConfig): void {\n if (!nitro.experimental?.database) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] [Nitro Database Plugin]: No database configuration found. Skipping database instrumentation.',\n );\n });\n\n return;\n }\n\n /**\n * This is a different option than the one in `experimental.database`, this configures multiple database instances.\n * keys represent database names to be passed to `useDatabase(name?)`.\n * We also use the config to populate database span attributes.\n * https://nitro.build/guide/database#configuration\n */\n const databaseConfig = nitro.database || { default: {} };\n\n // Create a virtual module to pass this data to runtime\n addServerTemplate({\n filename: '#sentry/database-config.mjs',\n getContents: () => {\n return `export const databaseConfig = ${JSON.stringify(databaseConfig)};`;\n },\n });\n\n addServerPlugin(createResolver(import.meta.url).resolve('./runtime/plugins/database.server'));\n}\n"],"names":[],"mappings":";;;;AAKA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,KAAK,EAAqB;AACrE,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE;AACrC,IAAI,cAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,uGAAuG;AAC/G,OAAO;AACP,KAAK,CAAC;;AAEN,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,cAAA,GAAiB,KAAK,CAAC,QAAA,IAAY,EAAE,OAAO,EAAE,EAAC,EAAG;;AAE1D;AACA,EAAE,iBAAiB,CAAC;AACpB,IAAI,QAAQ,EAAE,6BAA6B;AAC3C,IAAI,WAAW,EAAE,MAAM;AACvB,MAAM,OAAO,CAAC,8BAA8B,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAC/E,KAAK;AACL,GAAG,CAAC;;AAEJ,EAAE,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;AAC/F;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createResolver, addServerPlugin } from '@nuxt/kit';
|
|
2
|
+
import { addServerTemplate } from '../vendor/server-template.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Prepares the storage config export to be used in the runtime storage instrumentation.
|
|
6
|
+
*/
|
|
7
|
+
function addStorageInstrumentation(nuxt) {
|
|
8
|
+
const moduleDirResolver = createResolver(import.meta.url);
|
|
9
|
+
const userStorageMounts = Object.keys(nuxt.options.nitro.storage || {});
|
|
10
|
+
|
|
11
|
+
// Create a virtual module to pass this data to runtime
|
|
12
|
+
addServerTemplate({
|
|
13
|
+
filename: '#sentry/storage-config.mjs',
|
|
14
|
+
getContents: () => {
|
|
15
|
+
return `export const userStorageMounts = ${JSON.stringify(userStorageMounts)};`;
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/storage.server'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { addStorageInstrumentation };
|
|
23
|
+
//# sourceMappingURL=storageConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageConfig.js","sources":["../../../src/vite/storageConfig.ts"],"sourcesContent":["import { addServerPlugin, createResolver } from '@nuxt/kit';\nimport type { Nuxt } from 'nuxt/schema';\nimport { addServerTemplate } from '../vendor/server-template';\n\n/**\n * Prepares the storage config export to be used in the runtime storage instrumentation.\n */\nexport function addStorageInstrumentation(nuxt: Nuxt): void {\n const moduleDirResolver = createResolver(import.meta.url);\n const userStorageMounts = Object.keys(nuxt.options.nitro.storage || {});\n\n // Create a virtual module to pass this data to runtime\n addServerTemplate({\n filename: '#sentry/storage-config.mjs',\n getContents: () => {\n return `export const userStorageMounts = ${JSON.stringify(userStorageMounts)};`;\n },\n });\n\n addServerPlugin(moduleDirResolver.resolve('./runtime/plugins/storage.server'));\n}\n"],"names":[],"mappings":";;;AAIA;AACA;AACA;AACO,SAAS,yBAAyB,CAAC,IAAI,EAAc;AAC5D,EAAE,MAAM,iBAAA,GAAoB,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3D,EAAE,MAAM,iBAAA,GAAoB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;;AAEzE;AACA,EAAE,iBAAiB,CAAC;AACpB,IAAI,QAAQ,EAAE,4BAA4B;AAC1C,IAAI,WAAW,EAAE,MAAM;AACvB,MAAM,OAAO,CAAC,iCAAiC,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACrF,KAAK;AACL,GAAG,CAAC;;AAEJ,EAAE,eAAe,CAAC,iBAAiB,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;AAChF;;;;"}
|
package/build/module/module.json
CHANGED
package/build/module/module.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createResolver, addServerImports, defineNuxtModule, addPluginTemplate, addPlugin,
|
|
1
|
+
import { createResolver, useNuxt, addServerPlugin, addServerImports, defineNuxtModule, addPluginTemplate, addPlugin, addTemplate } from '@nuxt/kit';
|
|
2
2
|
import { consoleSandbox, debug } from '@sentry/core';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { existsSync } from 'node:fs';
|
|
@@ -253,6 +253,34 @@ ${reExportedFunctions}
|
|
|
253
253
|
};
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
function addServerTemplate(template) {
|
|
257
|
+
const nuxt = useNuxt();
|
|
258
|
+
if (template.filename) {
|
|
259
|
+
nuxt.options.nitro.virtual = nuxt.options.nitro.virtual || {};
|
|
260
|
+
nuxt.options.nitro.virtual[template.filename] = template.getContents;
|
|
261
|
+
}
|
|
262
|
+
return template;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function addDatabaseInstrumentation(nitro) {
|
|
266
|
+
if (!nitro.experimental?.database) {
|
|
267
|
+
consoleSandbox(() => {
|
|
268
|
+
console.log(
|
|
269
|
+
"[Sentry] [Nitro Database Plugin]: No database configuration found. Skipping database instrumentation."
|
|
270
|
+
);
|
|
271
|
+
});
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const databaseConfig = nitro.database || { default: {} };
|
|
275
|
+
addServerTemplate({
|
|
276
|
+
filename: "#sentry/database-config.mjs",
|
|
277
|
+
getContents: () => {
|
|
278
|
+
return `export const databaseConfig = ${JSON.stringify(databaseConfig)};`;
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
addServerPlugin(createResolver(import.meta.url).resolve("./runtime/plugins/database.server"));
|
|
282
|
+
}
|
|
283
|
+
|
|
256
284
|
function addMiddlewareImports() {
|
|
257
285
|
addServerImports([
|
|
258
286
|
{
|
|
@@ -563,6 +591,18 @@ function logSentryEnablesSourceMap(settingKey, settingValue) {
|
|
|
563
591
|
console.log(`[Sentry] Enabled source map generation in the build options with \`${settingKey}: ${settingValue}\`.`);
|
|
564
592
|
}
|
|
565
593
|
|
|
594
|
+
function addStorageInstrumentation(nuxt) {
|
|
595
|
+
const moduleDirResolver = createResolver(import.meta.url);
|
|
596
|
+
const userStorageMounts = Object.keys(nuxt.options.nitro.storage || {});
|
|
597
|
+
addServerTemplate({
|
|
598
|
+
filename: "#sentry/storage-config.mjs",
|
|
599
|
+
getContents: () => {
|
|
600
|
+
return `export const userStorageMounts = ${JSON.stringify(userStorageMounts)};`;
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/storage.server"));
|
|
604
|
+
}
|
|
605
|
+
|
|
566
606
|
const module = defineNuxtModule({
|
|
567
607
|
meta: {
|
|
568
608
|
name: "@sentry/nuxt/module",
|
|
@@ -611,11 +651,12 @@ const module = defineNuxtModule({
|
|
|
611
651
|
order: 1
|
|
612
652
|
});
|
|
613
653
|
nuxt.hook("prepare:types", (options) => {
|
|
614
|
-
|
|
615
|
-
|
|
654
|
+
const tsConfig = options.tsConfig;
|
|
655
|
+
if (!tsConfig.include) {
|
|
656
|
+
tsConfig.include = [];
|
|
616
657
|
}
|
|
617
658
|
const relativePath = path.relative(nuxt.options.buildDir, clientConfigFile);
|
|
618
|
-
|
|
659
|
+
tsConfig.include.push(relativePath);
|
|
619
660
|
});
|
|
620
661
|
}
|
|
621
662
|
const serverConfigFile = findDefaultSdkInitFile("server", nuxt);
|
|
@@ -646,6 +687,8 @@ const module = defineNuxtModule({
|
|
|
646
687
|
});
|
|
647
688
|
if (serverConfigFile) {
|
|
648
689
|
addMiddlewareImports();
|
|
690
|
+
addStorageInstrumentation(nuxt);
|
|
691
|
+
addDatabaseInstrumentation(nuxt.options.nitro);
|
|
649
692
|
}
|
|
650
693
|
nuxt.hooks.hook("nitro:init", (nitro) => {
|
|
651
694
|
if (serverConfigFile) {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addBreadcrumb,
|
|
3
|
+
captureException,
|
|
4
|
+
debug,
|
|
5
|
+
flushIfServerless,
|
|
6
|
+
SEMANTIC_ATTRIBUTE_SENTRY_OP,
|
|
7
|
+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
|
|
8
|
+
SPAN_STATUS_ERROR,
|
|
9
|
+
startSpan
|
|
10
|
+
} from "@sentry/core";
|
|
11
|
+
import { defineNitroPlugin, useDatabase } from "nitropack/runtime";
|
|
12
|
+
import { databaseConfig } from "#sentry/database-config.mjs";
|
|
13
|
+
import { getDatabaseSpanData } from "../utils/database-span-data.js";
|
|
14
|
+
const patchedStatement = /* @__PURE__ */ new WeakSet();
|
|
15
|
+
const SENTRY_ORIGIN = "auto.db.nuxt";
|
|
16
|
+
export default defineNitroPlugin(() => {
|
|
17
|
+
try {
|
|
18
|
+
const _databaseConfig = databaseConfig;
|
|
19
|
+
const databaseInstances = Object.keys(databaseConfig);
|
|
20
|
+
debug.log("[Nitro Database Plugin]: Instrumenting databases...");
|
|
21
|
+
for (const instance of databaseInstances) {
|
|
22
|
+
debug.log("[Nitro Database Plugin]: Instrumenting database instance:", instance);
|
|
23
|
+
const db = useDatabase(instance);
|
|
24
|
+
instrumentDatabase(db, _databaseConfig[instance]);
|
|
25
|
+
}
|
|
26
|
+
debug.log("[Nitro Database Plugin]: Databases instrumented.");
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (error instanceof Error && /Cannot access 'instances'/.test(error.message)) {
|
|
29
|
+
debug.log("[Nitro Database Plugin]: Database instrumentation skipped during build time.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
debug.error("[Nitro Database Plugin]: Failed to instrument database:", error);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
function instrumentDatabase(db, config) {
|
|
36
|
+
if (db.__sentry_instrumented__) {
|
|
37
|
+
debug.log("[Nitro Database Plugin]: Database already instrumented. Skipping...");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const metadata = {
|
|
41
|
+
"db.system.name": config?.connector ?? db.dialect,
|
|
42
|
+
...getDatabaseSpanData(config)
|
|
43
|
+
};
|
|
44
|
+
db.prepare = new Proxy(db.prepare, {
|
|
45
|
+
apply(target, thisArg, args) {
|
|
46
|
+
const [query] = args;
|
|
47
|
+
return instrumentPreparedStatement(target.apply(thisArg, args), query, metadata);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
db.sql = new Proxy(db.sql, {
|
|
51
|
+
apply(target, thisArg, args) {
|
|
52
|
+
const query = args[0]?.[0] ?? "";
|
|
53
|
+
const opts = createStartSpanOptions(query, metadata);
|
|
54
|
+
return startSpan(
|
|
55
|
+
opts,
|
|
56
|
+
handleSpanStart(() => target.apply(thisArg, args))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
db.exec = new Proxy(db.exec, {
|
|
61
|
+
apply(target, thisArg, args) {
|
|
62
|
+
return startSpan(
|
|
63
|
+
createStartSpanOptions(args[0], metadata),
|
|
64
|
+
handleSpanStart(() => target.apply(thisArg, args), { query: args[0] })
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
db.__sentry_instrumented__ = true;
|
|
69
|
+
}
|
|
70
|
+
function instrumentPreparedStatement(statement, query, data) {
|
|
71
|
+
statement.bind = new Proxy(statement.bind, {
|
|
72
|
+
apply(target, thisArg, args) {
|
|
73
|
+
return instrumentPreparedStatementQueries(target.apply(thisArg, args), query, data);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return instrumentPreparedStatementQueries(statement, query, data);
|
|
77
|
+
}
|
|
78
|
+
function instrumentPreparedStatementQueries(statement, query, data) {
|
|
79
|
+
if (patchedStatement.has(statement)) {
|
|
80
|
+
return statement;
|
|
81
|
+
}
|
|
82
|
+
statement.get = new Proxy(statement.get, {
|
|
83
|
+
apply(target, thisArg, args) {
|
|
84
|
+
return startSpan(
|
|
85
|
+
createStartSpanOptions(query, data),
|
|
86
|
+
handleSpanStart(() => target.apply(thisArg, args), { query })
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
statement.run = new Proxy(statement.run, {
|
|
91
|
+
apply(target, thisArg, args) {
|
|
92
|
+
return startSpan(
|
|
93
|
+
createStartSpanOptions(query, data),
|
|
94
|
+
handleSpanStart(() => target.apply(thisArg, args), { query })
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
statement.all = new Proxy(statement.all, {
|
|
99
|
+
apply(target, thisArg, args) {
|
|
100
|
+
return startSpan(
|
|
101
|
+
createStartSpanOptions(query, data),
|
|
102
|
+
handleSpanStart(() => target.apply(thisArg, args), { query })
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
patchedStatement.add(statement);
|
|
107
|
+
return statement;
|
|
108
|
+
}
|
|
109
|
+
function handleSpanStart(fn, breadcrumbOpts) {
|
|
110
|
+
return async (span) => {
|
|
111
|
+
try {
|
|
112
|
+
const result = await fn();
|
|
113
|
+
if (breadcrumbOpts) {
|
|
114
|
+
createBreadcrumb(breadcrumbOpts.query);
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
|
|
119
|
+
captureException(error, {
|
|
120
|
+
mechanism: {
|
|
121
|
+
handled: false,
|
|
122
|
+
type: SENTRY_ORIGIN
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
throw error;
|
|
126
|
+
} finally {
|
|
127
|
+
await flushIfServerless();
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function createBreadcrumb(query) {
|
|
132
|
+
addBreadcrumb({
|
|
133
|
+
category: "query",
|
|
134
|
+
message: query,
|
|
135
|
+
data: {
|
|
136
|
+
"db.query.text": query
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function createStartSpanOptions(query, data) {
|
|
141
|
+
return {
|
|
142
|
+
name: query,
|
|
143
|
+
attributes: {
|
|
144
|
+
"db.query.text": query,
|
|
145
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: SENTRY_ORIGIN,
|
|
146
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: "db.query",
|
|
147
|
+
...data
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
@@ -20,6 +20,7 @@ export const sentryCloudflareNitroPlugin = (optionsOrFn) => (nitroApp) => {
|
|
|
20
20
|
const request = new Request(url, {
|
|
21
21
|
method: event.method,
|
|
22
22
|
headers: event.headers,
|
|
23
|
+
// @ts-expect-error - 'cf' is a valid property in the RequestInit type for Cloudflare
|
|
23
24
|
cf: getCfProperties(event)
|
|
24
25
|
});
|
|
25
26
|
const requestHandlerOptions = {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("nitropack
|
|
1
|
+
declare const _default: import("nitropack").NitroAppPlugin;
|
|
2
2
|
export default _default;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import {
|
|
2
|
+
captureException,
|
|
3
|
+
debug,
|
|
4
|
+
flushIfServerless,
|
|
5
|
+
SEMANTIC_ATTRIBUTE_CACHE_HIT,
|
|
6
|
+
SEMANTIC_ATTRIBUTE_CACHE_KEY,
|
|
7
|
+
SEMANTIC_ATTRIBUTE_SENTRY_OP,
|
|
8
|
+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
|
|
9
|
+
SPAN_STATUS_ERROR,
|
|
10
|
+
SPAN_STATUS_OK,
|
|
11
|
+
startSpan
|
|
12
|
+
} from "@sentry/core";
|
|
13
|
+
import { defineNitroPlugin, useStorage } from "nitropack/runtime";
|
|
14
|
+
import { userStorageMounts } from "#sentry/storage-config.mjs";
|
|
15
|
+
const CACHE_HIT_METHODS = /* @__PURE__ */ new Set(["hasItem", "getItem", "getItemRaw"]);
|
|
16
|
+
export default defineNitroPlugin(async (_nitroApp) => {
|
|
17
|
+
const storage = useStorage();
|
|
18
|
+
const userMounts = new Set(userStorageMounts.map((m) => `${m}:`));
|
|
19
|
+
debug.log("[storage] Starting to instrument storage drivers...");
|
|
20
|
+
userMounts.add("cache:");
|
|
21
|
+
userMounts.add("");
|
|
22
|
+
const mounts = storage.getMounts();
|
|
23
|
+
for (const mount of mounts) {
|
|
24
|
+
if (!userMounts.has(mount.base)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
instrumentDriver(mount.driver, mount.base);
|
|
28
|
+
}
|
|
29
|
+
storage.mount = wrapStorageMount(storage);
|
|
30
|
+
});
|
|
31
|
+
function instrumentDriver(driver, mountBase) {
|
|
32
|
+
if (driver.__sentry_instrumented__) {
|
|
33
|
+
debug.log(`[storage] Driver already instrumented: "${driver.name}". Skipping...`);
|
|
34
|
+
return driver;
|
|
35
|
+
}
|
|
36
|
+
debug.log(`[storage] Instrumenting driver: "${driver.name}" on mount: "${mountBase}"`);
|
|
37
|
+
const methodsToInstrument = [
|
|
38
|
+
"hasItem",
|
|
39
|
+
"getItem",
|
|
40
|
+
"getItemRaw",
|
|
41
|
+
"getItems",
|
|
42
|
+
"setItem",
|
|
43
|
+
"setItemRaw",
|
|
44
|
+
"setItems",
|
|
45
|
+
"removeItem",
|
|
46
|
+
"getKeys",
|
|
47
|
+
"clear"
|
|
48
|
+
];
|
|
49
|
+
for (const methodName of methodsToInstrument) {
|
|
50
|
+
const original = driver[methodName];
|
|
51
|
+
if (typeof original !== "function") {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
driver[methodName] = createMethodWrapper(original, methodName, driver, mountBase);
|
|
55
|
+
}
|
|
56
|
+
driver.__sentry_instrumented__ = true;
|
|
57
|
+
return driver;
|
|
58
|
+
}
|
|
59
|
+
function createMethodWrapper(original, methodName, driver, mountBase) {
|
|
60
|
+
return new Proxy(original, {
|
|
61
|
+
async apply(target, thisArg, args) {
|
|
62
|
+
const options = createSpanStartOptions(methodName, driver, mountBase, args);
|
|
63
|
+
debug.log(`[storage] Running method: "${methodName}" on driver: "${driver.name ?? "unknown"}"`);
|
|
64
|
+
return startSpan(options, async (span) => {
|
|
65
|
+
try {
|
|
66
|
+
const result = await target.apply(thisArg, args);
|
|
67
|
+
span.setStatus({ code: SPAN_STATUS_OK });
|
|
68
|
+
if (CACHE_HIT_METHODS.has(methodName)) {
|
|
69
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, isCacheHit(args[0], result));
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
|
|
74
|
+
captureException(error, {
|
|
75
|
+
mechanism: {
|
|
76
|
+
handled: false,
|
|
77
|
+
type: options.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
throw error;
|
|
81
|
+
} finally {
|
|
82
|
+
await flushIfServerless();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function wrapStorageMount(storage) {
|
|
89
|
+
const original = storage.mount;
|
|
90
|
+
if (original.__sentry_instrumented__) {
|
|
91
|
+
return original;
|
|
92
|
+
}
|
|
93
|
+
function mountWithInstrumentation(base, driver) {
|
|
94
|
+
debug.log(`[storage] Instrumenting mount: "${base}"`);
|
|
95
|
+
const instrumentedDriver = instrumentDriver(driver, base);
|
|
96
|
+
return original(base, instrumentedDriver);
|
|
97
|
+
}
|
|
98
|
+
mountWithInstrumentation.__sentry_instrumented__ = true;
|
|
99
|
+
return mountWithInstrumentation;
|
|
100
|
+
}
|
|
101
|
+
function normalizeMethodName(methodName) {
|
|
102
|
+
return methodName.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
103
|
+
}
|
|
104
|
+
function isEmptyValue(value) {
|
|
105
|
+
return value === null || value === void 0;
|
|
106
|
+
}
|
|
107
|
+
function createSpanStartOptions(methodName, driver, mountBase, args) {
|
|
108
|
+
const keys = getCacheKeys(args?.[0], mountBase);
|
|
109
|
+
const attributes = {
|
|
110
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: `cache.${normalizeMethodName(methodName)}`,
|
|
111
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.cache.nuxt",
|
|
112
|
+
[SEMANTIC_ATTRIBUTE_CACHE_KEY]: keys.length > 1 ? keys : keys[0],
|
|
113
|
+
"db.operation.name": methodName,
|
|
114
|
+
"db.collection.name": mountBase.replace(/:$/, ""),
|
|
115
|
+
"db.system.name": driver.name ?? "unknown"
|
|
116
|
+
};
|
|
117
|
+
return {
|
|
118
|
+
name: keys.join(", "),
|
|
119
|
+
attributes
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function getCacheKeys(key, prefix) {
|
|
123
|
+
if (Array.isArray(key)) {
|
|
124
|
+
return key.map((k) => normalizeKey(k, prefix));
|
|
125
|
+
}
|
|
126
|
+
return [normalizeKey(key, prefix)];
|
|
127
|
+
}
|
|
128
|
+
function normalizeKey(key, prefix) {
|
|
129
|
+
if (typeof key === "string") {
|
|
130
|
+
return `${prefix}${key}`;
|
|
131
|
+
}
|
|
132
|
+
if (typeof key === "object" && key !== null && "key" in key) {
|
|
133
|
+
return `${prefix}${key.key}`;
|
|
134
|
+
}
|
|
135
|
+
return `${prefix}${isEmptyValue(key) ? "" : String(key)}`;
|
|
136
|
+
}
|
|
137
|
+
const CACHED_FN_HANDLERS_RE = /^nitro:(functions|handlers):/i;
|
|
138
|
+
function isCacheHit(key, value) {
|
|
139
|
+
try {
|
|
140
|
+
const isEmpty = isEmptyValue(value);
|
|
141
|
+
if (isEmpty || !CACHED_FN_HANDLERS_RE.test(key)) {
|
|
142
|
+
return !isEmpty;
|
|
143
|
+
}
|
|
144
|
+
return validateCacheEntry(key, JSON.parse(String(value)));
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function validateCacheEntry(key, entry) {
|
|
150
|
+
if (isEmptyValue(entry.value)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (Date.now() > (entry.expires || 0)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (isResponseCacheEntry(key, entry)) {
|
|
157
|
+
if (entry.value.status >= 400) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
if (entry.value.body === void 0) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (entry.value.headers.etag === "undefined" || entry.value.headers["last-modified"] === "undefined") {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
function isResponseCacheEntry(key, _) {
|
|
170
|
+
return key.startsWith("nitro:handlers:");
|
|
171
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DatabaseConnectionConfig as DatabaseConfig } from 'nitropack/types';
|
|
2
|
+
export interface DatabaseSpanData {
|
|
3
|
+
[key: string]: string | number | undefined;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Extracts span attributes from the database configuration.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getDatabaseSpanData(config?: DatabaseConfig): Partial<DatabaseSpanData>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function getDatabaseSpanData(config) {
|
|
2
|
+
try {
|
|
3
|
+
if (!config?.connector) {
|
|
4
|
+
return {
|
|
5
|
+
"db.namespace": "db.sqlite"
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
if (config.connector === "postgresql" || config.connector === "mysql2") {
|
|
9
|
+
return {
|
|
10
|
+
"server.address": config.options?.host,
|
|
11
|
+
"server.port": config.options?.port
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
if (config.connector === "pglite") {
|
|
15
|
+
return {
|
|
16
|
+
"db.namespace": config.options?.dataDir
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (["better-sqlite3", "bun", "sqlite", "sqlite3"].includes(config.connector)) {
|
|
20
|
+
return {
|
|
21
|
+
// DB is the default file name in nitro for sqlite-like connectors
|
|
22
|
+
"db.namespace": `${config.options?.name ?? "db"}.sqlite`
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {};
|
|
26
|
+
} catch {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAQ9D,MAAM,MAAM,aAAa,GAAG,uBAAuB,CAAC;;AAEpD,wBAgMG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/database.server.ts"],"names":[],"mappings":"AAkCA;;GAEG;;AACH,wBAsBG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentry-cloudflare.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/sentry-cloudflare.server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sentry-cloudflare.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/sentry-cloudflare.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAI5D,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAO1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,2BAA2B,GACrC,aAAa,iBAAiB,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,KAAK,iBAAiB,CAAC,KAAG,cAkF/E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/storage.server.ts"],"names":[],"mappings":"AAkCA;;GAEG;;AACH,wBA6BG"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DatabaseConnectionConfig as DatabaseConfig } from 'nitropack/types';
|
|
2
|
+
export interface DatabaseSpanData {
|
|
3
|
+
[key: string]: string | number | undefined;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Extracts span attributes from the database configuration.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getDatabaseSpanData(config?: DatabaseConfig): Partial<DatabaseSpanData>;
|
|
9
|
+
//# sourceMappingURL=database-span-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-span-data.d.ts","sourceRoot":"","sources":["../../../../src/runtime/utils/database-span-data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,IAAI,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAElF,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmCtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../../src/server/sdk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../../src/server/sdk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAS,cAAc,EAAe,MAAM,cAAc,CAAC;AAS/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAczE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,uBAAuB,GAAG,cAAc,CA0B7F;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,uBAAuB,GAAG,cAAc,CAY3F"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NuxtTemplate } from 'nuxt/schema';
|
|
2
|
+
/**
|
|
3
|
+
* Adds a virtual file that can be used within the Nuxt Nitro server build.
|
|
4
|
+
* Available in NuxtKit v4, so we are porting it here.
|
|
5
|
+
* https://github.com/nuxt/nuxt/blob/d6df732eec1a3bd442bdb325b0335beb7e10cd64/packages/kit/src/template.ts#L55-L62
|
|
6
|
+
*/
|
|
7
|
+
export declare function addServerTemplate(template: NuxtTemplate): NuxtTemplate;
|
|
8
|
+
//# sourceMappingURL=server-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-template.d.ts","sourceRoot":"","sources":["../../../src/vendor/server-template.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CAQtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databaseConfig.d.ts","sourceRoot":"","sources":["../../../src/vite/databaseConfig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CA6BnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageConfig.d.ts","sourceRoot":"","sources":["../../../src/vite/storageConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAa1D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/nuxt",
|
|
3
|
-
"version": "10.21.0
|
|
3
|
+
"version": "10.21.0",
|
|
4
4
|
"description": "Official Sentry SDK for Nuxt",
|
|
5
5
|
"repository": "git://github.com/getsentry/sentry-javascript.git",
|
|
6
6
|
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nuxt",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@nuxt/kit": "^3.13.2",
|
|
50
|
-
"@sentry/browser": "10.21.0
|
|
51
|
-
"@sentry/cloudflare": "10.21.0
|
|
52
|
-
"@sentry/core": "10.21.0
|
|
53
|
-
"@sentry/node": "10.21.0
|
|
50
|
+
"@sentry/browser": "10.21.0",
|
|
51
|
+
"@sentry/cloudflare": "10.21.0",
|
|
52
|
+
"@sentry/core": "10.21.0",
|
|
53
|
+
"@sentry/node": "10.21.0",
|
|
54
54
|
"@sentry/rollup-plugin": "^4.3.0",
|
|
55
55
|
"@sentry/vite-plugin": "^4.3.0",
|
|
56
|
-
"@sentry/vue": "10.21.0
|
|
56
|
+
"@sentry/vue": "10.21.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@nuxt/module-builder": "^0.8.4",
|