@sentry/nuxt 10.44.0 → 10.46.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.
Files changed (72) hide show
  1. package/build/cjs/module.js +15 -10
  2. package/build/cjs/module.js.map +1 -1
  3. package/build/cjs/vite/databaseConfig.js +10 -2
  4. package/build/cjs/vite/databaseConfig.js.map +1 -1
  5. package/build/cjs/vite/sentryVitePlugin.js.map +1 -1
  6. package/build/cjs/vite/storageConfig.js +6 -2
  7. package/build/cjs/vite/storageConfig.js.map +1 -1
  8. package/build/cjs/vite/utils.js +21 -2
  9. package/build/cjs/vite/utils.js.map +1 -1
  10. package/build/esm/module.js +16 -11
  11. package/build/esm/module.js.map +1 -1
  12. package/build/esm/package.json +1 -1
  13. package/build/esm/vite/databaseConfig.js +10 -2
  14. package/build/esm/vite/databaseConfig.js.map +1 -1
  15. package/build/esm/vite/sentryVitePlugin.js.map +1 -1
  16. package/build/esm/vite/storageConfig.js +6 -2
  17. package/build/esm/vite/storageConfig.js.map +1 -1
  18. package/build/esm/vite/utils.js +21 -3
  19. package/build/esm/vite/utils.js.map +1 -1
  20. package/build/module/module.json +1 -1
  21. package/build/module/module.mjs +38 -14
  22. package/build/module/runtime/plugins/database-legacy.server.d.ts +5 -0
  23. package/build/module/runtime/plugins/database-legacy.server.js +6 -0
  24. package/build/module/runtime/plugins/database.server.d.ts +1 -1
  25. package/build/module/runtime/plugins/database.server.js +3 -147
  26. package/build/module/runtime/plugins/handler-legacy.server.d.ts +2 -0
  27. package/build/module/runtime/plugins/handler-legacy.server.js +4 -0
  28. package/build/module/runtime/plugins/handler.server.d.ts +6 -0
  29. package/build/module/runtime/plugins/handler.server.js +6 -0
  30. package/build/module/runtime/plugins/sentry.server.js +6 -29
  31. package/build/module/runtime/plugins/storage-legacy.server.d.ts +5 -0
  32. package/build/module/runtime/plugins/storage-legacy.server.js +6 -0
  33. package/build/module/runtime/plugins/storage.server.d.ts +4 -2
  34. package/build/module/runtime/plugins/storage.server.js +3 -168
  35. package/build/module/runtime/utils/database-span-data.d.ts +16 -2
  36. package/build/module/runtime/utils/instrumentDatabase.d.ts +9 -0
  37. package/build/module/runtime/utils/instrumentDatabase.js +147 -0
  38. package/build/module/runtime/utils/instrumentStorage.d.ts +7 -0
  39. package/build/module/runtime/utils/instrumentStorage.js +169 -0
  40. package/build/module/runtime/utils/patchEventHandler.d.ts +6 -0
  41. package/build/module/runtime/utils/patchEventHandler.js +25 -0
  42. package/build/types/module.d.ts.map +1 -1
  43. package/build/types/runtime/plugins/database-legacy.server.d.ts +6 -0
  44. package/build/types/runtime/plugins/database-legacy.server.d.ts.map +1 -0
  45. package/build/types/runtime/plugins/database.server.d.ts +1 -1
  46. package/build/types/runtime/plugins/database.server.d.ts.map +1 -1
  47. package/build/types/runtime/plugins/handler-legacy.server.d.ts +3 -0
  48. package/build/types/runtime/plugins/handler-legacy.server.d.ts.map +1 -0
  49. package/build/types/runtime/plugins/handler.server.d.ts +7 -0
  50. package/build/types/runtime/plugins/handler.server.d.ts.map +1 -0
  51. package/build/types/runtime/plugins/sentry.server.d.ts.map +1 -1
  52. package/build/types/runtime/plugins/storage-legacy.server.d.ts +6 -0
  53. package/build/types/runtime/plugins/storage-legacy.server.d.ts.map +1 -0
  54. package/build/types/runtime/plugins/storage.server.d.ts +4 -2
  55. package/build/types/runtime/plugins/storage.server.d.ts.map +1 -1
  56. package/build/types/runtime/utils/database-span-data.d.ts +16 -2
  57. package/build/types/runtime/utils/database-span-data.d.ts.map +1 -1
  58. package/build/types/runtime/utils/instrumentDatabase.d.ts +10 -0
  59. package/build/types/runtime/utils/instrumentDatabase.d.ts.map +1 -0
  60. package/build/types/runtime/utils/instrumentStorage.d.ts +8 -0
  61. package/build/types/runtime/utils/instrumentStorage.d.ts.map +1 -0
  62. package/build/types/runtime/utils/patchEventHandler.d.ts +7 -0
  63. package/build/types/runtime/utils/patchEventHandler.d.ts.map +1 -0
  64. package/build/types/runtime/utils.d.ts.map +1 -1
  65. package/build/types/vite/databaseConfig.d.ts +1 -1
  66. package/build/types/vite/databaseConfig.d.ts.map +1 -1
  67. package/build/types/vite/sentryVitePlugin.d.ts.map +1 -1
  68. package/build/types/vite/storageConfig.d.ts +1 -1
  69. package/build/types/vite/storageConfig.d.ts.map +1 -1
  70. package/build/types/vite/utils.d.ts +6 -1
  71. package/build/types/vite/utils.d.ts.map +1 -1
  72. package/package.json +16 -8
@@ -2,6 +2,24 @@ import { consoleSandbox } from '@sentry/core';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
 
5
+ /**
6
+ * Gets the major version of the installed nitro package.
7
+ * Returns 2 as the default if nitro is not found or the version cannot be determined.
8
+ */
9
+ async function getNitroMajorVersion() {
10
+ try {
11
+ const { getPackageInfo } = await import('local-pkg');
12
+ const info = await getPackageInfo('nitro');
13
+ if (info?.version) {
14
+ const major = parseInt(info.version.split('.')[0] ?? '2', 10);
15
+ return isNaN(major) ? 2 : major;
16
+ }
17
+ } catch {
18
+ // If local-pkg is unavailable or nitro is not found, default to v2
19
+ }
20
+ return 2;
21
+ }
22
+
5
23
  /**
6
24
  * Find the default SDK init file for the given type (client or server).
7
25
  * The sentry.server.config file is prioritized over the instrument.server file.
@@ -189,8 +207,8 @@ function constructFunctionReExport(pathWithQuery, entryId) {
189
207
  *
190
208
  * @see https://nuxt.com/docs/guide/concepts/esm#aliasing-libraries
191
209
  */
192
- function addOTelCommonJSImportAlias(nuxt) {
193
- if (!nuxt.options.dev) {
210
+ function addOTelCommonJSImportAlias(nuxt, isNitroV3 = false) {
211
+ if (!nuxt.options.dev || isNitroV3) {
194
212
  return;
195
213
  }
196
214
 
@@ -203,5 +221,5 @@ function addOTelCommonJSImportAlias(nuxt) {
203
221
  }
204
222
  }
205
223
 
206
- export { QUERY_END_INDICATOR, SENTRY_REEXPORTED_FUNCTIONS, SENTRY_WRAPPED_ENTRY, SENTRY_WRAPPED_FUNCTIONS, addOTelCommonJSImportAlias, constructFunctionReExport, constructWrappedFunctionExportQuery, extractFunctionReexportQueryParameters, findDefaultSdkInitFile, getFilenameFromNodeStartCommand, removeSentryQueryFromPath };
224
+ export { QUERY_END_INDICATOR, SENTRY_REEXPORTED_FUNCTIONS, SENTRY_WRAPPED_ENTRY, SENTRY_WRAPPED_FUNCTIONS, addOTelCommonJSImportAlias, constructFunctionReExport, constructWrappedFunctionExportQuery, extractFunctionReexportQueryParameters, findDefaultSdkInitFile, getFilenameFromNodeStartCommand, getNitroMajorVersion, removeSentryQueryFromPath };
207
225
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/vite/utils.ts"],"sourcesContent":["import type { Nuxt } from '@nuxt/schema';\nimport { consoleSandbox } from '@sentry/core';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Find the default SDK init file for the given type (client or server).\n * The sentry.server.config file is prioritized over the instrument.server file.\n */\nexport function findDefaultSdkInitFile(type: 'server' | 'client', nuxt?: Nuxt): string | undefined {\n const possibleFileExtensions = ['ts', 'js', 'mjs', 'cjs', 'mts', 'cts'];\n const relativePaths: string[] = [];\n\n if (type === 'server') {\n for (const ext of possibleFileExtensions) {\n relativePaths.push(`sentry.${type}.config.${ext}`);\n relativePaths.push(path.join('public', `instrument.${type}.${ext}`));\n }\n } else {\n for (const ext of possibleFileExtensions) {\n relativePaths.push(`sentry.${type}.config.${ext}`);\n }\n }\n\n // Get layers from highest priority to lowest\n const layers = [...(nuxt?.options._layers ?? [])].reverse();\n\n for (const layer of layers) {\n for (const relativePath of relativePaths) {\n const fullPath = path.resolve(layer.cwd, relativePath);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n }\n\n // As a fallback, also check CWD (left for pure compatibility)\n const cwd = process.cwd();\n for (const relativePath of relativePaths) {\n const fullPath = path.resolve(cwd, relativePath);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts the filename from a node command with a path.\n */\nexport function getFilenameFromNodeStartCommand(nodeCommand: string): string | null {\n const regex = /[^/\\\\]+\\.[^/\\\\]+$/;\n const match = nodeCommand.match(regex);\n return match ? match[0] : null;\n}\n\nexport const SENTRY_WRAPPED_ENTRY = '?sentry-query-wrapped-entry';\nexport const SENTRY_WRAPPED_FUNCTIONS = '?sentry-query-wrapped-functions=';\nexport const SENTRY_REEXPORTED_FUNCTIONS = '?sentry-query-reexported-functions=';\nexport const QUERY_END_INDICATOR = 'SENTRY-QUERY-END';\n\n/**\n * Strips the Sentry query part from a path.\n * Example: example/path?sentry-query-wrapped-entry?sentry-query-functions-reexport=foo,SENTRY-QUERY-END -> /example/path\n *\n * Only exported for testing.\n */\nexport function removeSentryQueryFromPath(url: string): string {\n // oxlint-disable-next-line sdk/no-regexp-constructor\n const regex = new RegExp(`\\\\${SENTRY_WRAPPED_ENTRY}.*?\\\\${QUERY_END_INDICATOR}`);\n return url.replace(regex, '');\n}\n\n/**\n * Extracts and sanitizes function re-export and function wrap query parameters from a query string.\n * If it is a default export, it is not considered for re-exporting.\n *\n * Only exported for testing.\n */\nexport function extractFunctionReexportQueryParameters(query: string): { wrap: string[]; reexport: string[] } {\n // Regex matches the comma-separated params between the functions query\n // oxlint-disable-next-line sdk/no-regexp-constructor\n const wrapRegex = new RegExp(\n `\\\\${SENTRY_WRAPPED_FUNCTIONS}(.*?)(\\\\${QUERY_END_INDICATOR}|\\\\${SENTRY_REEXPORTED_FUNCTIONS})`,\n );\n // oxlint-disable-next-line sdk/no-regexp-constructor\n const reexportRegex = new RegExp(`\\\\${SENTRY_REEXPORTED_FUNCTIONS}(.*?)(\\\\${QUERY_END_INDICATOR})`);\n\n const wrapMatch = query.match(wrapRegex);\n const reexportMatch = query.match(reexportRegex);\n\n const wrap =\n wrapMatch?.[1]\n ?.split(',')\n .filter(param => param !== '')\n // Sanitize, as code could be injected with another rollup plugin\n .map((str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')) || [];\n\n const reexport =\n reexportMatch?.[1]\n ?.split(',')\n .filter(param => param !== '' && param !== 'default')\n // Sanitize, as code could be injected with another rollup plugin\n .map((str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')) || [];\n\n return { wrap, reexport };\n}\n\n/**\n * Constructs a comma-separated string with all functions that need to be re-exported later from the server entry.\n * It uses Rollup's `exportedBindings` to determine the functions to re-export. Functions which should be wrapped\n * (e.g. serverless handlers) are wrapped by Sentry.\n */\nexport function constructWrappedFunctionExportQuery(\n exportedBindings: Record<string, string[]> | null,\n entrypointWrappedFunctions: string[],\n debug?: boolean,\n): string {\n const functionsToExport: { wrap: string[]; reexport: string[] } = {\n wrap: [],\n reexport: [],\n };\n\n // `exportedBindings` can look like this: `{ '.': [ 'handler' ] }` or `{ '.': [], './firebase-gen-1.mjs': [ 'server' ] }`\n // The key `.` refers to exports within the current file, while other keys show from where exports were imported first.\n Object.values(exportedBindings || {}).forEach(functions =>\n functions.forEach(fn => {\n if (entrypointWrappedFunctions.includes(fn)) {\n functionsToExport.wrap.push(fn);\n } else {\n functionsToExport.reexport.push(fn);\n }\n }),\n );\n\n if (debug && functionsToExport.wrap.length === 0) {\n consoleSandbox(() =>\n // eslint-disable-next-line no-console\n console.warn(\n \"[Sentry] No functions found to wrap. In case the server needs to export async functions other than `handler` or `server`, consider adding the name(s) to Sentry's build options `sentry.experimental_entrypointWrappedFunctions` in `nuxt.config.ts`.\",\n ),\n );\n }\n\n const wrapQuery = functionsToExport.wrap.length\n ? `${SENTRY_WRAPPED_FUNCTIONS}${functionsToExport.wrap.join(',')}`\n : '';\n const reexportQuery = functionsToExport.reexport.length\n ? `${SENTRY_REEXPORTED_FUNCTIONS}${functionsToExport.reexport.join(',')}`\n : '';\n\n return [wrapQuery, reexportQuery].join('');\n}\n\n/**\n * Constructs a code snippet with function reexports (can be used in Rollup plugins as a return value for `load()`)\n */\nexport function constructFunctionReExport(pathWithQuery: string, entryId: string): string {\n const { wrap: wrapFunctions, reexport: reexportFunctions } = extractFunctionReexportQueryParameters(pathWithQuery);\n\n return wrapFunctions\n .reduce(\n (functionsCode, currFunctionName) =>\n functionsCode.concat(\n `async function ${currFunctionName}_sentryWrapped(...args) {\\n` +\n ` const res = await import(${JSON.stringify(entryId)});\\n` +\n ` return res.${currFunctionName}.call(this, ...args);\\n` +\n '}\\n' +\n `export { ${currFunctionName}_sentryWrapped as ${currFunctionName} };\\n`,\n ),\n '',\n )\n .concat(\n reexportFunctions.reduce(\n (functionsCode, currFunctionName) =>\n functionsCode.concat(`export { ${currFunctionName} } from ${JSON.stringify(entryId)};`),\n '',\n ),\n );\n}\n\n/**\n * Sets up alias to work around OpenTelemetry's incomplete ESM imports.\n * https://github.com/getsentry/sentry-javascript/issues/15204\n *\n * OpenTelemetry's @opentelemetry/resources package has incomplete imports missing\n * the .js file extensions (like execAsync for machine-id detection). This causes module resolution\n * errors in certain Nuxt configurations, particularly when local Nuxt modules in Nuxt 4 are present.\n *\n * @see https://nuxt.com/docs/guide/concepts/esm#aliasing-libraries\n */\nexport function addOTelCommonJSImportAlias(nuxt: Nuxt): void {\n if (!nuxt.options.dev) {\n return;\n }\n\n if (!nuxt.options.alias) {\n nuxt.options.alias = {};\n }\n\n if (!nuxt.options.alias['@opentelemetry/resources']) {\n nuxt.options.alias['@opentelemetry/resources'] = '@opentelemetry/resources/build/src/index.js';\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/vite/utils.ts"],"sourcesContent":["import type { Nuxt } from '@nuxt/schema';\nimport { consoleSandbox } from '@sentry/core';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Gets the major version of the installed nitro package.\n * Returns 2 as the default if nitro is not found or the version cannot be determined.\n */\nexport async function getNitroMajorVersion(): Promise<number> {\n try {\n const { getPackageInfo } = await import('local-pkg');\n const info = await getPackageInfo('nitro');\n if (info?.version) {\n const major = parseInt(info.version.split('.')[0] ?? '2', 10);\n return isNaN(major) ? 2 : major;\n }\n } catch {\n // If local-pkg is unavailable or nitro is not found, default to v2\n }\n return 2;\n}\n\n/**\n * Find the default SDK init file for the given type (client or server).\n * The sentry.server.config file is prioritized over the instrument.server file.\n */\nexport function findDefaultSdkInitFile(type: 'server' | 'client', nuxt?: Nuxt): string | undefined {\n const possibleFileExtensions = ['ts', 'js', 'mjs', 'cjs', 'mts', 'cts'];\n const relativePaths: string[] = [];\n\n if (type === 'server') {\n for (const ext of possibleFileExtensions) {\n relativePaths.push(`sentry.${type}.config.${ext}`);\n relativePaths.push(path.join('public', `instrument.${type}.${ext}`));\n }\n } else {\n for (const ext of possibleFileExtensions) {\n relativePaths.push(`sentry.${type}.config.${ext}`);\n }\n }\n\n // Get layers from highest priority to lowest\n const layers = [...(nuxt?.options._layers ?? [])].reverse();\n\n for (const layer of layers) {\n for (const relativePath of relativePaths) {\n const fullPath = path.resolve(layer.cwd, relativePath);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n }\n\n // As a fallback, also check CWD (left for pure compatibility)\n const cwd = process.cwd();\n for (const relativePath of relativePaths) {\n const fullPath = path.resolve(cwd, relativePath);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts the filename from a node command with a path.\n */\nexport function getFilenameFromNodeStartCommand(nodeCommand: string): string | null {\n const regex = /[^/\\\\]+\\.[^/\\\\]+$/;\n const match = nodeCommand.match(regex);\n return match ? match[0] : null;\n}\n\nexport const SENTRY_WRAPPED_ENTRY = '?sentry-query-wrapped-entry';\nexport const SENTRY_WRAPPED_FUNCTIONS = '?sentry-query-wrapped-functions=';\nexport const SENTRY_REEXPORTED_FUNCTIONS = '?sentry-query-reexported-functions=';\nexport const QUERY_END_INDICATOR = 'SENTRY-QUERY-END';\n\n/**\n * Strips the Sentry query part from a path.\n * Example: example/path?sentry-query-wrapped-entry?sentry-query-functions-reexport=foo,SENTRY-QUERY-END -> /example/path\n *\n * Only exported for testing.\n */\nexport function removeSentryQueryFromPath(url: string): string {\n // oxlint-disable-next-line sdk/no-regexp-constructor\n const regex = new RegExp(`\\\\${SENTRY_WRAPPED_ENTRY}.*?\\\\${QUERY_END_INDICATOR}`);\n return url.replace(regex, '');\n}\n\n/**\n * Extracts and sanitizes function re-export and function wrap query parameters from a query string.\n * If it is a default export, it is not considered for re-exporting.\n *\n * Only exported for testing.\n */\nexport function extractFunctionReexportQueryParameters(query: string): { wrap: string[]; reexport: string[] } {\n // Regex matches the comma-separated params between the functions query\n // oxlint-disable-next-line sdk/no-regexp-constructor\n const wrapRegex = new RegExp(\n `\\\\${SENTRY_WRAPPED_FUNCTIONS}(.*?)(\\\\${QUERY_END_INDICATOR}|\\\\${SENTRY_REEXPORTED_FUNCTIONS})`,\n );\n // oxlint-disable-next-line sdk/no-regexp-constructor\n const reexportRegex = new RegExp(`\\\\${SENTRY_REEXPORTED_FUNCTIONS}(.*?)(\\\\${QUERY_END_INDICATOR})`);\n\n const wrapMatch = query.match(wrapRegex);\n const reexportMatch = query.match(reexportRegex);\n\n const wrap =\n wrapMatch?.[1]\n ?.split(',')\n .filter(param => param !== '')\n // Sanitize, as code could be injected with another rollup plugin\n .map((str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')) || [];\n\n const reexport =\n reexportMatch?.[1]\n ?.split(',')\n .filter(param => param !== '' && param !== 'default')\n // Sanitize, as code could be injected with another rollup plugin\n .map((str: string) => str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')) || [];\n\n return { wrap, reexport };\n}\n\n/**\n * Constructs a comma-separated string with all functions that need to be re-exported later from the server entry.\n * It uses Rollup's `exportedBindings` to determine the functions to re-export. Functions which should be wrapped\n * (e.g. serverless handlers) are wrapped by Sentry.\n */\nexport function constructWrappedFunctionExportQuery(\n exportedBindings: Record<string, string[]> | null,\n entrypointWrappedFunctions: string[],\n debug?: boolean,\n): string {\n const functionsToExport: { wrap: string[]; reexport: string[] } = {\n wrap: [],\n reexport: [],\n };\n\n // `exportedBindings` can look like this: `{ '.': [ 'handler' ] }` or `{ '.': [], './firebase-gen-1.mjs': [ 'server' ] }`\n // The key `.` refers to exports within the current file, while other keys show from where exports were imported first.\n Object.values(exportedBindings || {}).forEach(functions =>\n functions.forEach(fn => {\n if (entrypointWrappedFunctions.includes(fn)) {\n functionsToExport.wrap.push(fn);\n } else {\n functionsToExport.reexport.push(fn);\n }\n }),\n );\n\n if (debug && functionsToExport.wrap.length === 0) {\n consoleSandbox(() =>\n // eslint-disable-next-line no-console\n console.warn(\n \"[Sentry] No functions found to wrap. In case the server needs to export async functions other than `handler` or `server`, consider adding the name(s) to Sentry's build options `sentry.experimental_entrypointWrappedFunctions` in `nuxt.config.ts`.\",\n ),\n );\n }\n\n const wrapQuery = functionsToExport.wrap.length\n ? `${SENTRY_WRAPPED_FUNCTIONS}${functionsToExport.wrap.join(',')}`\n : '';\n const reexportQuery = functionsToExport.reexport.length\n ? `${SENTRY_REEXPORTED_FUNCTIONS}${functionsToExport.reexport.join(',')}`\n : '';\n\n return [wrapQuery, reexportQuery].join('');\n}\n\n/**\n * Constructs a code snippet with function reexports (can be used in Rollup plugins as a return value for `load()`)\n */\nexport function constructFunctionReExport(pathWithQuery: string, entryId: string): string {\n const { wrap: wrapFunctions, reexport: reexportFunctions } = extractFunctionReexportQueryParameters(pathWithQuery);\n\n return wrapFunctions\n .reduce(\n (functionsCode, currFunctionName) =>\n functionsCode.concat(\n `async function ${currFunctionName}_sentryWrapped(...args) {\\n` +\n ` const res = await import(${JSON.stringify(entryId)});\\n` +\n ` return res.${currFunctionName}.call(this, ...args);\\n` +\n '}\\n' +\n `export { ${currFunctionName}_sentryWrapped as ${currFunctionName} };\\n`,\n ),\n '',\n )\n .concat(\n reexportFunctions.reduce(\n (functionsCode, currFunctionName) =>\n functionsCode.concat(`export { ${currFunctionName} } from ${JSON.stringify(entryId)};`),\n '',\n ),\n );\n}\n\n/**\n * Sets up alias to work around OpenTelemetry's incomplete ESM imports.\n * https://github.com/getsentry/sentry-javascript/issues/15204\n *\n * OpenTelemetry's @opentelemetry/resources package has incomplete imports missing\n * the .js file extensions (like execAsync for machine-id detection). This causes module resolution\n * errors in certain Nuxt configurations, particularly when local Nuxt modules in Nuxt 4 are present.\n *\n * @see https://nuxt.com/docs/guide/concepts/esm#aliasing-libraries\n */\nexport function addOTelCommonJSImportAlias(nuxt: Nuxt, isNitroV3 = false): void {\n if (!nuxt.options.dev || isNitroV3) {\n return;\n }\n\n if (!nuxt.options.alias) {\n nuxt.options.alias = {};\n }\n\n if (!nuxt.options.alias['@opentelemetry/resources']) {\n nuxt.options.alias['@opentelemetry/resources'] = '@opentelemetry/resources/build/src/index.js';\n }\n}\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.7.0"
6
6
  },
7
- "version": "10.44.0",
7
+ "version": "10.46.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "2.0.0"
@@ -6,6 +6,18 @@ import * as fs from 'fs';
6
6
  import { sentryRollupPlugin } from '@sentry/rollup-plugin';
7
7
  import { sentryVitePlugin } from '@sentry/vite-plugin';
8
8
 
9
+ async function getNitroMajorVersion() {
10
+ try {
11
+ const { getPackageInfo } = await import('local-pkg');
12
+ const info = await getPackageInfo("nitro");
13
+ if (info?.version) {
14
+ const major = parseInt(info.version.split(".")[0] ?? "2", 10);
15
+ return isNaN(major) ? 2 : major;
16
+ }
17
+ } catch {
18
+ }
19
+ return 2;
20
+ }
9
21
  function findDefaultSdkInitFile(type, nuxt) {
10
22
  const possibleFileExtensions = ["ts", "js", "mjs", "cjs", "mts", "cts"];
11
23
  const relativePaths = [];
@@ -108,8 +120,8 @@ export { ${currFunctionName}_sentryWrapped as ${currFunctionName} };
108
120
  )
109
121
  );
110
122
  }
111
- function addOTelCommonJSImportAlias(nuxt) {
112
- if (!nuxt.options.dev) {
123
+ function addOTelCommonJSImportAlias(nuxt, isNitroV3 = false) {
124
+ if (!nuxt.options.dev || isNitroV3) {
113
125
  return;
114
126
  }
115
127
  if (!nuxt.options.alias) {
@@ -262,7 +274,7 @@ function addServerTemplate(template) {
262
274
  return template;
263
275
  }
264
276
 
265
- function addDatabaseInstrumentation(nitro, moduleOptions) {
277
+ function addDatabaseInstrumentation(nitro, isLegacyNitro, moduleOptions) {
266
278
  if (!nitro.experimental?.database) {
267
279
  moduleOptions?.debug && consoleSandbox(() => {
268
280
  console.log(
@@ -278,7 +290,11 @@ function addDatabaseInstrumentation(nitro, moduleOptions) {
278
290
  return `export const databaseConfig = ${JSON.stringify(databaseConfig)};`;
279
291
  }
280
292
  });
281
- addServerPlugin(createResolver(import.meta.url).resolve("./runtime/plugins/database.server"));
293
+ if (isLegacyNitro) {
294
+ addServerPlugin(createResolver(import.meta.url).resolve("./runtime/plugins/database-legacy.server"));
295
+ } else {
296
+ addServerPlugin(createResolver(import.meta.url).resolve("./runtime/plugins/database.server"));
297
+ }
282
298
  }
283
299
 
284
300
  function addMiddlewareImports() {
@@ -610,7 +626,7 @@ function logSentryEnablesSourceMap(settingKey, settingValue) {
610
626
  console.log(`[Sentry] Enabled source map generation in the build options with \`${settingKey}: ${settingValue}\`.`);
611
627
  }
612
628
 
613
- function addStorageInstrumentation(nuxt) {
629
+ function addStorageInstrumentation(nuxt, isLegacyNitro) {
614
630
  const moduleDirResolver = createResolver(import.meta.url);
615
631
  const userStorageMounts = Object.keys(nuxt.options.nitro.storage || {});
616
632
  addServerTemplate({
@@ -619,7 +635,11 @@ function addStorageInstrumentation(nuxt) {
619
635
  return `export const userStorageMounts = ${JSON.stringify(userStorageMounts)};`;
620
636
  }
621
637
  });
622
- addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/storage.server"));
638
+ if (isLegacyNitro) {
639
+ addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/storage-legacy.server"));
640
+ } else {
641
+ addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/storage.server"));
642
+ }
623
643
  }
624
644
 
625
645
  const module = defineNuxtModule({
@@ -631,7 +651,7 @@ const module = defineNuxtModule({
631
651
  }
632
652
  },
633
653
  defaults: {},
634
- setup(moduleOptionsParam, nuxt) {
654
+ async setup(moduleOptionsParam, nuxt) {
635
655
  if (moduleOptionsParam?.enabled === false) {
636
656
  return;
637
657
  }
@@ -671,17 +691,26 @@ const module = defineNuxtModule({
671
691
  });
672
692
  }
673
693
  const serverConfigFile = findDefaultSdkInitFile("server", nuxt);
694
+ const isNitroV3 = await getNitroMajorVersion() >= 3;
674
695
  if (serverConfigFile) {
696
+ if (isNitroV3) {
697
+ addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/handler.server"));
698
+ } else {
699
+ addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/handler-legacy.server"));
700
+ }
675
701
  addServerPlugin(moduleDirResolver.resolve("./runtime/plugins/sentry.server"));
676
702
  addPlugin({
677
703
  src: moduleDirResolver.resolve("./runtime/plugins/route-detector.server"),
678
704
  mode: "server"
679
705
  });
706
+ addMiddlewareImports();
707
+ addStorageInstrumentation(nuxt, !isNitroV3);
708
+ addDatabaseInstrumentation(nuxt.options.nitro, !isNitroV3, moduleOptions);
680
709
  }
681
710
  if (clientConfigFile || serverConfigFile) {
682
711
  setupSourceMaps(moduleOptions, nuxt, addVitePlugin);
683
712
  }
684
- addOTelCommonJSImportAlias(nuxt);
713
+ addOTelCommonJSImportAlias(nuxt, isNitroV3);
685
714
  const pagesDataTemplate = addTemplate({
686
715
  filename: "sentry--nuxt-pages-data.mjs",
687
716
  // Initial empty array (later filled in pages:extend hook)
@@ -696,11 +725,6 @@ const module = defineNuxtModule({
696
725
  return `export default ${JSON.stringify(pagesSubset, null, 2)};`;
697
726
  };
698
727
  });
699
- if (serverConfigFile) {
700
- addMiddlewareImports();
701
- addStorageInstrumentation(nuxt);
702
- addDatabaseInstrumentation(nuxt.options.nitro, moduleOptions);
703
- }
704
728
  nuxt.hook("prepare:types", (options) => {
705
729
  const tsConfig = options.tsConfig;
706
730
  if (!tsConfig.include) {
@@ -719,7 +743,7 @@ const module = defineNuxtModule({
719
743
  if (nuxt.options?._prepare) {
720
744
  return;
721
745
  }
722
- if (serverConfigFile) {
746
+ if (serverConfigFile && !isNitroV3) {
723
747
  addMiddlewareInstrumentation(nitro);
724
748
  }
725
749
  if (serverConfigFile?.includes(".server.config")) {
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Nitro plugin that instruments database calls for Nuxt v3/v4 (Nitro v2)
3
+ */
4
+ declare const _default: () => void;
5
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { useDatabase } from "nitropack/runtime";
2
+ import { databaseConfig } from "#sentry/database-config.mjs";
3
+ import { createDatabasePlugin } from "../utils/instrumentDatabase.js";
4
+ export default () => {
5
+ createDatabasePlugin(useDatabase, databaseConfig);
6
+ };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Creates a Nitro plugin that instruments the database calls.
2
+ * Nitro plugin that instruments database calls for Nuxt v5+ (Nitro v3+)
3
3
  */
4
4
  declare const _default: () => void;
5
5
  export default _default;
@@ -1,150 +1,6 @@
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 { useDatabase } from "nitropack/runtime";
1
+ import { useDatabase } from "nitro/database";
12
2
  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";
3
+ import { createDatabasePlugin } from "../utils/instrumentDatabase.js";
16
4
  export default () => {
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
- }
5
+ createDatabasePlugin(useDatabase, databaseConfig);
34
6
  };
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
- }
@@ -0,0 +1,2 @@
1
+ declare const _default: (nitroApp: import("nitropack").NitroApp) => void;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import { patchEventHandler } from "../utils/patchEventHandler.js";
2
+ export default (nitroApp) => {
3
+ nitroApp.h3App.handler = patchEventHandler(nitroApp.h3App.handler);
4
+ };
@@ -0,0 +1,6 @@
1
+ import type { NitroApp } from 'nitro/types';
2
+ /**
3
+ * This plugin patches the h3 event handler for Nuxt v5+ (Nitro v3+).
4
+ */
5
+ declare const _default: (nitroApp: NitroApp) => void;
6
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { patchEventHandler } from "../utils/patchEventHandler.js";
2
+ export default (nitroApp) => {
3
+ if (nitroApp?.h3?.handler) {
4
+ nitroApp.h3.handler = patchEventHandler(nitroApp.h3.handler);
5
+ }
6
+ };
@@ -1,21 +1,16 @@
1
- import {
2
- debug,
3
- flushIfServerless,
4
- getDefaultIsolationScope,
5
- getIsolationScope,
6
- withIsolationScope
7
- } from "@sentry/core";
1
+ import { debug } from "@sentry/core";
8
2
  import { sentryCaptureErrorHook } from "../hooks/captureErrorHook.js";
9
3
  import { updateRouteBeforeResponse } from "../hooks/updateRouteBeforeResponse.js";
10
4
  import { addSentryTracingMetaTags } from "../utils.js";
11
5
  export default (nitroApp) => {
12
- nitroApp.h3App.handler = patchEventHandler(nitroApp.h3App.handler);
13
6
  nitroApp.hooks.hook("beforeResponse", updateRouteBeforeResponse);
14
7
  nitroApp.hooks.hook("error", sentryCaptureErrorHook);
15
8
  nitroApp.hooks.hook("render:html", (html, { event }) => {
16
- const headers = event.node.res?.getHeaders() || {};
17
- const isPreRenderedPage = Object.keys(headers).includes("x-nitro-prerender");
18
- const isSWRCachedPage = event?.context?.cache?.options.swr;
9
+ const nodeResHeadersH3v1 = event.node?.res?.getHeaders() || {};
10
+ const isPreRenderedPage = Object.keys(nodeResHeadersH3v1).includes("x-nitro-prerender") || // fix × typescript-eslint(no-unsafe-member-access): Unsafe member access .res on an `any` value.
11
+ // oxlint-disable-next-line typescript/no-explicit-any,typescript-oxlint/no-unsafe-member-access
12
+ !!event.res?.headers?.has?.("x-nitro-prerender");
13
+ const isSWRCachedPage = event?.context?.cache?.options?.swr;
19
14
  if (!isPreRenderedPage && !isSWRCachedPage) {
20
15
  addSentryTracingMetaTags(html.head);
21
16
  } else {
@@ -26,21 +21,3 @@ export default (nitroApp) => {
26
21
  }
27
22
  });
28
23
  };
29
- function patchEventHandler(handler) {
30
- return new Proxy(handler, {
31
- async apply(handlerTarget, handlerThisArg, handlerArgs) {
32
- const isolationScope = getIsolationScope();
33
- const newIsolationScope = isolationScope === getDefaultIsolationScope() ? isolationScope.clone() : isolationScope;
34
- debug.log(
35
- `Patched h3 event handler. ${isolationScope === newIsolationScope ? "Using existing" : "Created new"} isolation scope.`
36
- );
37
- return withIsolationScope(newIsolationScope, async () => {
38
- try {
39
- return await handlerTarget.apply(handlerThisArg, handlerArgs);
40
- } finally {
41
- await flushIfServerless();
42
- }
43
- });
44
- }
45
- });
46
- }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Nitro plugin that instruments storage driver calls for Nuxt v3/v4 (Nitro v2)
3
+ */
4
+ declare const _default: (_nitroApp: import("nitropack").NitroApp) => Promise<void>;
5
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { useStorage } from "nitropack/runtime";
2
+ import { userStorageMounts } from "#sentry/storage-config.mjs";
3
+ import { createStoragePlugin } from "../utils/instrumentStorage.js";
4
+ export default async (_nitroApp) => {
5
+ await createStoragePlugin(useStorage, userStorageMounts);
6
+ };
@@ -1,5 +1,7 @@
1
1
  /**
2
- * Creates a Nitro plugin that instruments the storage driver.
2
+ * Nitro plugin that instruments storage driver calls for Nuxt v5+ (Nitro v3+)
3
3
  */
4
- declare const _default: (_nitroApp: import("nitropack").NitroApp) => Promise<void>;
4
+ declare const _default: (_nitroApp: import("nitro/types").NitroApp & {
5
+ hooks: NonNullable<import("nitro/types").NitroApp["hooks"]>;
6
+ }) => Promise<void>;
5
7
  export default _default;