@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.
- package/README.md +5 -0
- package/build/cjs/common/devMode.js +12 -0
- package/build/cjs/common/devMode.js.map +1 -0
- package/build/cjs/module.js +9 -5
- package/build/cjs/module.js.map +1 -1
- package/build/cjs/server/sdk.js +2 -2
- package/build/cjs/server/sdk.js.map +1 -1
- package/build/cjs/vite/addServerConfig.js +64 -13
- package/build/cjs/vite/addServerConfig.js.map +1 -1
- package/build/cjs/vite/orchestrion.js +3 -0
- package/build/cjs/vite/orchestrion.js.map +1 -1
- package/build/cjs/vite/utils.js +26 -11
- package/build/cjs/vite/utils.js.map +1 -1
- package/build/esm/common/devMode.js +9 -0
- package/build/esm/common/devMode.js.map +1 -0
- package/build/esm/module.js +11 -7
- package/build/esm/module.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/server/sdk.js +5 -3
- package/build/esm/server/sdk.js.map +1 -1
- package/build/esm/vite/addServerConfig.js +62 -14
- package/build/esm/vite/addServerConfig.js.map +1 -1
- package/build/esm/vite/orchestrion.js +3 -0
- package/build/esm/vite/orchestrion.js.map +1 -1
- package/build/esm/vite/utils.js +24 -12
- package/build/esm/vite/utils.js.map +1 -1
- package/build/module/common/devMode.d.ts +4 -0
- package/build/module/module.json +1 -1
- package/build/module/module.mjs +94 -28
- package/build/module/runtime/hooks/captureErrorHook.js +2 -1
- package/build/module/runtime/hooks/wrapMiddlewareHandler.js +2 -1
- package/build/module/runtime/utils/instrumentDatabase.js +26 -6
- package/build/module/runtime/utils/instrumentStorage.js +10 -4
- package/build/module/runtime/utils/patchEventHandler.js +2 -1
- package/build/module/vite/addServerConfig.d.ts +22 -0
- package/build/module/vite/utils.d.ts +14 -1
- package/build/types/common/devMode.d.ts +5 -0
- package/build/types/common/devMode.d.ts.map +1 -0
- package/build/types/index.types.d.ts +0 -1
- package/build/types/index.types.d.ts.map +1 -1
- package/build/types/module.d.ts.map +1 -1
- package/build/types/runtime/hooks/captureErrorHook.d.ts.map +1 -1
- package/build/types/runtime/utils/instrumentDatabase.d.ts.map +1 -1
- package/build/types/runtime/utils/instrumentStorage.d.ts.map +1 -1
- package/build/types/runtime/utils/patchEventHandler.d.ts.map +1 -1
- package/build/types/server/sdk.d.ts.map +1 -1
- package/build/types/vite/addServerConfig.d.ts +22 -0
- package/build/types/vite/addServerConfig.d.ts.map +1 -1
- package/build/types/vite/orchestrion.d.ts.map +1 -1
- package/build/types/vite/utils.d.ts +14 -1
- package/build/types/vite/utils.d.ts.map +1 -1
- package/package.json +9 -8
package/build/esm/vite/utils.js
CHANGED
|
@@ -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":"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"}
|
|
@@ -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;
|
package/build/module/module.json
CHANGED
package/build/module/module.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { resolvePath, createResolver, useNuxt, addServerPlugin, addServerImports, defineNuxtModule, addPluginTemplate, addPlugin, addVitePlugin
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
232
|
-
|
|
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 &&
|
|
235
|
-
const resolution = await this.resolve(
|
|
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
|
|
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(
|
|
256
|
-
import(${JSON.stringify(
|
|
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
|
-
|
|
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 =
|
|
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 ${
|
|
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
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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
|
|
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
|
|
150
|
+
name,
|
|
132
151
|
attributes: {
|
|
133
|
-
|
|
152
|
+
[DB_QUERY_TEXT]: query,
|
|
153
|
+
[DB_QUERY_SUMMARY]: querySummary,
|
|
134
154
|
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: SENTRY_ORIGIN,
|
|
135
|
-
[
|
|
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,
|
|
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]:
|
|
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
|
-
|
|
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
|
|
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,
|
|
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;
|
|
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":"
|
|
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":"
|
|
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"}
|