@sentry/nuxt 11.0.0-alpha.2 → 11.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +5 -0
  2. package/build/cjs/common/devMode.js +12 -0
  3. package/build/cjs/common/devMode.js.map +1 -0
  4. package/build/cjs/module.js +9 -5
  5. package/build/cjs/module.js.map +1 -1
  6. package/build/cjs/server/sdk.js +2 -2
  7. package/build/cjs/server/sdk.js.map +1 -1
  8. package/build/cjs/vite/addServerConfig.js +64 -13
  9. package/build/cjs/vite/addServerConfig.js.map +1 -1
  10. package/build/cjs/vite/orchestrion.js +3 -0
  11. package/build/cjs/vite/orchestrion.js.map +1 -1
  12. package/build/cjs/vite/utils.js +26 -11
  13. package/build/cjs/vite/utils.js.map +1 -1
  14. package/build/esm/common/devMode.js +9 -0
  15. package/build/esm/common/devMode.js.map +1 -0
  16. package/build/esm/module.js +11 -7
  17. package/build/esm/module.js.map +1 -1
  18. package/build/esm/package.json +1 -1
  19. package/build/esm/server/sdk.js +5 -3
  20. package/build/esm/server/sdk.js.map +1 -1
  21. package/build/esm/vite/addServerConfig.js +62 -14
  22. package/build/esm/vite/addServerConfig.js.map +1 -1
  23. package/build/esm/vite/orchestrion.js +3 -0
  24. package/build/esm/vite/orchestrion.js.map +1 -1
  25. package/build/esm/vite/utils.js +24 -12
  26. package/build/esm/vite/utils.js.map +1 -1
  27. package/build/module/common/devMode.d.ts +4 -0
  28. package/build/module/module.json +1 -1
  29. package/build/module/module.mjs +94 -28
  30. package/build/module/runtime/hooks/captureErrorHook.js +2 -1
  31. package/build/module/runtime/hooks/wrapMiddlewareHandler.js +2 -1
  32. package/build/module/runtime/utils/instrumentDatabase.js +26 -6
  33. package/build/module/runtime/utils/instrumentStorage.js +10 -4
  34. package/build/module/runtime/utils/patchEventHandler.js +2 -1
  35. package/build/module/vite/addServerConfig.d.ts +22 -0
  36. package/build/module/vite/utils.d.ts +14 -1
  37. package/build/types/common/devMode.d.ts +5 -0
  38. package/build/types/common/devMode.d.ts.map +1 -0
  39. package/build/types/index.types.d.ts +0 -1
  40. package/build/types/index.types.d.ts.map +1 -1
  41. package/build/types/module.d.ts.map +1 -1
  42. package/build/types/runtime/hooks/captureErrorHook.d.ts.map +1 -1
  43. package/build/types/runtime/utils/instrumentDatabase.d.ts.map +1 -1
  44. package/build/types/runtime/utils/instrumentStorage.d.ts.map +1 -1
  45. package/build/types/runtime/utils/patchEventHandler.d.ts.map +1 -1
  46. package/build/types/server/sdk.d.ts.map +1 -1
  47. package/build/types/vite/addServerConfig.d.ts +22 -0
  48. package/build/types/vite/addServerConfig.d.ts.map +1 -1
  49. package/build/types/vite/orchestrion.d.ts.map +1 -1
  50. package/build/types/vite/utils.d.ts +14 -1
  51. package/build/types/vite/utils.d.ts.map +1 -1
  52. package/package.json +9 -8
@@ -1,6 +1,7 @@
1
1
  import { consoleSandbox } from '@sentry/core';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
+ import { fileURLToPath } from 'node:url';
4
5
  import { resolvePath } from '@nuxt/kit';
5
6
 
6
7
  async function getNitroMajorVersion() {
@@ -17,17 +18,7 @@ async function getNitroMajorVersion() {
17
18
  }
18
19
  async function findDefaultSdkInitFile(type, nuxt, options) {
19
20
  const possibleFileExtensions = ["ts", "js", "mjs", "cjs", "mts", "cts"];
20
- const relativePaths = [];
21
- if (type === "server") {
22
- for (const ext of possibleFileExtensions) {
23
- relativePaths.push(`sentry.${type}.config.${ext}`);
24
- relativePaths.push(path.join("public", `instrument.${type}.${ext}`));
25
- }
26
- } else {
27
- for (const ext of possibleFileExtensions) {
28
- relativePaths.push(`sentry.${type}.config.${ext}`);
29
- }
30
- }
21
+ const relativePaths = possibleFileExtensions.map((ext) => `sentry.${type}.config.${ext}`);
31
22
  const layers = [...nuxt?.options._layers ?? []].reverse();
32
23
  for (const layer of layers) {
33
24
  for (const relativePath of relativePaths) {
@@ -46,6 +37,10 @@ async function findDefaultSdkInitFile(type, nuxt, options) {
46
37
  }
47
38
  return void 0;
48
39
  }
40
+ const SERVER_CONFIG_FILENAME = "sentry.server.config";
41
+ function toImportSpecifier(fromDir, filePath) {
42
+ return `./${path.relative(fromDir, filePath).split(/[\\/]/).join("/")}`;
43
+ }
49
44
  function getFilenameFromNodeStartCommand(nodeCommand) {
50
45
  const regex = /[^/\\]+\.[^/\\]+$/;
51
46
  const match = nodeCommand.match(regex);
@@ -117,6 +112,23 @@ export { ${currFunctionName}_sentryWrapped as ${currFunctionName} };
117
112
  )
118
113
  );
119
114
  }
115
+ function toResolvablePath(source) {
116
+ if (!source.startsWith("file://")) {
117
+ return { path: source, wasFileUrl: false };
118
+ }
119
+ if (source === "file://" || source === "file:///") {
120
+ return void 0;
121
+ }
122
+ try {
123
+ const filePath = fileURLToPath(source);
124
+ if (!filePath || filePath === "/" || filePath === "\\") {
125
+ return void 0;
126
+ }
127
+ return { path: filePath, wasFileUrl: true };
128
+ } catch {
129
+ return void 0;
130
+ }
131
+ }
120
132
  function addOTelCommonJSImportAlias(nuxt, isNitroV3 = false) {
121
133
  if (!nuxt.options.dev || isNitroV3) {
122
134
  return;
@@ -129,5 +141,5 @@ function addOTelCommonJSImportAlias(nuxt, isNitroV3 = false) {
129
141
  }
130
142
  }
131
143
 
132
- export { QUERY_END_INDICATOR, SENTRY_REEXPORTED_FUNCTIONS, SENTRY_WRAPPED_ENTRY, SENTRY_WRAPPED_FUNCTIONS, addOTelCommonJSImportAlias, constructFunctionReExport, constructWrappedFunctionExportQuery, extractFunctionReexportQueryParameters, findDefaultSdkInitFile, getFilenameFromNodeStartCommand, getNitroMajorVersion, removeSentryQueryFromPath };
144
+ export { QUERY_END_INDICATOR, SENTRY_REEXPORTED_FUNCTIONS, SENTRY_WRAPPED_ENTRY, SENTRY_WRAPPED_FUNCTIONS, SERVER_CONFIG_FILENAME, addOTelCommonJSImportAlias, constructFunctionReExport, constructWrappedFunctionExportQuery, extractFunctionReexportQueryParameters, findDefaultSdkInitFile, getFilenameFromNodeStartCommand, getNitroMajorVersion, removeSentryQueryFromPath, toImportSpecifier, toResolvablePath };
133
145
  //# 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';\nimport type { SentryNuxtModuleOptions } from '../common/types';\nimport { resolvePath } from '@nuxt/kit';\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 async function findDefaultSdkInitFile(\n type: 'server' | 'client',\n nuxt?: Nuxt,\n options?: SentryNuxtModuleOptions,\n): Promise<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 rootDir = options?.configDir ? await resolvePath(options.configDir, { type: 'dir' }) : process.cwd();\n for (const relativePath of relativePaths) {\n const fullPath = path.resolve(rootDir, 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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"}
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';\nimport { fileURLToPath } from 'node:url';\nimport type { SentryNuxtModuleOptions } from '../common/types';\nimport { resolvePath } from '@nuxt/kit';\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 */\nexport async function findDefaultSdkInitFile(\n type: 'server' | 'client',\n nuxt?: Nuxt,\n options?: SentryNuxtModuleOptions,\n): Promise<string | undefined> {\n const possibleFileExtensions = ['ts', 'js', 'mjs', 'cjs', 'mts', 'cts'];\n const relativePaths = possibleFileExtensions.map(ext => `sentry.${type}.config.${ext}`);\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 rootDir = options?.configDir ? await resolvePath(options.configDir, { type: 'dir' }) : process.cwd();\n for (const relativePath of relativePaths) {\n const fullPath = path.resolve(rootDir, relativePath);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n return undefined;\n}\n\nexport const SERVER_CONFIG_FILENAME = 'sentry.server.config';\n\n/** Builds the value for `node --import`. Node reads it as a URL, so it needs forward slashes on Windows too. */\nexport function toImportSpecifier(fromDir: string, filePath: string): string {\n return `./${path.relative(fromDir, filePath).split(/[\\\\/]/).join('/')}`;\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 * `load()` emits `file://` specifiers because Node's ESM loader rejects bare Windows\n * paths (`ERR_UNSUPPORTED_ESM_URL_SCHEME`), but Rollup's resolver only understands\n * filesystem paths. Returns `undefined` for a malformed `file://` URL.\n *\n * Only exported for testing.\n */\nexport function toResolvablePath(source: string): { path: string; wasFileUrl: boolean } | undefined {\n if (!source.startsWith('file://')) {\n return { path: source, wasFileUrl: false };\n }\n if (source === 'file://' || source === 'file:///') {\n return undefined;\n }\n try {\n const filePath = fileURLToPath(source);\n if (!filePath || filePath === '/' || filePath === '\\\\') {\n return undefined;\n }\n return { path: filePath, wasFileUrl: true };\n } catch {\n return undefined;\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":";;;;;;AAYA,eAAsB,oBAAA,GAAwC;AAC5D,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,cAAA,EAAe,GAAI,MAAM,OAAO,WAAW,CAAA;AACnD,IAAA,MAAM,IAAA,GAAO,MAAM,cAAA,CAAe,OAAO,CAAA;AACzC,IAAA,IAAI,MAAM,OAAA,EAAS;AACjB,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,GAAA,EAAK,EAAE,CAAA;AAC5D,MAAA,OAAO,KAAA,CAAM,KAAK,CAAA,GAAI,CAAA,GAAI,KAAA;AAAA,IAC5B;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,CAAA;AACT;AAKA,eAAsB,sBAAA,CACpB,IAAA,EACA,IAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,yBAAyB,CAAC,IAAA,EAAM,MAAM,KAAA,EAAO,KAAA,EAAO,OAAO,KAAK,CAAA;AACtE,EAAA,MAAM,aAAA,GAAgB,uBAAuB,GAAA,CAAI,CAAA,GAAA,KAAO,UAAU,IAAI,CAAA,QAAA,EAAW,GAAG,CAAA,CAAE,CAAA;AAGtF,EAAA,MAAM,MAAA,GAAS,CAAC,GAAI,IAAA,EAAM,QAAQ,OAAA,IAAW,EAAG,CAAA,CAAE,OAAA,EAAQ;AAE1D,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,KAAA,MAAW,gBAAgB,aAAA,EAAe;AACxC,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,KAAK,YAAY,CAAA;AACrD,MAAA,IAAI,EAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC3B,QAAA,OAAO,QAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,OAAA,GAAU,OAAA,EAAS,SAAA,GAAY,MAAM,WAAA,CAAY,OAAA,CAAQ,SAAA,EAAW,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA,GAAI,QAAQ,GAAA,EAAI;AACzG,EAAA,KAAA,MAAW,gBAAgB,aAAA,EAAe;AACxC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,YAAY,CAAA;AACnD,IAAA,IAAI,EAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC3B,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,MAAM,sBAAA,GAAyB;AAG/B,SAAS,iBAAA,CAAkB,SAAiB,QAAA,EAA0B;AAC3E,EAAA,OAAO,CAAA,EAAA,EAAK,IAAA,CAAK,QAAA,CAAS,OAAA,EAAS,QAAQ,CAAA,CAAE,KAAA,CAAM,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AACvE;AAKO,SAAS,gCAAgC,WAAA,EAAoC;AAClF,EAAA,MAAM,KAAA,GAAQ,mBAAA;AACd,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,KAAK,CAAA;AACrC,EAAA,OAAO,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA;AAC5B;AAEO,MAAM,oBAAA,GAAuB;AAC7B,MAAM,wBAAA,GAA2B;AACjC,MAAM,2BAAA,GAA8B;AACpC,MAAM,mBAAA,GAAsB;AAQ5B,SAAS,0BAA0B,GAAA,EAAqB;AAE7D,EAAA,MAAM,QAAQ,IAAI,MAAA,CAAO,KAAK,oBAAoB,CAAA,KAAA,EAAQ,mBAAmB,CAAA,CAAE,CAAA;AAC/E,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAC9B;AAQO,SAAS,uCAAuC,KAAA,EAAuD;AAG5G,EAAA,MAAM,YAAY,IAAI,MAAA;AAAA,IACpB,CAAA,EAAA,EAAK,wBAAwB,CAAA,QAAA,EAAW,mBAAmB,MAAM,2BAA2B,CAAA,CAAA;AAAA,GAC9F;AAEA,EAAA,MAAM,gBAAgB,IAAI,MAAA,CAAO,KAAK,2BAA2B,CAAA,QAAA,EAAW,mBAAmB,CAAA,CAAA,CAAG,CAAA;AAElG,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,SAAS,CAAA;AACvC,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,KAAA,CAAM,aAAa,CAAA;AAE/C,EAAA,MAAM,IAAA,GACJ,YAAY,CAAC,CAAA,EACT,MAAM,GAAG,CAAA,CACV,OAAO,CAAA,KAAA,KAAS,KAAA,KAAU,EAAE,CAAA,CAE5B,GAAA,CAAI,CAAC,GAAA,KAAgB,GAAA,CAAI,QAAQ,qBAAA,EAAuB,MAAM,CAAC,CAAA,IAAK,EAAC;AAE1E,EAAA,MAAM,QAAA,GACJ,gBAAgB,CAAC,CAAA,EACb,MAAM,GAAG,CAAA,CACV,MAAA,CAAO,CAAA,KAAA,KAAS,KAAA,KAAU,EAAA,IAAM,UAAU,SAAS,CAAA,CAEnD,GAAA,CAAI,CAAC,GAAA,KAAgB,GAAA,CAAI,QAAQ,qBAAA,EAAuB,MAAM,CAAC,CAAA,IAAK,EAAC;AAE1E,EAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAC1B;AAOO,SAAS,mCAAA,CACd,gBAAA,EACA,0BAAA,EACA,KAAA,EACQ;AACR,EAAA,MAAM,iBAAA,GAA4D;AAAA,IAChE,MAAM,EAAC;AAAA,IACP,UAAU;AAAC,GACb;AAIA,EAAA,MAAA,CAAO,MAAA,CAAO,gBAAA,IAAoB,EAAE,CAAA,CAAE,OAAA;AAAA,IAAQ,CAAA,SAAA,KAC5C,SAAA,CAAU,OAAA,CAAQ,CAAA,EAAA,KAAM;AACtB,MAAA,IAAI,0BAAA,CAA2B,QAAA,CAAS,EAAE,CAAA,EAAG;AAC3C,QAAA,iBAAA,CAAkB,IAAA,CAAK,KAAK,EAAE,CAAA;AAAA,MAChC,CAAA,MAAO;AACL,QAAA,iBAAA,CAAkB,QAAA,CAAS,KAAK,EAAE,CAAA;AAAA,MACpC;AAAA,IACF,CAAC;AAAA,GACH;AAEA,EAAA,IAAI,KAAA,IAAS,iBAAA,CAAkB,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAChD,IAAA,cAAA;AAAA,MAAe;AAAA;AAAA,QAEb,OAAA,CAAQ,IAAA;AAAA,UACN;AAAA;AACF;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,iBAAA,CAAkB,IAAA,CAAK,MAAA,GACrC,CAAA,EAAG,wBAAwB,CAAA,EAAG,iBAAA,CAAkB,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GAC9D,EAAA;AACJ,EAAA,MAAM,aAAA,GAAgB,iBAAA,CAAkB,QAAA,CAAS,MAAA,GAC7C,CAAA,EAAG,2BAA2B,CAAA,EAAG,iBAAA,CAAkB,QAAA,CAAS,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GACrE,EAAA;AAEJ,EAAA,OAAO,CAAC,SAAA,EAAW,aAAa,CAAA,CAAE,KAAK,EAAE,CAAA;AAC3C;AAKO,SAAS,yBAAA,CAA0B,eAAuB,OAAA,EAAyB;AACxF,EAAA,MAAM,EAAE,IAAA,EAAM,aAAA,EAAe,UAAU,iBAAA,EAAkB,GAAI,uCAAuC,aAAa,CAAA;AAEjH,EAAA,OAAO,aAAA,CACJ,MAAA;AAAA,IACC,CAAC,aAAA,EAAe,gBAAA,KACd,aAAA,CAAc,MAAA;AAAA,MACZ,kBAAkB,gBAAgB,CAAA;AAAA,2BAAA,EACF,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA;AAAA,aAAA,EACrC,gBAAgB,CAAA;AAAA;AAAA,SAAA,EAEpB,gBAAgB,qBAAqB,gBAAgB,CAAA;AAAA;AAAA,KACrE;AAAA,IACF;AAAA,GACF,CACC,MAAA;AAAA,IACC,iBAAA,CAAkB,MAAA;AAAA,MAChB,CAAC,aAAA,EAAe,gBAAA,KACd,aAAA,CAAc,MAAA,CAAO,CAAA,SAAA,EAAY,gBAAgB,CAAA,QAAA,EAAW,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,MACxF;AAAA;AACF,GACF;AACJ;AASO,SAAS,iBAAiB,MAAA,EAAmE;AAClG,EAAA,IAAI,CAAC,MAAA,CAAO,UAAA,CAAW,SAAS,CAAA,EAAG;AACjC,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAA,EAAY,KAAA,EAAM;AAAA,EAC3C;AACA,EAAA,IAAI,MAAA,KAAW,SAAA,IAAa,MAAA,KAAW,UAAA,EAAY;AACjD,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,cAAc,MAAM,CAAA;AACrC,IAAA,IAAI,CAAC,QAAA,IAAY,QAAA,KAAa,GAAA,IAAO,aAAa,IAAA,EAAM;AACtD,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,UAAA,EAAY,IAAA,EAAK;AAAA,EAC5C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAYO,SAAS,0BAAA,CAA2B,IAAA,EAAY,SAAA,GAAY,KAAA,EAAa;AAC9E,EAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,SAAA,EAAW;AAClC,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO;AACvB,IAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,EAAC;AAAA,EACxB;AAEA,EAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,0BAA0B,CAAA,EAAG;AACnD,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,0BAA0B,CAAA,GAAI,6CAAA;AAAA,EACnD;AACF;;;;"}
@@ -0,0 +1,4 @@
1
+ /** Global flag set by the generated `<buildDir>/dev/sentry.server.config.mjs`. */
2
+ export declare const NUXT_DEV_MODE_FLAG = "__SENTRY_NUXT_DEV_MODE__";
3
+ /** Whether the SDK was preloaded by the generated `nuxt dev` server config file. */
4
+ export declare function isNuxtDevRuntime(): boolean;
@@ -4,5 +4,5 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.7.0"
6
6
  },
7
- "version": "11.0.0-alpha.2"
7
+ "version": "11.0.0-beta.1"
8
8
  }
@@ -1,7 +1,9 @@
1
- import { resolvePath, createResolver, useNuxt, addServerPlugin, addServerImports, defineNuxtModule, addPluginTemplate, addPlugin, addVitePlugin, addTemplate } from '@nuxt/kit';
1
+ import { resolvePath, createResolver, addTemplate, useNuxt, addServerPlugin, addServerImports, defineNuxtModule, addPluginTemplate, addPlugin, addVitePlugin } from '@nuxt/kit';
2
2
  import { consoleSandbox, debug, warnOnRemovedBuildOptions } from '@sentry/core';
3
3
  import * as path from 'path';
4
4
  import { existsSync } from 'node:fs';
5
+ import { basename } from 'node:path';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
5
7
  import * as fs from 'fs';
6
8
  import { INSTRUMENTED_MODULE_NAMES } from '@sentry/server-utils/orchestrion/config';
7
9
  import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/rollup';
@@ -9,6 +11,8 @@ import { sentryRollupPlugin } from '@sentry/bundler-plugins/rollup';
9
11
  import { sentryVitePlugin } from '@sentry/bundler-plugins/vite';
10
12
  import { createSentryBuildPluginManager } from '@sentry/bundler-plugins/core';
11
13
 
14
+ const NUXT_DEV_MODE_FLAG = "__SENTRY_NUXT_DEV_MODE__";
15
+
12
16
  async function getNitroMajorVersion() {
13
17
  try {
14
18
  const { getPackageInfo } = await import('local-pkg');
@@ -23,17 +27,7 @@ async function getNitroMajorVersion() {
23
27
  }
24
28
  async function findDefaultSdkInitFile(type, nuxt, options) {
25
29
  const possibleFileExtensions = ["ts", "js", "mjs", "cjs", "mts", "cts"];
26
- const relativePaths = [];
27
- if (type === "server") {
28
- for (const ext of possibleFileExtensions) {
29
- relativePaths.push(`sentry.${type}.config.${ext}`);
30
- relativePaths.push(path.join("public", `instrument.${type}.${ext}`));
31
- }
32
- } else {
33
- for (const ext of possibleFileExtensions) {
34
- relativePaths.push(`sentry.${type}.config.${ext}`);
35
- }
36
- }
30
+ const relativePaths = possibleFileExtensions.map((ext) => `sentry.${type}.config.${ext}`);
37
31
  const layers = [...nuxt?.options._layers ?? []].reverse();
38
32
  for (const layer of layers) {
39
33
  for (const relativePath of relativePaths) {
@@ -52,6 +46,10 @@ async function findDefaultSdkInitFile(type, nuxt, options) {
52
46
  }
53
47
  return void 0;
54
48
  }
49
+ const SERVER_CONFIG_FILENAME = "sentry.server.config";
50
+ function toImportSpecifier(fromDir, filePath) {
51
+ return `./${path.relative(fromDir, filePath).split(/[\\/]/).join("/")}`;
52
+ }
55
53
  function getFilenameFromNodeStartCommand(nodeCommand) {
56
54
  const regex = /[^/\\]+\.[^/\\]+$/;
57
55
  const match = nodeCommand.match(regex);
@@ -123,6 +121,23 @@ export { ${currFunctionName}_sentryWrapped as ${currFunctionName} };
123
121
  )
124
122
  );
125
123
  }
124
+ function toResolvablePath(source) {
125
+ if (!source.startsWith("file://")) {
126
+ return { path: source, wasFileUrl: false };
127
+ }
128
+ if (source === "file://" || source === "file:///") {
129
+ return void 0;
130
+ }
131
+ try {
132
+ const filePath = fileURLToPath(source);
133
+ if (!filePath || filePath === "/" || filePath === "\\") {
134
+ return void 0;
135
+ }
136
+ return { path: filePath, wasFileUrl: true };
137
+ } catch {
138
+ return void 0;
139
+ }
140
+ }
126
141
  function addOTelCommonJSImportAlias(nuxt, isNitroV3 = false) {
127
142
  if (!nuxt.options.dev || isNitroV3) {
128
143
  return;
@@ -135,7 +150,39 @@ function addOTelCommonJSImportAlias(nuxt, isNitroV3 = false) {
135
150
  }
136
151
  }
137
152
 
138
- const SERVER_CONFIG_FILENAME = "sentry.server.config";
153
+ const DEV_SERVER_CONFIG_PATH = `dev/${SERVER_CONFIG_FILENAME}.mjs`;
154
+ function addDevServerConfigFile(nuxt, serverConfigFile) {
155
+ const configPath = createResolver(nuxt.options.rootDir).resolve(serverConfigFile);
156
+ const importSpecifier = toImportSpecifier(
157
+ nuxt.options.rootDir,
158
+ path.join(nuxt.options.buildDir, DEV_SERVER_CONFIG_PATH)
159
+ );
160
+ const failureMessage = `[Sentry] Could not load \`${path.basename(configPath)}\`, so Sentry is disabled during development. Node loads this file without a build step, so it supports neither path aliases (like #import) nor non-erasable TypeScript syntax (like enums).`;
161
+ addTemplate({
162
+ filename: DEV_SERVER_CONFIG_PATH,
163
+ write: true,
164
+ getContents: () => [
165
+ "// Generated by @sentry/nuxt. Preload it to enable Sentry during development:",
166
+ `// NODE_OPTIONS='--import ${importSpecifier}' nuxt dev`,
167
+ // A static import would hoist above this assignment, and would make a broken config crash the dev server.
168
+ `globalThis.${NUXT_DEV_MODE_FLAG} = true;`,
169
+ "try {",
170
+ ` await import(${JSON.stringify(pathToFileURL(configPath).href)});`,
171
+ "} catch (error) {",
172
+ ` console.warn(${JSON.stringify(failureMessage)}, error);`,
173
+ "}",
174
+ ""
175
+ ].join("\n")
176
+ });
177
+ }
178
+ const CONFIG_EXTENSIONS = [".ts", ".js", ".mjs", ".cjs", ".mts", ".cts"];
179
+ function isServerConfigFile(sourcePath, resolvedPath) {
180
+ if (sourcePath === resolvedPath) {
181
+ return true;
182
+ }
183
+ const name = basename(sourcePath);
184
+ return name === SERVER_CONFIG_FILENAME || CONFIG_EXTENSIONS.some((ext) => name === `${SERVER_CONFIG_FILENAME}${ext}`);
185
+ }
139
186
  function addServerConfigToBuild(moduleOptions, nitro, serverConfigFile) {
140
187
  nitro.hooks.hook("rollup:before", (nitro2, rollupConfig) => {
141
188
  if (rollupConfig?.plugins === null || rollupConfig?.plugins === void 0) {
@@ -186,7 +233,7 @@ function addDynamicImportEntryFileWrapper(nitro, serverConfigFile, moduleOptions
186
233
  }
187
234
  nitro.options.rollupConfig.plugins.push(
188
235
  wrapEntryWithDynamicImport({
189
- resolvedSentryConfigPath: createResolver(nitro.options.rootDir).resolve(`/${serverConfigFile}`),
236
+ resolvedSentryConfigPath: createResolver(nitro.options.rootDir).resolve(serverConfigFile),
190
237
  experimental_entrypointWrappedFunctions: moduleOptions.experimental_entrypointWrappedFunctions
191
238
  })
192
239
  );
@@ -196,7 +243,7 @@ function injectServerConfigPlugin(nitro, serverConfigFile, isDebug) {
196
243
  return {
197
244
  name: "rollup-plugin-inject-sentry-server-config",
198
245
  buildStart() {
199
- const configPath = createResolver(nitro.options.rootDir).resolve(`/${serverConfigFile}`);
246
+ const configPath = createResolver(nitro.options.rootDir).resolve(serverConfigFile);
200
247
  if (!existsSync(configPath)) {
201
248
  if (isDebug) {
202
249
  debug.log(`[Sentry] Sentry server config file not found: ${configPath}`);
@@ -212,7 +259,7 @@ function injectServerConfigPlugin(nitro, serverConfigFile, isDebug) {
212
259
  resolveId(source) {
213
260
  if (source.startsWith(filePrefix)) {
214
261
  const originalFilePath = source.replace(filePrefix, "");
215
- const configPath = createResolver(nitro.options.rootDir).resolve(`/${originalFilePath}`);
262
+ const configPath = createResolver(nitro.options.rootDir).resolve(originalFilePath);
216
263
  return { id: configPath };
217
264
  }
218
265
  return null;
@@ -228,11 +275,16 @@ function wrapEntryWithDynamicImport({
228
275
  return {
229
276
  name: "sentry-wrap-entry-with-dynamic-import",
230
277
  async resolveId(source, importer, options) {
231
- if (source.includes(`/${SERVER_CONFIG_FILENAME}`)) {
232
- return { id: source, moduleSideEffects: true };
278
+ const resolvable = toResolvablePath(source);
279
+ if (!resolvable) {
280
+ return null;
281
+ }
282
+ const { path: normalizedSource, wasFileUrl } = resolvable;
283
+ if (isServerConfigFile(normalizedSource, resolvedSentryConfigPath)) {
284
+ return { id: normalizedSource, moduleSideEffects: true };
233
285
  }
234
- if (options.isEntry && source.includes(".mjs") && !source.includes(`.mjs${SENTRY_WRAPPED_ENTRY}`)) {
235
- const resolution = await this.resolve(source, importer, options);
286
+ if (options.isEntry && normalizedSource.includes(".mjs") && !normalizedSource.includes(`.mjs${SENTRY_WRAPPED_ENTRY}`)) {
287
+ const resolution = await this.resolve(normalizedSource, importer, options);
236
288
  if (!resolution || resolution?.external) return resolution;
237
289
  const moduleInfo = await this.load(resolution);
238
290
  moduleInfo.moduleSideEffects = true;
@@ -244,16 +296,23 @@ function wrapEntryWithDynamicImport({
244
296
  )
245
297
  ).concat(QUERY_END_INDICATOR)}`;
246
298
  }
299
+ if (wasFileUrl) {
300
+ const resolved = await this.resolve(normalizedSource, importer, { ...options, isEntry: false });
301
+ if (resolved) return resolved;
302
+ return { id: normalizedSource };
303
+ }
247
304
  return null;
248
305
  },
249
306
  load(id) {
250
307
  if (id.includes(`.mjs${SENTRY_WRAPPED_ENTRY}`)) {
251
308
  const entryId = removeSentryQueryFromPath(id).slice(resolutionIdPrefix.length);
252
- const reExportedFunctions = id.includes(SENTRY_WRAPPED_FUNCTIONS) || id.includes(SENTRY_REEXPORTED_FUNCTIONS) ? constructFunctionReExport(id, entryId) : "";
309
+ const entryIdUrl = pathToFileURL(entryId).href;
310
+ const configUrl = pathToFileURL(resolvedSentryConfigPath).href;
311
+ const reExportedFunctions = id.includes(SENTRY_WRAPPED_FUNCTIONS) || id.includes(SENTRY_REEXPORTED_FUNCTIONS) ? constructFunctionReExport(id, entryIdUrl) : "";
253
312
  return (
254
313
  // Regular `import` of the Sentry config
255
- `import ${JSON.stringify(resolvedSentryConfigPath)};
256
- import(${JSON.stringify(entryId)});
314
+ `import ${JSON.stringify(configUrl)};
315
+ import(${JSON.stringify(entryIdUrl)});
257
316
  ${reExportedFunctions}
258
317
  `
259
318
  );
@@ -367,6 +426,9 @@ function setupOrchestrion(nuxt, hasServerConfig, buildTimeInstrumentation) {
367
426
  if (nuxt.options?._prepare) {
368
427
  return;
369
428
  }
429
+ if (nuxt.options?.dev) {
430
+ return;
431
+ }
370
432
  const isCloudflare = !!nitroConfig.preset?.replace(/-/g, "_").startsWith("cloudflare");
371
433
  if (!hasServerConfig && !isCloudflare) {
372
434
  return;
@@ -759,6 +821,9 @@ var module$1 = defineNuxtModule({
759
821
  addMiddlewareImports();
760
822
  addStorageInstrumentation(nuxt, !isNitroV3);
761
823
  addDatabaseInstrumentation(nuxt.options.nitro, !isNitroV3, moduleOptions);
824
+ if (isNitroV3) {
825
+ addDevServerConfigFile(nuxt, serverConfigFile);
826
+ }
762
827
  }
763
828
  if (clientConfigFile || serverConfigFile) {
764
829
  setupSourceMaps(moduleOptions, nuxt, addVitePlugin);
@@ -803,8 +868,6 @@ var module$1 = defineNuxtModule({
803
868
  }
804
869
  if (serverConfigFile) {
805
870
  addMiddlewareInstrumentation(nitro);
806
- }
807
- if (serverConfigFile?.includes(".server.config")) {
808
871
  consoleSandbox(() => {
809
872
  const serverDir = nitro.options.output.serverDir;
810
873
  if (serverDir.includes(".netlify") || !!process.env.NETLIFY) {
@@ -819,18 +882,21 @@ var module$1 = defineNuxtModule({
819
882
  }
820
883
  });
821
884
  if (moduleOptions.autoInjectServerSentry !== "experimental_dynamic-import") {
822
- addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);
885
+ if (!(isNitroV3 && nitro.options.dev)) {
886
+ addServerConfigToBuild(moduleOptions, nitro, serverConfigFile);
887
+ }
823
888
  if (moduleOptions.debug) {
824
889
  const serverDirResolver = createResolver(nitro.options.output.serverDir);
825
890
  const serverConfigPath = serverDirResolver.resolve("sentry.server.config.mjs");
826
- const serverConfigRelativePath = `.${path.sep}${path.relative(nitro.options.rootDir, serverConfigPath)}`;
891
+ const serverConfigRelativePath = toImportSpecifier(nitro.options.rootDir, serverConfigPath);
892
+ const devConfigRelativePath = isNitroV3 ? toImportSpecifier(nuxt.options.rootDir, path.join(nuxt.options.buildDir, DEV_SERVER_CONFIG_PATH)) : serverConfigRelativePath;
827
893
  consoleSandbox(() => {
828
894
  console.log(
829
895
  `[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/.`
830
896
  );
831
897
  if (nitro.options.dev) {
832
898
  console.log(
833
- `[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.`
899
+ `[Sentry] During development, preload Sentry with the NODE_OPTIONS environment variable: \`NODE_OPTIONS='--import ${devConfigRelativePath}' nuxt dev\`. The file is generated in the build directory (usually '.nuxt'). If you delete the build directory, run \`nuxt prepare\` to regenerate it.`
834
900
  );
835
901
  } else {
836
902
  console.log(
@@ -1,4 +1,5 @@
1
- import { getClient, getCurrentScope, captureException, flushIfServerless } from '@sentry/core';
1
+ import { getClient, getCurrentScope, captureException } from '@sentry/core';
2
+ import { flushIfServerless } from '@sentry/core/server';
2
3
  import { H3Error } from 'h3';
3
4
  import { extractErrorContext } from '../utils.js';
4
5
 
@@ -1,6 +1,7 @@
1
1
  import { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP } from '@sentry/conventions/attributes';
2
2
  import { MIDDLEWARE } from '@sentry/conventions/op';
3
- import { debug, getClient, httpHeadersToSpanAttributes, startSpan, SPAN_STATUS_OK, SPAN_STATUS_ERROR, captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, flushIfServerless } from '@sentry/core';
3
+ import { debug, getClient, httpHeadersToSpanAttributes, startSpan, SPAN_STATUS_OK, SPAN_STATUS_ERROR, captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
4
+ import { flushIfServerless } from '@sentry/core/server';
4
5
 
5
6
  function wrapMiddlewareHandlerWithSentry(handler, fileName) {
6
7
  if (!isEventHandlerObject(handler)) {
@@ -1,4 +1,7 @@
1
- import { debug, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, captureException, flushIfServerless, addBreadcrumb } from '@sentry/core';
1
+ import { DB_SYSTEM_NAME, DB_NAMESPACE, SENTRY_OP, DB_QUERY_SUMMARY, DB_QUERY_TEXT } from '@sentry/conventions/attributes';
2
+ import { DB_QUERY } from '@sentry/conventions/op';
3
+ import { debug, startSpan, getClient, hasSpanStreamingEnabled, DB_SPAN_NAME_FALLBACK, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, captureException, addBreadcrumb } from '@sentry/core';
4
+ import { _INTERNAL_getSqlQuerySummary, _INTERNAL_sanitizeSqlQuery, flushIfServerless } from '@sentry/core/server';
2
5
  import { getDatabaseSpanData } from './database-span-data.js';
3
6
 
4
7
  const patchedStatement = /* @__PURE__ */ new WeakSet();
@@ -27,7 +30,7 @@ function instrumentDatabase(db, config) {
27
30
  return;
28
31
  }
29
32
  const metadata = {
30
- "db.system.name": config?.connector ?? db.dialect,
33
+ [DB_SYSTEM_NAME]: config?.connector ?? db.dialect,
31
34
  ...getDatabaseSpanData(config)
32
35
  };
33
36
  db.prepare = new Proxy(db.prepare, {
@@ -38,7 +41,8 @@ function instrumentDatabase(db, config) {
38
41
  });
39
42
  db.sql = new Proxy(db.sql, {
40
43
  apply(target, thisArg, args) {
41
- const query = args[0]?.[0] ?? "";
44
+ const [strings, ...values] = args;
45
+ const query = strings ? buildSqlTemplateQuery(strings, values) : "";
42
46
  const opts = createStartSpanOptions(query, metadata);
43
47
  return startSpan(
44
48
  opts,
@@ -56,6 +60,18 @@ function instrumentDatabase(db, config) {
56
60
  });
57
61
  db.__sentry_instrumented__ = true;
58
62
  }
63
+ function buildSqlTemplateQuery(strings, values) {
64
+ let query = strings[0] || "";
65
+ for (let i = 1; i < strings.length; i++) {
66
+ const chunk = strings[i] ?? "";
67
+ if (query.endsWith("{") && chunk.startsWith("}")) {
68
+ query = `${query.slice(0, -1)}${values[i - 1]}${chunk.slice(1)}`;
69
+ } else {
70
+ query += `?${chunk}`;
71
+ }
72
+ }
73
+ return query.trim();
74
+ }
59
75
  function instrumentPreparedStatement(statement, query, data) {
60
76
  statement.bind = new Proxy(statement.bind, {
61
77
  apply(target, thisArg, args) {
@@ -127,12 +143,16 @@ function createBreadcrumb(query) {
127
143
  });
128
144
  }
129
145
  function createStartSpanOptions(query, data) {
146
+ const querySummary = query ? _INTERNAL_getSqlQuerySummary(_INTERNAL_sanitizeSqlQuery(query)) : void 0;
147
+ const client = getClient();
148
+ const name = client && hasSpanStreamingEnabled(client) ? querySummary || data[DB_NAMESPACE] || DB_SPAN_NAME_FALLBACK : query;
130
149
  return {
131
- name: query,
150
+ name,
132
151
  attributes: {
133
- "db.query.text": query,
152
+ [DB_QUERY_TEXT]: query,
153
+ [DB_QUERY_SUMMARY]: querySummary,
134
154
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: SENTRY_ORIGIN,
135
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "db.query",
155
+ [SENTRY_OP]: DB_QUERY,
136
156
  ...data
137
157
  }
138
158
  };
@@ -1,6 +1,7 @@
1
- import { SENTRY_OP } from '@sentry/conventions/attributes';
1
+ import { CACHE_OPERATION, SENTRY_OP } from '@sentry/conventions/attributes';
2
2
  import { CACHE_REMOVE, CACHE_PUT, CACHE_GET } from '@sentry/conventions/op';
3
- import { debug, startSpan, SPAN_STATUS_OK, SEMANTIC_ATTRIBUTE_CACHE_HIT, SPAN_STATUS_ERROR, captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, flushIfServerless, SEMANTIC_ATTRIBUTE_CACHE_KEY, isObjectLike } from '@sentry/core';
3
+ import { debug, startSpan, SPAN_STATUS_OK, SEMANTIC_ATTRIBUTE_CACHE_HIT, SPAN_STATUS_ERROR, captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, CACHE_OPERATION_NAMES, SEMANTIC_ATTRIBUTE_CACHE_KEY, getClient, hasSpanStreamingEnabled, isObjectLike } from '@sentry/core';
4
+ import { flushIfServerless } from '@sentry/core/server';
4
5
 
5
6
  const CACHE_HIT_METHODS = /* @__PURE__ */ new Set(["hasItem", "getItem", "getItemRaw", "getItems"]);
6
7
  const METHOD_SPAN_OPS = {
@@ -102,16 +103,21 @@ function wrapStorageMount(storage) {
102
103
  }
103
104
  function createSpanStartOptions(methodName, driver, mountBase, args) {
104
105
  const keys = getCacheKeys(args?.[0], mountBase);
106
+ const cacheOperation = METHOD_SPAN_OPS[methodName];
107
+ const cacheOperationName = CACHE_OPERATION_NAMES[cacheOperation];
105
108
  const attributes = {
106
- [SENTRY_OP]: METHOD_SPAN_OPS[methodName],
109
+ [SENTRY_OP]: cacheOperation,
110
+ [CACHE_OPERATION]: cacheOperationName,
107
111
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.cache.nuxt",
108
112
  [SEMANTIC_ATTRIBUTE_CACHE_KEY]: keys.length > 1 ? keys : keys[0],
109
113
  "db.operation.name": methodName,
110
114
  "db.collection.name": mountBase.replace(/:$/, ""),
111
115
  "db.system.name": driver.name ?? "unknown"
112
116
  };
117
+ const client = getClient();
113
118
  return {
114
- name: keys.join(", "),
119
+ // With span streaming, span names have to be low cardinality, so we can't fall back to the cache keys.
120
+ name: client && hasSpanStreamingEnabled(client) ? cacheOperation : keys.join(", "),
115
121
  attributes
116
122
  };
117
123
  }
@@ -1,4 +1,5 @@
1
- import { getIsolationScope, getDefaultIsolationScope, debug, withIsolationScope, flushIfServerless } from '@sentry/core';
1
+ import { getIsolationScope, getDefaultIsolationScope, debug, withIsolationScope } from '@sentry/core';
2
+ import { flushIfServerless } from '@sentry/core/server';
2
3
 
3
4
  function patchEventHandler(handler) {
4
5
  return new Proxy(handler, {
@@ -1,5 +1,15 @@
1
+ import type { Nuxt } from '@nuxt/schema';
1
2
  import type { Nitro } from 'nitropack';
3
+ import type { InputPluginOption } from 'rollup';
2
4
  import type { SentryNuxtModuleOptions } from '../common/types';
5
+ /** Path of the generated dev-mode config file, relative to the Nuxt build directory. */
6
+ export declare const DEV_SERVER_CONFIG_PATH = "dev/sentry.server.config.mjs";
7
+ /**
8
+ * Writes the file users preload with `node --import` to enable Sentry in `nuxt dev` (for Nuxt 5 with Nitro 3).
9
+ *
10
+ * In dev-mode, Nitro v3 has no server bundle to emit into, so Node loads the server config file as it is written.
11
+ */
12
+ export declare function addDevServerConfigFile(nuxt: Nuxt, serverConfigFile: string): void;
3
13
  /**
4
14
  * Adds the `sentry.server.config.ts` file as `sentry.server.config.mjs` to the `.output` directory to be able to reference this file in the node --import option.
5
15
  *
@@ -20,3 +30,15 @@ export declare function addSentryTopImport(moduleOptions: SentryNuxtModuleOption
20
30
  * See: https://nodejs.org/api/module.html#enabling
21
31
  */
22
32
  export declare function addDynamicImportEntryFileWrapper(nitro: Nitro, serverConfigFile: string, moduleOptions: Omit<SentryNuxtModuleOptions, 'experimental_entrypointWrappedFunctions'> & Required<Pick<SentryNuxtModuleOptions, 'experimental_entrypointWrappedFunctions'>>): void;
33
+ /**
34
+ * A Rollup plugin which wraps the server entry with a dynamic `import()`. This makes it possible to initialize Sentry first
35
+ * by using a regular `import` and load the server after that.
36
+ * This also works with serverless `handler` functions, as it re-exports the `handler`.
37
+ *
38
+ * Only exported for testing.
39
+ */
40
+ export declare function wrapEntryWithDynamicImport({ resolvedSentryConfigPath, experimental_entrypointWrappedFunctions, debug, }: {
41
+ resolvedSentryConfigPath: string;
42
+ experimental_entrypointWrappedFunctions: string[];
43
+ debug?: boolean;
44
+ }): InputPluginOption;
@@ -7,9 +7,11 @@ import type { SentryNuxtModuleOptions } from '../common/types';
7
7
  export declare function getNitroMajorVersion(): Promise<number>;
8
8
  /**
9
9
  * Find the default SDK init file for the given type (client or server).
10
- * The sentry.server.config file is prioritized over the instrument.server file.
11
10
  */
12
11
  export declare function findDefaultSdkInitFile(type: 'server' | 'client', nuxt?: Nuxt, options?: SentryNuxtModuleOptions): Promise<string | undefined>;
12
+ export declare const SERVER_CONFIG_FILENAME = "sentry.server.config";
13
+ /** Builds the value for `node --import`. Node reads it as a URL, so it needs forward slashes on Windows too. */
14
+ export declare function toImportSpecifier(fromDir: string, filePath: string): string;
13
15
  /**
14
16
  * Extracts the filename from a node command with a path.
15
17
  */
@@ -45,6 +47,17 @@ export declare function constructWrappedFunctionExportQuery(exportedBindings: Re
45
47
  * Constructs a code snippet with function reexports (can be used in Rollup plugins as a return value for `load()`)
46
48
  */
47
49
  export declare function constructFunctionReExport(pathWithQuery: string, entryId: string): string;
50
+ /**
51
+ * `load()` emits `file://` specifiers because Node's ESM loader rejects bare Windows
52
+ * paths (`ERR_UNSUPPORTED_ESM_URL_SCHEME`), but Rollup's resolver only understands
53
+ * filesystem paths. Returns `undefined` for a malformed `file://` URL.
54
+ *
55
+ * Only exported for testing.
56
+ */
57
+ export declare function toResolvablePath(source: string): {
58
+ path: string;
59
+ wasFileUrl: boolean;
60
+ } | undefined;
48
61
  /**
49
62
  * Sets up alias to work around OpenTelemetry's incomplete ESM imports.
50
63
  * https://github.com/getsentry/sentry-javascript/issues/15204
@@ -0,0 +1,5 @@
1
+ /** Global flag set by the generated `<buildDir>/dev/sentry.server.config.mjs`. */
2
+ export declare const NUXT_DEV_MODE_FLAG = "__SENTRY_NUXT_DEV_MODE__";
3
+ /** Whether the SDK was preloaded by the generated `nuxt dev` server config file. */
4
+ export declare function isNuxtDevRuntime(): boolean;
5
+ //# sourceMappingURL=devMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devMode.d.ts","sourceRoot":"","sources":["../../../src/common/devMode.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,oFAAoF;AACpF,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
@@ -7,7 +7,6 @@ export * from './index.server';
7
7
  export declare function init(options: Options | SentryNuxtClientOptions | SentryNuxtServerOptions): Client | undefined;
8
8
  export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration;
9
9
  export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration;
10
- export declare const spanStreamingIntegration: typeof clientSdk.spanStreamingIntegration;
11
10
  export declare const startSpan: typeof clientSdk.startSpan;
12
11
  export declare const startSpanManual: typeof clientSdk.startSpanManual;
13
12
  export declare const startInactiveSpan: typeof clientSdk.startInactiveSpan;
@@ -1 +1 @@
1
- {"version":3,"file":"index.types.d.ts","sourceRoot":"","sources":["../../src/index.types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAIjD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAG/B,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,GAAG,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAAC;AACvH,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,wBAAwB,EAAE,OAAO,SAAS,CAAC,wBAAwB,CAAC;AACzF,MAAM,CAAC,OAAO,CAAC,MAAM,SAAS,EAAE,OAAO,SAAS,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,OAAO,CAAC,MAAM,eAAe,EAAE,OAAO,SAAS,CAAC,eAAe,CAAC;AACvE,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAC3E,MAAM,CAAC,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,SAAS,CAAC,cAAc,CAAC;AAErE,MAAM,CAAC,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,SAAS,CAAC,gBAAgB,CAAC;AACzE,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;AACjF,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,WAAW,CAAC;AAErD,MAAM,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAE/E,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB,EAAE,OAAO,SAAS,CAAC,qBAAqB,CAAC;AACnF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,gCAAgC,EAAE,OAAO,SAAS,CAAC,gCAAgC,CAAC;AACzG,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,OAAO,SAAS,CAAC,sBAAsB,CAAC;AACrF,MAAM,CAAC,OAAO,CAAC,MAAM,0BAA0B,EAAE,OAAO,SAAS,CAAC,0BAA0B,CAAC;AAC7F,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAC7E,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.types.d.ts","sourceRoot":"","sources":["../../src/index.types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAIjD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAG/B,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,GAAG,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAAC;AACvH,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,SAAS,EAAE,OAAO,SAAS,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,OAAO,CAAC,MAAM,eAAe,EAAE,OAAO,SAAS,CAAC,eAAe,CAAC;AACvE,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAC3E,MAAM,CAAC,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,SAAS,CAAC,cAAc,CAAC;AAErE,MAAM,CAAC,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,SAAS,CAAC,gBAAgB,CAAC;AACzE,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;AACjF,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,WAAW,CAAC;AAErD,MAAM,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAE/E,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB,EAAE,OAAO,SAAS,CAAC,qBAAqB,CAAC;AACnF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,gCAAgC,EAAE,OAAO,SAAS,CAAC,gCAAgC,CAAC;AACzG,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,OAAO,SAAS,CAAC,sBAAsB,CAAC;AACrF,MAAM,CAAC,OAAO,CAAC,MAAM,0BAA0B,EAAE,OAAO,SAAS,CAAC,0BAA0B,CAAC;AAC7F,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAC7E,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAS9D,MAAM,MAAM,aAAa,GAAG,uBAAuB,CAAC"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAoB9D,MAAM,MAAM,aAAa,GAAG,uBAAuB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"captureErrorHook.d.ts","sourceRoot":"","sources":["../../../../src/runtime/hooks/captureErrorHook.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG5D;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgD5G"}
1
+ {"version":3,"file":"captureErrorHook.d.ts","sourceRoot":"","sources":["../../../../src/runtime/hooks/captureErrorHook.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG5D;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgD5G"}
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentDatabase.d.ts","sourceRoot":"","sources":["../../../../src/runtime/utils/instrumentDatabase.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,KAAK,CAAC;AACvD,OAAO,EAAE,KAAK,wBAAwB,EAA8C,MAAM,sBAAsB,CAAC;AAgBjH;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,EACvC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GACvD,IAAI,CAqBN"}
1
+ {"version":3,"file":"instrumentDatabase.d.ts","sourceRoot":"","sources":["../../../../src/runtime/utils/instrumentDatabase.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,KAAK,CAAC;AACvD,OAAO,EAAE,KAAK,wBAAwB,EAA8C,MAAM,sBAAsB,CAAC;AAiBjH;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,EACvC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GACvD,IAAI,CAqBN"}